Ghost Blog on Docker Swarm

Ghost Blog on Docker Swarm

Here's a quick starter to running Ghost on Docker Swarm behind Traefik and using external volume for data persistence (e.g. using REX-Ray to mount external volume). This will create a container running Ghost, animate it using environmental variables so that you don't have to taint the container with non-transient config, and persist your data (SQLite DB, uploaded photos, etc) to an external volume. Check out REX-Ray to mount external volumes. I used the Digital Ocean driver to mount DO's Block Storage. Block Storage offers higher availability than using a volume on the Docker host. And using REX-Rey allows Docker to dynamically mount the volume regardless of which node my containers deploy to.

Docker Stack file:

version: "3"
  
services:
  ghost:
    image: ghost
    networks:
      - traefik-net
    environment:
      - NODE_ENV=production
      - url=https://<your-domain-here>.com
      - mail__transport=SMTP
      - mail__options__service=Mailgun
      - mail__options__auth__user=<your-mailgun-username-here>
      - mail__options__auth__pass=<your-mailgun-password-here>
    volumes:
      - ghost-volume:/var/lib/ghost/content
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
      labels:
        - "traefik.enable=true"
        - "traefik.port=2368"
        - "traefik.docker.network=traefik-net"
        - "traefik.frontend.rule=Host:<your-domain-here>.com"

volumes:
  ghost-volume:
    external: true

networks:
  traefik-net:
    external: true

Then in Docker using Swarm to create a stack:

docker stack deploy -c harvestnextdoor.yml harvestnextdoor

You should be able to do something similar to this if you are using Docker Compose instead of Swarm.

Note that Ghost environmental variables that are nested require double underscores to represent the nesting. So when Ghost recommends the following in your config.production.json file:

"mail": {
    "transport": "SMTP",
    "options": {
        "service": "Mailgun",
        "auth": {
            "user": "[email protected]",
            "pass": "1234567890"
        }
    }
}

You can use these environmental variables in your stack file:

    environment:
      - mail__transport=SMTP
      - mail__options__service=Mailgun
      - [email protected]
      - mail__options__auth__pass=1234567890