Appearance
Internet-facing server (Oloom-assisted)
Installing on your own servers?
Use the offline installation kit instead: Requirements and Install. It needs no internet, no public DNS and no registry access, and it is the supported way to self-host Tadbir. This page describes the older internet-facing setup (public DNS, Let's Encrypt certificates, images pulled from Oloom's registry), used only when Oloom runs the deployment with you. Running Tadbir as separate services ("distributed") is not supported for self-hosting.
These steps are identical whether the server is a cloud VPS or a machine in your own datacenter — Tadbir doesn't distinguish between the two, only between compact and distributed (see What to package). Where a step differs by topology, both are shown.
1. Server requirements
| Resource | Compact | Distributed |
|---|---|---|
| OS | Ubuntu 22.04/24.04 LTS or Debian 12 | same |
| RAM | 6 GB minimum, 8 GB+ recommended | 10 GB+ (scales with number of services) |
| Disk | 40 GB free, growing with your data | 60 GB+ |
| CPU | 2 vCPUs | 4 vCPUs+ |
| Network | Ports 80 and 443 open inbound; all outbound | same |
2. Point DNS at the server
Create DNS A records before starting the stack — TLS certificates are issued automatically on first boot and validation needs working DNS.
Compact needs 2 records:
| Record | Target |
|---|---|
yourdomain.com | server's public IP |
auth.yourdomain.com | server's public IP |
Distributed needs one record per service you deploy, in addition to the root domain and auth — for example crm.yourdomain.com, workorders.yourdomain.com, finance.yourdomain.com, and so on for every service in your edition.
3. Install Docker
bash
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER
newgrp docker
docker --version
docker compose version4. Get the deployment files and authenticate to the registry
Use the deployment repository access and registry token from your Oloom contact (see Getting access):
bash
git clone <deployment-repository-url> /opt/tadbir
cd /opt/tadbir
# Container registry login (token needs read-only package access)
docker login ghcr.io -u <your-username>5. Prepare the server
Run the setup script once, from the repo root, on the server:
bash
cd /opt/tadbir
sudo ./infra/compose/prod/setup-vm.shThis creates the persistent data directory (default /srv/tadbir, override with DATA_ROOT) and sets the permissions Let's Encrypt and Postgres need.
6. Configure the environment
Copy the template that matches your topology and fill in every value; each variable is explained by the comments in the template. (The Configuration page documents the offline kit, not this setup.)
bash
cp infra/compose/prod/compact/.env.template infra/compose/prod/compact/.env
# edit infra/compose/prod/compact/.envbash
cp infra/compose/prod/distributed/.env.template infra/compose/prod/distributed/.env
# edit infra/compose/prod/distributed/.envNever commit these files. They are already excluded from version control in the deployment repository.
7. Start the stack
Start order matters: the reverse proxy first, then infrastructure (database, auth), then application services. Provided scripts handle this for you.
bash
cd /opt/tadbir
infra/compose/prod/compact/start.shbash
cd /opt/tadbir
export IMAGE_TAG=1.4.2 # pin to a specific released version, not "latest"
infra/compose/prod/distributed/start.shFirst boot takes a few minutes — the identity service (Keycloak) needs about 30 seconds to start, and a one-time import configures your realm, roles, and clients.
8. Verify
bash
# All containers healthy
docker ps --format "table {{.Names}}\t{{.Status}}"
# Identity service reachable
curl -fsS https://auth.yourdomain.com/health/ready
# Application reachable (compact: same host as your domain; distributed: per-service subdomain)
curl -fsS https://yourdomain.com/actuator/healthThen open https://yourdomain.com in a browser and confirm you can log in. If anything fails here, see Troubleshooting.
Next step
Check TADBIR_LICENSING_MODE in particular: every real deployment must set it explicitly (connected or airgap), or the application refuses to start.