/services/ghost/
└── docker-compose.yml

πŸ’‘
Replace every "BLOG.YOURHOSTNAME.TLD".
version: '3'

services:
  ghost:
    image: ghost:5
    restart: always
    networks:
      - proxy
      - default
    labels:
      - traefik.enable=true
      - traefik.http.routers.blog.rule=Host(`BLOG.YOURHOSTNAME.TLD`)
      - traefik.http.routers.blog.tls=true
      - traefik.http.routers.blog.tls.certresolver=le
      - traefik.http.services.blog.loadbalancer.server.port=2368
      - traefik.docker.network=proxy
    environment:
      # see https://ghost.org/docs/config/#configuration-options
      url: https://BLOG.YOURHOSTNAME.TLD
      database__client: mysql
      database__connection__host: db
      database__connection__database: ghost
      database__connection__user: ghost
      database__connection__password: "${MYSQL_PASSWORD}"
      mail__transport: "${MAIL_TRANSPORT}"
      mail__options__host: "${MAIL_HOST}"
      mail__options__port: "${MAIL_PORT}"
      mail__options__auth__user: "${MAIL_USER}"
      mail__options__auth__pass: "${MAIL_PASSWORD}"
    volumes:
      - ghost-data:/var/lib/ghost/content
    links:
      - db

  db:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_RANDOM_ROOT_PASSWORD: "yes"
      MYSQL_DATABASE: ghost
      MYSQL_USER: ghost
      MYSQL_PASSWORD: "${MYSQL_PASSWORD}"
    cap_add:
      - SYS_NICE
    volumes:
      - ghost-db:/var/lib/mysql

networks:
 proxy:
   external: true

volumes:
  ghost-data:
  ghost-db:

/services/ghost/
└── .env

#MYSQL
MYSQL_PASSWORD=xxxxxxxxxxxx

#MAIL
MAIL_TRANSPORT=SMTP
MAIL_USER=
MAIL_PASSWORD=
MAIL_HOST=
MAIL_PORT=587

/services/traefik/
└── docker-compose.yml

πŸ’‘
Replace "YOUR@EMAIL.ADRESS" with your own.
version: '3'

services:

    traefik:
        container_name: traefik
        image: traefik:v2.7
        command:
            - "--accesslog=true"
            - "--providers.docker=true"
            - "--entryPoints.web.address=:80"
            - "--entryPoints.websecure.address=:443"
            - "--certificatesResolvers.le.acme.email=YOUR@EMAIL.ADRESS"
            - "--certificatesResolvers.le.acme.storage=acme.json"
            - "--certificatesResolvers.le.acme.tlsChallenge=true"
            - "--certificatesResolvers.le.acme.httpChallenge=true"
            - "--certificatesResolvers.le.acme.httpChallenge.entryPoint=web"
        restart: always
        ports:
            - 80:80
            - 443:443
        networks:
            - proxy
        volumes:
            - /var/run/docker.sock:/var/run/docker.sock
            - ./certs/acme.json:/acme.json
        labels:
            #### set core configs
            - "traefik.enable=true"

            #### set TLS
            - "traefik.http.routers.traefik.tls=true"
            - "traefik.http.routers.traefik.entrypoints=websecure"
            - "traefik.http.routers.traefik.tls.certresolver=le"

           #### set a rule to redirect all http requests to https
            - "traefik.http.routers.http-catchall.entrypoints=web"
            - "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
            - "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
            - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"

networks:
  proxy:
    external: true

How to setup Ghost 5.x on Linux using Docker and Traefik with letsencrypt