Run Ghost inside a Docker container on DigitalOcean
Tags: howto, tutorials, digitalocean, ghost
Published: 2019-04-01 20:55:56

---
title: Run Ghost inside a Docker container on DigitalOcean
published: true
tags: how to,tutorials,digitalocean,ghost
canonical_url: https://stefancosma.xyz/2019/04/01/run-ghost-inside-docker-container-digitalocean/
---

Recently I created a new theme for Ghost, that you can find [here](https://github.com/stefanbc/Asgar) and can currently experience on my [website](https://stefancosma.xyz). I wanted a way of showing it off, so anyone that wants to contribute to it or just plain use it, can get a feel of what it looks like in a live environment.

Initially I looked at Heroku, but I soon fell into a rabbit hole of errors, because Docker doesn't play nice with Heroku and I didn't like that I would have to jump through hoops just to keep the app online. Keep in mind that this is an open source project and having to pay for keeping the Heroku app was not something I was prepared to do at that moment.

But, Stefan, you already have a server, where you host your website! Why don't you use that? Initially, I wanted to keep my server clean off other systems and just use it for my website. I changed my mind and here we are.

Enough backstory, let's get to the actual implementation. Bellow is my current stack and the process I followed that works for my setup. It may work differently for you and your stack.

My whole stack is like this:

1. I have the `stefancosma.xyz` domain registered and I use Cloudflare as a DNS provider.
2. The website itself is hosted on a DigitalOcean droplet, that runs their Ghost image (an older version but I keep it up to date).

Nothing fancy, right?

So, the first thing I did was to get Docker working on my droplet. After running `apt-get update` I installed Docker using this:

```
apt-get install docker.io
```

Once that was done, I just spun up a new Docker container for Ghost. Luckily there is already a Docker image for Ghost. You can check it out [here](https://hub.docker.com/_/ghost).

Now the tricky part. I ran this command to expose the Ghost instance in the Docker container, to the outside world.

```
docker run -d --name name_your_container -p 3001:2368 -e url=https://ghost_url ghost
```

So, what this command does, is that it runs a new container with a custom name and it exposes the Ghost port `2368` on the host's `3001` port. Of course you can use a different port on your machine, if you so desire. Another cool thing is that this Docker image accepts, as parameters, any Ghost configuration parameters, found [here](https://docs.ghost.org/concepts/config/). The Docker image name is `ghost`.

So now, if you access your droplets IP followed by the `3001` port, you should see a new Ghost instance up and running.

The last thing I did was to spin up a new subdomain inside Nginx and add it to Cloudflare. The configuration I used for Nginx is similar to the one bellow:

```
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name subdomain.domain.com;

    ssl_certificate certificate.cert;
    ssl_certificate_key key.key;
    include conf.conf;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_pass http://127.0.0.1:3001;

    }

    location ~ /.well-known {
        allow all;
    }

    client_max_body_size 50m;
}
```
Besides the above configuration, I've added a CNAME record with the subdomain name that points to the root domain.

And that's it. All good and done.

Nothing out of the ordinary. How would you have done it differently? Tweet [@stefanbc](https://twitter.com/stefanbc) or email me [hello@stefancosma.xyz](mailto:hello@stefancosma.xyz).

Until next time, code long and prosper.