Skip to content
← All sections

Deployment reference

This page covers running the stack by hand. The installer does all of it automatically.

Terminal window
cp .env.example .env # set TIFUSI_SECRET_KEY; set TIFUSI_PUBLIC_URL when behind a reverse proxy
docker compose up -d --build
Service Container Ports
Panel API tifusi-panel 8000 (API, loopback only), 80 (ACME HTTP-01 challenge only)
Dashboard tifusi-dashboard 8080 (HTTP), 443 (HTTPS)

Every port above is chosen during installation and changeable afterwards with tifusi panel port; answer r at any prompt for a random free one. The only exception is 80, which is fixed because the panel answers Let’s Encrypt’s HTTP-01 challenge there. The HTTPS port is TIFUSI_DASHBOARD_HTTPS_PORT and defaults to 443; set it to one of 2053, 2083, 2087, 2096 or 8443 for an origin behind Cloudflare’s proxy, and keep TIFUSI_PUBLIC_URL in step, since only 443 is implied by a bare https://host.

SQLite data is stored in ./data. TIFUSI_PUBLIC_URL defines the base URL used in subscription links; without it, links are derived from the request Host header, which is not reachable from clients when the panel runs behind a proxy. The value can later be changed from Settings at runtime.

The dashboard container terminates TLS on port 443 and proxies /api/, /sub/, /code/ and /app/ to the panel. It reads fullchain.pem and privkey.pem from ./certs, which is watched continuously; certificate changes take effect without a restart. Certificates can be supplied by the installer, uploaded under Settings → SSL Certificate, or placed in ./certs manually.

For deployments without the dashboard container, uvicorn can terminate TLS directly:

Terminal window
TIFUSI_SSL_CERTFILE=/app/certs/fullchain.pem
TIFUSI_SSL_KEYFILE=/app/certs/privkey.pem

Mount ./certs:/app/certs:ro in docker-compose.yml. Both variables must be set together; setting only one aborts startup rather than falling back to plain HTTP.

The schema is managed with Alembic, and alembic upgrade head runs on every startup. When a model changes, generate and review a migration:

Terminal window
cd backend
alembic revision --autogenerate -m "describe the change"

SQLite requires op.batch_alter_table(...) for column alterations that cannot be applied in place; review autogenerated revisions before committing. The test suite fails when the migration chain has more than one head, when a recent migration can’t be reversed, or when the migrated schema differs from the models.