At the risk of giving away details which will hurt me, here's the stackup I'm running:
Traefik as a reverse-proxy, Ghost running in a docker instance
Here's my file tree:
Home:
Docker:
ghost-blog:
docker-compose.yml
data:
config.production.json
content:
traefik:
data:
acme.json
config.yml
traefik.yml
Here's the docker-compose configuration that worked for me, with obvious redactions: (I mostly followed https://www.benjaminrancourt.ca/a-complete-traefik-configuration/
version: "3"
services:
traefik:
image: traefik:latest
container_name: traefik
restart: unless-stopped
networks:
- proxy
ports:
- 80:80
- 443:443
environment:
- NAMECHEAP_API_USER=fromNamecheap
#I use namecheap for my domain
- NAMECHEAP_API_KEY=FromNamecheap
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./data/config.yml:/config.yml:ro #maybe dynamic? Def external
- ./data/traefik.yml:/traefik.yml:ro #statc
#Where the certificates are installed
- ./data/acme.json:/acme.json
labels:
- 'traefik.enable=true'
# create a router called traefik that matches all hosts that are in the backticks
- 'traefik.http.routers.traefik.rule=Host(`traefik.access.url`)' #Update to your domain
# Listen for https
- "traefik.http.routers.traefik.entrypoints=https"
- "traefik.http.routers.traefik.tls=true"
#Use the resolver name from the traefik.yml
- "traefik.http.routers.traefik.tls.certresolver=letsEncrypt"
- "traefik.http.routers.traefik.service=api@internal"
# Make the traefik router point to the middleware called traefik-auth
- "traefik.http.routers.traefik.middlewares=traefik-auth"
#And make a traefik-auth middleware to handle this
#Geneate this string with echo $(^Cpasswd -nb username password) | sed -e s/\\$/\\$\\$/g
- "traefik.http.middlewares.traefik-auth.basicauth.users=admin:$$hash."
whoami:
#Create a simple whoami service that will just show that everything is working
image: traefik/whoami
labels:
- "traefik.enable=true"
# Make a router called whoami, that matches the URL in the backticks
- "traefik.http.routers.whoami.rule=Host(`whoami.access.url`)"
- "traefik.http.routers.whoami.entrypoints=http"
networks:
- proxy
#Use the network proxy for everything, you need to create this with docker network create proxy
networks:
proxy:
external: true
Here's my traefik.yml:
## traefik.yml
# Docker configuration backend
providers:
docker:
defaultRule: Host(`{{ normalize .Name }}.ab1tj.com`)
entryPoints:
http:
address: ":80"
https:
address: ":443"
certificatesResolvers:
letsEncrypt:
acme:
email: email@email.com
storage: "/acme.json"
httpChallenge:
entrypoint: http
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
file:
filename: /config.yml
api:
#Make sure the dashboard is secure
dashboard: true
insecure: false
#This is needed to route both http and https to external services
serversTransport:
insecureSkipVerify: true
And finally the config.yml, only needed for external services (IE not in docker)
http:
routers:
router-ext:
entryPoints:
- https
rule: Host(`external.ab1tj.com`)
tls:
certResolver: letsEncrypt
service: service-ext
router-ext-http:
entryPoints:
- http
rule: Host(`external.ab1tj.com`)
service: service-ext-http
services:
service-ext:
loadBalancer:
servers:
- url: "https://192.168.1.1"
service-ext-http:
loadBalancer:
servers:
- url: "http://192.168.1.1"
And my ghost docker-compose file: (I mostly followed https://tech.aufomm.com/deploy-ghost-with-docker-and-traefik-2/ )
version: '3.7'
services:
ghost:
image: ghost:4-alpine
container_name: ghost
environment:
NODE_ENV: production
volumes:
- ./data/content:/var/lib/ghost/content
- ./data/config.production.json:/var/lib/ghost/config.production.json
networks:
- proxy
restart: always
labels:
- "traefik.enable=true"
- "traefik.http.routers.ghost.entrypoints=http"
- "traefik.http.routers.ghost.rule=Host(`ab1tj.com`)"
- "traefik.http.middlewares.ghost-https-redirect.redirectscheme.scheme=https"
- "traefik.http.routers.ghost.middlewares=ghost-https-redirect"
- "traefik.http.routers.ghost-secure.entrypoints=https"
- "traefik.http.routers.ghost-secure.rule=Host(`ab1tj.com`)"
- "traefik.http.routers.ghost-secure.tls=true"
- "traefik.http.routers.ghost-secure.tls.certresolver=letsEncrypt"
- "traefik.http.routers.ghost-secure.service=ghost"
- "traefik.http.services.ghost.loadbalancer.server.port=2368"
- "traefik.docker.network=proxy"
networks:
proxy:
external: true
And the ghost directory/data/config.json:
{
"url": "https://ab1tj.com",
"server": {
"port": 2368,
"host": "0.0.0.0"
},
"database": {
"client": "sqlite3",
"connection": {
"filename": "/var/lib/ghost/content/data/ghost.db"
}
},
"mail": {
"transport": "Direct"
},
"logging": {
"path": "/var/lib/ghost/content/logs/",
"level": "info",
"rotation": {
"enabled": true,
"count": 15,
"period": "1d"
},
"transports": ["stdout", "file"]
},
"paths": {
"contentPath": "/var/lib/ghost/content"
}
}
This config seems to work freaking great, I have external stuff running, I have docker instances running, the only thing that is missing right now is www.ab1tj.com doesn't work, there's a weird middleware thing that needs to be done. I'll be posting that when I figure it out!