a1635218a8
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.
68 lines
2.1 KiB
YAML
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:
|