docker-compose.yml
Rama main · réplica de lectura del repositorio original.
# Production docker-compose for Spanlens self-hosted deployment.
#
# Prerequisites:
# 1. Apply the database schema (one-time setup):
# Open Supabase Dashboard → SQL Editor → New query
# Paste the contents of supabase/init.sql and click Run
# 2. Create a .env file in this directory with the required variables below.
# 3. Run: docker compose up -d
#
# Required .env variables:
# NEXT_PUBLIC_SUPABASE_URL e.g. https://abc.supabase.co
# NEXT_PUBLIC_SUPABASE_ANON_KEY eyJ...
# SUPABASE_URL same as NEXT_PUBLIC_SUPABASE_URL (used by server)
# SUPABASE_ANON_KEY same as NEXT_PUBLIC_SUPABASE_ANON_KEY
# SUPABASE_SERVICE_ROLE_KEY service_role key (never expose to browser)
# ENCRYPTION_KEY 32-byte base64 string (see apps/server/.env.example)
# CRON_SECRET random secret for cron endpoint auth
#
# Optional .env variables:
# WEB_URL public URL of the web app (for invite emails)
# RESEND_API_KEY for transactional email
# RESEND_FROM sender address (e.g. Spanlens <no-reply@yourdomain.com>)
# PADDLE_API_KEY / PADDLE_NOTIFICATION_SECRET / PADDLE_ENVIRONMENT
# PADDLE_PRICE_STARTER / PADDLE_PRICE_TEAM / PADDLE_PRICE_ENTERPRISE
#
# Postgres pooled connection (the `requests` log is read and written over this):
# SUPABASE_DB_POOLER_URL transaction-mode pooler URL on port 6543
# (Supabase Dashboard -> Project Settings ->
# Database -> Connection string -> Transaction pooler).
# A full DB credential: never log it.
services:
web:
# Default: pull pre-built image from GHCR (no build required).
# docker-entrypoint.sh patches NEXT_PUBLIC_* placeholders at startup.
# To build locally instead: docker compose up -d --build
image: ghcr.io/spanlens/spanlens-web:latest
build:
context: .
dockerfile: apps/web/Dockerfile
# Build args override the placeholder defaults so the bundle already
# contains real values (entrypoint sed is then a no-op). Omit args
# to rely on entrypoint patching instead (works either way).
args:
NEXT_PUBLIC_SUPABASE_URL: ${NEXT_PUBLIC_SUPABASE_URL}
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${NEXT_PUBLIC_SUPABASE_ANON_KEY}
API_URL: http://server:3001
ports:
- '3000:3000'
environment:
API_URL: http://server:3001
NEXT_PUBLIC_SUPABASE_URL: ${NEXT_PUBLIC_SUPABASE_URL}
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${NEXT_PUBLIC_SUPABASE_ANON_KEY}
SUPABASE_SERVICE_ROLE_KEY: ${SUPABASE_SERVICE_ROLE_KEY}
depends_on:
server:
condition: service_healthy
restart: unless-stopped
healthcheck:
test: ['CMD-SHELL', 'wget --quiet --spider http://localhost:3000/ || exit 1']
interval: 30s
timeout: 10s
start_period: 20s
retries: 3
server:
# Default: pull pre-built image from GHCR.
# To build locally instead: docker compose up -d --build
image: ghcr.io/spanlens/spanlens-server:latest
build:
context: .
dockerfile: apps/server/Dockerfile
ports:
- '3001:3001'
environment:
PORT: 3001
SUPABASE_URL: ${SUPABASE_URL}
SUPABASE_ANON_KEY: ${SUPABASE_ANON_KEY}
SUPABASE_SERVICE_ROLE_KEY: ${SUPABASE_SERVICE_ROLE_KEY}
ENCRYPTION_KEY: ${ENCRYPTION_KEY}
CRON_SECRET: ${CRON_SECRET}
WEB_URL: ${WEB_URL:-http://localhost:3000}
RESEND_API_KEY: ${RESEND_API_KEY:-}
RESEND_FROM: ${RESEND_FROM:-}
PADDLE_API_KEY: ${PADDLE_API_KEY:-}
PADDLE_NOTIFICATION_SECRET: ${PADDLE_NOTIFICATION_SECRET:-}
PADDLE_ENVIRONMENT: ${PADDLE_ENVIRONMENT:-sandbox}
PADDLE_PRICE_STARTER: ${PADDLE_PRICE_STARTER:-}
PADDLE_PRICE_TEAM: ${PADDLE_PRICE_TEAM:-}
PADDLE_PRICE_ENTERPRISE: ${PADDLE_PRICE_ENTERPRISE:-}
SUPABASE_DB_POOLER_URL: ${SUPABASE_DB_POOLER_URL}
restart: unless-stopped
healthcheck:
test: ['CMD-SHELL', 'wget --quiet --spider http://localhost:3001/health || exit 1']
interval: 30s
timeout: 5s
start_period: 10s
retries: 3