How To: Run Orcpub Docker and Traefik 2.x - Orcpub/orcpub GitHub Wiki
Using Orcpub with Docker and Traefik 2.x with LetsEncrypt against CloudFlare's DNS challenge.
This assumes you have a working docker environment with:
- Domain is on CloudFlare
- Traefik 2.x
- Docker
See the documentation if you want to use other acme providers for issuing certificates automatically.
https://doc.traefik.io/traefik/https/acme/#providers
First you will have to create a couple network for the containers.
docker network create -d overlay --attachable postfix
docker network create -d overlay --attachable orcpub-network
Create your CloudFlare API key if you don't have one already
https://support.cloudflare.com/hc/en-us/articles/200167836-Managing-API-Tokens-and-Keys
Traefik 2.x compose file
Edit the file to match your environment
version: '3.3'
services:
reverse-proxy:
image: traefik:v2.3.4
restart: always
command:
# Optional debug levels for Traefik
#- --log.level=DEBUG
- --log.level=INFO
# http listener
- --entrypoints.web.address=:80
- --entryPoints.web.forwardedHeaders.insecure=true
# https listener
- --entrypoints.websecure.address=:443
- --entryPoints.websecure.forwardedHeaders.insecure=true
- --providers.docker.endpoint=unix:///var/run/docker.sock
# If running on a docker swarm
#- --providers.docker.swarmMode=true
- --providers.docker.exposedbydefault=false
- --providers.docker.network=traefik-public
# Traefik Dashboard
- --api=false
- --api.dashboard=true
# Letsencrypt resolvers for DNS Challenge
# https://doc.traefik.io/traefik/https/acme/#providers
- --certificatesresolvers.letsencryptresolver.acme.email=<[email protected]>
- --certificatesresolvers.letsencryptresolver.acme.storage=/letsencrypt/acme.json
- --certificatesresolvers.letsencryptresolver.acme.dnschallenge.provider=cloudflare
# For testing rem out for production use
- --certificatesresolvers.letsencryptresolver.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory
# The machine your running Traefix on must be able to get to CloudFlare's DNS servers
- --certificatesResolvers.letsencryptresolver.acme.dnsChallenge.resolvers=1.1.1.1:53,1.0.0.1:53
ports:
- 80:80
- 443:443
volumes:
# Container gets the right time
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
# So that Traefik can listen to the Docker events
- /var/run/docker.sock:/var/run/docker.sock:ro
# Traefik volume to store certificates
- traefik:/letsencrypt
environment:
# Cloud flare API keys
# https://doc.traefik.io/traefik/https/acme/#providers
- CF_API_EMAIL=<cloudflare api email address>
- CF_API_KEY=<cloudflare api key>
networks:
- traefik-public
deploy:
labels:
# Traefik console
- traefik.enable=true
- traefik.http.routers.traefik.rule=Host(`traefik.<example.com>`)
- traefik.http.routers.traefik.entrypoints=websecure
- traefik.http.routers.traefik.tls.certresolver=letsencryptresolver
- traefik.http.routers.traefik.service=api@internal
- traefik.http.routers.traefik.middlewares=traefik
# Basic Auth middle ware to protect the traefik console
# https://doc.traefik.io/traefik/middlewares/basicauth/
# Update the change:me with a new user/password!
- traefik.http.middlewares.traefik.basicauth.users=change:$$apr1$$QjQG6kSz$$8J14ZN42RGObAlKJynES0.
- traefik.http.services.traefik.loadbalancer.server.port=8080
- traefik.frontend.headers.STSSeconds=31536000
- traefik.frontend.headers.STSIncludeSubdomains=true
- traefik.frontend.headers.STSPreload=true
volumes:
traefik:
networks:
traefik-public:
external: true
Orcpub docker compose file
This is a much simpler setup than the Nginx configuration - ssl is handled by Traefix and LetsEncrypt, and doesn't use Nginx at all.
version: '3.2'
services:
orcpub:
image: orcpub/orcpub:latest
environment:
PORT: 8890
# Using the postfix container below - feel free to use gmail or another smtp relay service here and rem out the postfix container
EMAIL_SERVER_URL: 'postfix'
EMAIL_ACCESS_KEY: '' # If using postfix below leave blank
EMAIL_SECRET_KEY: '' # If using postfix below leave blank
EMAIL_SERVER_PORT: 587
# Email address to send from, will default to '[email protected]'
EMAIL_FROM_ADDRESS: '[email protected]' # If using postfix below - make sure your domain name matches.
# Email address to send errors to
EMAIL_ERRORS_TO: ''
EMAIL_SSL: 'FALSE'
EMAIL_TLS: 'FALSE'
# Datomic connection string - Make sure the <change this> matches the DATOMIC_PASSWORD below
DATOMIC_URL: datomic:free://datomic:4334/orcpub?password=<change this>
# The secret used to hash your password in the browser, 20+ characters recommended
SIGNATURE: '<change me to something unique>'
restart: always
depends_on:
- datomic
restart: unless-stopped
# Java Container memory, don't go higher than this
JAVA_OPTS: "-Xms4g -Xmx4g -XX:+UseG1GC"
deploy:
labels:
# If redirecting http > https in Cloudflare rem this out
# http listener
- traefik.enable=true
- traefik.http.routers.orcpub.entrypoints=web
- traefik.http.routers.orcpub.rule=Host(`<host.example.com>`)
- traefik.http.routers.orcpub.middlewares=redirect-to-https@docker
- traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https
# https listener
- traefik.http.routers.orcpub-ssl.entrypoints=websecure
# Match all the web urls for Orcpub itself and send it to this container
- traefik.http.routers.orcpub-ssl.rule=(Host(`<host.example.com>`) && ( PathPrefix(`/health`) || PathPrefix(`/css`) || PathPrefix(`/dnld`) || PathPrefix(`/image`) || PathPrefix(`/js`) || PathPrefix(`/assets`) ||PathPrefix(`/favicon.ico`) || PathPrefix(`/favicon`) || PathPrefix(`/user`) || PathPrefix(`/dnd`) || PathPrefix(`/pages`) || PathPrefix(`/5e`) || PathPrefix(`/verify`) || PathPrefix(`/verification-expired`) || PathPrefix(`/verification-successful`) || PathPrefix(`/verification-sent`) || PathPrefix(`/re-verify`) || PathPrefix(`/register`) || PathPrefix(`/login`) || PathPrefix(`/user`) || PathPrefix(`/character.pdf`) || PathPrefix(`/check-email`) || PathPrefix(`/check-username`) || PathPrefix(`/reset-password`) || PathPrefix(`/send-password-reset`) || PathPrefix(`/password-reset-sent`) || PathPrefix(`/password-reset-success`) || PathPrefix(`/password-reset-expired`) || PathPrefix(`/password-reset-used`) || PathPrefix(`/terms-of-use`) || PathPrefix(`/privacy-policy`) || PathPrefix(`/community-guidelines`) || PathPrefix(`/cookies-policy`) || PathPrefix(`/following`) ))
- traefik.http.routers.orcpub-ssl.service=orcpub-ssl
- traefik.http.routers.orcpub-ssl.tls=true
- traefik.http.routers.orcpub-ssl.tls.domains[0].main=<host.example.com>
- traefik.http.routers.orcpub-ssl.tls.certresolver=letsencryptresolver
- traefik.http.routers.orcpub-ssl.priority=3
- traefik.http.services.orcpub-ssl.loadbalancer.server.port=8890
# Container health checks every 30 seconds
- traefik.http.services.orcpub-ssl.loadBalancer.healthcheck.path=/health
- traefik.http.services.orcpub-ssl.loadBalancer.healthcheck.port=8890
- traefik.http.services.orcpub-ssl.loadBalancer.healthcheck.scheme=http
- traefik.http.services.orcpub-ssl.loadBalancer.healthcheck.interval=30s
- traefik.http.services.orcpub-ssl.loadBalancer.healthcheck.timeout=2s
resources:
limits:
memory: 4G
reservations:
memory: 4G
depends_on:
- datomic
networks:
- traefik-public
- orcpub-network
- postfix
#Datomic - database server
datomic:
image: akiel/datomic-free
restart: always
environment:
# Datomic passwords
ADMIN_PASSWORD: <admin password>
# Make sure the DATOMIC_PASSWORD is the same one you used in the DATOMIC_URL above
DATOMIC_PASSWORD: <datomic password>
# Java memory limits Don't change these
XMS: -Xms4g
XMX: -Xmx4g
ALT_HOST: datomic
volumes:
# Where datomic stores it's database files
- data:/data
- data:/log
# Backup directory - set this to a path on the host
# To backup the orcpub database put this in a @hourly crontab:
# container=$(docker ps -aqf "name=^orcpub_datomic")
# docker exec $container /datomic/bin/datomic -Xmx4g -Xms4g backup-db datomic:free://datomic:4334/orcpub?password=<change this> file:/backups/datomic/
- /var/backups:/backups
networks:
- orcpub-network
deploy:
resources:
limits:
# Set memory limits to 2x+1gb so backups can run.
memory: 9G
reservations:
memory: 9G
# Optional but nice to have
# Random generator container
dndgenerator:
image: dndgenerator:latest
deploy:
labels:
- traefik.enable=true
# If redirecting http > https in Cloudflare rem this out
- traefik.http.routers.gen.entrypoints=web
- traefik.http.routers.gen.rule=Host(`<host.example.com>`)
- traefik.http.routers.gen.middlewares=redirect-to-https@docker
- traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https
- traefik.http.routers.gen-ssl.entrypoints=websecure
# Match all the web urls for dndgenerator itself and send it to this container
- traefik.http.routers.gen-ssl.rule=(Host(`<host.example.com>`) && PathPrefix(`/generator`))
- traefik.http.routers.gen-ssl.service=gen-ssl
- traefik.http.routers.gen-ssl.tls=true
- traefik.http.routers.gen-ssl.tls.domains[0].main=<host.example.com>
- traefik.http.routers.gen-ssl.tls.certresolver=letsencryptresolver
- traefik.http.routers.gen-ssl.priority=2
- traefik.http.services.gen-ssl.loadbalancer.server.port=80
networks:
- traefik-public
postfix:
# If you need to relay through gmail please see https://github.com/bokysan/docker-postfix
hostname: "postfix"
image: "boky/postfix"
restart: always
environment:
ALLOWED_SENDER_DOMAINS: "<example.com>"
POSTFIX_hostname: "<host.example.com>"
POSTFIX_myhostname: "<host.example.com>"
# Debug inbound mail
#INBOUND_DEBUGGING: 1
networks:
- postfix
volumes:
data:
networks:
postfix:
external:
name: postfix
orcpub-network:
driver: overlay
attachable: true
traefik-public:
external: true