Fully dockerized deployment with automatic Let's Encrypt certificates via Traefik's static file provider (no docker.sock needed), bind-mounted data folders instead of named volumes, and domain/secrets kept out of git via .env + rendered templates. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
104 lines
2.8 KiB
YAML
104 lines
2.8 KiB
YAML
networks:
|
|
web:
|
|
name: matrix_web
|
|
internal:
|
|
name: matrix_internal
|
|
|
|
services:
|
|
traefik:
|
|
image: traefik:v3.5
|
|
container_name: matrix-traefik
|
|
restart: unless-stopped
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
networks:
|
|
- web
|
|
ports:
|
|
- "80:80"
|
|
- "443:443"
|
|
environment:
|
|
- TRAEFIK_DASHBOARD_AUTH=${TRAEFIK_DASHBOARD_AUTH}
|
|
command:
|
|
- --api.dashboard=true
|
|
- --providers.file.directory=/etc/traefik/dynamic
|
|
- --providers.file.watch=true
|
|
- --entrypoints.web.address=:80
|
|
- --entrypoints.web.http.redirections.entrypoint.to=websecure
|
|
- --entrypoints.web.http.redirections.entrypoint.scheme=https
|
|
- --entrypoints.web.http.redirections.entrypoint.permanent=true
|
|
- --entrypoints.websecure.address=:443
|
|
- --certificatesresolvers.letsencrypt.acme.email=${ACME_EMAIL}
|
|
- --certificatesresolvers.letsencrypt.acme.storage=/etc/traefik/acme/acme.json
|
|
- --certificatesresolvers.letsencrypt.acme.httpchallenge=true
|
|
- --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web
|
|
- --log.level=INFO
|
|
- --accesslog=true
|
|
volumes:
|
|
- ./traefik/dynamic:/etc/traefik/dynamic:ro
|
|
- ./traefik/acme:/etc/traefik/acme
|
|
|
|
postgres:
|
|
image: postgres:16-alpine
|
|
container_name: matrix-postgres
|
|
restart: unless-stopped
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
networks:
|
|
- internal
|
|
environment:
|
|
- POSTGRES_DB=${POSTGRES_DB}
|
|
- POSTGRES_USER=${POSTGRES_USER}
|
|
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
|
- POSTGRES_INITDB_ARGS=--encoding=UTF8 --locale=C
|
|
- PGDATA=/var/lib/postgresql/data/pgdata
|
|
volumes:
|
|
- ./postgres/data:/var/lib/postgresql/data
|
|
|
|
synapse:
|
|
image: matrixdotorg/synapse:latest
|
|
container_name: matrix-synapse
|
|
restart: unless-stopped
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
depends_on:
|
|
- postgres
|
|
networks:
|
|
- web
|
|
- internal
|
|
volumes:
|
|
- ./synapse/data:/data
|
|
|
|
element:
|
|
image: vectorim/element-web:latest
|
|
container_name: matrix-element
|
|
restart: unless-stopped
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
networks:
|
|
- web
|
|
volumes:
|
|
- ./element/config/config.json:/app/config.json:ro
|
|
|
|
synapse-admin:
|
|
image: awesometechnologies/synapse-admin:latest
|
|
container_name: matrix-synapse-admin
|
|
restart: unless-stopped
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
networks:
|
|
- web
|
|
volumes:
|
|
- ./synapse-admin/config/config.json:/app/config.json:ro
|
|
|
|
wellknown:
|
|
image: nginx:1.27-alpine
|
|
container_name: matrix-wellknown
|
|
restart: unless-stopped
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
networks:
|
|
- web
|
|
volumes:
|
|
- ./wellknown/html:/usr/share/nginx/html:ro
|
|
- ./wellknown/nginx.conf:/etc/nginx/conf.d/default.conf:ro
|