Prerequisites
- Docker and Docker Compose
- A domain name with DNS configured
- Ports 80 and 443 available
Quick Start
Run the automated install script on a fresh server:Manual Setup
Clone the repository and configure your environment:.env with your values. Set CONTROL_PLANE_UPDATER_TOKEN to
the generated token.
For an external PostgreSQL database, keep:
TECHULUS_CLOUD_VERSION to the release tag you are installing:
tip only for rolling installs. Rolling installs do not show release
update prompts.
Then start the stack:
/etc/docker/daemon.json with json-file rotation on fresh hosts. If Docker is
already configured, keep your existing daemon settings and add equivalent log
rotation manually.
Manual upgrades
Use the one-click upgrade flow in Settings when possible. If the updater cannot run, update the deployment from the host manually. Back up your.env file and database before upgrading. Then fetch the Compose
files for the release, update TECHULUS_CLOUD_VERSION, pull images, and restart
the stack:
Environment Variables
Required
AWS KMS BYOK
AWS KMS BYOK is available for AWS-hosted dedicated control planes. The control plane can run in your AWS account or in the Techulus AWS account. Attach an EC2 instance profile or ECS task role to the web service. Do not store static AWS credentials in.env.
Set these variables instead of ENCRYPTION_KEY for a new installation:
kms:GenerateDataKey, kms:Encrypt, kms:Decrypt, and kms:DescribeKey for the configured key. Restrict the cryptographic operations to the role, the exact key, and this encryption context:
Control plane in the Techulus AWS account
You can keep the KMS key and compute agents in your AWS account while running the dedicated control plane in the Techulus AWS account. Grant the Techulus control-plane role direct cross-account access to the KMS key. The application uses that role through the standard AWS credential chain. It does not call AWS STSAssumeRole.
Merge statements like these into the KMS key policy in your AWS account. Replace the account IDs and role name. DescribeKey is separate because that operation does not accept an encryption context:
Resource to the full ARN of your KMS key:
ENCRYPTION_KMS_KEY_ARN with the customer-account key ARN and set AWS_REGION to that key’s region. Your compute agents do not need AWS credentials or KMS permissions. They continue receiving the data encryption key during registration.
You can revoke future cold-start unwraps by removing the Techulus role from the key policy or disabling the key. This does not erase a key already cached by a running control-plane process or persisted by an existing agent.
The first secret operation generates a 32-byte data encryption key. The control plane stores only its KMS-wrapped form in PostgreSQL. Each web process unwraps and caches the key when first needed. The secret ciphertext format and agent behavior remain unchanged.
To migrate an existing installation:
- Back up PostgreSQL and
.env. - Add
ENCRYPTION_KMS_KEY_ARNandAWS_REGION. Keep the existingENCRYPTION_KEYtemporarily. - Restart the web service and verify that you can reveal an existing secret and register an agent.
- Remove
ENCRYPTION_KEYand restart all web replicas.
ENCRYPTION_KEY must contain the same key bytes. The control plane fails closed if they differ. Do not add a newly generated ENCRYPTION_KEY to an existing KMS installation.
Do not change ENCRYPTION_KMS_KEY_ARN after initialization. Automatic rotation of the same KMS key is transparent. Moving to another KMS key requires a reviewed rewrap procedure.
If KMS is unavailable, cold-started web processes return a service-unavailable response for secret operations and agent registration. Other control-plane features remain available. Warm processes and existing agents can continue using keys already held in memory or local agent configuration.
Back up both PostgreSQL and continued access to the KMS key. Deleting the KMS key can make a database restore unrecoverable. Disabling the key blocks future unwraps, but it does not erase keys already cached by running processes or registered agents.
Control plane deployment
Victoria Logs
Victoria Metrics
Registry
Inngest
Control Plane Replicas
When
WEB_REPLICAS is greater than 1, Traefik discovers the replicated web
containers through Docker and load balances requests for <ROOT_DOMAIN> across
them. Schema sync runs once from the dedicated migrate service before the
replicated web containers start, so scaling WEB_REPLICAS does not run
migrations from every replica.
GitHub Integration (Optional)
Generating Secrets
Services
Once running, the following services are available:
Traefik handles TLS termination and automatic certificate renewal via Let’s Encrypt.
Database Migrations
The schema is synced automatically by the one-shotmigrate service via drizzle-kit push. Non-destructive changes (adding tables, columns, indexes) are applied automatically. Destructive changes like dropping columns require manual intervention. If schema sync fails, web startup is blocked; inspect the failure with docker compose logs migrate.
Common Commands
latest and tip are convenient, but they can
move between pulls.