Initial commit v1

This commit is contained in:
Rolf
2026-03-18 12:37:17 +01:00
commit 4897d3003f
55 changed files with 14241 additions and 0 deletions
+255
View File
@@ -0,0 +1,255 @@
name: mulliganmates
x-supabase-env: &supabase-env
POSTGRES_HOST: ${POSTGRES_HOST:-db}
POSTGRES_PORT: ${POSTGRES_PORT:-5432}
POSTGRES_DB: ${POSTGRES_DB:-postgres}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
JWT_SECRET: ${JWT_SECRET}
ANON_KEY: ${ANON_KEY}
SERVICE_ROLE_KEY: ${SERVICE_ROLE_KEY}
services:
# ── Application ────────────────────────────────────────────
app:
build:
context: .
dockerfile: Dockerfile
restart: unless-stopped
environment:
NEXT_PUBLIC_SUPABASE_URL: ${SUPABASE_PUBLIC_URL}
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${ANON_KEY}
SUPABASE_SERVICE_ROLE_KEY: ${SERVICE_ROLE_KEY}
ADMIN_EMAIL: ${ADMIN_EMAIL}
labels:
- "traefik.enable=true"
- "traefik.http.routers.mulliganmates.rule=Host(`${APP_DOMAIN}`)"
- "traefik.http.routers.mulliganmates.entrypoints=websecure"
- "traefik.http.routers.mulliganmates.tls.certresolver=letsencrypt"
- "traefik.http.services.mulliganmates.loadbalancer.server.port=3000"
networks:
- traefik
- internal
depends_on:
db:
condition: service_healthy
auth:
condition: service_started
# ── Supabase: Database ─────────────────────────────────────
db:
image: supabase/postgres:15.8.1.085
restart: unless-stopped
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres", "-d", "postgres"]
interval: 5s
timeout: 5s
retries: 10
environment:
<<: *supabase-env
POSTGRES_HOST: /var/run/postgresql
volumes:
- db_data:/var/lib/postgresql/data
- ./supabase/migrations:/docker-entrypoint-initdb.d:ro
networks:
- internal
# ── Supabase: Kong (API Gateway) ───────────────────────────
kong:
image: kong/kong:3.9.1
restart: unless-stopped
environment:
KONG_DATABASE: "off"
KONG_DECLARATIVE_CONFIG: /etc/kong/kong.yml
KONG_DNS_ORDER: LAST,A,CNAME
KONG_PLUGINS: request-transformer,cors,key-auth,acl,basic-auth
KONG_NGINX_PROXY_PROXY_BUFFER_SIZE: 160k
KONG_NGINX_PROXY_PROXY_BUFFERS: 64 160k
SUPABASE_ANON_KEY: ${ANON_KEY}
SUPABASE_SERVICE_ROLE_KEY: ${SERVICE_ROLE_KEY}
volumes:
- ./volumes/api/kong.yml:/etc/kong/kong.yml:ro
labels:
- "traefik.enable=true"
- "traefik.http.routers.supabase-api.rule=Host(`${SUPABASE_DOMAIN}`)"
- "traefik.http.routers.supabase-api.entrypoints=websecure"
- "traefik.http.routers.supabase-api.tls.certresolver=letsencrypt"
- "traefik.http.services.supabase-api.loadbalancer.server.port=8000"
networks:
- traefik
- internal
depends_on:
db:
condition: service_healthy
# ── Supabase: Auth (GoTrue) ────────────────────────────────
auth:
image: supabase/gotrue:v2.186.0
restart: unless-stopped
environment:
<<: *supabase-env
GOTRUE_API_HOST: "0.0.0.0"
GOTRUE_API_PORT: 9999
API_EXTERNAL_URL: ${SUPABASE_PUBLIC_URL}
GOTRUE_DB_DRIVER: postgres
GOTRUE_DB_DATABASE_URL: "postgres://supabase_auth_admin:${POSTGRES_PASSWORD}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-postgres}"
GOTRUE_SITE_URL: ${SITE_URL}
GOTRUE_URI_ALLOW_LIST: ${ADDITIONAL_REDIRECT_URLS:-}
GOTRUE_DISABLE_SIGNUP: "true"
GOTRUE_JWT_SECRET: ${JWT_SECRET}
GOTRUE_JWT_EXP: ${JWT_EXPIRY:-3600}
GOTRUE_MAILER_AUTOCONFIRM: "false"
GOTRUE_SMTP_HOST: ${SMTP_HOST}
GOTRUE_SMTP_PORT: ${SMTP_PORT:-1025}
GOTRUE_SMTP_USER: ${SMTP_USER:-}
GOTRUE_SMTP_PASS: ${SMTP_PASS:-}
GOTRUE_SMTP_SENDER_NAME: ${SMTP_SENDER_NAME:-MulliganMates}
GOTRUE_MAILER_URLPATHS_INVITE: "/auth/v1/verify"
GOTRUE_MAILER_URLPATHS_CONFIRMATION: "/auth/v1/verify"
GOTRUE_MAILER_URLPATHS_RECOVERY: "/auth/v1/verify"
GOTRUE_MAILER_URLPATHS_EMAIL_CHANGE: "/auth/v1/verify"
networks:
- internal
depends_on:
db:
condition: service_healthy
# ── Supabase: REST (PostgREST) ─────────────────────────────
rest:
image: postgrest/postgrest:v14.6
restart: unless-stopped
environment:
PGRST_DB_URI: "postgres://authenticator:${POSTGRES_PASSWORD}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-postgres}"
PGRST_DB_SCHEMAS: "public,storage,graphql_public"
PGRST_DB_ANON_ROLE: anon
PGRST_JWT_SECRET: ${JWT_SECRET}
PGRST_DB_USE_LEGACY_GUCS: "false"
PGRST_APP_SETTINGS_JWT_SECRET: ${JWT_SECRET}
PGRST_APP_SETTINGS_JWT_EXP: ${JWT_EXPIRY:-3600}
networks:
- internal
depends_on:
db:
condition: service_healthy
# ── Supabase: Realtime ─────────────────────────────────────
realtime:
image: supabase/realtime:v2.76.5
restart: unless-stopped
environment:
PORT: 4000
DB_HOST: ${POSTGRES_HOST:-db}
DB_PORT: ${POSTGRES_PORT:-5432}
DB_USER: supabase_admin
DB_PASSWORD: ${POSTGRES_PASSWORD}
DB_NAME: ${POSTGRES_DB:-postgres}
DB_AFTER_CONNECT_QUERY: "SET search_path TO _realtime"
DB_ENC_KEY: ${SECRET_KEY_BASE}
API_JWT_SECRET: ${JWT_SECRET}
FLY_ALLOC_ID: fly123
FLY_APP_NAME: realtime
SECRET_KEY_BASE: ${SECRET_KEY_BASE}
ERL_AFLAGS: -proto_dist inet_tcp
DNS_NODES: "''"
RLIMIT_NOFILE: "10000"
networks:
- internal
depends_on:
db:
condition: service_healthy
# ── Supabase: Storage ──────────────────────────────────────
storage:
image: supabase/storage-api:v1.44.2
restart: unless-stopped
environment:
<<: *supabase-env
ANON_KEY: ${ANON_KEY}
SERVICE_KEY: ${SERVICE_ROLE_KEY}
POSTGREST_URL: http://rest:3000
PGRST_JWT_SECRET: ${JWT_SECRET}
DATABASE_URL: "postgres://supabase_storage_admin:${POSTGRES_PASSWORD}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-postgres}"
FILE_SIZE_LIMIT: 52428800
STORAGE_BACKEND: file
FILE_STORAGE_BACKEND_PATH: /var/lib/storage
TENANT_ID: stub
REGION: stub
GLOBAL_S3_BUCKET: stub
volumes:
- storage_data:/var/lib/storage
networks:
- internal
depends_on:
db:
condition: service_healthy
rest:
condition: service_started
# ── Supabase: Meta ─────────────────────────────────────────
meta:
image: supabase/postgres-meta:v0.95.2
restart: unless-stopped
environment:
PG_META_PORT: 8080
PG_META_DB_HOST: ${POSTGRES_HOST:-db}
PG_META_DB_PORT: ${POSTGRES_PORT:-5432}
PG_META_DB_NAME: ${POSTGRES_DB:-postgres}
PG_META_DB_USER: supabase_admin
PG_META_DB_PASSWORD: ${POSTGRES_PASSWORD}
networks:
- internal
depends_on:
db:
condition: service_healthy
# ── Supabase: Studio (dev only) ────────────────────────────
studio:
image: supabase/studio:2026.03.16-sha-5528817
restart: unless-stopped
profiles: ["dev"]
environment:
STUDIO_PG_META_URL: http://meta:8080
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
DEFAULT_ORGANIZATION_NAME: MulliganMates
DEFAULT_PROJECT_NAME: MulliganMates
SUPABASE_URL: http://kong:8000
SUPABASE_PUBLIC_URL: ${SUPABASE_PUBLIC_URL}
SUPABASE_ANON_KEY: ${ANON_KEY}
SUPABASE_SERVICE_KEY: ${SERVICE_ROLE_KEY}
LOGFLARE_API_KEY: ${LOGFLARE_PUBLIC_ACCESS_TOKEN:-}
NEXT_PUBLIC_ENABLE_LOGS: "false"
labels:
- "traefik.enable=true"
- "traefik.http.routers.supabase-studio.rule=Host(`${STUDIO_DOMAIN}`)"
- "traefik.http.routers.supabase-studio.entrypoints=websecure"
- "traefik.http.routers.supabase-studio.tls.certresolver=letsencrypt"
- "traefik.http.services.supabase-studio.loadbalancer.server.port=3000"
networks:
- traefik
- internal
# ── Email: Mailpit (dev only) ──────────────────────────────
mailpit:
image: axllent/mailpit:latest
restart: unless-stopped
profiles: ["dev"]
labels:
- "traefik.enable=true"
- "traefik.http.routers.mailpit.rule=Host(`${MAILPIT_DOMAIN}`)"
- "traefik.http.routers.mailpit.entrypoints=websecure"
- "traefik.http.routers.mailpit.tls.certresolver=letsencrypt"
- "traefik.http.services.mailpit.loadbalancer.server.port=8025"
networks:
- traefik
- internal
volumes:
db_data:
storage_data:
networks:
traefik:
external: true
internal:
driver: bridge