From e677d69bbe4d52059983665f54f8f5cb2239e1d1 Mon Sep 17 00:00:00 2001 From: Poyraz Avsever Date: Sun, 14 Jun 2026 12:02:26 +0300 Subject: [PATCH] feat: add docker-compose configuration for Neta services including web, auth, and database components --- docker-compose.dokploy.yml | 158 +++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 docker-compose.dokploy.yml diff --git a/docker-compose.dokploy.yml b/docker-compose.dokploy.yml new file mode 100644 index 0000000..55b788e --- /dev/null +++ b/docker-compose.dokploy.yml @@ -0,0 +1,158 @@ +services: + neta-web: + build: + context: . + dockerfile: Dockerfile + args: + NEXT_PUBLIC_SUPABASE_URL: ${NEXT_PUBLIC_SUPABASE_URL:?Set NEXT_PUBLIC_SUPABASE_URL in Dokploy env} + NEXT_PUBLIC_SUPABASE_ANON_KEY: ${NEXT_PUBLIC_SUPABASE_ANON_KEY:?Set NEXT_PUBLIC_SUPABASE_ANON_KEY in Dokploy env} + NEXT_PUBLIC_SITE_URL: ${NEXT_PUBLIC_SITE_URL:-http://localhost:3000} + restart: unless-stopped + depends_on: + neta-migrations: + condition: service_completed_successfully + neta-supabase-proxy: + condition: service_healthy + expose: + - "3000" + environment: + NODE_ENV: production + NEXT_PUBLIC_SUPABASE_URL: ${NEXT_PUBLIC_SUPABASE_URL:?Set NEXT_PUBLIC_SUPABASE_URL in Dokploy env} + NEXT_PUBLIC_SUPABASE_ANON_KEY: ${NEXT_PUBLIC_SUPABASE_ANON_KEY:?Set NEXT_PUBLIC_SUPABASE_ANON_KEY in Dokploy env} + SUPABASE_SERVICE_ROLE_KEY: ${SUPABASE_SERVICE_ROLE_KEY:?Set SUPABASE_SERVICE_ROLE_KEY in Dokploy env} + SUPABASE_INTERNAL_URL: http://neta-supabase-proxy:8000 + NEXT_PUBLIC_SITE_URL: ${NEXT_PUBLIC_SITE_URL:-http://localhost:3000} + + neta-supabase-proxy: + image: nginx:1.27-alpine + restart: unless-stopped + depends_on: + neta-auth: + condition: service_started + neta-rest: + condition: service_started + neta-storage: + condition: service_started + expose: + - "8000" + volumes: + - ./deploy/supabase/nginx/default.conf.template:/etc/nginx/templates/default.conf.template:ro + healthcheck: + test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:8000/health >/dev/null"] + interval: 10s + timeout: 5s + retries: 12 + + neta-auth: + image: supabase/gotrue:v2.189.0 + restart: unless-stopped + depends_on: + neta-db: + condition: service_healthy + environment: + GOTRUE_API_HOST: 0.0.0.0 + GOTRUE_API_PORT: 9999 + API_EXTERNAL_URL: ${NEXT_PUBLIC_SUPABASE_URL:?Set NEXT_PUBLIC_SUPABASE_URL in Dokploy env}/auth/v1 + GOTRUE_SITE_URL: ${NEXT_PUBLIC_SITE_URL:-http://localhost:3000} + GOTRUE_URI_ALLOW_LIST: ${NEXT_PUBLIC_SITE_URL:-http://localhost:3000} + GOTRUE_DB_DRIVER: postgres + GOTRUE_DB_DATABASE_URL: postgres://supabase_auth_admin:${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in Dokploy env}@neta-db:5432/postgres + GOTRUE_JWT_SECRET: ${JWT_SECRET:?Set JWT_SECRET in Dokploy env} + GOTRUE_JWT_EXP: ${JWT_EXPIRY:-3600} + GOTRUE_JWT_DEFAULT_GROUP_NAME: authenticated + GOTRUE_DISABLE_SIGNUP: "false" + GOTRUE_EXTERNAL_EMAIL_ENABLED: "true" + GOTRUE_MAILER_AUTOCONFIRM: "true" + GOTRUE_SMTP_ADMIN_EMAIL: ${SMTP_ADMIN_EMAIL:-admin@neta.local} + GOTRUE_SMTP_HOST: ${SMTP_HOST:-} + GOTRUE_SMTP_PORT: ${SMTP_PORT:-587} + GOTRUE_SMTP_USER: ${SMTP_USER:-} + GOTRUE_SMTP_PASS: ${SMTP_PASS:-} + GOTRUE_SMTP_SENDER_NAME: ${SMTP_SENDER_NAME:-Neta} + + neta-rest: + image: postgrest/postgrest:v12.2.12 + restart: unless-stopped + depends_on: + neta-db: + condition: service_healthy + environment: + PGRST_DB_URI: postgres://authenticator:${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in Dokploy env}@neta-db:5432/postgres + PGRST_DB_SCHEMAS: public,storage + PGRST_DB_ANON_ROLE: anon + PGRST_JWT_SECRET: ${JWT_SECRET:?Set JWT_SECRET in Dokploy env} + PGRST_DB_USE_LEGACY_GUCS: "false" + + neta-storage: + image: supabase/storage-api:v1.24.7 + restart: unless-stopped + depends_on: + neta-db: + condition: service_healthy + neta-rest: + condition: service_started + environment: + ANON_KEY: ${NEXT_PUBLIC_SUPABASE_ANON_KEY:?Set NEXT_PUBLIC_SUPABASE_ANON_KEY in Dokploy env} + SERVICE_KEY: ${SUPABASE_SERVICE_ROLE_KEY:?Set SUPABASE_SERVICE_ROLE_KEY in Dokploy env} + POSTGREST_URL: http://neta-rest:3000 + PGRST_JWT_SECRET: ${JWT_SECRET:?Set JWT_SECRET in Dokploy env} + DATABASE_URL: postgres://supabase_storage_admin:${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in Dokploy env}@neta-db:5432/postgres + FILE_SIZE_LIMIT: ${STORAGE_FILE_SIZE_LIMIT:-52428800} + STORAGE_BACKEND: file + FILE_STORAGE_BACKEND_PATH: /var/lib/storage + TENANT_ID: stub + REGION: local + GLOBAL_S3_BUCKET: stub + ENABLE_IMAGE_TRANSFORMATION: "false" + volumes: + - neta-storage-data:/var/lib/storage + + neta-migrations: + image: postgres:16-alpine + depends_on: + neta-db: + condition: service_healthy + neta-storage: + condition: service_started + environment: + DATABASE_URL: postgres://postgres:${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in Dokploy env}@neta-db:5432/postgres + volumes: + - ./supabase:/app/supabase:ro + - ./scripts:/app/scripts:ro + working_dir: /app + command: + - sh + - -c + - | + tries=0 + until psql "$$DATABASE_URL" -v ON_ERROR_STOP=1 -tAc "select case when to_regclass('auth.users') is not null and to_regclass('storage.buckets') is not null then 'ready' else 'waiting' end" | grep -q "ready"; do + tries=$$((tries + 1)) + if [ "$$tries" -gt 60 ]; then + echo "Timed out waiting for Supabase Auth/Storage schemas." + exit 1 + fi + echo "Waiting for Supabase Auth/Storage schemas..." + sleep 2 + done + sh ./scripts/apply-migrations.sh + + neta-db: + image: pgvector/pgvector:pg16 + restart: unless-stopped + environment: + POSTGRES_DB: postgres + POSTGRES_USER: postgres + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in Dokploy env} + POSTGRES_INITDB_ARGS: --auth-host=scram-sha-256 + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"] + interval: 5s + timeout: 5s + retries: 20 + volumes: + - neta-db-data:/var/lib/postgresql/data + - ./deploy/supabase/db/init.sh:/docker-entrypoint-initdb.d/00-neta-init.sh:ro + +volumes: + neta-db-data: + neta-storage-data: