Ghost-CLI: Add Unix socket support for speed and performance


#1

From How Fast Are Unix Domain Sockets? | Linux.com:

The Unix socket implementation can send and receive more than twice the number of messages, over the course of a second, when compared to the IP one.

Of course the increased speed and performance with Unix sockets instead of ports, etc. is only important for high traffic sites, because Ghost is already very fast. But in any case it’s nice to have it for possible traffic spikes.

Magentaize wrote (Ghost-CLI issue #417):

if I use NODE_ENV=production node current/index.js to start ghost, all things work properly, but if I use ghost start to start ghost, I cannot access my site and nginx says it cannot connect to socket (using the same config file).

Yes, Ghost works well with Unix sockets (see docs Unix Sockets - Config - Ghost Dodumentation, article Binding Ghost To A Unix Domain Socket - Igu.io, file core/server/ghost-server.js, etc.). The only problem is

ghost start

and

ghost restart

not yet supporting Unix sockets.

Apart from the one mentioned by Magentaize, another quick workaround (on Ubuntu 16.04) without restarting the server is to call the systemd service file created by Ghost-CLI, something like /etc/systemd/system/ghost_example-com.service, with:

sudo service ghost_example-com start

or

sudo service ghost_example-com restart

To test Unix sockets by modifying the default files created by Ghost-CLI, a very simple configuration that works well is the following.

In Ghost’s /var/www/ghost/config.production.json, replace

  "server": {
    "port": 2368,
    "host": "127.0.0.1"
  },

with

  "server": {
    "socket": {
      "path": "/tmp/ghost.socket",
      "permissions": "0660"
    }
  },

In Nginx’s /var/www/ghost/system/files/example.com.conf, replace

proxy_pass http://127.0.0.1:2368;

with

proxy_pass http://unix:/tmp/ghost.socket;

You can test the Nginx change:

sudo nginx -t

Also, if using socket permissions 0660 (which are Ghost’s default, so that the above permissions line is optional), then the Nginx user (usually www-data) should be aded to the ghost group, the socket owner:

sudo gpasswd -a www-data ghost

For this group assignment to take effect, there are various ways with no need to restart the server, that of course also would work.

Remember to reload the Nginx configuration and restart Ghost:

sudo nginx -s reload
sudo service ghost_example-com restart

Magentaize’s different configuration (#417) should equally work.

About a possible Ghost-CLI enhancement for Unix sockets, users can easily adapt the configuration files created by Ghost-CLI as explained above, but if ghost start and ghost restart, rather than giving error “Port is required” would directly use Ghost’s systemd service file when it exists, then I think just this would be enough to complete the already working Unix socket support for increased speed and performance.


#2

I used to do the unix socket thing with Ghost 0.x versions, but when I bit the bullet and (eventually) migrated to Ghost 1.x, it was too much faff to work around the lack of support from ghost-cli, unfortunately.
I persisted for a bit at first, using methods similar to those you’ve stated above, but when I enquired (on the Slack channel) about support for unix sockets, the feedback was essentially that it was a rarely-used option and probably wouldn’t be supported by ghost-cli anytime soon. A little disappointing to those of us who had used sockets successfully before ghost 1.0, but not surprising given that it’s not widely-used functionality.

On a brighter note though: my personal view is that the performance gains from using sockets are negligible compared to those you can get via some careful nginx performance tuning and/or implementing caching. With some careful nginx tuning, I was able to reach around 1.5k responses per second using the ab performance testing tool, even on a Raspberry Pi 2 (or roughly 150 per second when using TLS/HTTPS). Without optimising nginx config (when everything goes to origin/ghost itself) I could only manage about 7 responses per second - or perhaps 12 with unix sockets - on such modest hardware.
Also, a lot of people nowadays use CloudFlare or similar CDN services in front of their ghost server, which again dilutes any benefits of using a unix socket between ghost and nginx at origin. :slight_smile:


#3

It depends on the situation. For example integrating dynamic/interactive features from external applications there is less caching, etc. As I mentioned, given the lightning speed that Ghost has by default, in normal cases it’s not necessary to maybe duplicate it with Unix sockets. But for some it’s always nice to be able to do all they can for performance, preventing possible high traffic spikes, solving odd problems with sometimes occupied ports, simplifying multiple site setups, etc.

Anyhow, Unix sockets work well with Ghost. It’s just that, for starting/restarting, a little longer command is needed at this moment, or maybe a short shell script, simply calling the systemd service file. Not a high priority to solve, of course. The rest is OK. :slightly_smiling_face:

Thanks for your really interesting performance data.