Docker Setup Docs
All WoWSQL services are published as pre-built Docker images on Docker Hub. Pull them directly, add your configuration, and run. No Git required.
Official Docker Images
We publish 6 images under the wowsql namespace on Docker Hub:
| Image | Description | Pull Command |
|---|---|---|
wowsql/postgres |
PostgreSQL 18 with pgvector, pg_cron, pgjwt & more | docker pull wowsql/postgres:18 |
wowsql/auth |
Authentication (signup, login, JWT, OAuth) | docker pull wowsql/auth:latest |
wowsql/storage |
File storage with bucket-based access | docker pull wowsql/storage:latest |
wowsql/realtime |
WebSocket database change notifications | docker pull wowsql/realtime:latest |
wowsql/backend |
Dashboard API (admin auth, settings, DB ops) | docker pull wowsql/backend:latest |
wowsql/studio |
Web dashboard UI (Next.js) | docker pull wowsql/studio:latest |
Pull all images at once
docker pull wowsql/postgres:18
docker pull wowsql/auth:latest
docker pull wowsql/storage:latest
docker pull wowsql/realtime:latest
docker pull wowsql/backend:latest
docker pull wowsql/studio:latest
Additionally, we use two community images (not published by us):
postgrest/postgrest:v12.2.0— auto-generated REST API from your schemakong:3.9— API gateway for routingredis:7-alpine— caching and pub/sub
Prerequisites
- Docker Engine 20.10 or later
- Docker Compose v2.0 or later (included with Docker Desktop)
- At least 2 GB RAM available for containers
- Ports
8080,5432, and3000available on the host
Setup Steps
Create a project directory
mkdir wowsql && cd wowsql
Create the environment file
Create a .env file — this is the only config you need to customize:
# .env
# REQUIRED — change these
POSTGRES_PASSWORD=your-strong-password-here
JWT_SECRET=your-jwt-secret-at-least-32-characters-long
# OPTIONAL — defaults shown
POSTGRES_USER=postgres
POSTGRES_DB=postgres
POSTGRES_PORT=5432
API_PORT=8080
STUDIO_PORT=3000
API_EXTERNAL_URL=http://localhost:8080
STUDIO_EXTERNAL_URL=http://localhost:3000
JWT_SECRET is used to generate your API keys (anon and service_role). Keep it private. If you change it later, all existing keys are invalidated.Create docker-compose.yml
This file tells Docker how to run all WoWSQL images together:
services:
db:
image: wowsql/postgres:18
restart: unless-stopped
ports:
- "${POSTGRES_PORT:-5432}:5432"
environment:
POSTGRES_USER: ${POSTGRES_USER:-postgres}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB:-postgres}
JWT_SECRET: ${JWT_SECRET}
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 10
rest:
image: postgrest/postgrest:v12.2.0
restart: unless-stopped
depends_on:
db: { condition: service_healthy }
environment:
PGRST_DB_URI: postgres://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB:-postgres}
PGRST_DB_SCHEMAS: public,storage
PGRST_DB_ANON_ROLE: anon
PGRST_JWT_SECRET: ${JWT_SECRET}
auth:
image: wowsql/auth:latest
restart: unless-stopped
depends_on:
db: { condition: service_healthy }
environment:
DATABASE_URL: postgres://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB:-postgres}
JWT_SECRET: ${JWT_SECRET}
API_EXTERNAL_URL: ${API_EXTERNAL_URL:-http://localhost:8080}
storage:
image: wowsql/storage:latest
restart: unless-stopped
depends_on:
db: { condition: service_healthy }
environment:
DATABASE_URL: postgres://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB:-postgres}
JWT_SECRET: ${JWT_SECRET}
volumes:
- storage-data:/var/lib/storage
realtime:
image: wowsql/realtime:latest
restart: unless-stopped
depends_on:
db: { condition: service_healthy }
redis: { condition: service_started }
environment:
DATABASE_URL: postgres://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB:-postgres}
JWT_SECRET: ${JWT_SECRET}
REDIS_URL: redis://redis:6379
redis:
image: redis:7-alpine
restart: unless-stopped
volumes:
- redis-data:/data
kong:
image: kong:3.9
restart: unless-stopped
ports:
- "${API_PORT:-8080}:8000"
environment:
KONG_DATABASE: "off"
KONG_DECLARATIVE_CONFIG: /kong/kong.yml
KONG_DNS_ORDER: LAST,A,SRV,CNAME
KONG_PLUGINS: bundled,cors,key-auth,request-transformer
volumes:
- ./kong.yml:/kong/kong.yml:ro
depends_on: [rest, auth, storage, realtime, backend]
backend:
image: wowsql/backend:latest
restart: unless-stopped
depends_on:
db: { condition: service_healthy }
environment:
DATABASE_URL: postgres://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB:-postgres}
JWT_SECRET: ${JWT_SECRET}
API_EXTERNAL_URL: ${API_EXTERNAL_URL:-http://localhost:8080}
studio:
image: wowsql/studio:latest
restart: unless-stopped
ports:
- "${STUDIO_PORT:-3000}:3000"
environment:
NEXT_PUBLIC_API_URL: ${API_EXTERNAL_URL:-http://localhost:8080}
depends_on: [kong]
volumes:
db-data:
storage-data:
redis-data:
Create Kong gateway config
Create kong.yml — this routes API requests to the correct service:
_format_version: "3.0"
services:
- name: rest
url: http://rest:3000
routes:
- name: rest-route
paths: ["/rest/v1"]
strip_path: true
- name: auth
url: http://auth:9999
routes:
- name: auth-route
paths: ["/auth/v1"]
strip_path: true
- name: storage
url: http://storage:5000
routes:
- name: storage-route
paths: ["/storage/v1"]
strip_path: true
- name: realtime
url: http://realtime:4000
routes:
- name: realtime-route
paths: ["/realtime/v1"]
strip_path: true
- name: backend
url: http://backend:8000
routes:
- name: backend-route
paths: ["/api/v1"]
strip_path: true
plugins:
- name: cors
config:
origins: ["*"]
methods: [GET, POST, PUT, PATCH, DELETE, OPTIONS]
headers: [Content-Type, Authorization, apikey, X-Client-Info]
exposed_headers: [Content-Range]
credentials: true
- name: request-transformer
config:
add:
headers: ["X-Forwarded-Proto:https"]
Run it
docker compose up -d
Docker pulls all images from Docker Hub and starts the stack. First run takes 1-2 minutes.
Verify everything is up
docker compose ps
All services should show running or healthy within 30 seconds.
Open the dashboard
Visit http://localhost:3000 — create your admin account on first launch.
Your File Structure
That's it — just 3 files:
wowsql/
├── .env # your secrets & config
├── docker-compose.yml # service definitions
└── kong.yml # API gateway routing
Configuration Reference
| Variable | Required | Default | Description |
|---|---|---|---|
POSTGRES_PASSWORD | Yes | — | PostgreSQL superuser password |
JWT_SECRET | Yes | — | Secret for signing JWTs (min 32 chars) |
POSTGRES_USER | No | postgres | PostgreSQL username |
POSTGRES_DB | No | postgres | Default database name |
POSTGRES_PORT | No | 5432 | Host port for PostgreSQL |
API_PORT | No | 8080 | Host port for API gateway |
STUDIO_PORT | No | 3000 | Host port for dashboard |
API_EXTERNAL_URL | No | http://localhost:8080 | Public URL for API (set if behind reverse proxy) |
STUDIO_EXTERNAL_URL | No | http://localhost:3000 | Public URL for dashboard |
Image-Specific Configuration
Each WoWSQL image accepts these environment variables:
wowsql/postgres:18
| Variable | Description |
|---|---|
POSTGRES_PASSWORD | Superuser password (required) |
POSTGRES_USER | Superuser name (default: postgres) |
POSTGRES_DB | Default database (default: postgres) |
JWT_SECRET | Used by init scripts to configure pgjwt |
Pre-installed extensions: pgvector, pg_cron, pgjwt, pgaudit, http, pg_hint_plan, hypopg, pg_repack, pg_partman, rum, pgtap, plpgsql_check.
wowsql/auth:latest
| Variable | Description |
|---|---|
DATABASE_URL | PostgreSQL connection string |
JWT_SECRET | Secret for signing auth tokens |
API_EXTERNAL_URL | Public API URL (for OAuth redirect) |
wowsql/storage:latest
| Variable | Description |
|---|---|
DATABASE_URL | PostgreSQL connection string |
JWT_SECRET | Secret for verifying access tokens |
Mount a volume to /var/lib/storage for persistent file storage.
wowsql/realtime:latest
| Variable | Description |
|---|---|
DATABASE_URL | PostgreSQL connection string |
JWT_SECRET | Secret for verifying WebSocket tokens |
REDIS_URL | Redis connection for pub/sub |
wowsql/backend:latest
| Variable | Description |
|---|---|
DATABASE_URL | PostgreSQL connection string |
JWT_SECRET | Secret for admin token signing |
API_EXTERNAL_URL | Public API URL |
wowsql/studio:latest
| Variable | Description |
|---|---|
NEXT_PUBLIC_API_URL | API gateway URL (where the browser calls) |
Updating Images
Pull the latest versions and restart:
docker compose pull
docker compose up -d
Or update a specific service:
docker pull wowsql/backend:latest
docker compose up -d backend
Management
Stop all services
docker compose down
Stop and delete all data
docker compose down -v
-v removes all database data, uploaded files, and Redis data permanently.View logs
docker compose logs -f
docker compose logs -f auth
Restart a service
docker compose restart backend
Troubleshooting
Image pull fails
Make sure you can reach Docker Hub:
docker pull hello-world
If behind a corporate proxy, configure Docker daemon proxy settings.
Services not starting
docker compose ps
docker compose logs [service-name]
Database not ready
PostgreSQL takes a few seconds to initialize on first run:
docker compose logs db | grep "ready to accept connections"
API returns 401
Pass the correct API key in both apikey and Authorization: Bearer headers. Get keys from dashboard Settings.