So before I put this site up I couldn't find many good articles or guides on getting Ghost setup with Let's Encrypt. Thankfully I already have a few services that use a similar configuration I've used in the docker-compose file for this blog. I'm just going to go over it a little bit and hopefully somebody else can find this to be helpful.
Ghost conveniently comes with a Docker image. To use this all we need to do is specify it in with the image tag. Aside from that the only real configuration I had to do was set the url env variable to this website's URL. This basically tells Ghost where to refer a user. So if you have it set as localhost for instance, when you clicked Author at the top, or any other hyperlink and you had it set to 'localhost', you'd get redirected to 'localhost/author'.
Next we need to setup the MySQL service, pretty standard stuff. Just use the MySQL image. By default the user created will be root unless you specify otherwise. Ghost will also take care of creating the ghost database for you. Just make sure the password you specify matches the one you've defined in the ghost service above.
db: image: mysql:5.7 restart: always environment: MYSQL_ROOT_PASSWORD: [Redacted] volumes: - db_data:/var/lib/mysql
After you setup ghost and the db all you really have left to do is serve the app. To do so we're going to use Nginx with a nice tool called docker-letsencrypt-nginx-proxy-companion and another called nginx-proxy.
To do so we create three new services. One for the proxy, another for the LetsEncrypt proxy companion, and of course lastly the Nginx.
As you can see above I'm using a proxy.conf here. This is what it looks like:
# START OF DEFAULT SETTINGS # HTTP 1.1 support proxy_http_version 1.1; proxy_buffering off; proxy_set_header Host $http_host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $proxy_connection; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl; proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port; # Mitigate httpoxy attack (see README for details) proxy_set_header Proxy ""; # END OF DEFAULT SETTINGS proxy_read_timeout 300s;
Once we have our proxy and have it configured to be compatible with the Let's Encrypt proxy companion we need to setup the letsencrypt service.
letsencrypt: container_name: letsencrypt environment: - NGINX_PROXY_CONTAINER=proxy image: jrcs/letsencrypt-nginx-proxy-companion restart: always volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - letsencrypt_certs:/etc/nginx/certs - letsencrypt_challenge:/usr/share/nginx/html - letsencrypt_vhosts:/etc/nginx/vhost.d
Configuration is simple enough. Just need to specify the proxy container and the volumes to persist the certificates to. I'd advise you to check out the letsencrypt proxy companion repo more if you're interested in knowing its implementation details.
Once both of these are setup the only thing we have left to do is setup the Nginx service and the volumes for MySQL persistence and the LetsEncrypt certs etc.
First let's start with the Nginx service.
nginx: container_name: nginx depends_on: - ghost environment: - VIRTUAL_HOST=www.hexed.io,hexed.io - LETSENCRYPT_HOST=www.hexed.io,hexed.io - LETSENCRYPT_EMAIL=[Redacted] image: nginx:1.15.6-alpine logging: options: max-size: "200k" max-file: "10" restart: always volumes: - ./default.conf:/etc/nginx/conf.d/default.conf
This is a pretty simple configuration, take note of the environment variables. You can replace these with your own. I believe most settings are pretty clear on what you'd change to your own. Now for the Nginx configuration I'm using.
It's a pretty simple Nginx conf. I don't currently have it setup to handle caching but I'll go over that in a subsequent post when I get around to setting the rest up. For now I didn't really find it necessary, just wanted something to write posts on for now.
The last thing to do is just setup the volumes.
volumes: db_data: letsencrypt_certs: letsencrypt_challenge: letsencrypt_vhosts:
And that's it, now you can deploy your blog on your VPS or cloud granted you have docker setup on your machine. All you should need to do is
docker-compose up -d --build.
Here's a link to the source: