networks: traefik: external: true leantime: driver: bridge services: # ── Database ──────────────────────────────────────────────────────────────── leantime-db: image: mysql:8.4 container_name: leantime-db restart: always networks: - leantime environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: ${LEAN_DB_DATABASE} MYSQL_USER: ${LEAN_DB_USER} MYSQL_PASSWORD: ${LEAN_DB_PASSWORD} command: --character-set-server=UTF8MB4 --collation-server=UTF8MB4_unicode_ci volumes: - /pwspool/software/leantime/db:/var/lib/mysql healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 30s timeout: 10s retries: 5 # ── Application ───────────────────────────────────────────────────────────── leantime: image: leantime/leantime:${LEAN_VERSION:-latest} container_name: leantime restart: always networks: - leantime - traefik depends_on: leantime-db: condition: service_healthy security_opt: - no-new-privileges:true cap_add: - CAP_CHOWN - CAP_SETGID - CAP_SETUID environment: LEAN_APP_URL: ${LEAN_APP_URL} LEAN_SESSION_PASSWORD: ${LEAN_SESSION_PASSWORD} LEAN_SESSION_SECURE: ${LEAN_SESSION_SECURE:-true} LEAN_DB_HOST: leantime-db LEAN_DB_PORT: 3306 LEAN_DB_DATABASE: ${LEAN_DB_DATABASE} LEAN_DB_USER: ${LEAN_DB_USER} LEAN_DB_PASSWORD: ${LEAN_DB_PASSWORD} LEAN_DEFAULT_TIMEZONE: ${LEAN_DEFAULT_TIMEZONE:-America/Los_Angeles} LEAN_EMAIL_RETURN: ${LEAN_EMAIL_RETURN} LEAN_EMAIL_USE_SMTP: ${LEAN_EMAIL_USE_SMTP:-false} LEAN_EMAIL_SMTP_HOSTS: ${LEAN_EMAIL_SMTP_HOSTS} LEAN_EMAIL_SMTP_USERNAME: ${LEAN_EMAIL_SMTP_USERNAME} LEAN_EMAIL_SMTP_PASSWORD: ${LEAN_EMAIL_SMTP_PASSWORD} LEAN_EMAIL_SMTP_SECURE: ${LEAN_EMAIL_SMTP_SECURE} LEAN_EMAIL_SMTP_PORT: ${LEAN_EMAIL_SMTP_PORT} volumes: - /pwspool/software/leantime/public_userfiles:/var/www/html/public/userfiles - /pwspool/software/leantime/userfiles:/var/www/html/userfiles - /pwspool/software/leantime/plugins:/var/www/html/app/Plugins - /pwspool/software/leantime/logs:/var/www/html/storage/logs labels: - traefik.enable=true - traefik.docker.network=traefik - traefik.http.routers.leantime.rule=Host(`${DOMAIN}`) - traefik.http.routers.leantime.tls=true - traefik.http.routers.leantime.tls.certresolver=lets-encrypt - traefik.http.services.leantime.loadbalancer.server.port=8080