Set up Tier 2
Fresh installation
Section titled “Fresh installation”Use a release containing the versioned cloud-processing client and a matching
cloud service. An older server will reject processing.v1 calls; a successful
/health response alone does not prove compatibility.
Set SCANI_DEPLOYMENT_TIER=2, SCANI_PUBLIC_URL=https://your-scani-hostname and
SCANI_S3_PUBLIC_URL=https://your-storage-hostname and SCANI_CLOUD_API_KEY in your shell, then run scripts/self-host.sh. Supply the
key through your normal secret manager or a hidden shell prompt; do not paste
it into a committed file. Configure your HTTPS reverse proxy for the public URL.
The installer generates local infrastructure secrets, keeps SeaweedFS, and writes
COMPOSE_FILE=docker-compose.prod.yml:docker-compose.tier2.yml into .env.
The overlay excludes the local data-provider and mail catcher. Use Docker
Compose 2.20 or later, which supports optional service dependencies.
Manual configuration
Section titled “Manual configuration”Set these on both API and worker:
SCANI_DEPLOYMENT_TIER=2SCANI_CLOUD_URL=https://api.cloud.scani.xyzSCANI_CLOUD_API_KEY=<your Scani Cloud key>Keep your DATABASE_URL, REDIS_URL, all S3_* values, ENCRYPTION_KEY,
BETTER_AUTH_SECRET, JOBS_HMAC_SECRET and LOG_ID_PEPPER. API and worker
must use the same bucket and encryption key. Set FRONTEND_URL and
BACKEND_URL to the same HTTPS origin, with no path. The bundled nginx proxies
/api to the API service. Tier 2 auth links must stay on that same origin so an
email cannot claim one instance while linking to another.
SeaweedFS exposes only its authenticated S3 endpoint on loopback port 9000.
Set S3_PUBLIC_ENDPOINT to your browser-reachable HTTPS S3 origin (the installer
uses SCANI_S3_PUBLIC_URL). Route that origin to 127.0.0.1:9000, preserving
the original Host header and request path for S3 signatures. Do not expose the
filer, master or administration ports. The compose default includes your S3
endpoint in CSP_CONNECT_SRC. If you override that variable, include the S3
origin alongside 'self' or the browser will block uploads before they reach S3. This does not make the bucket public.
For example, Caddy on the Docker host:
scani.example.com { reverse_proxy 127.0.0.1:8080}files.example.com { reverse_proxy 127.0.0.1:9000}Set the app and S3 URLs to those two origins. Ensure the browser can send OPTIONS, PUT and GET requests to the S3 origin; SeaweedFS handles S3 CORS. An existing MinIO installation needs the storage migration before switching its bucket endpoint.
Do not supply upstream provider keys or an SMTP/Fastmail account. Tier 2 uses
the cloud for these operations. The local DATA_PROVIDER_API_KEY generated by
the installer is unused while the local data-provider is disabled.
For explicit compose commands, include both files:
docker compose -f docker-compose.prod.yml -f docker-compose.tier2.yml config --servicesdocker compose -f docker-compose.prod.yml -f docker-compose.tier2.yml --profile migrate run --rm migratedocker compose -f docker-compose.prod.yml -f docker-compose.tier2.yml up -dconfig --services should include SeaweedFS, Postgres, Redis, API, worker and
frontend, and exclude data-provider and mailpit.
Verify sign-in email, upload/import of a small document, a price refresh and a wallet query. Confirm the uploaded object is in your bucket. A health check alone does not exercise these boundaries.