services: db: image: postgres:17 restart: always env_file: ./app/.env.db ports: - "127.0.0.1:5433:5432" volumes: - ./data/postgres:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] interval: 5s timeout: 5s retries: 5 tutortool: build: context: ./app dockerfile: Dockerfile env_file: ./app/.env.tutortool ports: - "127.0.0.1:5000:5000" volumes: - ./data/slides:/src/data/slides - ./data/exports:/src/data/exports - ./logs:/src/logs depends_on: db: condition: service_healthy redis: condition: service_started restart: on-failure redis: image: redis:alpine restart: unless-stopped prometheus: image: prom/prometheus:latest restart: unless-stopped ports: - "127.0.0.1:9090:9090" volumes: - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml - ./data/prometheus:/prometheus command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.retention.time=15d' - '--storage.tsdb.retention.size=512MB' depends_on: - blackbox-exporter blackbox-exporter: image: prom/blackbox-exporter:latest restart: unless-stopped volumes: - ./prometheus/blackbox.yml:/etc/blackbox-exporter/config.yml grafana: image: grafana/grafana:latest restart: unless-stopped env_file: ./app/.env.db ports: - "127.0.0.1:3000:3000" volumes: - ./data/grafana:/var/lib/grafana - ./grafana/provisioning:/etc/grafana/provisioning environment: - GF_SECURITY_ADMIN_PASSWORD=changeme - GF_SECURITY_ADMIN_USER=admin - GF_USERS_ALLOW_SIGN_UP=false # Only allow access from localhost/reverse proxy - GF_SERVER_ROOT_URL=http://localhost:3000 depends_on: - prometheus - db