feat/Update_Controllers_to_Allow_for_Premium_Membership
This commit is contained in:
+46
-15
@@ -16,6 +16,7 @@ services:
|
||||
- HttpsRedirection__Enabled=false
|
||||
# Backend is internal-only here; nginx is the sole trusted ingress.
|
||||
- Proxy__TrustForwardedHeaders=true
|
||||
- Proxy__KnownNetworks__0=${WEB_PROXY_SUBNET:-172.31.250.0/29}
|
||||
# Authentication (recommended for any non-local deployment)
|
||||
- Auth__Require=true
|
||||
- Auth__JwtKey=${AUTH_JWT_KEY}
|
||||
@@ -31,15 +32,17 @@ services:
|
||||
# Optional: allow Google / Microsoft ID-token bearer auth (sign-in, not mail access)
|
||||
- Auth__GoogleClientId=${AUTH_GOOGLE_CLIENT_ID}
|
||||
- Auth__MicrosoftClientId=${AUTH_MICROSOFT_CLIENT_ID}
|
||||
- Auth__MicrosoftTenant=${AUTH_MICROSOFT_TENANT}
|
||||
- Google__GmailClientSecret=${GOOGLE_GMAIL_CLIENT_SECRET}
|
||||
- Google__GmailRedirectUri=${GOOGLE_GMAIL_REDIRECT_URI}
|
||||
# Optional: Outlook / Microsoft 365 mail linking via Microsoft Graph
|
||||
- Microsoft__ClientId=${MICROSOFT_CLIENT_ID}
|
||||
- Microsoft__ClientSecret=${MICROSOFT_CLIENT_SECRET}
|
||||
- Microsoft__TenantId=${MICROSOFT_TENANT_ID}
|
||||
- Microsoft__RedirectUri=${MICROSOFT_REDIRECT_URI}
|
||||
- Ai__BaseUrl=${AI_SERVICE_BASE_URL:-http://ai-service:8001}
|
||||
- Summarizer__BaseUrl=${SUMMARIZER_BASE_URL:-http://ai-service:8001}
|
||||
# External processing requires this admin gate AND a per-user opt-in. Default is local-only.
|
||||
- Ai__ExternalProcessingEnabled=${EXTERNAL_AI_ENABLED:-false}
|
||||
- Ai__ExternalProvider=${AI_PROVIDER:-ollama}
|
||||
# Shared secret for calls to ai-service. Must match AI_SERVICE_TOKEN below.
|
||||
# Quoted: the `:?` message contains a colon-space, which YAML would otherwise read as a map.
|
||||
- "Ai__ServiceToken=${AI_SERVICE_TOKEN:?AI_SERVICE_TOKEN must be set - generate one with python -c 'import secrets; print(secrets.token_hex(32))'}"
|
||||
@@ -62,14 +65,31 @@ services:
|
||||
- Email__SmtpPassword=${EMAIL_SMTP_PASSWORD}
|
||||
- Email__From=${EMAIL_FROM}
|
||||
- Email__FromName=${EMAIL_FROM_NAME}
|
||||
- Email__FollowUpReminders__Enabled=${EMAIL_FOLLOWUPREMINDERS_ENABLED:-false}
|
||||
- Email__FollowUpReminders__UpcomingDays=${EMAIL_FOLLOWUPREMINDERS_UPCOMINGDAYS:-2}
|
||||
# These formerly inert workers stay off until their owner-safe behavior and downstream
|
||||
# notification/privacy/entitlement prerequisites have been explicitly rolled out.
|
||||
- Workers__RulesEnabled=${WORKER_RULES_ENABLED:-false}
|
||||
- Workers__FollowUpRemindersEnabled=${WORKER_FOLLOWUP_REMINDERS_ENABLED:-false}
|
||||
- Workers__DailyExportEnabled=${WORKER_DAILY_EXPORT_ENABLED:-false}
|
||||
- Workers__JobEnrichmentEnabled=${WORKER_JOB_ENRICHMENT_ENABLED:-false}
|
||||
- Workers__AiOperationsEnabled=${WORKER_AI_OPERATIONS_ENABLED:-false}
|
||||
- AiQueue__WorkerConcurrency=${AI_QUEUE_WORKER_CONCURRENCY:-1}
|
||||
- AiQueue__GlobalCapacity=${AI_QUEUE_GLOBAL_CAPACITY:-100}
|
||||
- AiQueue__PerUserCapacity=${AI_QUEUE_PER_USER_CAPACITY:-10}
|
||||
- AiQueue__DeadlineMinutes=${AI_QUEUE_DEADLINE_MINUTES:-15}
|
||||
- AiQueue__OperationTimeoutSeconds=${AI_QUEUE_OPERATION_TIMEOUT_SECONDS:-300}
|
||||
expose:
|
||||
- "8080"
|
||||
networks:
|
||||
- default
|
||||
- shared_services
|
||||
default:
|
||||
shared_services:
|
||||
web_proxy:
|
||||
aliases:
|
||||
- backend-web
|
||||
# The only other member of ai_internal — the backend is the sole permitted caller of
|
||||
# ai-service.
|
||||
- ai_internal
|
||||
ai_internal:
|
||||
restart: unless-stopped
|
||||
logging:
|
||||
options:
|
||||
@@ -94,16 +114,19 @@ services:
|
||||
args:
|
||||
- NEXT_PUBLIC_GOOGLE_CLIENT_ID=${AUTH_GOOGLE_CLIENT_ID}
|
||||
- NEXT_PUBLIC_MICROSOFT_CLIENT_ID=${AUTH_MICROSOFT_CLIENT_ID}
|
||||
- NEXT_PUBLIC_MICROSOFT_TENANT=${AUTH_MICROSOFT_TENANT}
|
||||
# Optional override; default in production is `/api`
|
||||
- NEXT_PUBLIC_API_BASE_URL=${NEXT_PUBLIC_API_BASE_URL}
|
||||
ports:
|
||||
- "3000:80"
|
||||
expose:
|
||||
- "80"
|
||||
environment:
|
||||
- APP_PUBLIC_BASE_URL=${APP_PUBLIC_BASE_URL}
|
||||
depends_on:
|
||||
backend:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- default
|
||||
- shared_services
|
||||
- web_proxy
|
||||
restart: unless-stopped
|
||||
logging:
|
||||
options:
|
||||
@@ -111,7 +134,7 @@ services:
|
||||
max-file: "3"
|
||||
# Cheap liveness: nginx answering on its own port. wget ships with the alpine base.
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:80/"]
|
||||
test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:80/health"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
@@ -131,6 +154,7 @@ services:
|
||||
# AI provider for heavy /cv/* calls: ollama (default) | gemini | groq.
|
||||
# Set AI_PROVIDER=gemini + GEMINI_API_KEY in prod to offload a weak local GPU.
|
||||
- AI_PROVIDER=${AI_PROVIDER:-ollama}
|
||||
- EXTERNAL_AI_ENABLED=${EXTERNAL_AI_ENABLED:-false}
|
||||
- GEMINI_API_KEY=${GEMINI_API_KEY:-}
|
||||
- GEMINI_MODEL=${GEMINI_MODEL:-gemini-2.0-flash}
|
||||
- GROQ_API_KEY=${GROQ_API_KEY:-}
|
||||
@@ -141,7 +165,7 @@ services:
|
||||
- "AI_SERVICE_TOKEN=${AI_SERVICE_TOKEN:?AI_SERVICE_TOKEN must be set - generate one with python -c 'import secrets; print(secrets.token_hex(32))'}"
|
||||
# Deliberately NOT published to the host: this service has no user auth and can spend a
|
||||
# paid provider's API key (AI_PROVIDER=gemini/groq). The backend reaches it in-network at
|
||||
# http://ai-service:8001. To debug locally, use docker-compose.override.yml rather than
|
||||
# http://ai-service:8001. To debug locally, use docker-compose.dev.yml rather than
|
||||
# re-adding a `ports:` here.
|
||||
expose:
|
||||
- "8001"
|
||||
@@ -165,14 +189,15 @@ services:
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
||||
# Opt-in only: start with `docker compose --profile bundled-ollama up`.
|
||||
# Opt-in only: start locally with
|
||||
# `docker compose -f docker-compose.yml -f docker-compose.dev.yml --profile bundled-ollama up`.
|
||||
# Left out of the default set so deploys reuse an existing/shared Ollama
|
||||
# (configured via OLLAMA_BASE_URL) instead of spinning up a duplicate.
|
||||
ollama:
|
||||
profiles: ["bundled-ollama"]
|
||||
image: ollama/ollama:latest
|
||||
ports:
|
||||
- "11434:11434"
|
||||
expose:
|
||||
- "11434"
|
||||
environment:
|
||||
- OLLAMA_HOST=0.0.0.0:11434
|
||||
volumes:
|
||||
@@ -184,8 +209,6 @@ services:
|
||||
# it by host IP (e.g. http://<host-ip>:11435) — ai-service can no longer resolve container
|
||||
# names on `shared_services`, by design.
|
||||
networks:
|
||||
- default
|
||||
- shared_services
|
||||
- ai_internal
|
||||
restart: unless-stopped
|
||||
logging:
|
||||
@@ -215,3 +238,11 @@ networks:
|
||||
# this is a normal bridge (not `internal: true`).
|
||||
ai_internal:
|
||||
driver: bridge
|
||||
|
||||
# Only nginx and the backend join this network. The backend trusts forwarded headers solely
|
||||
# from this CIDR; set WEB_PROXY_SUBNET explicitly in production after checking for overlap.
|
||||
web_proxy:
|
||||
internal: true
|
||||
ipam:
|
||||
config:
|
||||
- subnet: ${WEB_PROXY_SUBNET:-172.31.250.0/29}
|
||||
|
||||
Reference in New Issue
Block a user