Ignis Infrastructure
Kubernetes deployment for the Ignis FHIR Server using Helm. This chart allows you to deploy the API, Web frontend, and MongoDB database with configurable options for development and production environments. It also includes an optional Traefik reverse proxy for routing and TLS termination.
[!IMPORTANT] Ignis k8s is an experimental deployment setup for early-stage exploration. Thus, the implementations in this repository are not intended for production use.
Prerequisites
- Helm v3+
- A Kubernetes cluster (e.g. k3d for local development)
- Container images for
ignis-apiandignis-web - cert-manager with a
ClusterIssuer(only required for TLS)
Quick Start
# Create a local k3d clusterk3d cluster create ignis# Build and import imagesdocker build -t ignis-api:latest -f src/Ignis.Api/Dockerfile src/Ignis.Api/docker build -t ignis-web:latest -f src/Ignis.Web/Dockerfile src/Ignis.Web/k3d image import ignis-api:latest ignis-web:latest -c ignis# Download chart dependencies (Traefik etc.)helm dependency update infra/helm# Generate a MongoDB password and installexport MONGO_PASSWORD=$(openssl rand -hex 32)helm install ignis infra/helm \--set db.auth.password="$MONGO_PASSWORD"# Access the APIkubectl port-forward svc/ignis-api 8080:8080# Visit http://localhost:8080/fhir
With default values, the chart keeps the API and Web internal-only. Add
app.api.hostnames and/or app.web.hostnames when you want the Gateway to
publish routes for them.
Components
The chart is organized as sub-charts:
| Sub-chart | Description | Default |
|---|---|---|
app | Ignis.Api and Ignis.Web deployments | Both on |
db | MongoDB StatefulSet | On |
traefik | Traefik reverse proxy with Gateway API | On |
Local Development
Run only MongoDB in Kubernetes, and the API locally with dotnet run:
helm dependency update infra/helmexport MONGO_PASSWORD=$(openssl rand -hex 32)# Install with API and Web disabled (only MongoDB + Traefik)helm install ignis infra/helm \--set db.auth.password="$MONGO_PASSWORD" \--set app.api.replicaCount=0 \--set app.web.enabled=false# Port-forward MongoDBkubectl port-forward svc/ignis-mongodb 27017:27017# Run the API locally (retrieve the connection string from the secret)cd src/Ignis.ApiStoreSettings__ConnectionString=$(kubectl get secret ignis-api -o jsonpath='{.data.StoreSettings__ConnectionString}' | base64 -d) dotnet run
External MongoDB
Use an existing MongoDB instance instead of deploying one:
helm install ignis infra/helm \--set db.enabled=false \--set app.api.externalMongodbConnectionString="mongodb://user:pass@mongo-host:27017/ignis?authSource=admin"
Existing Traefik
If your cluster already has Traefik installed, disable the bundled one and point the HTTPRoutes at the existing Gateway:
helm install ignis infra/helm \--set db.auth.password="$MONGO_PASSWORD" \--set traefik.enabled=false \--set app.gateway.name=traefik-gateway \--set app.gateway.namespace=traefik
Hostnames
API and Web require separate hostnames to be published through the Gateway. Pass them as lists:
helm install ignis infra/helm \--set db.auth.password="$MONGO_PASSWORD" \--set 'app.api.hostnames[0]=api.ignis.example.com' \--set 'app.web.hostnames[0]=ignis.example.com'
Multiple hostnames per service are supported:
--set 'app.web.hostnames[0]=ignis.example.com' \--set 'app.web.hostnames[1]=ignis.example.org'
Leaving a hostname list empty keeps that service internal-only and skips the
corresponding HTTPRoute.
TLS
TLS termination is handled by the Gateway using certificates issued by cert-manager. The chart does not install cert-manager — it expects a ClusterIssuer to already exist in the cluster.
1. Install cert-manager (if not already installed)
helm repo add jetstack https://charts.jetstack.iohelm install cert-manager jetstack/cert-manager \--namespace cert-manager --create-namespace \--set crds.enabled=true
2. Create a ClusterIssuer
For HTTP-01 (simplest — works with any DNS provider):
apiVersion: cert-manager.io/v1kind: ClusterIssuermetadata:name: letsencryptspec:acme:email: you@example.comserver: https://acme-v02.api.letsencrypt.org/directoryprivateKeySecretRef:name: letsencrypt-keysolvers:- http01:gatewayHTTPRoute:parentRefs:- name: ignis-gateway
[!TIP] Use
https://acme-staging-v02.api.letsencrypt.org/directoryas server while testing to avoid rate limits.
3. Create a Certificate
apiVersion: cert-manager.io/v1kind: Certificatemetadata:name: ignis-tlsnamespace: ignisspec:secretName: ignis-tlsissuerRef:name: letsencryptkind: ClusterIssuerdnsNames:- ignis.example.com- api.ignis.example.com
4. Add HTTPS listeners to the Gateway
Add a listener for each hostname on the Gateway, referencing the TLS secret:
listeners:- name: https-ignisport: 8443protocol: HTTPShostname: ignis.example.comallowedRoutes:namespaces:from: Alltls:mode: TerminatecertificateRefs:- name: ignis-tlsnamespace: ignis
If the Gateway is in a different namespace than the Certificate, create a ReferenceGrant to allow it to read the TLS secret:
apiVersion: gateway.networking.k8s.io/v1beta1kind: ReferenceGrantmetadata:name: allow-gateway-tlsnamespace: ignisspec:from:- group: gateway.networking.k8s.iokind: Gatewaynamespace: traefikto:- group: ""kind: Secretname: ignis-tls
Argo CD
[!WARNING] Do not pass secrets (like
db.auth.password) as Helm parameters in Argo CD — they are visible in the UI. Usedb.auth.existingSecretand create the Secret separately, or use Sealed Secrets / External Secrets.
Create the MongoDB secret before deploying:
kubectl create secret generic ignis-mongodb \--from-literal=MONGO_INITDB_ROOT_USERNAME=ignis \--from-literal=MONGO_INITDB_ROOT_PASSWORD="$(openssl rand -hex 32)"
Then create the API secret with the connection string:
MONGO_PASS=$(kubectl get secret ignis-mongodb -o jsonpath='{.data.MONGO_INITDB_ROOT_PASSWORD}' | base64 -d)kubectl create secret generic ignis-api \--from-literal=StoreSettings__ConnectionString="mongodb://ignis:${MONGO_PASS}@ignis-mongodb:27017/ignis?authSource=admin"
Argo CD Application manifest:
apiVersion: argoproj.io/v1alpha1kind: Applicationmetadata:name: ignisnamespace: argocdspec:project: defaultsource:repoURL: https://github.com/incendilabs/ignis.gittargetRevision: mainpath: infra/helmhelm:valueFiles:- values.yaml- values-production.yamlparameters:- name: db.auth.existingSecretvalue: ignis-mongodbdestination:server: https://kubernetes.default.svcnamespace: ignissyncPolicy:automated:prune: trueselfHeal: truesyncOptions:- CreateNamespace=true
Retrieving the MongoDB password
If you need to retrieve the password after installation:
kubectl get secret ignis-mongodb -o jsonpath='{.data.MONGO_INITDB_ROOT_PASSWORD}' | base64 -d
Troubleshooting
# Check pod statuskubectl get pods -l app.kubernetes.io/part-of=ignis# View API logskubectl logs -l app.kubernetes.io/name=ignis-api# View MongoDB logskubectl logs -l app.kubernetes.io/name=ignis-mongodb
[!NOTE] MongoDB password changes are handled automatically on
helm upgradevia a pre-upgrade hook that syncs the new password into the database before updating the Secret. This only applies when using a chart-managed password (db.auth.password), notdb.auth.existingSecret.