- API Portal
- 1.0.0
- Deployment
Deploy & Verify¶
Work through Security Hardening, Database Configuration, and Resources & Scaling first — the schema applied, the secrets provisioned, and the configuration assembled. This page installs the result and confirms it.
Provision the secrets¶
The chart refuses to render without them, so this comes first:
It writes values-secrets.yaml, naming each Secret it created along with the has* flags for whichever optional keys it provisioned. Keep that file alongside your own values and pass both at install time.
Run the setup script once, on the first VM only:
It provisions the TLS pair under resources/certificates/ and the portal's encryption key and session secret under resources/keys/, and writes .env and api-platform.env.
Then copy the generated material to every other VM before starting them, so all instances share it:
Do not run setup.sh independently on each VM — it would generate a different key and session secret per host, which is the failure described in Security Hardening.
Deploy¶
The api-portal chart pulls its components as OCI dependencies, so fetch them before installing:
Then install with your production values last, so they win:
helm install my-release ./api-portal-helm-chart \
--namespace api-portal --create-namespace \
-f values-secrets.yaml \
-f values-production.yaml
Render before you install if you want to see what a values change actually produces — this is also where the chart's fail-fast guards fire, before anything is created:
helm template my-release ./api-portal-helm-chart \
-f values-secrets.yaml -f values-production.yaml > /dev/null
A missing secrets.existingSecret or tls.certificateProvider: selfSigned fails here with an explicit message.
On each VM, from the distribution directory:
COMPOSE_PROFILES in .env decides what starts. For a standalone portal against an external database, that is api-portal alone.
Check the configuration was read as you intended before putting the VM into the load balancer pool — the startup log reports the resolved database driver and the authorization mode:
Verify¶
Confirm every instance is serving, not just that the deploy command succeeded.
Then verify the two things a single-instance smoke test cannot catch, on either substrate:
Sessions are shared. Log in through the load balancer or ingress, then stop the instance that served the login. The next request should land on another instance with the session intact. If you are logged out instead, the instances are not reading the same session table — check that every instance points at the same external database and resolves the same encryption key and session secret.
Only one instance dispatches each event. Trigger a credential change and confirm the registered subscriber receives exactly one delivery, not one per instance. See Control Plane Connection.
Upgrade¶
helm dependency update ./api-portal-helm-chart
helm diff upgrade my-release ./api-portal-helm-chart \
-f values-secrets.yaml -f values-production.yaml # requires the helm-diff plugin
helm upgrade my-release ./api-portal-helm-chart \
-f values-secrets.yaml -f values-production.yaml
Always pass the secrets values file. Omitting it on an upgrade fails the render rather than silently dropping the Secret reference — intended behavior, but it does mean an upgrade command is no shorter than an install command.
Roll back a bad release with helm rollback my-release.
Upgrade one VM at a time so the others keep serving:
- Remove the VM from the load balancer pool.
- Update the image tag in
docker-compose.yaml, thendocker compose up -dto recreate the container. - Confirm
https://localhost:9543/healthresponds, and check the startup log. - Return it to the pool, then move to the next VM.
Re-running setup.sh is safe — it fills in only what is missing and never overwrites an existing value — so an upgrade won't rotate the encryption key out from under stored credentials.
Roll back by putting the previous image tag back and recreating the container.
Two things hold on both substrates:
- Old and new instances overlap during a rolling upgrade, so peak database connections briefly exceed
instances × max_open_conns. Leave headroom for it. - A rollback reverts configuration, not database schema changes. Check the release notes before upgrading across a version that migrates the schema.
Related¶
- Security Hardening: what the secrets provisioning covers
- Resources & Scaling: the instance count and health checks installed here
- Control Plane Connection: the post-install webhook registration