Docker Compose Deployment
Deploy Magnet AI in a production-like, single-host setup using Docker Compose (PostgreSQL + pgvector + Nginx reverse proxy).
Prerequisites
- Docker 20.10+
- Docker Compose v2 (
docker compose) - 4GB+ RAM
- 20GB+ disk space
Overview
- Public entrypoint:
nginx(ports 80/443) - Application:
app(internal port 5000, serves Admin/Panel/Help +/api) - Database:
postgres(internal, persisted via a named volume)
1. Create a deployment directory
bash
mkdir magnet-ai-deploy
cd magnet-ai-deployThis guide uses the prebuilt image
ghcr.io/ideaportriga/magnet-ai:latest.
2. Environment configuration (.env)
This file serves two purposes:
- Docker Compose variable substitution: the compose file uses
${...}values from.env. - Runtime configuration: the same values are passed into the Magnet AI container as environment variables.
Create .env next to your docker-compose.prod.yml:
bash
# Database (used by both Postgres and Magnet AI)
DB_NAME=magnet_prod
DB_USER=magnet
DB_PASSWORD=strong-password-here
# Encrypt/decrypt secrets stored in the database (provider keys, OAuth secrets, etc.)
# Keep this stable across restarts.
SECRET_ENCRYPTION_KEY=generate-strong-secret-key
# Auth / CORS
AUTH_ENABLED=true
# Leave empty when serving UI from the same domain; otherwise set explicitly.
CORS_OVERRIDE_ALLOWED_ORIGINS=https://yourdomain.com3. Create Docker Compose file
Create docker-compose.prod.yml:
yaml
version: "3.8"
services:
postgres:
image: pgvector/pgvector:pg16
environment:
POSTGRES_DB: ${DB_NAME:-magnet_prod}
POSTGRES_USER: ${DB_USER:-magnet}
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-magnet} -d ${DB_NAME:-magnet_prod}"]
interval: 10s
timeout: 5s
retries: 5
restart: always
app:
image: ghcr.io/ideaportriga/magnet-ai:latest
environment:
ENV: production
PORT: 5000
DB_TYPE: postgresql
DB_HOST: postgres
DB_PORT: 5432
DB_NAME: ${DB_NAME:-magnet_prod}
DB_USER: ${DB_USER:-magnet}
DB_PASSWORD: ${DB_PASSWORD}
WEB_INCLUDED: "true"
AUTH_ENABLED: ${AUTH_ENABLED:-true}
CORS_OVERRIDE_ALLOWED_ORIGINS: ${CORS_OVERRIDE_ALLOWED_ORIGINS:-https://yourdomain.com}
RUN_MIGRATIONS: "true"
# Encrypt/decrypt secrets stored in the database (provider keys, OAuth secrets, etc.)
SECRET_ENCRYPTION_KEY: ${SECRET_ENCRYPTION_KEY}
depends_on:
postgres:
condition: service_healthy
restart: always
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
- ./ssl:/etc/nginx/ssl:ro
depends_on:
- app
restart: always
volumes:
postgres_data:4. Configure TLS + Nginx
Using Let's Encrypt
bash
# Install certbot
sudo apt-get update
sudo apt-get install -y certbot
# Get certificate
sudo certbot certonly --standalone -d yourdomain.com
# Certificates will be in:
# /etc/letsencrypt/live/yourdomain.com/
#
# Copy the certificate files to ./ssl for the nginx container:
# - fullchain.pem
# - privkey.pemNginx Configuration
Create nginx.conf:
nginx
server {
listen 80;
server_name yourdomain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name yourdomain.com;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
location / {
proxy_pass http://app:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}5. Deploy
bash
docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -dAfter deploy, open:
https://yourdomain.com/admin/https://yourdomain.com/panel/https://yourdomain.com/help/https://yourdomain.com/api
6. Upgrades
For updates, pull the latest image and restart:
bash
docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -d