As first post for this new tech blog, I am going to introduce you on how to install Ghost on you very own server, with Docker.


I always create a for each container I want to start, with all the properties in place. This allow me to backup with git, all my containers configuration scripts.

Folder structure

mkdir starters/ghost && cd $_
mkdir data && touch config.js
chmod +x


This file contains the needed configurations for Ghost, like email and the most important, the host. If you need more details, check this.

Be sure to change mail.options.auth.pass and url fields.

// # Ghost Configuration
// Setup your Ghost install for various [environments](

// Ghost runs in `development` mode by default. Full documentation can be found at

var path = require('path'), config;

config = {
    // ### Production
    // When running Ghost in the wild, use the production environment.
    // Configure your URL and mail settings here
    production: {
        url: '',
        database: {
            client: 'sqlite3',
            connection: {
                filename: path.join(process.env.GHOST_CONTENT, '/data/ghost.db')
            debug: false

        server: {
            host: '',
            port: '2368'

        mail: {
              transport: 'SMTP',
              options: {
                  service: 'Mailgun',
                  auth: {
                      user: '', // mailgun username
                      pass: '<password here>'  // mailgun password

module.exports = config;

Put the following script in your config.js.

replace the port 8080 with the one you want use. do the very same for the --name

docker run -d \
  --restart=always \
  -v $PWD/data:/var/lib/ghost/data \
  -v $PWD/config.js:/var/lib/ghost/config.js \
  -p 8080:2368 \
  --name \
  ghost:latest \
  /bin/bash -c 'npm start --production'

first run

simple as


Check everything is working as expected:

docker logs -f

> ghost@0.11.4 start /usr/src/ghost
> node index

Ghost is running in production...
Your blog is now available on
Ctrl+C to shut down

backup your blog

You can do daily backup the data folder, which contains the ghost.db sqlite database file.


The last thing to do, is to let your Nginx proxy the requests to the backend. This is a simple configuration file you will put in your /etc/nginx/sites-available/ Remember to set server_name with your domain and to set the right port in proxy_pass

server {
  listen                *:80;

  server_name ;

  access_log            /var/log/nginx/blog.access.log;
  error_log             /var/log/nginx/blog.error.log;

  location / {
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade; 
    proxy_set_header Connection 'upgrade';
    proxy_set_header X-Forwarded-For $remote_addr;

Now go to /etc/nginx/sites-enabled/ and do

ln -s ../sites-available/
/etx/init.d/nginx restart


If not already done, configure your DNS to point to the server' public IP.