Deploy in your infrastructure
Prepare, configure, and validate the Maleus application foundation in your private cloud, data center, or orchestrated platform.
In the appApplication · InfrastructureUpdated September 19, 2026
On this page
- Understand the reference topology
- Prepare your platform
- Build and publish immutable images
- Configure without exposing secrets
- PostgreSQL container
- Backend
- Frontend and Maleus SDK
- Configure SSO
- Orchestrate startup and migrations
- Adapt the contract to the orchestrator
- Docker Compose
- Kubernetes and OpenShift
- ECS or Nomad
- Complete TLS, persistence, and health checks


You receive the foundation with reference Dockerfiles and a portable runtime contract. Your platform provides the registry, network, secrets, TLS termination, persistent storage, and monitoring. You then connect the integrations specific to your application.
This procedure presents the invariants to preserve, followed by the choices you can adapt to Docker Compose, Kubernetes, OpenShift, ECS, or Nomad.
Understand the reference topology
The nominal runtime brings together three roles:
/api/*and/sso/*to the backend;The browser accesses your application through the frontend. The backend and PostgreSQL remain on the private network. PostgreSQL can run in a container with persistent storage or be replaced by a compatible managed service.
The default ports are
3000for the frontend,14000for the backend, and5432for PostgreSQL. They may change as long as services, probes, and network rules use the same values. The frontend and backend do not rely on their local filesystems to store business data.Prepare your platform
Before the first deployment, provide:
Builds start from the repository root so that the workspace and its lockfile are included. The reference Dockerfiles currently target
linux/amd64. If your platform uses another CPU architecture, plan a dedicated build and acceptance test.The Dockerfiles use the
docker/dockerfile:1BuildKit syntax andCOPY --parents. Use Docker with BuildKit or, for an OpenShiftBuildConfig, Buildah 1.40 or later. Resolving the syntax image may also require outbound access to the Docker registry during the build.The backend image runs
pnpmcommands at startup through Corepack. If the required pnpm version is not already present in the image cache, allow outbound access toregistry.npmjs.orgor prepare that version in the image before publishing it.Build and publish immutable images
Build the frontend and backend from the same commit:
Publish an immutable tag or digest, then record both references in the acceptance evidence. No secret should be injected at build time or remain in an image layer. Keep
MOCK_API=falsefor the frontend build so your application uses the real API.The official PostgreSQL image is sufficient when your migrations only use extensions available on your platform. The foundation's PostgreSQL Dockerfile can derive an image when your project requires an additional extension. Record the version and extensions in your compatibility matrix.
Configure without exposing secrets
Inject configuration at runtime. Keep secret values in your platform's secret mechanism and never commit them.
PostgreSQL container
POSTGRES_USERPOSTGRES_DBPOSTGRES_PASSWORDPGDATABackend
APP_ENVIRONMENTPOSTGRES_HOST,POSTGRES_PORTPOSTGRES_DB_NAME,POSTGRES_DB_USERPOSTGRES_PASSWORDPOSTGRES_DB_USER_PASSWORDJWT_SECRET,COOKIE_SECRET,PASSWORD_PEPPERBACKEND_URLThe backend also accepts conditional or optional variables:
DEFAULT_USER_PASSWORDfor initial bootstrap;FRONTEND_URLfor SSO redirects;PORT, defaulting to14000;POSTGRES_SSLandPOSTGRES_SSL_CAfor PostgreSQL over TLS;NODE_EXTRA_CA_CERTSfor a private PKI, including an IdP's CA;CORS_ALLOWED_ORIGINSfor a genuinely cross-origin topology;COOKIE_DOMAINto explicitly share a session across multiple hosts;WORKSPACE_SSO_ENABLEDfor workspace-specific SSO providers;CRON_ENABLED,CRON_INSTANCE_ID, andCRON_SHUTDOWN_DRAIN_MSfor scheduled tasks;LOG_LEVELfor logging verbosity;HTTPS_PROXYandNO_PROXYwhen Corepack reaches the package registry through a corporate proxy;COREPACK_HOMEwhen your platform enforces an arbitrary UID;OTEL_EXPORTER_OTLP_ENDPOINT,OTEL_SERVICE_NAME,OTEL_TRACES_EXPORTER, andOTEL_SDK_DISABLEDfor OpenTelemetry.DATABASE_URLcan configure the application pool, but does not replace the separate PostgreSQL variables in the current image: startup bootstrap still consumes them.OpenTelemetry remains disabled until an exporter is configured.
OTEL_EXPORTER_OTLP_ENDPOINTenables export to the collector,OTEL_SERVICE_NAMEidentifies your application in traces,OTEL_TRACES_EXPORTER=consolesupports local checks, andOTEL_SDK_DISABLED=trueforces instrumentation off.In the current backend image, PostgreSQL bootstrap authenticates with
POSTGRES_DB_USERandPOSTGRES_PASSWORD, while the application runtime usesPOSTGRES_DB_USERandPOSTGRES_DB_USER_PASSWORD. With the nominal PostgreSQL container, these values generally identify the same account and secret. Strict separation between an administrative account and the application account requires adapting the bootstrap job or entrypoint.Frontend and Maleus SDK
BACKEND_URL/api/*and/sso/*proxiesPROJECT_NAMEBACKEND_API_URLBASE_PATHPORT3000FRAME_ANCESTORSMALEUS_APP_API_KEYMALEUS_API_PUBLIC_URL,MALEUS_FRONTEND_PUBLIC_URLMALEUS_PROJECT_ID,MALEUS_ENVIRONMENTMALEUS_SDK_CONFIGThe Maleus SDK is optional and disabled while
MALEUS_APP_API_KEYis empty. This key is a sensitive, limited-scope configuration value, but it is not a server-side secret: when enabled, the frontend injects it intomaleus-config.js, where the browser can read it. It must not grant any administrative privilege or access to application data.MALEUS_SDK_CONFIGcontains a valid JSON object. A missing or invalid value applies a fail-closed configuration that disables the widget and its features. When the SDK is enabled, browsers must be able to reach the origins configured byMALEUS_FRONTEND_PUBLIC_URLandMALEUS_API_PUBLIC_URLover HTTPS.This list covers the current foundation. Variables introduced by generated features, such as object storage, SMTP, business APIs, or other integrations, are added from the delivered repository's code and configuration contract.
Configure SSO
Configure OIDC or SAML providers in the administration interface. The foundation stores them in the database. Their issuer, client ID, client secret, certificates, and mappings are not foundation environment variables.
On the backend, set
BACKEND_URLandFRONTEND_URLto your application's complete public URL, including any path prefix. Login and callback routes use the/sso/...path under the public URL and pass through the frontend's/sso/*proxy. The backend remains private.If the IdP uses a private certificate authority, mount the PEM CA chain in the backend and point
NODE_EXTRA_CA_CERTSto that file.WORKSPACE_SSO_ENABLED=falsedisables workspace-specific providers.Orchestrate startup and migrations
The first backend follows an ordered sequence:
The frontend receives traffic once the backend is ready. The base model starts a single backend against a given database while migrations run. For multiple replicas, run migrations in an exclusive job or separate bootstrap from the server before allowing parallel deployment.
Before a sensitive migration, produce a restorable backup. A restore rehearsal validates the procedure, recovery time, and required permissions.
Adapt the contract to the orchestrator
Docker Compose
The deployment file contains a named PostgreSQL volume, a
pg_isreadyhealth check, a backend that depends on a healthy database, and a frontend that depends on the backend. Only the frontend port is published.Inject secrets as environment variables through your platform's secret mechanism, or from a Git-ignored local file for Compose validation. Docker secrets mounted as files require an adapter entrypoint because the current images do not automatically read
*_FILEvariants.Add a restart policy to the services.
depends_onorders initial startup but does not guarantee that a restarted backend waits for PostgreSQL. The backend exits when bootstrap fails and must then be restarted. Validate the resolved configuration, check service status, and inspect logs. A second startup must remain idempotent.Kubernetes and OpenShift
Deploy the frontend and backend as separate
Deploymentresources with privateServiceresources. The Ingress or Route targets only the frontend. PostgreSQL uses a managed service or aStatefulSetwith persistent storage.Distinguish
startupProbe,readinessProbe, andlivenessProbe. While migrations remain part of backend startup, keep one replica or run an exclusive migration job. On OpenShift, also validate the SCC policy, runtime UID, read-only filesystem, and volume permissions. If your platform assigns an arbitrary UID, setCOREPACK_HOME=/tmp/corepackand keep/tmpwritable.ECS or Nomad
On ECS, the frontend and backend can share a task and communicate through
localhost, or become separate services connected by the private network. The ALB targets the frontend. Secrets come from your platform's secret manager and logs are centralized.On Nomad, group tasks that communicate over loopback or declare private services. Checks drive restarts and traffic removal. PostgreSQL storage comes from CSI or a managed database. The update strategy prevents two migrations from running simultaneously.
Complete TLS, persistence, and health checks
The reverse proxy or load balancer terminates TLS, redirects HTTP to HTTPS, and applies HSTS. It forwards the original host and protocol correctly.
/api/*and/sso/*enter through the frontend, which forwards requests to the private backend. The browser does not connect directly to the backend.To serve your application under
/myapp, setBASE_PATH=/myappandBACKEND_API_URL=/myapp/apion the frontend, then setBACKEND_URL=https://application.example/myappand, when SSO is enabled,FRONTEND_URL=https://application.example/myappon the backend. Route the entire/myappprefix to the frontend without URL rewriting. The frontend serves the SPA and proxies/myapp/api/*and/myapp/sso/*. The same frontend image can be reused without rebuilding it.The reference health checks are:
pg_isready;GET /server/health-check;GET /api/server/health-check;BASE_PATH.The backend health check returns
200when the dependencies it checks are healthy and503otherwise. Startup delays cover migration time without causing a restart loop.PostgreSQL carries the persistence of the nominal foundation. The operating policy defines the RPO, RTO, retention, encryption, backup monitoring, and restore-test frequency. Each storage service added by the project follows its own policy.