How I run my Ghost blog on Docker, with Nginx and MariaDB
In this blog post, I will describe how I set up my blog using:
- : obviously the blogging platform
- : frontend proxy
- : database backend
- ๐: to run the whole thing
Background
I have been wanting to start my personal blog for a while. And after weighing the pros and cons of the different options, I have finally decided to use Ghost for my personal blog, running on a cloud VM on .
Although offers fully managed Ghost infrastructure, it was too expensive for a personal blog as the pricing starts from 29$/month. Besides, I really like getting my hands dirty so I also opted against using the offered by DigitalOcean.
I have decided to use Docker to run the blog stack (Ghost + MariaDB + Nginx) to be able to spin up the blog easily, and also to be able to replicate the same setup locally or anywhere else when needed.
In order to achieve this, I have created the github repository to make it easier to deploy the blog.
In the course of this post, I will describe how you can use my github repository to easily deploy your Ghost blog.
Preparing the setup
If you are only interested in running Ghost locally for testing/experimenting purposes, skip directly to the "Deploying the Ghost blog" section.
As I mentioned earlier in this post, I have opted for running my blog on a Digitalocean Ubuntu 18.04 VM.
In this section, I will describe the steps that I have followed to prepare my setup, which only costs me around 7$/month including the domain name registration.
Register a domain name
Of course, first you need to choose and register a domain name for your blog. There are multiple domain name registrars to choose from such as , or .
I chose to register my myedes.io domain with because that's where I was able to get a good deal for an .io domain for only 25$/year.
Provision a cloud instance
Since this is just personal blog, I wasn't expecting much traffic so a standard 5$/month instance on Digitalocean would do the job. I chose Ubuntu 18.04 for for the OS, but there shouldn't be much difference when choosing another OS since the setup relies on Docker.
If you choose to use Digitalocean for hosting your blog, you can use this and get 100$ of free credits.
You can also enable backups for your instance for 20% of the price, which would cost around 1$/month for a 5$ droplet.
Point to your cloud provider's name servers
Although you can configure this directly through your domain name registrar using your VM's public IP, it's better to point to the cloud provider's name servers and configure the name resolution there.
For the Namecheap + Digitalocean combination, this can be easily configured as described in the 2 links below:
After that, you can point your domain to your cloud instance directly from your cloud hosting provider's dashboard.
You might need to wait for around 24h for the DNS changes to propagate.
Deploying the Ghost blog
In this section, I will describe how you can use the github repository to deploy Ghost.
Pre-requisites
Since everything will be running on Docker, the only dependencies needed are and which they can be installed using the command below on Ubuntu 18.04:
You also need to make sure that your non-root user (here ubuntu) is in the docker group to be able to run docker commands:
I used docker-compose here because it offers an easy way to orchestrate the deployment of multiple Docker containers; in this case: ghost, nginx and MariaDB.
Preparing the environment
First, you need to clone the github on your machine:
The files provided in the github repository contains default configuration which can be used for running ghost locally. However, for running a public blog it must be changed accordingly. In that case, create a .env.prod file and set your configuration there:
The environment variables defined above are used by docker-compose to configure the Docker containers during (re)creation:
Since you don't want to lose your data if the containers die, host folders are needed for storing the blog and the database data. A host folder is also used to store the nginx configuration files to avoid the need for building a custom nginx Docker image.
The folders are created by default under the home directory, and this default Nginx would be used:
It is not recommended to use this default nginx configuration for your public Ghost blog. You'd want to enable SSL encryption for your blog to have that fancy green lock ๐ next to your domain name in the browser, and also to protect your credentials when accessing the Ghost admin panel.
Please check the "Adding SSL Encryption" section in the end of the post to see how you can do that.
Deploying
In order to deploy ghost, you just need to run the script provided in the github repository:
You can see that the containers are now up and running:
By navigating to your VM's public IP address or to (if you are running ghost on your local environment), you should now be able to access your new ghost blog:
Adding SSL Encryption
You'd also like to enable SSL encryption for your blog to avoid your admin credentials from being sent in clear-text over the internet.
Unless you already have your SSL certificate issued, you can achieve this easily with and get a new certificate. However, the validity of the certificates would be only 90 days. But luckily, the certificate renewal can be automated using .
You can install certbot easily and order a new certificate in a matter of minutes:
# Install certbot
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt install certbot python-certbot-nginx
There are several methods for ordering a certificate using certbot, the instructions are provided depending on your OS and choice of webserver. I have opted for the standalone approach because I am running nginx in a container. The certificate and key will be created under /etc/letsencrypt/live/YOUR_DOMAIN/
, so they would need to be copied to your nginx host folder:
Once the files are in place, the nginx which should be under ${NGINX_HOST_PATH}/blog.conf
must be modified now. Since the ${NGINX_HOST_PATH}/
will be mounted inside the container, the certificate and key files will be available in the container under the /etc/nginx/conf.d/ssl/
folder:
It's important to restart the nginx container after updating the configuration file to pick up the changes:
$ docker restart blog_nginx_1
Now you should see that your blog is now serving in HTTPS ๐ :
Conclusion
In this article, I have described how you can run your ghost blog with MariaDB and nginx using Docker. Although it might seem like a lot of work, it all comes down to personal preference in the end. Personally, I like to have full control over my personal blog, and like getting my hands dirty. But this comes at the cost of having to maintain everything on my own, which I don't really mind.
If you want to focus more on the content without spending much time for creating and maintaining your blog, there are other alternatives like where you can directly start writing content after creating your account. Or you can still create your fully-managed but that comes at a price starting from 29$/month.
I hope this article was useful for you. Please feel free to leave a comment below or contact me through my email.