services: mealie: image: ghcr.io/mealie-recipes/mealie:latest container_name: mealie restart: always networks: - traefik - internal volumes: - ./mealie-data:/app/data environment: # Backend settings ALLOW_SIGNUP: "false" PUID: 1000 PGID: 1000 TZ: Europe/Ljubljana # <-- Already set here BASE_URL: https://mealie.rozic-dev.com # Database DB_ENGINE: postgres POSTGRES_USER: mealie POSTGRES_PASSWORD: mealie POSTGRES_SERVER: postgres POSTGRES_PORT: 5432 POSTGRES_DB: mealie depends_on: postgres: condition: service_healthy # ----------------------------- # Traefik Reverse Proxy Labels # ----------------------------- labels: # ────────────────────────────── # Enable Traefik for this container # ────────────────────────────── - "traefik.enable=true" # ────────────────────────────── # HTTP → HTTPS redirect router # ────────────────────────────── - "traefik.http.routers.mealie-http.entrypoints=web" - "traefik.http.routers.mealie-http.rule=Host(`mealie.rozic-dev.com`)" - "traefik.http.routers.mealie-http.middlewares=mealie-redirect" # ────────────────────────────── # HTTPS router (the real one) # ────────────────────────────── - "traefik.http.routers.mealie.entrypoints=websecure" - "traefik.http.routers.mealie.rule=Host(`mealie.rozic-dev.com`)" - "traefik.http.routers.mealie.tls=true" - "traefik.http.routers.mealie.tls.certresolver=letsencrypt" # ← change only if your resolver has a different name - "traefik.http.routers.mealie.middlewares=mealie-chain" # ────────────────────────────── # Service (where Traefik forwards the traffic) # ────────────────────────────── - "traefik.http.services.mealie.loadbalancer.server.port=9000" # ────────────────────────────── # Middleware: redirect HTTP → HTTPS # ────────────────────────────── - "traefik.http.middlewares.mealie-redirect.redirectscheme.scheme=https" - "traefik.http.middlewares.mealie-redirect.redirectscheme.permanent=true" # ────────────────────────────── # Middleware: security headers # ────────────────────────────── - "traefik.http.middlewares.mealie-security.headers.stsSeconds=63072000" - "traefik.http.middlewares.mealie-security.headers.stsIncludeSubdomains=true" - "traefik.http.middlewares.mealie-security.headers.stsPreload=true" - "traefik.http.middlewares.mealie-security.headers.contentTypeNosniff=true" - "traefik.http.middlewares.mealie-security.headers.browserXssFilter=true" - "traefik.http.middlewares.mealie-security.headers.referrerPolicy=same-origin" - "traefik.http.middlewares.mealie-security.headers.customResponseHeaders.X-Robots-Tag=none" # ────────────────────────────── # Chain: redirect + security headers (applied only to HTTPS router) # ────────────────────────────── - "traefik.http.middlewares.mealie-chain.chain.middlewares=mealie-security" deploy: resources: limits: cpus: '1.0' memory: 1024M postgres: image: postgres:15 container_name: mealie-postgres restart: always networks: - internal - traefik environment: POSTGRES_DB: mealie POSTGRES_USER: mealie POSTGRES_PASSWORD: mealie # Added for Time Zone consistency (Suggestion 2) TZ: Europe/Ljubljana PGTZ: Europe/Ljubljana volumes: - ./mealie-pgdata:/var/lib/postgresql/data healthcheck: test: ["CMD", "pg_isready", "-U", "mealie"] interval: 30s timeout: 10s retries: 5 # ------------------ # NETWORKS & VOLUMES # ------------------ networks: traefik: external: true name: traefik_default internal: driver: bridge volumes: mealie-data: driver: local mealie-pgdata: driver: local