Deployment
Deploy Rakiba projects to local Docker containers for testing or remote VPS servers for production. Both use the same bb deploy command with zero-downtime blue/green deployment by default.
Overview
Rakiba supports two deployment targets:
| Target Type | Use Case | Mechanism |
|---|---|---|
| Docker Container | Local testing, development sandboxes | docker exec / docker cp |
| VPS Server | Remote deployment, staging, production | SSH / rsync |
Both use the same bb deploy command with the --target flag.
Prerequisites
Local Machine
Where you run bb deploy:
- Babashka (
bb) installed - Docker (for container targets)
- SSH client and rsync (for VPS targets)
- Project built with
bb buildcapability
Target Server (VPS)
Before deploying to a VPS, ensure these are installed:
# Update packages
apt-get update
# Install Java 21, nginx, curl
DEBIAN_FRONTEND=noninteractive apt-get install -y openjdk-21-jre-headless nginx curl
# Create application user
useradd -m -s /bin/bash rakiba
# Create Java symlink (optional but recommended)
mkdir -p /opt/java
ln -sf /usr/lib/jvm/java-21-openjdk-amd64/* /opt/java/
# Create app directory
mkdir -p /home/rakiba
chown rakiba:rakiba /home/rakiba
Local Sandbox Deployment
Test deployments locally with a production-like environment using Docker containers.
Quick Start
# One-time DNS setup (requires sudo)
bb local:dns-setup
# Create a sandbox
bb local:create ubuntu@24.04 --name dev
# Deploy your project
bb deploy my-app --target dev
# Access it
open http://my-app.rakiba.test:9080
What You Get
A local sandbox provisions a full production stack:
| Service | Description |
|---|---|
| PostgreSQL 16 | With TimescaleDB extension |
| Valkey | Redis-compatible cache |
| nginx | Reverse proxy with hostname routing |
| Datomic | Transactor with PostgreSQL storage |
| Garage | S3-compatible object storage |
Sandbox Commands
| Command | Description |
|---|---|
bb local:create ubuntu@24.04 --name <name> | Create new sandbox |
bb local:list | List all sandboxes |
bb local:status <name> | Service health check |
bb local:start/stop <name> | Start/stop sandbox |
bb local:destroy <name> | Remove sandbox |
bb local:shell <name> | Interactive shell |
bb local:logs <name> [service] | View logs |
bb local:upgrade <name> | Sync services to config |
bb deploy <project> --target <name> | Deploy project |
Port Mapping
| Service | Default Port |
|---|---|
| HTTP (nginx) | 9080 |
| PostgreSQL | 5432 |
| Valkey | 6379 |
| Garage S3 API | 3900 |
| Garage Admin | 3903 |
Multiple sandboxes use incremented ports (9081, 5433, etc.).
VPS Deployment
VPS deployment uses the Rakiba Agent - a lightweight service running on your server that handles deployments, log streaming, and service management. See VPS Agent for the full architecture.
1. Add VPS to Inventory
Register your VPS with Rakiba:
# Basic usage (uses default SSH key and port 22)
bb vps:add root@192.168.1.100 --name prod
# With custom port and key
bb vps:add deploy@192.168.1.100 --name prod --port 2222 --key ~/.ssh/deploy_key
This creates an entry in .remote-inventory.edn.
2. Verify Connectivity
# Quick connectivity check
bb vps:status prod
# Full deployment readiness check (SSH + rsync)
bb vps:verify prod
3. Setup Agent (First Time)
Install the Rakiba agent on your VPS:
bb vps:setup prod
This installs a lightweight agent service that handles deployments and enables remote management from your local Admin Dashboard.
4. Deploy
# Deploy a project
bb deploy myproject --target prod
# Deploy with options
bb deploy myproject --target prod --skip-build --timeout 120
5. Verify Deployment
After deployment, the app is accessible at http://<vps-ip>:8001/ (port 8001 is the default).
curl http://192.168.1.100:8001/api/health
Blue/Green Deployment
By default, Rakiba uses blue/green deployment for zero-downtime updates. This strategy ensures your users never experience downtime during deployments.
How It Works
- A new version starts on a temporary “blue” port (primary port + 100)
- Health check verifies the new version is working
- Nginx switches traffic to the new version
- Old connections drain gracefully
- Old service is stopped
Benefits
- Zero downtime during deployment
- Instant rollback if health check fails
- Traffic switch happens in milliseconds
Memory Consideration: Blue/green temporarily runs two JVM processes. Servers with less than 1GB RAM should use the
:restartstrategy instead.
Configuration
Add a :deployment key to your project’s rakiba.edn:
{:state-management :mount
:server :jetty
;; ... other config ...
:deployment
{:strategy :blue-green ; :blue-green (default) or :restart
:health-check-timeout-ms 120000 ; 2 minutes (default)
:drain-timeout-ms 30000 ; 30 seconds (default)
:blue-port-offset 100}} ; Port offset for blue service (default: 100)
Options
| Option | Default | Description |
|---|---|---|
:strategy | :blue-green | Deployment strategy (:blue-green or :restart) |
:health-check-timeout-ms | 120000 | How long to wait for health check (ms) |
:drain-timeout-ms | 30000 | Time to drain connections before stopping old service (ms) |
:blue-port-offset | 100 | Blue service port = primary port + offset |
CLI Overrides
CLI flags override rakiba.edn configuration:
# Force legacy restart (overrides :strategy in config)
bb deploy myproject --target prod --no-blue-green
# Custom timeouts (override config values)
bb deploy myproject --target prod --timeout 180 --drain-timeout 60
Precedence: CLI flags > rakiba.edn :deployment > defaults
Deployment Flow
When you run bb deploy, the following steps occur:
- Resolve Target - Check if target is VPS (
.remote-inventory.edn) or container (.local-envs/) - Test Connection - Verify SSH connectivity (VPS) or Docker container is running
- Build - Run
bb buildto create uberjar (unless--skip-build) - Upload - Transfer JAR and .env file via rsync (VPS) or docker cp (container)
- Install Service - Create systemd unit file
- Deploy - Blue/green deployment (default) or restart based on strategy
- Health Check - Poll
/api/healthuntil it responds - Traffic Switch - Update nginx to route to new version (blue/green only)
- Drain & Cleanup - Gracefully stop old service (blue/green only)
Command Reference
VPS Management
| Command | Description |
|---|---|
bb vps:add <user@host> --name <name> | Add VPS to inventory |
bb vps:add ... --port <port> --key <path> | Add with custom SSH port and key |
bb vps:list | List registered VPS targets |
bb vps:remove <name> | Remove VPS from inventory |
bb vps:status <name> | Check SSH connectivity |
bb vps:verify <name> | Verify deployment prerequisites (SSH + rsync) |
Deployment
| Command | Description |
|---|---|
bb deploy <project> --target <name> | Deploy project to target |
bb deploy:status --target <name> | Check deployment status |
Deployment Options
| Flag | Description |
|---|---|
--target, -t | Target name (required) |
--skip-build | Skip building uberjar |
--timeout | Health check timeout in seconds (default: from config or 60) |
--no-blue-green | Force legacy restart deployment |
--drain-timeout | Connection drain timeout in seconds (default: from config or 30) |
Container Management
| Command | Description |
|---|---|
bb test:deploy:container:create | Create E2E test container |
bb test:deploy:container:destroy | Remove container |
bb test:deploy:container:status | Check container status |
bb test:deploy:e2e <project> | Full E2E deployment test |
Troubleshooting
SSH Connection Failed
# Check SSH connectivity manually
ssh -i /path/to/key -p <port> user@host "echo ok"
# Verify key permissions
chmod 600 ~/.ssh/id_rsa
Service Won’t Start
# Check service status on target
ssh user@host "systemctl status rakiba-<project>.service"
# View logs
ssh user@host "journalctl -u rakiba-<project>.service -n 50"
Health Check Timeout
The health check polls /api/health for 60 seconds by default. If your app takes longer to start:
bb deploy myproject --target prod --timeout 120
Permission Denied on Upload
For non-root SSH users, ensure:
- The SSH user owns
/home/rakiba/or has write access - The SSH user has passwordless sudo for systemctl commands
# Fix ownership (run as root)
chown -R deploy:deploy /home/rakiba
# Add sudo access for systemctl
echo "deploy ALL=(ALL) NOPASSWD: /bin/systemctl" >> /etc/sudoers.d/deploy
Files Reference
| File | Purpose |
|---|---|
.remote-inventory.edn | VPS targets (name, host, user, port, key) |
.local-envs/<name>.edn | Docker container state (ports, timestamps) |
/etc/systemd/system/rakiba-<project>.service | Systemd unit (on target) |
/home/rakiba/<project>/ | Application directory (on target) |