Deploy
Last updated on June 26, 2026
Once .env is ready, re-run the deploy script. The license key is saved in .env, so you do not need to pass it again:
curl -fsSL https://tofupilot.sh/deploy | bashThe script validates your configuration, pulls the Docker images, and starts six containers.
| Container | Role |
|---|---|
tofupilot-dashboard | TofuPilot application |
tofupilot-pg | PostgreSQL |
tofupilot-seaweed | SeaweedFS file storage |
tofupilot-proxy | Traefik reverse proxy with automatic HTTPS |
tofupilot-centrifugo | Realtime WebSocket server (live status, telemetry, build logs) |
tofupilot-deployer | Build worker for the deployments pipeline (Docker-in-Docker) |
After each deploy or update, the script reports the running version and domain to Orbit so you can monitor instances. No other data leaves your server.
The tofupilot-deployer container needs standard (root) Docker because it runs a privileged build sandbox. Under rootless Docker it stays down and the build pipeline is unavailable; everything else, including realtime, works normally.
First login
Open your domain (e.g. https://tofupilot.yourcompany.com) and create your first account. That account becomes the organization admin, and each self-hosted instance supports one organization.
Upload runs
To upload test Runs, point your scripts to your instance URL. The SDK reads your API key from the TOFUPILOT_API_KEY environment variable, or you can pass it directly.
import openhtf as htffrom tofupilot.openhtf import TofuPilotdef main(): test = htf.Test( procedure_id="FVT1", part_number="PCB1", ) with TofuPilot(test, url="https://tofupilot.yourcompany.com"): test.execute(lambda: "PCB1A001")if __name__ == '__main__': main()from tofupilot import TofuPilotClientfrom datetime import timedeltadef main(): client = TofuPilotClient(url="https://tofupilot.yourcompany.com") client.create_run( procedure_id="FVT1", run_passed=True, unit_under_test={ "serial_number": "PCB1A001", "part_number": "PCB1" }, duration=timedelta(minutes=1, seconds=45), )if __name__ == '__main__': main()from datetime import datetime, timezone, timedeltafrom tofupilot.v2 import TofuPilotdef main(): client = TofuPilot( api_key="your_api_key", server_url="https://tofupilot.yourcompany.com/api" ) started_at = datetime.now(timezone.utc) ended_at = started_at + timedelta(seconds=30) run = client.runs.create( procedure_id="FVT1", serial_number="PCB1A001", part_number="PCB1", outcome="PASS", started_at=started_at, ended_at=ended_at, ) print(f"Run created: {run.id}")if __name__ == '__main__': main()Custom CA certificates
When your instance uses a self-signed or internal CA cert, tell the Python client to trust it.
First, export the certificate from your server:
echo | openssl s_client -connect tofupilot.yourcompany.com:443 -showcerts 2>/dev/null | openssl x509 -outform PEM > ca-certificate.pemThen pass it to the client.
from tofupilot import TofuPilotClientclient = TofuPilotClient( url="https://tofupilot.yourcompany.com", verify="/path/to/ca-certificate.pem")# For OpenHTFfrom tofupilot.openhtf import uploadtest.add_output_callbacks( upload( url="https://tofupilot.yourcompany.com", verify="/path/to/ca-certificate.pem" ))from tofupilot.v2 import TofuPilotimport httpxhttp_client = httpx.Client( verify="/path/to/ca-certificate.pem")client = TofuPilot( api_key="your_api_key", server_url="https://tofupilot.yourcompany.com/api", client=http_client)How is this guide?