Guides
Deploying
Production deployment on Hetzner with Docker Compose.
Server Setup (Hetzner)
- Provision a server (recommended: CX32 or larger — 4 vCPU, 8 GB RAM)
- Install Docker + Docker Compose
- Clone the repository
- Configure environment
Production Environment
Create a .env.production with production values:
# Required
GITHUB_TOKEN=ghp_... # Private package access
HOST_IP=your-server-ip
# LLM — at least one required for AI features
OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...
# Security — generate unique keys
ENCRYPTION_KEY=$(php -r "echo bin2hex(random_bytes(32));")
BLIND_INDEX_KEY=$(php -r "echo bin2hex(random_bytes(32));")
# Tenant
TENANT_SLUG=your-tenant
# App URLs
APP_URL=https://api.yourdomain.com
FRONTEND_URL=https://yourdomain.comWarning
Never reuse the default encryption keys (dev_encryption_key_32chars_change_me) in production. Generate unique keys for each deployment.
Start Production Stack
docker compose -f docker-compose.yml --env-file .env.production up -d --build
# Initialize
docker exec -it ubios_api php artisan key:generate --force
docker exec -it ubios_api php artisan migrate
docker exec -it ubios_api php artisan db:seed --class=UbiosDatabaseSeederSSL / Reverse Proxy
Use Nginx or Caddy as a reverse proxy in front of the Nuxt container:
server {
listen 443 ssl;
server_name yourdomain.com;
ssl_certificate /etc/ssl/yourdomain.crt;
ssl_certificate_key /etc/ssl/yourdomain.key;
location / {
proxy_pass http://127.0.0.1:6080;
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;
}
}Backups
PostgreSQL data lives in a Docker volume. Back up regularly:
# Create backup
docker exec ubios_postgres pg_dump -U postgres ubios > backup_$(date +%Y%m%d).sql
# Restore
cat backup_20260410.sql | docker exec -i ubios_postgres psql -U postgres ubiosMonitoring
docker ps— check all containers are runningdocker compose logs -f— live log tailing- Agno health:
curl http://localhost:8001/health - PostgreSQL health:
docker inspect ubios_postgres --format='{{.State.Health.Status}}'
Scaling Notes
Each customer gets their own Docker Compose stack. For multiple customers:
- Use separate Hetzner servers (simplest, most isolated)
- Or use Docker Compose profiles / separate compose files on a single high-spec server