Quick Start
# Clone and start
git clone https://github.com/steelengineai/steelengine.git && cd steelengine
docker compose -f docker-compose.prod.yml up -dProduction Setup
1. Configure Environment
# Generate secrets
cat > .env << EOF
DATABASE_URL=postgresql://postgres:postgres@db:5432/steelengine
BETTER_AUTH_SECRET=$(openssl rand -hex 32)
ENCRYPTION_KEY=$(openssl rand -hex 32)
INTERNAL_API_SECRET=$(openssl rand -hex 32)
TEMPORAL_WORKER_BROKER_SECRET=$(openssl rand -hex 32)
NEXT_PUBLIC_APP_URL=https://steelengine.yourdomain.com
BETTER_AUTH_URL=https://steelengine.yourdomain.com
NEXT_PUBLIC_SOCKET_URL=https://steelengine.yourdomain.com
TEMPORAL_WORKER_APP_URL=https://steelengine.yourdomain.com
EOFTEMPORAL_WORKER_APP_URL must be an HTTPS URL reachable from the Worker. The
Worker authenticates to that web endpoint with the normal internal-service
token plus a separate, purpose-bound proof signed by
TEMPORAL_WORKER_BROKER_SECRET. Use different random values for the two
secrets. Only web and Worker receive the broker secret. Production Compose does
not accept a static TEMPORAL_API_KEY for the Worker.
2. Start Services
docker compose -f docker-compose.prod.yml up -d3. Set Up SSL
Caddy automatically handles SSL certificates.
# Install Caddy
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update && sudo apt install caddyCreate /etc/caddy/Caddyfile:
steelengine.yourdomain.com {
reverse_proxy localhost:3000
handle /socket.io/* {
reverse_proxy localhost:3002
}
}sudo systemctl restart caddy# Install
sudo apt install nginx certbot python3-certbot-nginx -y
# Create /etc/nginx/sites-available/steelengine
server {
listen 80;
server_name steelengine.yourdomain.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /socket.io/ {
proxy_pass http://127.0.0.1:3002;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
# Enable and get certificate
sudo ln -s /etc/nginx/sites-available/steelengine /etc/nginx/sites-enabled/
sudo certbot --nginx -d steelengine.yourdomain.comOllama
# With GPU
docker compose -f docker-compose.ollama.yml --profile gpu --profile setup up -d
# CPU only
docker compose -f docker-compose.ollama.yml --profile cpu --profile setup up -dPull additional models:
docker compose -f docker-compose.ollama.yml exec ollama ollama pull llama3.2External Ollama
If Ollama runs on your host machine (not in Docker):
# macOS/Windows
OLLAMA_URL=http://host.docker.internal:11434 docker compose -f docker-compose.prod.yml up -d
# Linux - use your host IP
OLLAMA_URL=http://192.168.1.100:11434 docker compose -f docker-compose.prod.yml up -dInside Docker, localhost refers to the container, not your host. Use host.docker.internal or your host's IP.
Commands
# View logs
docker compose -f docker-compose.prod.yml logs -f steelengine
# Stop
docker compose -f docker-compose.prod.yml down
# Update
docker compose -f docker-compose.prod.yml pull && docker compose -f docker-compose.prod.yml up -d
# Backup database
docker compose -f docker-compose.prod.yml exec db pg_dump -U postgres steelengine > backup.sqlCommon Questions
Five services are started: steelengine (main app on port 3000, 8 GB memory limit), steelengine-worker (Temporal Worker, 4 GB memory limit, internal only), realtime (WebSocket server on port 3002, 1 GB memory limit), db (PostgreSQL 17 with pgvector on port 5432), and migrations (runs once to apply database schema changes, then exits). Configure the worker's TEMPORAL_* variables to connect it to your Temporal cluster.
You can use either Caddy (recommended, handles certificates automatically) or Nginx with Certbot. Both need to reverse-proxy port 3000 for the main app and port 3002 for WebSocket connections at the /socket.io/ path.
Inside a Docker container, localhost refers to the container itself, not your host machine. On macOS and Windows, use http://host.docker.internal:11434. On Linux, use your host machine's actual IP address (e.g., http://192.168.1.100:11434).
The GPU profile (--profile gpu) configures NVIDIA driver capabilities and reserves GPU devices for accelerated inference. The CPU profile (--profile cpu) runs Ollama without GPU acceleration. Both use the --profile setup flag to automatically pull the gemma3:4b starter model.
Run docker compose -f docker-compose.prod.yml pull to fetch the latest images, then docker compose -f docker-compose.prod.yml up -d to restart with the new versions. The migrations container will automatically apply any new database schema changes on startup.
Back up with: docker compose -f docker-compose.prod.yml exec db pg_dump -U postgres steelengine > backup.sql. Restore with: docker compose -f docker-compose.prod.yml exec -T db psql -U postgres steelengine < backup.sql. The database data is persisted in a Docker volume named postgres_data.
Yes. The docker-compose.prod.yml uses environment variable defaults: POSTGRES_USER (default: postgres), POSTGRES_PASSWORD (default: postgres), POSTGRES_DB (default: steelengine), and POSTGRES_PORT (default: 5432). Set these in your .env file to override them.