/ Ghost

Deploying Ghost with Docker to Vultr

I used to have Ghost deployed on OpenShift for free, but unfortunately recently they decided to shut down their OpenShift Online v2 and their v3 in the free variant does not offer enough to run Ghost anymore, and the paid option is too expensive. So I decided to search for a new place for my blog. I wanted to eliminate all solutions that required a unique deploying process as it was a case for OpenShift, so I searched for a traditional VPS. In the past, I played with Docker, and I liked it, so I decided I want to deploy Ghost with Docker.

There are many VPS providers, but I wanted something that might integrate a bit with Docker. After reading some benchmarks and evaluations I decided for Vultr that offered a great value and performance for the price. There is also a Docker Machine driver plugin for Vultr.

Provisioning and deploying

After creating an account with Vultr, you need to install Docker and the driver for Docker Machine.

brew install docker-machine-driver-vultr

In a case, you are not using macOS you might want to follow the instructions on the driver page.

Once you got the driver, it is time to provision a new machine. You will need to get your API key from the Vultr control panel and pass that to docker-machine create with the --vultr-api-key option. You might also want to pass a plan and a location that you want. You can find all locations and plans on this website. Once you have that, it is time to provision the machine.

docker-machine create --driver vultr --vultr-api-key=abc123 --vultr-region-id 9 --vultr-plan-id 201 ghost-machine

It will take some time, and once it finishes you can make the machine active in Docker Machine.

eval $(docker-machine env ghost-machine)

Once that is done it is time to create docker-compose.yml.

version: '3.2'

# It makes sure all containers share one network so they can connect to each other (Ghost connects to a database).
        image: ghost:1.12.0
        container_name: ghost
        # This will make sure the container is started after the server reboots.
        restart: always
          - db
        # This will make Ghost accessible outside on port 8080.
          - 8080:2368
        # This will store all uploaded images in a dedicated volume that survives a restart.
          - ghost-images:/var/lib/ghost/content/images
          # Configuring Ghost with env variables.
          # https://docs.ghost.org/v1/docs/config#section-running-ghost-with-config-env-variables
          # It might be desired to configure also a mail service.
          url: "http://your-domain.com"
          database__client: mysql
          database__connection__host: db
          database__connection__user: ghost
          database__connection__password: ghost
          database__connection__database: ghost
          # A host used by nginx-proxy.
          VIRTUAL_HOST: "your-domain.com"
        image: mysql:5.7
        container_name: mysql-ghost
        restart: always
            # This will make root user not accessible until it is set up.
            MYSQL_ONETIME_PASSWORD: "yes"
            # These credentials are not very important because MySQL will not be accessible outside of the service.
            MYSQL_USER: ghost
            MYSQL_PASSWORD: ghost
            MYSQL_DATABASE: ghost
          - ghost-mysql:/var/lib/mysql
    # It makes sure Ghost is accessible from your-domain.com.
        image: jwilder/nginx-proxy
        container_name: nginx-proxy
        restart: always
          - 80:80
          - /var/run/docker.sock:/tmp/docker.sock:ro

# All used volumes need to be defined.

After that it is simple.

docker-compose up -d

And it will start downloading images on the machine and after a few seconds once everything boots up you will be able to access Ghost on the machine IP address with the port 8080.

You might want to play a bit more with a configuration and make sure you set up DNS records if you desire to use a virtual host, and it might be worth also to configure a mail service for Ghost and other options that are available.

That was easy, wasn't it? You can also do all this on your computer without deploying it anywhere.

Tomáš Linhart

Tomáš Linhart

Principal iOS Engineer at Lesson Nine GmbH • Swift & iOS and Mac lover and enthusiast •  • A bit .NET, Android lover...

Read More