coturn drops to nobody, but Let's Encrypt keeps privkey.pem root:root 0600, so it could not read the key and started without TLS listeners -- turns: on 5349 was silently unavailable while STUN/TURN on 3478 worked. Copy the cert at container start into a directory owned by the runtime user, the same approach the Prosody entrypoint already uses here, rather than relaxing permissions on the shared Let's Encrypt tree and exposing the key to every other container on the host. The container now starts as root for the copy and coturn drops privileges itself via proc-user/proc-group. Since the copy happens at start, a renewal requires a restart, matching the existing Prosody deploy hook. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
88 lines
3.0 KiB
YAML
88 lines
3.0 KiB
YAML
services:
|
|
prosody:
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
container_name: prosody-xmpp
|
|
environment:
|
|
XMPP_DOMAIN: ${XMPP_DOMAIN}
|
|
XMPP_USER: ${XMPP_USER}
|
|
XMPP_PASSWORD: ${XMPP_PASSWORD}
|
|
MYSQL_HOST: ${MYSQL_HOST:-host.docker.internal}
|
|
MYSQL_USER: ${MYSQL_USER}
|
|
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
|
|
MYSQL_DATABASE: ${MYSQL_DATABASE}
|
|
SLIDGRAM_COMPONENT_SECRET: ${SLIDGRAM_COMPONENT_SECRET}
|
|
TURN_HOST: ${TURN_HOST}
|
|
TURN_SECRET: ${TURN_SECRET}
|
|
extra_hosts:
|
|
- "host.docker.internal:172.17.0.1"
|
|
ports:
|
|
- "5222:5222"
|
|
- "5269:5269"
|
|
- "5280:5280"
|
|
- "5281:5281"
|
|
volumes:
|
|
- ./data/prosody:/var/lib/prosody
|
|
- ./logs/prosody:/var/log/prosody
|
|
- ./data/prosody/configuration:/etc/prosody/conf.d
|
|
- /etc/letsencrypt/live/xmpp.guschin.info:/etc/prosody/certs/letsencrypt/live/xmpp.guschin.info:ro
|
|
- /etc/letsencrypt/archive/xmpp.guschin.info:/etc/prosody/certs/letsencrypt/archive/xmpp.guschin.info:ro
|
|
- /etc/letsencrypt/live/guschin.info:/etc/prosody/certs/letsencrypt/live/guschin.info:ro
|
|
- /etc/letsencrypt/archive/guschin.info:/etc/prosody/certs/letsencrypt/archive/guschin.info:ro
|
|
restart: unless-stopped
|
|
mem_limit: 200M
|
|
healthcheck:
|
|
test: ["CMD", "nc", "-z", "localhost", "5222"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 40s
|
|
networks:
|
|
- prosody
|
|
|
|
slidgram:
|
|
image: codeberg.org/slidge/slidgram:latest
|
|
container_name: slidgram
|
|
user: "100:102"
|
|
environment:
|
|
SLIDGE_JID: telegram.guschin.info
|
|
SLIDGE_SECRET: ${SLIDGRAM_COMPONENT_SECRET}
|
|
SLIDGE_SERVER: prosody-xmpp
|
|
SLIDGE_PORT: 5347
|
|
SLIDGE_UPLOAD_SERVICE: upload.guschin.info
|
|
volumes:
|
|
- ./data/slidgram:/var/lib/slidge
|
|
restart: unless-stopped
|
|
depends_on:
|
|
prosody:
|
|
condition: service_healthy
|
|
networks:
|
|
- prosody
|
|
|
|
coturn:
|
|
image: coturn/coturn:4.6-alpine
|
|
container_name: coturn
|
|
# Host networking: a TURN relay needs its whole UDP port range reachable,
|
|
# and Docker's userland NAT both mangles the source addresses coturn needs
|
|
# to see and makes publishing the range impractical.
|
|
network_mode: host
|
|
volumes:
|
|
- ./coturn/turnserver.conf:/etc/coturn/turnserver.conf:ro
|
|
- ./coturn/entrypoint.sh:/coturn-entrypoint.sh:ro
|
|
# The live/ files are relative symlinks into ../../archive/, so both
|
|
# trees must be mounted at their real paths for the links to resolve.
|
|
- /etc/letsencrypt/live/guschin.info:/etc/letsencrypt/live/guschin.info:ro
|
|
- /etc/letsencrypt/archive/guschin.info:/etc/letsencrypt/archive/guschin.info:ro
|
|
# Start as root so the entrypoint can stage the TLS key for the
|
|
# unprivileged runtime user; coturn itself drops to nobody via -u below.
|
|
user: "0:0"
|
|
entrypoint: ["/coturn-entrypoint.sh"]
|
|
command: ["turnserver", "-c", "/etc/coturn/turnserver.conf"]
|
|
restart: unless-stopped
|
|
mem_limit: 128M
|
|
|
|
networks:
|
|
prosody:
|
|
driver: bridge
|