Skip to content
Operations · Self-host Intermediate

Deploy to production

Run Sluicio for real on a single hardened host — Podman or Docker behind Caddy (automatic HTTPS), a firewall, daily Postgres backups and systemd — via a one-shot bootstrap. Plus database options, updates, backups and the Kubernetes path.

SLSluicio team 10 min read Updated Jul 2026

The quickstart gets Sluicio running on your machine, but it ships weak passwords and no TLS. For real users you want HTTPS, strong secrets, a firewall and backups. Sluicio ships a one-shot bootstrap that stands all of that up on a single host — the right shape for solo-developer to small-team scale — plus a Helm chart for Kubernetes.

ResourceMinimumComfortable
vCPU4 dedicated8 dedicated
RAM16 GB32 GB
Disk200 GB NVMe SSD500 GB NVMe SSD
Network1 Gbit1 Gbit

ClickHouse compresses telemetry 5–20×, but NVMe matters more than raw capacity — spinning disks make merge cycles painful. A Hetzner CCX23 (4 vCPU / 16 GB / 240 GB NVMe, ~€25/month) is about the cheapest box that runs Sluicio comfortably; AWS/GCP equivalents cost roughly 3–5× that.

  1. A fresh Ubuntu 24.04 LTS host with sudo access and a public IP.
  2. Two DNS A records, both pointing at the server’s IP:
    • sluicio.example.com — the UI + API
    • ingest.sluicio.example.com — the OTLP ingest endpoint (a separate subdomain so producers stay pointed at ingest even if the UI moves)
  3. Clone the repo to /opt/sluicio:
    Terminal window
    sudo mkdir -p /opt
    sudo git clone https://github.com/SLUICIO/sluicio-app.git /opt/sluicio
Terminal window
sudo /opt/sluicio/deploy/server/bootstrap.sh \
--domain sluicio.example.com \
--email admin@example.com

It defaults to Podman (no root daemon, no docker group — one less privilege-escalation vector on a public box). Prefer Docker? Add --runtime=docker.

In 5–15 minutes it:

  • installs Podman + podman-compose (or Docker), Caddy, ufw, fail2ban, Node.js and postgresql-client;
  • creates a sluicio system user and the data layout under /var/lib/sluicio/{postgres,clickhouse,backups};
  • generates strong random DB passwords into /etc/sluicio/sluicio.env (mode 600, root-owned);
  • renders Caddy with your domain + email so it gets automatic HTTPS (Let’s Encrypt) for sluicio.example.com (UI + /api) and ingest.sluicio.example.com (OTLP);
  • builds the frontend and serves it from Caddy;
  • installs a systemd unit (sluicio.service) and a daily Postgres backup cron (03:00 UTC);
  • configures the firewall (allow 22 / 80 / 443, deny the rest), enables fail2ban, and disables password SSH;
  • starts the stack and waits for cell-api to pass its healthcheck.

Sluicio needs a Postgres (control plane: orgs, integrations, rules, audit) and a ClickHouse (telemetry). The bootstrap bundles both. If you already run one or both, choose the matching compose files and env template instead:

You have…Compose filesEnv template
Neither (bundle both — default)docker-compose.registry.ymlsluicio.env.example
Both your owndocker-compose.registry.external-db.ymlsluicio.env.external.example
Postgres only (bundle ClickHouse)…external-db.yml + docker-compose.bundled-clickhouse.ymlsluicio.env.external.example
ClickHouse only (bundle Postgres)…external-db.yml + docker-compose.bundled-postgres.ymlsluicio.env.external.example
Terminal window
# e.g. you run your own databases:
cd /opt/sluicio/deploy/server
cp sluicio.env.external.example sluicio.env # then edit POSTGRES_DSN + CLICKHOUSE_*
docker compose --env-file sluicio.env \
-f docker-compose.registry.external-db.yml up -d

cell-api applies its Postgres migrations and creates the ClickHouse tables on startup, so external databases only need to exist and be reachable with the credentials you provide.

Terminal window
systemctl status sluicio # stack status
journalctl -u sluicio -f # follow logs
curl https://sluicio.example.com/api/v1/auth/install-state # → {"fresh":true} until first login
ls -la /var/lib/sluicio/backups/ # backups landing?
URL: https://sluicio.example.com/
Email: admin@sluicio.local
Password: admin

Change the password immediately via Account → Password. The seeded admin keeps working until you rotate it, so don’t leave it on the default.

Terminal window
sudo /opt/sluicio/deploy/server/update.sh

It fetches, prints the incoming commits and changed files, asks you to confirm, then redeploys only what changed (Caddy config, systemd unit, backup script, frontend rebuild, container rebuild), pulls --ff-only, restarts, and waits for the healthcheck.

Handy flags: --yes (skip the prompt, for cron), --dry-run, --snapshot (back up Postgres before pulling), --no-frontend (skip the npm rebuild when only Go code changed).

Rollback — update never touches the data volumes, so reverting is code-only:

Terminal window
cd /opt/sluicio
sudo git reset --hard <previous-sha>
sudo /opt/sluicio/deploy/server/update.sh --yes

Postgres migrations are forward-only: adding a column is rollback-safe (old code just ignores it); a rename/drop needs a roll-forward, not a rollback.

The cron writes nightly pg_dumps to /var/lib/sluicio/backups/ and keeps 30 days — but that’s only as durable as the disk it’s on. Get them off-machine: rclone the directory to S3 / Backblaze B2 / a Storage Box nightly, or scp to a second host.

ClickHouse telemetry is not backed up — it ages out at your retention window and is regenerable while ingest keeps flowing. If you start treating Sluicio as a system of record, look at Altinity/clickhouse-backup.

Terminal window
sudo /opt/sluicio/deploy/server/bootstrap.sh \
--domain sluicio.example.com --email admin@example.com --regen-secrets

Generates new DB passwords and restarts the stack. (Rotation stops future use of leaked secrets; if they were exfiltrated, assess data exposure separately.)

Prefer Kubernetes? The deploy/helm/cell chart deploys the cell (Apache-2.0 licensed, so you can freely fork it). It does not deploy Postgres or ClickHouse — point at managed instances (recommended) or bundle them for evaluation:

Terminal window
# bring your own databases (recommended for production):
helm install my-cell ./deploy/helm/cell -f deploy/helm/cell/values-external-db.yaml
# …or bundle single-replica databases for a quick eval:
helm install my-cell ./deploy/helm/cell -f deploy/helm/cell/values-bundled.yaml

cell-api migrates the databases on startup here too — they just need to exist and be reachable. See the chart’s values.yaml for the full set of options.

Worth knowing before you commit:

  • Single host = no HA. One box, one Postgres, one ClickHouse — if it dies you rebuild from backups, so keep off-machine copies.
  • Multi-tenant isolation is at the query layer. All orgs share one ClickHouse cell; the access policy narrows visibility per query rather than physically separating data.
  • No self-instrumentation yet. Sluicio’s own services don’t emit their own metrics — run something like netdata on the host to watch the box itself.

See also: the capacity planner for sizing, the security model for ingest keys, API/MCP tokens and TLS, and the quickstart for a local trial first.