Setting up ghost blog in 5 minutes with ssl auto renewal support (docker compose, nginx)

Here is how i setup my ghost blog up in 5 minutes by using docker compose to spin up several containers, the ghost blog itself, nginx which will act as a reverse proxy and docker gen and acme-companion containers, which will help me to auto renew my ssl certificate

Prerequisites

  • A virtual machine with docker and docker compose installed (in this example, i am using docker compose v2)
  • A purchased domain name
  • Port 80 and 443 exposed to the internet so that auto renewal will work
  • Ghost js requirements met for the virtual machine

Instructions

ssh into the machine and create the two folders by running the following commands

mkdir ~/ghost
mkdir ~/nginx

After which, create a file called docker-compose.yml in the ghost directory and populate its contents with this

version: "3.5"

networks:
  nginx_proxy:
    external: true
    name: nginx_proxy
  ghost:

services:
  ghost-db:
    container_name: ghost-db
    image: mysql:8
    restart: unless-stopped
    networks:
      - ghost
    volumes:
      - ghost-db:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: <<DATABASE_PASSWORD>>

  ghost:
    container_name: ghost
    image: ghost:5-alpine
    restart: unless-stopped
    networks:
      - nginx_proxy
      - ghost
    security_opt:
      - label:type:docker_t
    volumes:
      - ghost-content:/var/lib/ghost/content
    expose:
      - 2368
    environment:
      VIRTUAL_HOST: <<DOMAIN_NAME>>
      VIRTUAL_PORT: 2368
      LETSENCRYPT_HOST: <<DOMAIN_NAME>>
      url: https://<<DOMAIN_NAME>>
      database__client: mysql
      database__connection__host: ghost-db
      database__connection__user: root
      database__connection__password: <<DATABASE_PASSWORD>>
      database__connection__database: ghost
      mail__transport: "SMTP"
      mail__options__host: "email-smtp.us-east-1.amazonaws.com"
      mail__options__port: "465"
      mail__options__service: "SES"
      mail__options__auth__user: <<MAIL_USER_NAME>>
      mail__options__auth__pass: <<MAIL_USER_PASSWORD>>

volumes:
  ghost-content:
  ghost-db:

make sure to replace the <<DATABASE_PASSWORD>>, <<DOMAIN_NAME>>, <<MAIL_USER_NAME>>, <<MAIL_USER_PASSWORD>> with your own preferred values

For email support, i am using aws ses which is a paid service, you may wish to use other providers, to do that, please refer to the documentation for configuring ghost here

Now, create a file called docker-compose.yml in the nginx directory and populate its contents with this

version: "2"

networks:
  proxy:

services:
  nginx-proxy:
    image: nginx:alpine
    container_name: nginx-proxy
    restart: always
    networks:
      - proxy
    ports:
      - "80:80"
      - "443:443"
    security_opt:
      - label:type:docker_t
    volumes:
      - conf:/etc/nginx/conf.d
      - vhost:/etc/nginx/vhost.d
      - html:/usr/share/nginx/html
      - certs:/etc/nginx/certs:ro

  docker-gen:
    image: nginxproxy/docker-gen
    container_name: nginx-proxy-gen
    restart: always
    networks:
      - proxy
    security_opt:
      - label:type:docker_t
    command: -notify-sighup nginx-proxy -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
    volumes_from:
      - nginx-proxy
    volumes:
      - ./nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro
      - /var/run/docker.sock:/tmp/docker.sock:ro
    labels:
      - "com.github.jrcs.letsencrypt_nginx_proxy_companion.docker_gen"

  acme-companion:
    image: nginxproxy/acme-companion
    container_name: nginx-proxy-acme
    restart: always
    networks:
      - proxy
    security_opt:
      - label:type:docker_t
    environment:
      DEFAULT_EMAIL: <<LETSENCRYPT_EMAIL>>
    volumes_from:
      - nginx-proxy
    volumes:
      - certs:/etc/nginx/certs:rw
      - acme:/etc/acme.sh
      - /var/run/docker.sock:/var/run/docker.sock:ro

volumes:
  conf:
  vhost:
  html:
  certs:
  acme:

make sure to replace the <<LETSENCRYPT_EMAIL>> with your preferred email to be registered with letsencrypt

Finally, download the file nginx.tmpl from this url and ensure it is placed in the nginx directory

Change the file permissions of the nginx.tmpl file by running the following command

chmod 664 nginx.tmpl

Starting your services

once all done, you can start your service by running the following commands

sudo docker compose -f ~/nginx/docker-compose.yml up -d
sudo docker compose -f ~/ghost/docker-compose.yml up -d

Hope this helped! Leave a comment or a like if you enjoyed this tutorial and would like to see more!