services: # Traefik reverse proxy traefik: image: traefik:v3.5.1 container_name: quixotic-traefik restart: unless-stopped env_file: - .env.docker command: - --api.dashboard=true - --api.insecure=false - --providers.docker=true - --providers.docker.exposedbydefault=false - --entrypoints.web.address=:80 - --entrypoints.websecure.address=:443 - --certificatesresolvers.letsencrypt.acme.httpchallenge=true - --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web - --certificatesresolvers.letsencrypt.acme.email=${ACME_EMAIL:-admin@example.com} - --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json - --log.level=INFO ports: - "80:80" - "443:443" - "8080:8080" # Traefik dashboard volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - traefik-ssl-certs:/letsencrypt labels: - "traefik.enable=true" - "traefik.http.routers.traefik.rule=Host(`traefik.${DOMAIN:-localhost}`)" - "traefik.http.routers.traefik.service=api@internal" - "traefik.http.routers.traefik.middlewares=auth" - "traefik.http.middlewares.auth.basicauth.users=${TRAEFIK_AUTH:-admin:$$2y$$10$$8qCUOc.FKLB8o4X8ZGVb7OU4xrslBUjOdBPtRz9wM7YJ9.XsGVzui}" # admin:password networks: - quixotic # PostgreSQL database postgres: image: postgres:15-alpine container_name: quixotic-postgres restart: unless-stopped env_file: - .env.docker environment: POSTGRES_DB: ${POSTGRES_DB:-quixotic} POSTGRES_USER: ${POSTGRES_USER:-quixotic} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-quixotic123} volumes: - postgres-data:/var/lib/postgresql/data - ./database/init:/docker-entrypoint-initdb.d networks: - quixotic healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-quixotic}"] interval: 5s timeout: 5s retries: 5 # Main application (Python Backend) quixotic-app: build: context: . dockerfile: Dockerfile container_name: quixotic-app restart: unless-stopped env_file: - .env.docker environment: PORT: 8000 HOST: 0.0.0.0 DATABASE_URL: postgresql://${POSTGRES_USER:-quixotic}:${POSTGRES_PASSWORD:-quixotic123}@postgres:5432/${POSTGRES_DB:-quixotic} volumes: - downloads:/app/downloads labels: - "traefik.enable=true" # HTTPS router for production domains - "traefik.http.routers.quixotic.rule=Host(`${DOMAIN:-localhost}`) && !Host(`localhost`)" - "traefik.http.routers.quixotic.entrypoints=websecure" - "traefik.http.routers.quixotic.tls.certresolver=letsencrypt" - "traefik.http.routers.quixotic.service=quixotic" # HTTP router for localhost (no SSL) - "traefik.http.routers.quixotic-http.rule=Host(`localhost`)" - "traefik.http.routers.quixotic-http.entrypoints=web" - "traefik.http.routers.quixotic-http.service=quixotic" # HTTP to HTTPS redirect only for non-localhost - "traefik.http.routers.quixotic-redirect.rule=Host(`${DOMAIN:-localhost}`) && !Host(`localhost`)" - "traefik.http.routers.quixotic-redirect.entrypoints=web" - "traefik.http.routers.quixotic-redirect.middlewares=redirect-to-https" - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https" - "traefik.http.services.quixotic.loadbalancer.server.port=8000" depends_on: traefik: condition: service_started postgres: condition: service_healthy networks: - quixotic volumes: traefik-ssl-certs: downloads: postgres-data: networks: quixotic: driver: bridge