253 lines
13 KiB
Plaintext
253 lines
13 KiB
Plaintext
# Copy this file to .env. Compose intentionally refuses to start without the
|
|
# required values. Replace every credential before any public deployment.
|
|
# Deployment selection is consumed by scripts/deploy-up.sh and
|
|
# scripts/compose.sh; the application does not try to start an orchestrator.
|
|
DEPLOYMENT_TARGET=compose
|
|
DEPLOYMENT_ENV=development
|
|
COMPOSE_PROJECT_NAME=who_need_help
|
|
# Every independently deployable checkout must use its own image tags. This
|
|
# prevents a test build from replacing the image used by production.
|
|
APP_IMAGE=who-need-help:local
|
|
SOCKET_PROXY_IMAGE=who-need-help:socket-proxy-local
|
|
POSTGIS_IMAGE=who-need-help:postgis-local
|
|
# split runs independently scalable web and worker replicas behind Traefik.
|
|
# compact runs one combined Phoenix + Oban VM directly on HTTP_PORT.
|
|
APP_TOPOLOGY=split
|
|
# container starts the project-owned PostGIS service. external excludes that
|
|
# service completely and connects every application role through DATABASE_URL.
|
|
DATABASE_MODE=container
|
|
# Only used when DEPLOYMENT_TARGET=kubernetes.
|
|
KUBERNETES_MODE=kind
|
|
KUBE_CONTEXT=
|
|
KUBE_NAMESPACE=who-need-help
|
|
KUBE_RELEASE=who-need-help
|
|
KUBE_VALUES_FILE=
|
|
HTTP_PORT=4010
|
|
# Bind the public Compose proxy to loopback when a reverse proxy runs on the
|
|
# same host. The current VPN staging path needs an address reachable by its
|
|
# verified tunnel topology, so choose this per deployment.
|
|
HTTP_BIND_ADDRESS=0.0.0.0
|
|
# Attach the selected app service to the separately managed public Caddy
|
|
# network. Keep disabled for ordinary local development.
|
|
PUBLIC_EDGE_ENABLED=false
|
|
PUBLIC_EDGE_NETWORK=who_need_help_public_edge
|
|
PUBLIC_ROUTE_ID=who_need_help
|
|
PUBLIC_UPSTREAM_NAME=who-need-help-local
|
|
PUBLIC_UPSTREAM_PORT=4000
|
|
PUBLIC_HEALTH_PATH=/healthz/ready
|
|
PUBLIC_WWW_REDIRECT=false
|
|
# Legacy shared-edge settings remain while the submitted test deployment is
|
|
# frozen. New application releases do not build or restart Caddy. After the
|
|
# judging freeze, migrate these routes to the independent server_edge project.
|
|
EDGE_COMPOSE_PROJECT_NAME=who_need_help_edge
|
|
CADDY_IMAGE=who-need-help:caddy-local
|
|
EDGE_BIND_ADDRESS=0.0.0.0
|
|
EDGE_HTTP_PORT=80
|
|
EDGE_HTTPS_PORT=443
|
|
PRIMARY_DOMAIN=whoneedhelp.com
|
|
PRIMARY_UPSTREAM=who-need-help-production:4000
|
|
TEST_DOMAIN=test.whoneedhelp.com
|
|
TEST_UPSTREAM=who-need-help-test:4000
|
|
MAILPIT_PORT=8027
|
|
MAILPIT_BIND_ADDRESS=127.0.0.1
|
|
DOCKER_SOCKET_GID=REPLACE_WITH_DOCKER_SOCKET_NUMERIC_GID
|
|
# Comma-separated proxy IP/CIDR values whose X-Forwarded-* headers Traefik
|
|
# accepts. Keep loopback locally; set the exact VPN proxy address for staging.
|
|
TRAEFIK_TRUSTED_IPS=127.0.0.1/32
|
|
TRAEFIK_RETRY_ATTEMPTS=3
|
|
# Keep false for ordinary deployments. The isolated load profile enables the
|
|
# unbound port-8080 API only inside its private Compose networks so its rolling
|
|
# drill can observe when a drained backend leaves service.
|
|
TRAEFIK_API_INSECURE=false
|
|
# Docker-provider isolation and names. A second Compose project must use its
|
|
# own project constraint, router/service name, Docker network, and Host rule.
|
|
TRAEFIK_PROJECT_CONSTRAINT=who_need_help
|
|
TRAEFIK_APP_NAME=who-need-help
|
|
TRAEFIK_DOCKER_NETWORK=who_need_help_ingress
|
|
TRAEFIK_ROUTER_RULE='PathPrefix(`/`)'
|
|
PHX_HOST=localhost
|
|
PHX_SCHEME=http
|
|
PHX_URL_PORT=4010
|
|
# Optional comma-separated additional browser origins for Phoenix sockets.
|
|
# Keep this empty when the site is reached only through PHX_HOST. For a local
|
|
# Compose instance also exposed through an HTTPS tunnel, list both exact
|
|
# origins, for example: https://dev.example.com,http://localhost:4010
|
|
PHX_CHECK_ORIGINS=
|
|
# Android debug builds compile this origin into BuildConfig. The Docker
|
|
# emulator uses adb reverse to expose the local Compose proxy on loopback.
|
|
WNH_DEBUG_BASE_URL=http://localhost:4010
|
|
# Development/staging/release builds require a public HTTPS origin. Keep the value
|
|
# environment-specific; scripts/ensure-local-public-origin.sh can derive it
|
|
# from the three PHX_* values in the ignored .env.
|
|
WNH_BASE_URL=
|
|
# These local values preserve the existing five-second client freshness window
|
|
# and fifteen-second request timeout. They are build inputs, not measured
|
|
# production capacity recommendations.
|
|
WNH_TRACKING_MIN_TIME_MS=5000
|
|
WNH_TRACKING_HTTP_TIMEOUT_MS=15000
|
|
WNH_ANDROID_VERSION_CODE=1
|
|
WNH_ANDROID_VERSION_NAME=0.1.0
|
|
# Public Firebase Android client configuration. These values are embedded in
|
|
# the APK and are not service-account credentials. Set all four per environment
|
|
# to enable native FCM registration, or leave all four empty to disable it.
|
|
WNH_FIREBASE_APPLICATION_ID=
|
|
WNH_FIREBASE_API_KEY=
|
|
WNH_FIREBASE_PROJECT_ID=
|
|
WNH_FIREBASE_GCM_SENDER_ID=
|
|
# Verified Android App Links are configured by the web deployment rather than
|
|
# embedded as secrets in the application. Use
|
|
# org.whoneedhelp.mobile.development with the development certificate on DEV,
|
|
# org.whoneedhelp.mobile.staging with the staging certificate on test, and
|
|
# org.whoneedhelp.mobile with every active Play signing certificate on
|
|
# production. Keep both empty until the matching signed APK/AAB is available.
|
|
ANDROID_APP_LINKS_PACKAGE_NAME=
|
|
ANDROID_APP_LINKS_SHA256_CERT_FINGERPRINTS=
|
|
# Production-only evidence from Google Play Console. This must contain the
|
|
# Play App Signing certificate fingerprint(s), not the local upload key, and
|
|
# every value must also appear in ANDROID_APP_LINKS_SHA256_CERT_FINGERPRINTS.
|
|
# Development and test leave this empty.
|
|
ANDROID_PLAY_APP_SIGNING_SHA256_CERT_FINGERPRINTS=
|
|
# Public identifier of the locally held Google Play upload key. The private
|
|
# keystore and its randomized password live outside the repository under
|
|
# ~/.config/who_need_help/android-release/.
|
|
WNH_ANDROID_SIGNING_KEY_ALIAS=who-need-help-upload
|
|
# The DEV-domain APK uses a stable signing identity under
|
|
# ~/.config/who_need_help/android-development/.
|
|
WNH_ANDROID_DEVELOPMENT_SIGNING_KEY_ALIAS=who-need-help-development
|
|
# The test-domain staging APK uses a different stable signing identity under
|
|
# ~/.config/who_need_help/android-staging/. This keeps App Link verification
|
|
# reproducible without reusing the future production upload key.
|
|
WNH_ANDROID_STAGING_SIGNING_KEY_ALIAS=who-need-help-staging
|
|
WNH_ANDROID_TEST_API_MATRIX="24 30 34 37.0"
|
|
WNH_ANDROID_TEST_DATA_PARTITION_SIZE=1G
|
|
# Public raster tile template used by MapLibre. Use a provider whose policy and
|
|
# capacity match the deployment before a public launch.
|
|
MAP_TILE_URL=https://tile.openstreetmap.org/{z}/{x}/{y}.png
|
|
# Optional verified GitHub linking. Leave both empty until a GitHub OAuth App
|
|
# exists. Its callback URL must be:
|
|
# https://YOUR_PHX_HOST/auth/social/github/callback
|
|
GITHUB_OAUTH_CLIENT_ID=
|
|
GITHUB_OAUTH_CLIENT_SECRET=
|
|
# Optional endpoint and timeout overrides exist for the isolated boundary drill.
|
|
# Leave them empty for GitHub's official endpoints and Req's library timeouts.
|
|
GITHUB_OAUTH_BASE_URL=
|
|
GITHUB_OAUTH_AUTHORIZE_URL=
|
|
GITHUB_OAUTH_TOKEN_URL=
|
|
GITHUB_OAUTH_USER_URL=
|
|
GITHUB_OAUTH_HTTP_CONNECT_TIMEOUT_MS=
|
|
GITHUB_OAUTH_HTTP_RECEIVE_TIMEOUT_MS=
|
|
|
|
# Optional Google OpenID Connect registration and sign-in. Leave both empty
|
|
# until a Google OAuth Web client exists. Android Credential Manager obtains
|
|
# the public client ID from Phoenix at runtime; never copy the secret into the
|
|
# APK or Gradle configuration. The browser callback URL must be:
|
|
# https://YOUR_PHX_HOST/auth/google/callback
|
|
GOOGLE_OAUTH_CLIENT_ID=
|
|
GOOGLE_OAUTH_CLIENT_SECRET=
|
|
# Comma-separated Android OAuth client IDs allowed as the verified azp claim
|
|
# for Credential Manager cross-client ID tokens. Keep environments isolated.
|
|
GOOGLE_OAUTH_AUTHORIZED_PARTY_IDS=
|
|
# Leave endpoint and timeout overrides empty for Google's discovery endpoint
|
|
# and Req defaults. The base URL override exists for isolated protocol tests.
|
|
GOOGLE_OAUTH_BASE_URL=
|
|
GOOGLE_OAUTH_HTTP_CONNECT_TIMEOUT_MS=
|
|
GOOGLE_OAUTH_HTTP_RECEIVE_TIMEOUT_MS=
|
|
|
|
# Optional provider-neutral HTTP push boundary. Leave both endpoint and token
|
|
# empty to disable product push jobs. When enabled, all four numeric values are
|
|
# required deployment inputs; the project does not claim universal production
|
|
# values for them.
|
|
PUSH_HTTP_ENDPOINT=
|
|
PUSH_HTTP_BEARER_TOKEN=
|
|
PUSH_HTTP_MAX_ATTEMPTS=
|
|
PUSH_HTTP_RECEIVE_TIMEOUT_MS=
|
|
PUSH_HTTP_CONNECT_TIMEOUT_MS=
|
|
PUSH_HTTP_RETRY_DELAY_MS=
|
|
|
|
# Direct browser Web Push. Generate one VAPID key pair per environment with
|
|
# scripts/generate-vapid-env.sh and keep the private key only in that
|
|
# environment's .env. The subject must be a mailto: or HTTPS contact owned by
|
|
# the operator.
|
|
WEB_PUSH_VAPID_PUBLIC_KEY=
|
|
WEB_PUSH_VAPID_PRIVATE_KEY=
|
|
WEB_PUSH_VAPID_SUBJECT=
|
|
|
|
# Native Android push through Firebase Cloud Messaging. Either mount the
|
|
# service-account JSON read-only and set its absolute in-container path, or put
|
|
# standard Base64 of that JSON in the single environment file. Never set both.
|
|
# Leave all three values empty to disable FCM.
|
|
FCM_PROJECT_ID=
|
|
FCM_SERVICE_ACCOUNT_FILE=
|
|
FCM_SERVICE_ACCOUNT_JSON_BASE64=
|
|
|
|
POSTGRES_DB=who_need_help
|
|
POSTGRES_USER=postgres
|
|
POSTGRES_PASSWORD=replace-with-a-local-or-deployment-secret
|
|
|
|
# Required only by scripts/dev-scale-seed.sh for the local synthetic viewer.
|
|
# Generate a distinct value; never reuse a real user or deployment password.
|
|
DEV_SCALE_VIEWER_PASSWORD=replace-with-a-random-local-fixture-password
|
|
DATABASE_URL=ecto://postgres:replace-with-url-encoded-password@db/who_need_help
|
|
# Optional absolute host directory containing PostgreSQL Unix sockets. When it
|
|
# is set in external mode, Compose mounts it read-only and Ecto uses it instead
|
|
# of the hostname in DATABASE_URL. Leave empty for container or remote TCP DBs.
|
|
DATABASE_SOCKET_DIR=
|
|
|
|
WEB_POOL_SIZE=4
|
|
WORKER_POOL_SIZE=2
|
|
MIGRATE_POOL_SIZE=2
|
|
COMBINED_POOL_SIZE=4
|
|
OBAN_MAINTENANCE_CONCURRENCY=2
|
|
OBAN_PUSH_CONCURRENCY=1
|
|
OBAN_MAIL_CONCURRENCY=1
|
|
WEB_REPLICAS=2
|
|
WORKER_REPLICAS=2
|
|
# Maximum simultaneously existing Erlang ports (files, sockets and drivers).
|
|
# Keeping this explicit prevents a host's very large nofile ulimit from making
|
|
# every BEAM instance preallocate a multi-gigabyte port table.
|
|
ERLANG_PORT_LIMIT=65536
|
|
SECRET_KEY_BASE=generate-with-mix-phx-gen-secret
|
|
HANDOVER_SECRET=generate-an-independent-random-secret
|
|
RELEASE_COOKIE=generate-an-independent-beam-cluster-cookie
|
|
METRICS_TOKEN=generate-an-independent-random-bearer-token
|
|
|
|
# Use Mailpit locally or a transactional SMTP relay in public environments.
|
|
EMAIL_DELIVERY_PROVIDER=smtp
|
|
SMTP_RELAY=mailpit
|
|
SMTP_PORT=1025
|
|
SMTP_USERNAME=
|
|
SMTP_PASSWORD=
|
|
SMTP_AUTH=never
|
|
SMTP_TLS=never
|
|
SMTP_SSL=false
|
|
EMAIL_FROM_NAME="Who Need Help"
|
|
EMAIL_FROM_ADDRESS=contact@example.com
|
|
# Optional monitored inbox used as Reply-To for support and legal correspondence.
|
|
SUPPORT_INBOX_ADDRESS=
|
|
# Operator email alerts are disabled by default because the permission-scoped
|
|
# staff workspace is the canonical queue. Set immediate only when a monitored
|
|
# mailbox should receive one metadata-only alert for each newly verified case.
|
|
# Ongoing conversation stays in the staff workspace and in-app inbox. Both
|
|
# operator alerts and user-facing support updates use the separate Oban mail queue.
|
|
SUPPORT_OPERATOR_EMAIL_MODE=disabled
|
|
# Pilot policy: an anonymous support/removal email must be confirmed within one
|
|
# day. Confirmed case links remain usable for one year. Both values are seconds
|
|
# and can be changed without rebuilding the release.
|
|
PUBLIC_CONTACT_VERIFICATION_MAX_AGE_SECONDS=86400
|
|
PUBLIC_CASE_ACCESS_MAX_AGE_SECONDS=31536000
|
|
|
|
CODEX_SESSION_ID=copy-the-main-local-codex-session-id
|
|
# Shared PostgreSQL-backed pilot policies. This explicit value makes an
|
|
# operator's effective policy reviewable without inspecting the image. Remove
|
|
# the value to use the same compiled pilot default; set exactly {} only to
|
|
# disable every counter in an isolated benchmark/test environment.
|
|
# Shape: {"action_name":{"limit":POSITIVE_INTEGER,"window_seconds":POSITIVE_INTEGER}}
|
|
# Authentication delivery uses paired email/IP actions:
|
|
# registration_email + registration_ip, magic_link_email + magic_link_ip,
|
|
# password_login_email + password_login_ip, email_change_email + email_change_ip.
|
|
# Public support intake uses support_request (account/email scope) together with
|
|
# support_request_ip (trusted client-IP scope). IP ceilings are intentionally
|
|
# higher than account/email ceilings so shared networks are not treated as one
|
|
# person. These are initial pilot product limits, not universal recommendations.
|
|
RATE_LIMIT_POLICIES_JSON={"registration_email":{"limit":4,"window_seconds":3600},"registration_ip":{"limit":120,"window_seconds":3600},"magic_link_email":{"limit":4,"window_seconds":3600},"magic_link_ip":{"limit":120,"window_seconds":3600},"password_login_email":{"limit":10,"window_seconds":900},"password_login_ip":{"limit":300,"window_seconds":900},"email_change_email":{"limit":3,"window_seconds":86400},"email_change_ip":{"limit":60,"window_seconds":3600},"support_request":{"limit":5,"window_seconds":86400},"support_request_ip":{"limit":120,"window_seconds":3600},"content_removal_notice":{"limit":20,"window_seconds":86400},"content_removal_notice_ip":{"limit":120,"window_seconds":3600}}
|