Brokoli
Deployment

Single Binary Deployment

Deploy Brokoli as a single binary with no external dependencies.

Deploy Brokoli as a single binary with no external dependencies.

Download and run

curl -L https://github.com/Tnsor-Labs/brokoli/releases/latest/download/broked-linux-amd64 -o broked
chmod +x broked
./broked serve

Brokoli is now running on http://localhost:8080 with SQLite storage.

CLI flags

FlagDefaultDescription
--port, -p8080HTTP server port
--db./broked.dbDatabase path (SQLite file or PostgreSQL URI)
--api-key(none)Enable API key authentication
--modeallRun mode: all, api, scheduler, worker

Examples

# Custom port
broked serve --port 3000

# PostgreSQL backend
broked serve --db "postgres://user:pass@localhost:5432/brokoli?sslmode=disable"

# With API key
broked serve --api-key brk_$(openssl rand -hex 24)

Systemd service

Create /etc/systemd/system/brokoli.service:

[Unit]
Description=Brokoli Data Orchestration
After=network.target

[Service]
Type=simple
User=brokoli
Group=brokoli
WorkingDirectory=/opt/brokoli
ExecStart=/opt/brokoli/broked serve --port 8080 --db /opt/brokoli/data/broked.db
Restart=always
RestartSec=5
Environment=BROKOLI_DATA_DIRS=/opt/brokoli/data
Environment=BROKOLI_MAX_CONCURRENT_RUNS=8
Environment=BROKOLI_CORS_ORIGINS=https://brokoli.example.com

# Security
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/opt/brokoli/data

[Install]
WantedBy=multi-user.target

Enable and start:

sudo systemctl enable brokoli
sudo systemctl start brokoli
sudo systemctl status brokoli

Nginx reverse proxy

server {
    listen 443 ssl;
    server_name brokoli.example.com;

    ssl_certificate     /etc/letsencrypt/live/brokoli.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/brokoli.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8080;
        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;

        # WebSocket support
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 86400;
    }
}

WebSocket support: The Upgrade and Connection headers are required for real-time monitoring via WebSocket.

Health check

curl http://localhost:8080/health

Returns 200 OK when the server is running and the database is accessible.

Metrics

Prometheus-compatible metrics:

curl http://localhost:8080/metrics

Both /health and /metrics endpoints are unauthenticated for monitoring integration.

Graceful shutdown

Brokoli handles SIGINT and SIGTERM gracefully:

  1. Stops accepting new requests
  2. Waits up to 30 seconds for in-flight requests to complete
  3. Stops the cron scheduler
  4. Closes the database connection

Running pipelines are not interrupted -- they continue to completion. If you need to force-stop, send SIGKILL.

File structure

After running, your directory contains:

/opt/brokoli/
├── broked           # binary
├── data/
│   ├── broked.db    # SQLite database
│   ├── broked.db.key # encryption key for secrets
│   └── uploads/     # file uploads
└── .brokoli-jwt-secret  # JWT signing key

Back up broked.db, broked.db.key, and .brokoli-jwt-secret regularly.