This guide explains how to deploy BosBase as a standalone single-node installation using Docker Compose, with optional reverse proxy configuration using NGINX or Caddy.
- Docker and Docker Compose installed
- A server with at least 2G RAM and 10GB disk space
- Domain name (optional, for production deployments)
For freshly provisioned hosts you can run the bundled installers instead of performing every step manually.
The unified installer automatically detects your OS (Ubuntu or Rocky Linux):
git clone https://github.com/bosbase/self-host.git
cd self-host
chmod +x install.sh
sudo ./install.sh --domain yourdomain.com --email you@example.comgit clone https://github.com/bosbase/self-host.git
cd self-host
chmod +x install-ubuntu.sh
sudo ./install-ubuntu.sh --domain yourdomain.com --email you@example.comgit clone https://github.com/bosbase/self-host.git
cd self-host
chmod +x install-rocky.sh
sudo ./install-rocky.sh --domain yourdomain.com --email you@example.com- Important:
--openai-key/--openai-base-urlcan be set during installation for vector and LLM document features:sudo ./install.sh --domain yourdomain.com --email you@example.com \ --openai-key sk-xxxxx \ --openai-base-url https://api.openai.com/v1
- The script will prompt for any values you do not pass via flags (domain, email,
BS_ENCRYPTION_KEY). --non-interactiveforces the script to fail when required values are missing instead of prompting.- Assets are installed under
/opt/bosbase, Docker + Caddy are installed if missing, anddocker-compose@bosbase.serviceis enabled automatically.
If you didn't set the OpenAI configuration during installation, or need to update it later, follow these steps:
sudo nano /opt/bosbase/.envUpdate or add the following lines:
OPENAI_API_KEY=sk-your-api-key-here
OPENAI_BASE_URL=https://api.openai.com/v1Then restart the service:
sudo systemctl restart docker-compose@bosbase.servicesudo nano /opt/bosbase/docker-compose.ymlFind and update the environment variables:
environment:
OPENAI_API_KEY: sk-your-api-key-here
OPENAI_BASE_URL: https://api.openai.com/v1Then restart:
cd /opt/bosbase
sudo docker compose down
sudo docker compose -f docker-compose.db.yml up -d
sudo docker compose -f docker-compose.yml up -d| Provider | Base URL |
|---|---|
| OpenAI | https://api.openai.com/v1 |
| Azure OpenAI | https://YOUR_RESOURCE.openai.azure.com/openai/deployments/YOUR_DEPLOYMENT |
| Custom/Self-hosted | Your custom endpoint URL |
After restarting, check that the service is running:
sudo docker logs bosbase-bosbase-node-1 | grep -i openaiPull the required Docker images from Docker Hub:
docker pull pgvector/pgvector:pg16
docker pull bosbase/bosbase:ve1Create a docker-compose.yml file in your working directory:
docker-compose.db.yml (database):
services:
postgres-db:
image: pgvector/pgvector:pg16
restart: unless-stopped
environment:
POSTGRES_DB: pbosbase
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
volumes:
- ./postgres-data:/var/lib/postgresql/data
ports:
- "5432:5432"
networks:
- basenode
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d pbosbase"]
interval: 2s
timeout: 5s
retries: 10
start_period: 10s
networks:
basenode:
driver: bridge
name: basenodedocker-compose.yml (application):
services:
bosbase-node:
image: bosbase/bosbase:ve1
restart: unless-stopped
environment:
SASSPB_POSTGRES_URL: postgres://postgres:postgres@postgres-db:5432/pbosbase?sslmode=disable
BS_ENCRYPTION_KEY: your-32-character-encryption-key-here
OPENAI_API_KEY: ${OPENAI_API_KEY:-sk-af61vU1kIT0uw5YzOM7VRM3KGrxBAfuhVgJX9ghtkHfdRVsu}
OPENAI_BASE_URL: ${OPENAI_BASE_URL:-https://api.chatanywhere.org/v1}
PB_ACTIVATION_VERIFY_URL: ${PB_ACTIVATION_VERIFY_URL:-https://ve.bosbase.com/verify}
# REDIS_URL: ${REDIS_URL:-192.168.1.60:6379}
# REDIS_PASSWORD: ${REDIS_PASSWORD:-}
WASM_ENABLE: ${WASM_ENABLE:-true}
WASM_INSTANCE_NUM: ${WASM_INSTANCE_NUM:-8}
SCRIPT_CONCURRENCY: ${SCRIPT_CONCURRENCY:-8}
FUNCTION_CONN_NUM: ${FUNCTION_CONN_NUM:-10}
EXECUTE_PATH: ${EXECUTE_PATH:-/pb/functions}
# BOOSTER_PATH: ${BOOSTER_PATH:-/pb/booster-wasm}
# BOOSTER_POOL_MAX: ${BOOSTER_POOL_MAX:-2}
# BOOSTER_WASMTIME_MEMORY_GUARD_SIZE: ${BOOSTER_WASMTIME_MEMORY_GUARD_SIZE:-65536}
# BOOSTER_WASMTIME_MEMORY_RESERVATION: ${BOOSTER_WASMTIME_MEMORY_RESERVATION:-0}
# BOOSTER_WASMTIME_MEMORY_RESERVATION_FOR_GROWTH: ${BOOSTER_WASMTIME_MEMORY_RESERVATION_FOR_GROWTH:-1048576}
PB_DATA_MAX_OPEN_CONNS: ${PB_DATA_MAX_OPEN_CONNS:-30}
PB_DATA_MAX_IDLE_CONNS: ${PB_DATA_MAX_IDLE_CONNS:-15}
PB_AUX_MAX_OPEN_CONNS: ${PB_AUX_MAX_OPEN_CONNS:-10}
PB_AUX_MAX_IDLE_CONNS: ${PB_AUX_MAX_IDLE_CONNS:-3}
PB_QUERY_TIMEOUT: ${PB_QUERY_TIMEOUT:-300s}
ports:
- "8090:8090"
- "2678:2678"
volumes:
- ./bosbase-data:/pb/pb_data
- ./pb_hooks:/pb_hooks
networks:
- basenode
networks:
basenode:
external: true
name: basenodeImportant: Generate a strong encryption key and replace your-32-character-encryption-key-here:
openssl rand -hex 16Create a .env file for environment variables:
OPENAI_API_KEY=sk-your-key-here
OPENAI_BASE_URL=https://api.openai.com/v1Start the services using Docker Compose:
docker compose -f docker-compose.db.yml up -d
docker compose -f docker-compose.yml up -dThis will start:
- postgres-db: PostgreSQL database with pgvector extension (port 5432)
- bosbase-node: BosBase application server (ports 8090, 2678)
- Admin UI: http://localhost:8090/_/
- API: http://localhost:8090
Create your first admin user by accessing the admin UI and following the setup wizard.
Alternatively, create a superuser via command line:
docker exec docker-bosbase-node-1 /pb/bosbase superuser upsert yourloginemail yourpassworddocker compose -f docker-compose.yml down
docker compose -f docker-compose.db.yml downTo also remove volumes (
docker compose -f docker-compose.yml down -v
docker compose -f docker-compose.db.yml down -vFor production deployments, it's recommended to use a reverse proxy (NGINX or Caddy) to:
- Handle SSL/TLS certificates
- Provide a custom domain
- Add security headers
- Enable load balancing (if scaling later)
# Ubuntu/Debian
sudo apt update && sudo apt install nginx
# CentOS/RHEL
sudo yum install nginxCreate /etc/nginx/sites-available/bosbase (or /etc/nginx/conf.d/bosbase.conf on CentOS):
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
# Redirect HTTP to HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name yourdomain.com www.yourdomain.com;
# SSL Certificate (use Let's Encrypt)
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
# SSL Configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Security Headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
# Proxy Settings
client_max_body_size 50M;
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
location / {
proxy_pass http://localhost:8090;
proxy_http_version 1.1;
# WebSocket support (for realtime subscriptions)
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Standard proxy headers
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;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
# Disable buffering for realtime features
proxy_buffering off;
}
}# Ubuntu/Debian
sudo ln -s /etc/nginx/sites-available/bosbase /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
# CentOS/RHEL
sudo nginx -t
sudo systemctl reload nginxsudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.comCertbot will automatically configure NGINX and set up auto-renewal.
Caddy automatically handles SSL certificates and is easier to configure.
# Ubuntu/Debian
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
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 caddy
# Or use the official installer
curl https://getcaddy.com | bashCreate /etc/caddy/Caddyfile:
yourdomain.com {
reverse_proxy localhost:8090 {
# WebSocket support
header_up Upgrade {http.upgrade}
header_up Connection {http.connection}
# Standard headers
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
# Security headers
header {
X-Frame-Options "SAMEORIGIN"
X-Content-Type-Options "nosniff"
X-XSS-Protection "1; mode=block"
Referrer-Policy "no-referrer-when-downgrade"
}
# File upload size limit
reverse_proxy localhost:8090 {
transport http {
max_conns_per_host 0
}
}
}
www.yourdomain.com {
redir https://yourdomain.com{uri} permanent
}sudo systemctl enable caddy
sudo systemctl start caddyCaddy will automatically:
- Obtain SSL certificates from Let's Encrypt
- Configure HTTPS
- Renew certificates automatically
The single-node setup includes two compose files:
-
postgres-db: PostgreSQL database with pgvector extension
- Image: pgvector/pgvector:pg16
- Port: 5432
- Data:
./postgres-data - Health check enabled
-
bosbase-node: BosBase application
- Image: bosbase/bosbase:ve1
- Connected to PostgreSQL via
SASSPB_POSTGRES_URL - Ports: 8090 (main API), 2678 (additional service)
- Data:
./bosbase-data,./pb_hooks
Key environment variables you can customize:
environment:
# PostgreSQL connection (for bosbase-node)
SASSPB_POSTGRES_URL: postgres://postgres:postgres@postgres-db:5432/pbosbase?sslmode=disable
# Encryption key (32 hex characters)
BS_ENCRYPTION_KEY: your-encryption-key-here
# OpenAI API (optional, for vector and LLM features)
OPENAI_API_KEY: sk-your-key-here
OPENAI_BASE_URL: https://api.openai.com/v1
# Activation verification
PB_ACTIVATION_VERIFY_URL: https://ve.bosbase.com/verify
# Optional: Redis configuration
# REDIS_URL: 192.168.1.60:6379
# REDIS_PASSWORD:
# WASM and Script execution
WASM_ENABLE: true
WASM_INSTANCE_NUM: 8
SCRIPT_CONCURRENCY: 8
FUNCTION_CONN_NUM: 10
EXECUTE_PATH: /pb/functions
# Optional: Booster configuration
# BOOSTER_PATH: /pb/booster-wasm
# BOOSTER_POOL_MAX: 2
# BOOSTER_WASMTIME_MEMORY_GUARD_SIZE: 65536
# BOOSTER_WASMTIME_MEMORY_RESERVATION: 0
# BOOSTER_WASMTIME_MEMORY_RESERVATION_FOR_GROWTH: 1048576
# Database connection pool settings
PB_DATA_MAX_OPEN_CONNS: 30
PB_DATA_MAX_IDLE_CONNS: 15
PB_AUX_MAX_OPEN_CONNS: 10
PB_AUX_MAX_IDLE_CONNS: 3
PB_QUERY_TIMEOUT: 300sData persistence is handled via Docker volumes:
./postgres-data- PostgreSQL database files with pgvector./bosbase-data- BosBase application data./pb_hooks- Custom hooks directory (preserved on reinstall)
Important: Make regular backups of these directories!
# Backup PostgreSQL database
docker exec $(docker compose -f docker-compose.db.yml ps -q postgres-db) pg_dump -U postgres pbosbase > database-backup.sql
# Or backup entire data directory
docker exec $(docker compose -f docker-compose.db.yml ps -q postgres-db) tar czf - /var/lib/postgresql/data > postgres-backup.tar.gz
# Backup bosbase data
docker exec $(docker compose -f docker-compose.yml ps -q bosbase-node) tar czf - /pb/pb_data > bosbase-backup.tar.gzOr use BosBase's built-in backup API:
curl -X POST http://localhost:8090/api/backups \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
-o backup.zip# Restore PostgreSQL database
docker exec -i $(docker compose -f docker-compose.db.yml ps -q postgres-db) psql -U postgres -d pbosbase < database-backup.sql
# Restore bosbase
docker exec -i $(docker compose -f docker-compose.yml ps -q bosbase-node) tar xzf - < bosbase-backup.tar.gzTo update to a new version:
docker compose -f docker-compose.yml pull
docker compose -f docker-compose.yml up -dOr rebuild if using local builds:
docker compose -f docker-compose.yml build
docker compose -f docker-compose.yml up -d# All services
docker compose -f docker-compose.yml logs -f
docker compose -f docker-compose.db.yml logs -f
# Specific service
docker compose -f docker-compose.yml logs -f bosbase-node
docker compose -f docker-compose.db.yml logs -f postgres-db# BosBase health
curl http://localhost:8090/api/health
# PostgreSQL health
docker exec $(docker compose -f docker-compose.db.yml ps -q postgres-db) pg_isready -U postgres -d pbosbaseIf port 8090, 2678, or 5432 is already in use:
# In docker-compose.yml or docker-compose.db.yml, change:
ports:
- "8091:8090" # Change 8090 to 8091
- "5433:5432" # Change 5432 to 5433If you encounter permission errors:
sudo chown -R $USER:$USER bosbase-data postgres-data pb_hooksCheck if database is ready:
docker compose -f docker-compose.db.yml logs postgres-db | grep "ready to accept connections"Wait for the message "ready to accept connections" before accessing bosbase-node.
docker compose -f docker-compose.yml down -v
docker compose -f docker-compose.db.yml down -v
rm -rf bosbase-data postgres-data pb_hooks
docker compose -f docker-compose.db.yml up -d
docker compose -f docker-compose.yml up -d- Use Environment Variables: Store sensitive keys in
.envfiles (not in git) - Enable Backups: Set up automated backups using cron or a backup service
- Monitor Resources: Use tools like
docker statsor monitoring services - Keep Updated: Regularly update Docker images and dependencies
- Use Reverse Proxy: Always use NGINX or Caddy with SSL in production
- Firewall: Only expose ports 80 and 443 (via reverse proxy), not 8090 directly
- Resource Limits: Add resource limits in docker-compose.yml:
services:
bosbase-node:
deploy:
resources:
limits:
cpus: '2'
memory: 1G
reservations:
cpus: '1'
memory: 1GFor issues and questions:
- Check the main README.md
- Review Docker Compose logs
- Check doc.bosbase.com
- Configure your first collection in the Admin UI
- Set up authentication and user management
- Configure file storage (S3 recommended for production)
- Review API documentation