Quick Start: Run
./install.shto get started in minutes! See DEPLOYMENT.md for full hosting guide.
A single-container solution for running multiple isolated PocketBase instances with path-based routing. No DNS setup required.
- Single Container - One Docker container, one port, hundreds of instances
- Path-Based Routing - Access instances via
http://host:port/{instance}/_/ - Web Dashboard - UI to manage instances, view logs, and monitor status
- CLI Management - Add/remove/start/stop instances with shell commands
- Auto-Routing - Caddy reverse proxy auto-configured from manifest
# Clone and install
git clone https://github.com/n3-rd/multi-pb.git
cd multi-pb
./install.sh
# Or use docker compose directly
docker compose up -d
# Create your first instance
docker exec multipb add-instance.sh myapp
# Access at: http://localhost:25983/myapp/_/
# Dashboard: http://localhost:25983/dashboard./install.sh # Full installation
./install.sh --cli-only # Skip dashboard build
./install.sh --port 8080 # Custom port
./install.sh --non-interactive # No promptsdocker compose up -ddocker build -t multipb .
docker run -d --name multipb -p 25983:25983 -v multipb-data:/var/multipb/data multipbAll commands run via docker exec multipb <command>:
Create and start a new PocketBase instance.
docker exec multipb add-instance.sh myapp
docker exec multipb add-instance.sh myapp --email admin@example.com --password secret123List all configured instances with status.
docker exec multipb list-instances.shControl instance lifecycle.
docker exec multipb stop-instance.sh myapp
docker exec multipb start-instance.sh myappStop and remove a PocketBase instance.
docker exec multipb remove-instance.sh myappRegenerate Caddy configuration from manifest.
docker exec multipb reload-proxy.sh┌─────────────────────────────────────────────┐
│ Docker Container │
│ ┌───────────────────────────────────────┐ │
│ │ Caddy (:25983) │ │
│ │ - /_health → Health check │ │
│ │ - /_instances → List instances │ │
│ │ - /{instance}/* → PB Instance │ │
│ └──────────────┬────────────────────────┘ │
│ │ │
│ ┌────────────┴──────────────┐ │
│ │ Supervisord │ │
│ │ (Process Manager) │ │
│ └────────────┬──────────────┘ │
│ │ │
│ ┌──────┬───────┴───────┬──────┐ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ PB-1 PB-2 ... PB-N │
│:30000 :30001 :30N │
└─────────────────────────────────────────────┘
▲
│
One Port: 25983
| Variable | Default | Description |
|---|---|---|
MULTIPB_PORT |
25983 |
External port exposed from container |
MULTIPB_DATA_DIR |
/var/multipb/data |
Data directory inside container |
Instances are assigned internal ports from 30000-39999 (up to 10,000 instances).
/var/multipb/data/
├── alpha/ # Instance "alpha" data
│ ├── pb_data/
│ └── pb_migrations/
├── beta/ # Instance "beta" data
└── instances.json # Manifest mapping instances to ports
# nginx example
server {
listen 80;
server_name pb.yourdomain.com;
location / {
proxy_pass http://localhost:25983;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}# Traefik example
services:
multipb:
labels:
- "traefik.enable=true"
- "traefik.http.routers.multipb.rule=Host(`pb.yourdomain.com`)"
- "traefik.http.services.multipb.loadbalancer.server.port=25983"Set up wildcard DNS (*.pb.yourdomain.com) and route subdomains to paths:
server {
server_name ~^(?<instance>.+)\.pb\.yourdomain\.com$;
location / {
proxy_pass http://localhost:25983/$instance/;
}
}# Backup all data
docker run --rm -v multipb-data:/data -v $(pwd):/backup \
alpine tar czf /backup/multipb-backup-$(date +%Y%m%d).tar.gz /data
# Restore
docker run --rm -v multipb-data:/data -v $(pwd):/backup \
alpine tar xzf /backup/multipb-backup-20240113.tar.gz -C /# Container health
curl http://localhost:25983/_health
# List all instances
curl http://localhost:25983/_instances# Check container health
docker ps
# View logs
docker logs multipb
# Check instance status
docker exec multipb list-instances.sh
# Check supervisord status
docker exec multipb supervisorctl statusdocker logs multipb
docker volume inspect multipb-data
netstat -tuln | grep 25983# Check logs
docker exec multipb cat /var/log/multipb/<instance>.log
docker exec multipb cat /var/log/multipb/<instance>.err.log
# Check status
docker exec multipb supervisorctl status
# Restart instance
docker exec multipb stop-instance.sh <instance>
docker exec multipb start-instance.sh <instance># Verify Caddy
docker exec multipb supervisorctl status caddy
# Check config
docker exec multipb cat /etc/caddy/Caddyfile
# Reload proxy
docker exec multipb reload-proxy.sh
# Test direct access
docker exec multipb curl http://localhost:30000/api/healthgit clone https://github.com/n3-rd/multi-pb.git
cd multi-pb
docker compose up -d --build
docker logs -f multipb
# Test commands
docker exec multipb add-instance.sh test1
docker exec multipb list-instances.sh
docker exec multipb remove-instance.sh test1Contributions welcome! This project prioritizes simplicity and reliability over features.
MIT