# docker-compose.selfhost.yml — Minimal self-hosted LynxPrompt deployment # Usage: docker compose -f docker-compose.selfhost.yml up -d # # Required env vars (set in .env or environment): # NEXTAUTH_SECRET — generate with: openssl rand -base64 32 # DB_PASSWORD — database password, generate with: openssl rand -hex 24 # # Optional: # ADMIN_EMAIL — your email (auto-promoted to superadmin) # APP_URL — your domain (default: http://localhost:3000) # SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASSWORD, SMTP_FROM: the mail server for # sign-in links services: postgres: image: postgres:18-alpine restart: unless-stopped volumes: # Postgres 18+ keeps its data in a versioned subdirectory and refuses a # mount at /var/lib/postgresql/data, so the volume goes one level up. - pgdata:/var/lib/postgresql environment: POSTGRES_DB: lynxprompt POSTGRES_USER: lynxprompt POSTGRES_PASSWORD: ${DB_PASSWORD:?DB_PASSWORD must be set, generate one with openssl rand -hex 24} healthcheck: test: ["CMD-SHELL", "pg_isready -U lynxprompt -d lynxprompt"] interval: 5s timeout: 5s retries: 5 lynxprompt: # A published release tag (tests/workflows/selfhost-compose.test.ts checks # it exists on Docker Hub). Newer releases: https://hub.docker.com/r/drumsergio/lynxprompt/tags image: drumsergio/lynxprompt:2.1.40 # The image is built for amd64 only; this lets ARM hosts (Apple Silicon, # Raspberry Pi) run it under emulation instead of failing at pull. platform: linux/amd64 restart: unless-stopped ports: - "${PORT:-3000}:3000" depends_on: postgres: condition: service_healthy environment: # One PostgreSQL server, one database per Prisma schema: prisma db push # drops the tables it does not know, so two schemas in one database would # delete each other's tables at every start. The entrypoint's db push # creates the three databases after lynxprompt on the first start. The # password is defined once and shared with the Postgres container. DB_APP_HOST: postgres DB_APP_USER: lynxprompt DB_APP_PASSWORD: ${DB_PASSWORD:?DB_PASSWORD must be set, generate one with openssl rand -hex 24} DB_APP_NAME: lynxprompt DB_USERS_HOST: postgres DB_USERS_USER: lynxprompt DB_USERS_PASSWORD: ${DB_PASSWORD:?DB_PASSWORD must be set, generate one with openssl rand -hex 24} DB_USERS_NAME: lynxprompt_users DB_BLOG_HOST: postgres DB_BLOG_USER: lynxprompt DB_BLOG_PASSWORD: ${DB_PASSWORD:?DB_PASSWORD must be set, generate one with openssl rand -hex 24} DB_BLOG_NAME: lynxprompt_blog DB_SUPPORT_HOST: postgres DB_SUPPORT_USER: lynxprompt DB_SUPPORT_PASSWORD: ${DB_PASSWORD:?DB_PASSWORD must be set, generate one with openssl rand -hex 24} DB_SUPPORT_NAME: lynxprompt_support NEXTAUTH_SECRET: ${NEXTAUTH_SECRET:?NEXTAUTH_SECRET must be set, generate one with openssl rand -base64 32} NEXTAUTH_URL: ${APP_URL:-http://localhost:3000} APP_URL: ${APP_URL:-http://localhost:3000} SUPERADMIN_EMAIL: ${ADMIN_EMAIL:-} # Sign-in mail. The default login is a link sent by mail, so a real # deployment sets these in .env. To try it out without a mail server, # add -f docker-compose.mailpit.yml to the docker compose line. SMTP_HOST: ${SMTP_HOST:-} SMTP_PORT: ${SMTP_PORT:-587} SMTP_USER: ${SMTP_USER:-} SMTP_PASSWORD: ${SMTP_PASSWORD:-} SMTP_FROM: ${SMTP_FROM:-} NODE_ENV: production volumes: pgdata: