Ghost is an open-source blogging platform written in Javascript for Node.js. It ships with a brilliant interface for creating professional looking blog entrees. The following instructions can be used to setup and manage a Ghost instance on your own Linux server in a very simple and proper way. In this tutorial, we will use Docker and Nginx to manage the Node environment. Nginx will be used for serving static content like images and CSS files as well as forwarding relevant HTTP requests to the Ghost process. Docker is used to easily contain the Ghost process and its dependencies as well as offer simple installation.

Installing Docker and Nginx

This is very much dependent on the package manager you use. For Ubuntu, installing these programs is as simple as:

sudo apt-get install nginx

After installation, make sure both daemons are running and working properly. To do so on a Linux system running Systemd, execute:

systemctl status docker nginx

Building the Ghost Docker Container

We will be exposing a directory on the host for the Docker container to persistently store the Ghost data files. This directory will hold everything from the SQLite database to the static files that we want Nginx to serve. Create the directory using the following command:

sudo mkdir -p /var/lib/ghost/

Next, we create our Ghost Docker image.

sudo docker create -p 2368:2368 --name ghost -v /var/lib/ghost/:/var/lib/ghost --restart=always ghost

This command builds a docker container called "ghost" using the official Ghost Docker image as its base. Port 2368 will be bound on the host system for the Ghost process. The data directory we created earlier is linked to the same path in the Docker container. Also, we instruct the container to restart itself if the process crashes or if the system is rebooted. Once the create command is complete, you may inspect /var/lib/ghost/ on the host to view the directory structure.

  • /var/lib/ghost/config.js - The main Ghost configuration file used to specify domain, port, and mail settings.
  • /var/lib/ghost/images/ - The directory which holds all uploaded images.
  • /var/lib/ghost/themes/ - The directory which holds static assets such as the Mustache templates, CSS files and front-end Javascript files.
  • /var/lib/ghost/data/ghost-dev.db - The Sqlite3 database that holds persistent data such as posts, users, and tags.

At this point, you have completed the Ghost installation. Congratulations! Treat yourself to a nice cold beer or a freshly brewed cup of coffee or tea as DevOps undoubtedly makes a person thirsty.

Configuring Nginx

Nginx offers excellent performance for serving static files. We could let the Node process serve these files but it would be difficult to configure compression, file expiration, as well as forwarding HTTP requests to the Ghost process in the way we want. Also, Nginx is used by many companies in these exciting days of cloud computing and is a great technology to put on your resume!

Lets create the following file to configure Nginx:

sudo vim /etc/nginx/sites-available/ghost

server {
    listen 80;
    access_log /var/log/nginx/ghost.log;

    location /blog/ {
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   Host      $http_host;

    location /blog/assets/ {
        alias /var/lib/ghost/themes/casper/assets/;
        autoindex off;

        sendfile on;
        sendfile_max_chunk 1m;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;

        gzip on;
        gzip_comp_level 2;
        gzip_proxied expired no-cache no-store private auth;
        gzip_types *;
        gzip_vary on;

        expires 365d;

    location /blog/content/images/ {
        alias /var/lib/ghost/images/;
        autoindex off;

        sendfile on;
        sendfile_max_chunk 1m;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;

        expires 365d;

Be sure to change server_name to your host. In this configuration file, we are specifying the Ghost instance URL to be located at HTTP requests on port 80 will be forward to our Ghost Node server. We also specify our compression, expiration, and location of the static files.

Create a symbolic link in sites-enabled to enable the Nginx configuration file:

sudo ln -s /etc/nginx/sites-available/ghost /etc/nginx/sites-enabled/ghost

At this point, we can reload Nginx to apply our new configuration:

sudo nginx -s reload

Starting the Docker Container

Starting our Ghost process is as simple as:

sudo docker start ghost

It will take a few seconds for the Node server to initialize after this command exits successfully before it will serve content. Go to (replacing with your domain) to see your brand new blogging interface!


We have successfully setup a Docker container for Ghost and Nginx to serve our static files.