services: app: image: ${REPO:?set REPO in .env}:${TAG:-latest} restart: unless-stopped # A bind mount rather than a named volume: the database sits in ./data on # the host, where it can be listed, copied and backed up without going # through the container engine. The image runs as UID 65534, so the # container has to be told which host user owns that directory. # # PUID/PGID rather than UID/GID: UID is a read-only variable in bash, so a # value set here would be silently replaced by the invoking shell's own. user: "${PUID:-1000}:${PGID:-1000}" volumes: - ./data:/data environment: PASSWORD: ${PASSWORD:?set PASSWORD in .env} DB: /data/foodster.db ENV: ${ENV:-prod} TZ: ${TZ:-Europe/Helsinki} # No published ports: Traefik reaches the container over the shared # network. Publishing 8080 as well would put an unencrypted copy of the # app on the host, bypassing TLS. labels: - traefik.enable=true - traefik.http.routers.foodster.entrypoints=websecure - traefik.http.routers.foodster.rule=Host(`${HOST:?set HOST in .env}`) - traefik.http.routers.foodster.tls=true - traefik.http.services.foodster.loadbalancer.server.port=8080 - traefik.docker.network=traefik networks: - traefik networks: traefik: external: true