Files
YesChef/docker-compose.yml
Josh Rogers a1635218a8 Add SMTP infrastructure + auth rate limiting
Foundation for the upcoming email-based invite and password-reset flows.

- IEmailSender abstraction with SmtpEmailSender (MailKit 4.16) and a
  LoggingEmailSender fallback used automatically when SMTP is unconfigured
  so local dev works without a real SMTP server.
- Fixed-window rate limits keyed by remote IP: 10 / 15 min on /login,
  5 / hour on /register. Returns 429 with Retry-After. Bypassed in the
  Testing environment so the existing integration suite is unaffected.
- New env vars (SMTP_*, APP_BASE_URL) plumbed through docker-compose
  and documented in .env.example.
2026-05-08 22:35:57 -05:00

68 lines
2.1 KiB
YAML

services:
postgres:
image: postgres:17
environment:
POSTGRES_DB: yeschef
POSTGRES_USER: yeschef
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- yeschef-pgdata:/var/lib/postgresql/data
expose:
- "5432"
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U yeschef"]
interval: 10s
timeout: 5s
retries: 5
backend:
build:
context: ./src/backend/YesChef.Api
dockerfile: Dockerfile
environment:
ConnectionStrings__DefaultConnection: "Host=postgres;Database=yeschef;Username=yeschef;Password=${POSTGRES_PASSWORD}"
Jwt__Secret: ${JWT_SECRET}
FamilyCode: ${FAMILY_CODE}
Smtp__Host: ${SMTP_HOST:-}
Smtp__Port: ${SMTP_PORT:-587}
Smtp__Username: ${SMTP_USERNAME:-}
Smtp__Password: ${SMTP_PASSWORD:-}
Smtp__FromAddress: ${SMTP_FROM_ADDRESS:-}
Smtp__FromName: ${SMTP_FROM_NAME:-YesChef}
AppBaseUrl: ${APP_BASE_URL:-https://${DOMAIN}}
expose:
- "5000"
depends_on:
postgres:
condition: service_healthy
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.yeschef-api.rule=Host(`${DOMAIN}`) && (PathPrefix(`/api`) || PathPrefix(`/hubs`) || Path(`/health`))"
- "traefik.http.routers.yeschef-api.entrypoints=websecure"
- "traefik.http.routers.yeschef-api.tls.certresolver=letsencrypt"
- "traefik.http.services.yeschef-api.loadbalancer.server.port=5000"
frontend:
build:
context: ./src/frontend
dockerfile: Dockerfile
environment:
ORIGIN: https://${DOMAIN}
expose:
- "3000"
depends_on:
- backend
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.yeschef-web.rule=Host(`${DOMAIN}`)"
- "traefik.http.routers.yeschef-web.entrypoints=websecure"
- "traefik.http.routers.yeschef-web.tls.certresolver=letsencrypt"
- "traefik.http.routers.yeschef-web.priority=1"
- "traefik.http.services.yeschef-web.loadbalancer.server.port=3000"
volumes:
yeschef-pgdata: