-
-
Save smashnet/38cf7c30cb06427bab78ae5ab0fd2ae3 to your computer and use it in GitHub Desktop.
version: "3.5" | |
# Variables to fill in: | |
# Line 23: <LETSENCRYPT_MAIL_ADDRESS> - your mail address for contact with Let's Encrypt | |
# Line 36: <TRAEFIK_DASHBOARD_ADMIN_PASSWORD> - MD5 hash of your password (use http://www.htaccesstools.com/htpasswd-generator/) | |
# Line 54: <POSTGRES_PASSWORD> - the password for the postgres db. Use the same during mastodon:setup! | |
# Lines 31, 86, 111: <DOMAIN> - e.g. social.yourdomain.com (Must have an A record pointing to your box' IP) (AAAA for IPv6 ;) | |
services: | |
traefik: | |
image: traefik:v2.9 | |
container_name: "traefik" | |
restart: always | |
command: | |
# - "--log.level=DEBUG" | |
- "--api.dashboard=true" | |
- "--entrypoints.web.address=:80" | |
- "--entrypoints.websecure.address=:443" | |
- "--providers.docker=true" | |
- "--providers.docker.exposedbydefault=false" | |
- "--certificatesresolvers.letsencrypt.acme.httpchallenge=true" | |
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web" | |
- "--certificatesresolvers.letsencrypt.acme.email=<LETSENCRYPT_MAIL_ADDRESS>" | |
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" | |
ports: | |
- "80:80" | |
- "443:443" | |
labels: | |
- "traefik.enable=true" | |
# Dashboard | |
- "traefik.http.routers.traefik.rule=(Host(`<DOMAIN>`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`)))" | |
- "traefik.http.routers.traefik.service=api@internal" | |
- "traefik.http.routers.traefik.tls.certresolver=letsencrypt" | |
- "traefik.http.routers.traefik.entrypoints=websecure" | |
- "traefik.http.routers.traefik.middlewares=dashboardauth" | |
- "traefik.http.middlewares.dashboardauth.basicauth.users=admin:<TRAEFIK_DASHBOARD_ADMIN_PASSWORD>" | |
# HTTPS Redirect | |
- "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)" | |
- "traefik.http.routers.http-catchall.entrypoints=web" | |
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https@docker" | |
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https" | |
volumes: | |
- /var/run/docker.sock:/var/run/docker.sock | |
- ./letsencrypt:/letsencrypt | |
networks: | |
- external_network | |
db: | |
restart: always | |
image: postgres:14-alpine | |
healthcheck: | |
test: ["CMD", "pg_isready", "-U", "postgres"] | |
environment: | |
- POSTGRES_PASSWORD=<POSTGRES_PASSWORD> | |
volumes: | |
- ./postgres:/var/lib/postgresql/data | |
networks: | |
- internal_network | |
redis: | |
restart: always | |
image: redis:7-alpine | |
healthcheck: | |
test: ["CMD", "redis-cli", "ping"] | |
volumes: | |
- ./redis:/data | |
networks: | |
- internal_network | |
web: | |
image: tootsuite/mastodon:v3.5.3 | |
restart: always | |
env_file: .env.production | |
command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000" | |
healthcheck: | |
test: ["CMD-SHELL", "wget -q --spider --proxy=off localhost:3000/health || exit 1"] | |
expose: | |
- "3000" | |
depends_on: | |
- db | |
- redis | |
- traefik | |
labels: | |
- "traefik.enable=true" | |
- "traefik.docker.network=mastodon_external_network" | |
- "traefik.http.services.mastodon-web.loadbalancer.server.port=3000" | |
- "traefik.http.routers.mastodon-web.rule=Host(`<DOMAIN>`)" | |
- "traefik.http.routers.mastodon-web.entrypoints=websecure" | |
- "traefik.http.routers.mastodon-web.tls.certresolver=letsencrypt" | |
volumes: | |
- ./public/system:/mastodon/public/system | |
networks: | |
- external_network | |
- internal_network | |
streaming: | |
image: tootsuite/mastodon:v3.5.3 | |
restart: always | |
env_file: .env.production | |
command: node ./streaming | |
healthcheck: | |
test: ["CMD-SHELL", "wget -q --spider --proxy=off localhost:4000/api/v1/streaming/health || exit 1"] | |
expose: | |
- "4000" | |
depends_on: | |
- db | |
- redis | |
- traefik | |
labels: | |
- "traefik.enable=true" | |
- "traefik.docker.network=mastodon_external_network" | |
- "traefik.http.services.mastodon-streaming.loadbalancer.server.port=4000" | |
- "traefik.http.routers.mastodon-streaming.rule=(Host(`<DOMAIN>`) && PathPrefix(`/api/v1/streaming`))" | |
- "traefik.http.routers.mastodon-streaming.entrypoints=websecure" | |
- "traefik.http.routers.mastodon-streaming.tls.certresolver=letsencrypt" | |
networks: | |
- external_network | |
- internal_network | |
sidekiq: | |
image: tootsuite/mastodon:v3.5.3 | |
restart: always | |
env_file: .env.production | |
command: bundle exec sidekiq | |
depends_on: | |
- db | |
- redis | |
- traefik | |
volumes: | |
- ./public/system:/mastodon/public/system | |
networks: | |
- external_network | |
- internal_network | |
networks: | |
external_network: | |
name: mastodon_external_network | |
internal_network: | |
internal: true |
Alright, I have forked your gist @ https://gist.github.com/peterrus/0753fc3cf09b33a6253924cfc9f9b32f and made some changes:
- The streaming service was not working because traefik was trying to connect to port 3000 instead of the exposed 4000. I corrected this with an explicit configuration.
- This explicit configuration (for traefik) had to be applied on a traefik service. Traefik instantiates new services with names based on docker-compose project name. We can't guess this in advance (if we want to keep the docker-compose file universal) so we have to specify that through an environment variable. I added instructions on how to create an .env file that gets loaded by docker-compose automatically
- this .env file now also contains other configuration parameters, so as to keep them out of git and to keep the docker-compose file universal.
- Traefik was trying to connect to the web and streaming through the 'internal_network' network. This does not seem to be correct nor desirable. I have created an explicit configuration to use the 'external_network' network. Again, I needed to refer to the docker-compose project name.
Feel free to port any of my changes back to your file as you see fit and thank you for setting up the initial example! You have saved me quite some headaches ;)
where did you get the documentation for using these labels?
i can't find documentation on using these labels anywhere on the traefik website
labels:
- "traefik.enable=true"
# Dashboard
- "traefik.http.routers.traefik.rule=(Host(`<DOMAIN>`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`)))"
- "traefik.http.routers.traefik.service=api@internal"
- "traefik.http.routers.traefik.tls.certresolver=letsencrypt"
- "traefik.http.routers.traefik.entrypoints=websecure"
- "traefik.http.routers.traefik.middlewares=dashboardauth"
- "traefik.http.middlewares.dashboardauth.basicauth.users=admin:<TRAEFIK_DASHBOARD_ADMIN_PASSWORD>"
# HTTPS Redirect
- "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
- "traefik.http.routers.http-catchall.entrypoints=web"
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https@docker"
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
i am looking for the v2 replacement for targeting network
labels:
- "traefik.docker.network=traefiknetwork"
where did you get the documentation for using these labels?
i can't find documentation on using these labels anywhere on the traefik website
You may have a look at this section of the Traefik docs: Traefik & Docker
... but especially here: Docker network
There it says that traefik.docker.network
is still a valid label in v2.
I created a set of scripts with the help of your gist and @peterrus project.
It builds a docker-compose.yml
from the official project's file and modifies it to include the traefik labels with some tweaks, so you can use an external running traefik container instead.
https://gitlab.com/dweipert.de/devops/mastodon-docker-traefik
I added
- "traefik.http.services.streaming.loadbalancer.server.port=4000"
to the streaming service, and that seems to fix it, but it is not playing along nicely with the web service. Will have a look at it this weekend probably, will report back ;)(traefik tried to connect to the streaming service on port 3000, while it is running on 4000)