Portable, self-hosted Supabase deployment for FieldFleet.
# 1. Configure environment
cp .env.example .env
nano .env # Fill in your values
# 2. Deploy
./scripts/deploy.shdeployment/
├── docker-compose.yml # All services definition
├── kong.yml # API gateway config
├── Caddyfile # Reverse proxy + HTTPS
├── .env.example # Environment template
├── .env # Your configuration (git-ignored)
├── migrations/ # Database migrations
├── functions/ # Edge functions
├── backups/ # Backup storage
└── scripts/
├── deploy.sh # Initial deployment
├── backup.sh # Create backup
├── restore.sh # Restore from backup
└── migrate-server.sh # Migrate to new server
| Service | Port | Description |
|---|---|---|
| Kong | 8000 | API Gateway |
| PostgreSQL | 5432 | Database |
| GoTrue | 9999 | Authentication |
| PostgREST | 3000 | REST API |
| Realtime | 4000 | WebSocket subscriptions |
| Storage | 5000 | File storage |
| Studio | 3000 | Admin dashboard |
| Caddy | 80/443 | HTTPS reverse proxy |
# View logs
docker compose logs -f
# View specific service
docker compose logs -f db
docker compose logs -f auth
# Restart services
docker compose restart
# Stop everything
docker compose down
# Stop and remove volumes (DESTROYS DATA)
docker compose down -v./scripts/backup.shCreates:
backups/db_TIMESTAMP.sql.gz- Databasebackups/storage_TIMESTAMP.tar.gz- Filesbackups/config_TIMESTAMP.tar.gz- Configurationbackups/taskfleet_backup_TIMESTAMP.tar.gz- Combined
./scripts/restore.sh taskfleet_backup_20240115_120000.tar.gz./scripts/migrate-server.sh user@newserver.com api.newdomain.com-
Before Migration
- Run
./scripts/backup.shon current server - Note down any custom
.envvalues
- Run
-
On New Server
- Install Docker and Docker Compose
- Copy deployment folder
- Run
./scripts/restore.sh <backup> - Update
.envwith new domain
-
DNS Updates
- Point API domain to new server
- Point Studio domain to new server
- Wait for propagation
-
App Updates
- Update Flutter app's Supabase URL
- Test authentication
- Test file uploads
-
Cleanup
- Verify everything works
- Shut down old server
# Pull latest images
docker compose pull
# Restart with new images
docker compose up -d
# Check logs for issues
docker compose logs -fdocker compose logs db
# Check disk space
df -hdocker compose logs auth
# Verify JWT_SECRET matches in all servicesdocker compose logs storage
# Check permissions
docker compose exec storage ls -la /var/lib/storageIf browser devtools shows net::ERR_FAILED 413 (Content Too Large) with a CORS error,
the 413 is usually coming from Kong/nginx before CORS headers are applied.
Set KONG_CLIENT_MAX_BODY_SIZE in .env (for example 100m) and restart Kong:
docker compose up -d kong caddy
docker compose logs --tail=100 kongdocker compose logs caddy
# Caddy auto-renews, check if ports 80/443 are open- Generated unique
POSTGRES_PASSWORD - Generated unique
JWT_SECRET(min 32 chars) - Generated proper
ANON_KEYandSERVICE_ROLE_KEY - HTTPS enabled (Caddy handles this)
- Studio behind VPN or basic auth
- Regular backups scheduled
- Firewall configured (only 80/443 open)