Deploy
Deploy services using the mini-PaaS system. Use when deploying, checking deployment status, or troubleshooting deployments.
Process
- Build and publish with
Omni/Ide/push.sh <namespace>orOmni/Ide/ship.sh. - Verify the manifest update with
deploy-manifest show. - Check service status on the target host.
- Review logs if the service fails to start.
- Roll back if necessary and trigger deployer.
Examples
Omni/Ide/push.sh Biz/PodcastItLater/Web.py
Omni/Ide/ship.sh Omni/Ava.hs
deploy-manifest show | jq '.services[] | select(.name == "ava")'
Deploying a Service
# Build, cache, and update manifest
Omni/Ide/push.sh Biz/PodcastItLater/Web.py
# Or for Ava specifically
Omni/Ide/ship.sh Omni/Ava.hs
The deployer on target hosts polls every 5 minutes and applies changes.
Force Immediate Deploy
ssh biz sudo systemctl start deployer
Checking Status
# View current manifest
deploy-manifest show
# Check specific service
deploy-manifest show | jq '.services[] | select(.name == "ava")'
# Check deployer on target
ssh biz sudo systemctl status deployer
ssh biz cat /var/lib/deployer/state.json
Viewing Logs
# Service logs
ssh biz sudo journalctl -u <service-name> -f
# Deployer logs
ssh biz sudo journalctl -u deployer -f
# Caddy (reverse proxy) logs
ssh biz sudo journalctl -u caddy -f
Rollback
# List available versions
deploy-manifest list
# Rollback to previous
deploy-manifest rollback manifest-YYYYMMDD.json
# Force deploy after rollback
ssh biz sudo systemctl start deployer
Secrets
Secrets are stored on target hosts, never in S3:
- Location:
/var/lib/deployer-secrets/<service>.env - Format: Standard env file
- Permissions: 600, owned by root
# View secrets (on target)
ssh biz sudo cat /var/lib/deployer-secrets/ava.env
# Edit secrets (on target)
ssh biz sudo vim /var/lib/deployer-secrets/ava.env
# Restart service to pick up secret changes
ssh biz sudo systemctl restart <service-name>
Adding New Service
- Add service to manifest:
deploy-manifest add-service '{
"name": "my-service",
"artifact": {"storePath": "/nix/store/placeholder"},
"hosts": ["biz"],
"exec": {"command": null, "user": "root", "group": "root"},
"env": {"PORT": "8080"},
"envFile": "/var/lib/deployer-secrets/my-service.env",
"http": {"domain": "my.example.com", "path": "/", "internalPort": 8080}
}'
- Create secrets file on target:
ssh biz sudo tee /var/lib/deployer-secrets/my-service.env << 'EOF'
SECRET_KEY=...
DATABASE_URL=...
EOF
ssh biz sudo chmod 600 /var/lib/deployer-secrets/my-service.env
- Deploy:
Omni/Ide/push.sh Biz/MyService.py
Troubleshooting
Service won’t start
- Check logs:
ssh biz sudo journalctl -u <service> -n 50 - Check if binary exists:
ssh biz ls -la /nix/store/<path> - Check permissions on secrets file
- Try running manually:
ssh biz sudo /nix/store/<path>/bin/<name>
Deployment not picked up
- Check deployer is running:
ssh biz sudo systemctl status deployer - Check manifest was updated:
deploy-manifest show | jq '.services[] | .artifact.storePath' - Force deploy:
ssh biz sudo systemctl start deployer
502 Bad Gateway
- Is the service running?
ssh biz sudo systemctl status <service> - Is it on the right port? Check manifest’s
internalPort - Check Caddy config:
ssh biz curl -s localhost:2019/config/ | jq .
Store path not found
The binary wasn’t cached to S3. Re-run:
Omni/Ide/push.sh <namespace>
This builds, caches to S3, and updates the manifest.
Architecture
Developer Machine S3 Cache Target Host
│ │ │
│ push.sh Biz/App.py │ │
├───────────────────────────────►│ │
│ 1. bild builds │ │
│ 2. nix copy to S3 │ │
│ 3. deploy-manifest update │ │
│ │ poll every 5 min │
│ │◄─────────────────────────────┤
│ │ deployer checks manifest │
│ │ - pulls closure from S3 │
│ │ - generates systemd unit │
│ │ - updates Caddy route │
│ │ - restarts service │