Image
Default tag scheme:
<registry>/aletyx/decision-control-tower:<version>. Customers receiving this image through Aletyx distribution will be issued the registry endpoint and pull credentials separately.
The image is signed using cosign. Validate the signature before promoting an image into a production registry; the signing key is published alongside each release.
Runtime requirements
The image’s
JAVA_TOOL_OPTIONS is set to use -Xms2g -Xmx2g -XX:MaxMetaspaceSize=256m. The container must be allocated enough memory for the heap, metaspace, code cache, native overhead and Tomcat threads. Allocating less than 2.5 GiB of memory will cause OOMKilled events under any GC pressure.
If you need a smaller footprint (for example, an evaluation deployment on a constrained host), override JAVA_TOOL_OPTIONS to set a smaller heap:
Networking and ports
Tower binds to
0.0.0.0 on BACKEND_PORT by default. There is no internal admin port — /actuator/health is exposed on the same port and is the only Actuator endpoint reachable without authentication.
Filesystem
A read-only root filesystem is supported provided
/tmp is mounted as a writable tmpfs or emptyDir (Kubernetes). In OpenShift, the default restricted-v2 SCC permits this configuration without modification.
Configuration surface (environment variables)
Variables are grouped by concern. All variables are optional unless marked required; defaults are shown for reference.Server
Database
See chapter 2 for full details.OIDC / Security
See chapter 1 for provider-specific details.Resilience (Feign / circuit breaker / retry)
Tunes the outbound HTTP client (Feign) and the resilience4j circuit breaker and retry policy applied to all Tower → Sidecar / Data Index / Decision Control calls. The defaults below are sensible for most deployments — adjust only when an upstream service has known latency characteristics.Sidecar and Data Index
When deploying both Tower and Sidecar in the same Kubernetes cluster, set these to the in-cluster Service hostname (e.g.
http://decision-control-tower-sidecar.<namespace>.svc.cluster.local) — never the public Cloudflare / load-balancer hostname.
Environments seed
The file format and behavior are documented in chapter 4 (sidecar / static-config section).
Email Notification
Frontend
Health probe loop (Tower → Decision Control instances)
Task list
Logging
Secrets and credential management
The image accepts secret values via plain environment variables. Never embed secrets in the container image, in command-line arguments visible to other processes, or in version-controlled configuration. Use the secret-management primitive of your platform:- Container / Podman: pass secrets via
--env-file <file>where the file is restricted (chmod 600) and stored under a directory not backed up to version control. For longer-running deployments use Container secrets or Podman’s--secretflag. - Kubernetes: use a
Secretand reference it viaenvFromor per-keyvalueFrom.secretKeyRef. Secret encryption at rest must be enabled on the cluster (--encryption-provider-config). If your platform integrates an external secret store (HashiCorp Vault, AWS Secrets Manager, Azure Key Vault), surface the values as environment variables — Tower itself only consumes environment variables. - OpenShift: use a
SecretwithrestrictedVolumeor the OpenShift Vault integration. Inherit the tenant’s encryption-at-rest policy.
Worked examples
Production-shaped: PostgreSQL + Entra + sidecar
/etc/tower/tower.env (mode 0600, owned by the deployment user) contains:
Custom port
If8080 conflicts with another service on the host, remap consistently:
Sidecar (required companion container)
The Sidecar is a separate container image (decision-control-tower-sidecar) that Tower calls for process state, data index queries, jobs, and the SVG audit-trail rendering. A Tower deployment without a matching Sidecar will start and accept logins, but workflow-driven endpoints will silently no-op — deploy both together.
The Sidecar needs its own PostgreSQL database (distinct from Tower’s), the URL of the Tower instance it should call back into, and the shared callback secret that matches Tower’s ALETYX_OIDC_CALLBACK_SECRET:
/etc/tower/sidecar.env (mode 0600) contains:
tower.env shown earlier, point ALETYX_DC_TOWER_SIDECAR_URL and ALETYX_DC_TOWER_DATA_INDEX_URL at this Sidecar — http://sidecar.internal:8181 for the host-port mapping above, or the in-cluster Service hostname on Kubernetes (see chapter 4 under “Sidecar component (required)”).
Health and verification
The container exposes a single unauthenticated health endpoint. Both Kubernetes liveness and readiness probes target it:200 with body:
DOWN and the endpoint returns a non-200 status. Diagnose by checking the logs for a Hibernate / Hikari connection error.
The OIDC bootstrap endpoint:
Operational considerations
- The image runs as a non-root user. Volume mounts must be readable by the user defined in the base image.
imagePullPolicy(Kubernetes / OpenShift): useIfNotPresentfor tagged immutable releases (e.g. a specific version such as1.0.0) andAlwaysonly for floating tags (:latest,:main,:stage,:dev).- Image pinning by digest is recommended for production:
Extract the digest of a running pod with:
- Graceful shutdown: Tower honors
SIGTERMand finishes in-flight requests before exiting. Default Tomcat shutdown timeout is 30 seconds; allow at least that on container stop policies. - Cold-start time: 6–10 seconds on a 2-core / 2 GiB allocation. The first authenticated request after startup may take longer because the JVM lazily warms up the OIDC HTTP client and the database connection pool. This is expected; subsequent requests return promptly.