Initial commit for chart

This commit is contained in:
Jörn Guy Süß 2025-07-16 10:01:45 +10:00
parent 7d69ca27ae
commit 410dd003f7
6 changed files with 594 additions and 0 deletions

View File

@ -0,0 +1,19 @@
apiVersion: v2
name: fhirflare-ig-toolkit
version: 0.1.0
description: Helm chart for deploying the fhirflare-ig-toolkit application
type: application
appVersion: "latest"
icon: https://github.com/jgsuess/FHIRFLARE-IG-Toolkit/raw/main/static/FHIRFLARE.png
keywords:
- fhir
- healthcare
- ig-toolkit
home: https://github.com/jgsuess/FHIRFLARE-IG-Toolkit
maintainers:
- name: FHIRFLARE Team
email: jgsuess@gmail.com
dependencies:
- name: hapi-fhir-jpaserver
version: 0.20.0
repository: https://hapifhir.github.io/hapi-fhir-jpaserver-starter/

View File

@ -0,0 +1,152 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "hapi-fhir-jpaserver.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "hapi-fhir-jpaserver.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "hapi-fhir-jpaserver.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "hapi-fhir-jpaserver.labels" -}}
helm.sh/chart: {{ include "hapi-fhir-jpaserver.chart" . }}
{{ include "hapi-fhir-jpaserver.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "hapi-fhir-jpaserver.selectorLabels" -}}
app.kubernetes.io/name: {{ include "hapi-fhir-jpaserver.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "hapi-fhir-jpaserver.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "hapi-fhir-jpaserver.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
{{/*
Create a default fully qualified postgresql name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
*/}}
{{- define "hapi-fhir-jpaserver.postgresql.fullname" -}}
{{- $name := default "postgresql" .Values.postgresql.nameOverride -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Get the Postgresql credentials secret name.
*/}}
{{- define "hapi-fhir-jpaserver.postgresql.secretName" -}}
{{- if .Values.postgresql.enabled -}}
{{- if .Values.postgresql.auth.existingSecret -}}
{{- printf "%s" .Values.postgresql.auth.existingSecret -}}
{{- else -}}
{{- printf "%s" (include "hapi-fhir-jpaserver.postgresql.fullname" .) -}}
{{- end -}}
{{- else }}
{{- if .Values.externalDatabase.existingSecret -}}
{{- printf "%s" .Values.externalDatabase.existingSecret -}}
{{- else -}}
{{ printf "%s-%s" (include "hapi-fhir-jpaserver.fullname" .) "external-db" }}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Get the Postgresql credentials secret key.
*/}}
{{- define "hapi-fhir-jpaserver.postgresql.secretKey" -}}
{{- if .Values.postgresql.enabled -}}
{{- if .Values.postgresql.auth.username -}}
{{- printf "%s" .Values.postgresql.auth.secretKeys.userPasswordKey -}}
{{- else -}}
{{- printf "%s" .Values.postgresql.auth.secretKeys.adminPasswordKey -}}
{{- end -}}
{{- else }}
{{- if .Values.externalDatabase.existingSecret -}}
{{- printf "%s" .Values.externalDatabase.existingSecretKey -}}
{{- else -}}
{{- printf "postgres-password" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Add environment variables to configure database values
*/}}
{{- define "hapi-fhir-jpaserver.database.host" -}}
{{- ternary (include "hapi-fhir-jpaserver.postgresql.fullname" .) .Values.externalDatabase.host .Values.postgresql.enabled -}}
{{- end -}}
{{/*
Add environment variables to configure database values
*/}}
{{- define "hapi-fhir-jpaserver.database.user" -}}
{{- if .Values.postgresql.enabled -}}
{{- printf "%s" .Values.postgresql.auth.username | default "postgres" -}}
{{- else -}}
{{- printf "%s" .Values.externalDatabase.user -}}
{{- end -}}
{{- end -}}
{{/*
Add environment variables to configure database values
*/}}
{{- define "hapi-fhir-jpaserver.database.name" -}}
{{- ternary .Values.postgresql.auth.database .Values.externalDatabase.database .Values.postgresql.enabled -}}
{{- end -}}
{{/*
Add environment variables to configure database values
*/}}
{{- define "hapi-fhir-jpaserver.database.port" -}}
{{- ternary "5432" .Values.externalDatabase.port .Values.postgresql.enabled -}}
{{- end -}}
{{/*
Create the JDBC URL from the host, port and database name.
*/}}
{{- define "hapi-fhir-jpaserver.database.jdbcUrl" -}}
{{- $host := (include "hapi-fhir-jpaserver.database.host" .) -}}
{{- $port := (include "hapi-fhir-jpaserver.database.port" .) -}}
{{- $name := (include "hapi-fhir-jpaserver.database.name" .) -}}
{{- $appName := .Release.Name -}}
{{ printf "jdbc:postgresql://%s:%d/%s?ApplicationName=%s" $host (int $port) $name $appName }}
{{- end -}}

View File

@ -0,0 +1,37 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: fhirflare
spec:
replicas: 1
selector:
matchLabels:
io.kompose.service: fhirflare
strategy:
type: Recreate
template:
spec:
containers:
- args:
- supervisord
- -c
- /etc/supervisord.conf
env:
- name: APP_BASE_URL
value: http://localhost:5000
- name: APP_MODE
value: lite
- name: FLASK_APP
value: app.py
- name: FLASK_ENV
value: development
- name: HAPI_FHIR_URL
value: http://localhost:8080/fhir
- name: NODE_PATH
value: /usr/lib/node_modules
image: ghcr.io/jgsuess/fhirflare-ig-toolkit:latest
name: fhirflare
ports:
- containerPort: 5000
protocol: TCP
restartPolicy: Always

View File

@ -0,0 +1,11 @@
apiVersion: v1
kind: Service
metadata:
name: fhirflare
spec:
ports:
- name: "5000"
port: 5000
targetPort: 5000
selector:
io.kompose.service: fhirflare

View File

@ -0,0 +1,73 @@
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "hapi-fhir-jpaserver.fullname" . }}-test-endpoints"
labels:
{{- include "hapi-fhir-jpaserver.labels" . | nindent 4 }}
{{ include "hapi-fhir-jpaserver.fullname" . }}-client: "true"
app.kubernetes.io/component: tests
annotations:
"helm.sh/hook": test
spec:
restartPolicy: Never
automountServiceAccountToken: {{ .Values.tests.automountServiceAccountToken }}
securityContext:
{{- toYaml .Values.tests.podSecurityContext | nindent 4 }}
containers:
- name: test-metadata-endpoint
image: "{{ .Values.curl.image.registry }}/{{ .Values.curl.image.repository }}:{{ .Values.curl.image.tag }}"
command: ["curl", "--fail-with-body"]
args: ["http://{{ include "hapi-fhir-jpaserver.fullname" . }}:{{ .Values.service.port }}/fhir/metadata?_summary=true"]
{{- with .Values.restrictedContainerSecurityContext }}
securityContext:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.tests.resources }}
resources: {{- toYaml .Values.tests.resources | nindent 10 }}
{{- else if ne .Values.tests.resourcesPreset "none" }}
resources: {{- include "common.resources.preset" (dict "type" .Values.tests.resourcesPreset) | nindent 10 }}
{{- end }}
livenessProbe:
exec:
command: ["true"]
readinessProbe:
exec:
command: ["true"]
- name: test-patient-endpoint
image: "{{ .Values.curl.image.registry }}/{{ .Values.curl.image.repository }}:{{ .Values.curl.image.tag }}"
command: ["curl", "--fail-with-body"]
args: ["http://{{ include "hapi-fhir-jpaserver.fullname" . }}:{{ .Values.service.port }}/fhir/Patient?_count=1&_summary=true"]
{{- with .Values.restrictedContainerSecurityContext }}
securityContext:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.tests.resources }}
resources: {{- toYaml .Values.tests.resources | nindent 10 }}
{{- else if ne .Values.tests.resourcesPreset "none" }}
resources: {{- include "common.resources.preset" (dict "type" .Values.tests.resourcesPreset) | nindent 10 }}
{{- end }}
livenessProbe:
exec:
command: ["true"]
readinessProbe:
exec:
command: ["true"]
- name: test-metrics-endpoint
image: "{{ .Values.curl.image.registry }}/{{ .Values.curl.image.repository }}:{{ .Values.curl.image.tag }}"
command: ["curl", "--fail-with-body"]
args: ["http://{{ include "hapi-fhir-jpaserver.fullname" . }}:{{ .Values.metrics.service.port }}/actuator/prometheus"]
{{- with .Values.restrictedContainerSecurityContext }}
securityContext:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.tests.resources }}
resources: {{- toYaml .Values.tests.resources | nindent 10 }}
{{- else if ne .Values.tests.resourcesPreset "none" }}
resources: {{- include "common.resources.preset" (dict "type" .Values.tests.resourcesPreset) | nindent 10 }}
{{- end }}
livenessProbe:
exec:
command: ["true"]
readinessProbe:
exec:
command: ["true"]

View File

@ -0,0 +1,302 @@
# -- number of replicas to deploy
replicaCount: 1
image:
# -- registry where the HAPI FHIR server image is hosted
registry: docker.io
# -- the path inside the repository
repository: hapiproject/hapi
# -- the image tag. As of v5.7.0, this is the `distroless` flavor by default, add `-tomcat` to use the Tomcat-based image.
tag: "v8.0.0-1@sha256:9fbac7b012b4be91ba481e7008f1353ede4598bc99a36f3902b8abf873e70ed8"
# -- image pullPolicy to use
pullPolicy: IfNotPresent
# -- image pull secrets to use when pulling the image
imagePullSecrets: []
# -- override the chart name
nameOverride: ""
# -- override the chart fullname
fullnameOverride: ""
# -- annotations applied to the server deployment
deploymentAnnotations: {}
# -- annotations applied to the server pod
podAnnotations: {}
# -- pod security context
podSecurityContext:
fsGroupChangePolicy: OnRootMismatch
runAsNonRoot: true
runAsGroup: 65532
runAsUser: 65532
fsGroup: 65532
seccompProfile:
type: RuntimeDefault
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 65532
runAsGroup: 65532
privileged: false
seccompProfile:
type: RuntimeDefault
# service to expose the server
service:
# -- service type
type: ClusterIP
# -- port where the server will be exposed at
port: 8080
ingress:
# -- whether to create an Ingress to expose the FHIR server HTTP endpoint
enabled: false
# -- provide any additional annotations which may be required. Evaluated as a template.
annotations:
{}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: fhir-server.127.0.0.1.nip.io
pathType: ImplementationSpecific
paths: ["/"]
# -- ingress TLS config
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
# -- set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge).
# This is ignored if `resources` is set (`resources` is recommended for production).
# More information: <https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15>
resourcesPreset: "medium"
# -- configure the FHIR server's resource requests and limits
resources:
{}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
# -- node selector for the pod
nodeSelector: {}
# -- pod tolerations
tolerations: []
# -- pod affinity
affinity: {}
# -- pod topology spread configuration
# see: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/#api
topologySpreadConstraints:
[]
# - maxSkew: 1
# topologyKey: topology.kubernetes.io/zone
# whenUnsatisfiable: ScheduleAnyway
# labelSelector:
# matchLabels:
# app.kubernetes.io/instance: hapi-fhir-jpaserver
# app.kubernetes.io/name: hapi-fhir-jpaserver
postgresql:
# -- enable an included PostgreSQL DB.
# see <https://github.com/bitnami/charts/tree/master/bitnami/postgresql> for details
# if set to `false`, the values under `externalDatabase` are used
enabled: true
auth:
# -- name for a custom database to create
database: "fhir"
# -- Name of existing secret to use for PostgreSQL credentials
# `auth.postgresPassword`, `auth.password`, and `auth.replicationPassword` will be ignored and picked up from this secret
# The secret must contain the keys `postgres-password` (which is the password for "postgres" admin user),
# `password` (which is the password for the custom user to create when `auth.username` is set),
# and `replication-password` (which is the password for replication user).
# The secret might also contains the key `ldap-password` if LDAP is enabled. `ldap.bind_password` will be ignored and
# picked from this secret in this case.
# The value is evaluated as a template.
existingSecret: ""
# -- readiness probe
# @ignored
readinessProbe:
httpGet:
path: /readyz
port: http
failureThreshold: 5
initialDelaySeconds: 30
periodSeconds: 20
successThreshold: 1
timeoutSeconds: 20
# -- liveness probe
# @ignored
livenessProbe:
httpGet:
path: /livez
port: http
failureThreshold: 5
initialDelaySeconds: 30
periodSeconds: 20
successThreshold: 1
timeoutSeconds: 30
# -- startup probe
# @ignored
startupProbe:
httpGet:
path: /readyz
port: http
failureThreshold: 10
initialDelaySeconds: 30
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 30
externalDatabase:
# -- external database host used with `postgresql.enabled=false`
host: localhost
# -- database port number
port: 5432
# -- username for the external database
user: fhir
# -- database password
password: ""
# -- name of an existing secret resource containing the DB password in the `existingSecretKey` key
existingSecret: ""
# -- name of the key inside the `existingSecret`
existingSecretKey: "postgresql-password"
# -- database name
database: fhir
# -- extra environment variables to set on the server container
extraEnv:
[]
# - name: SPRING_FLYWAY_BASELINE_ON_MIGRATE
# value: "true"
podDisruptionBudget:
# -- Enable PodDisruptionBudget for the server pods.
# uses policy/v1/PodDisruptionBudget thus requiring k8s 1.21+
enabled: false
# -- minimum available instances
minAvailable: 1
# -- maximum unavailable instances
maxUnavailable: ""
serviceAccount:
# -- Specifies whether a service account should be created.
create: false
# -- Annotations to add to the service account
annotations: {}
# -- The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
# -- Automatically mount a ServiceAccount's API credentials?
automount: true
metrics:
serviceMonitor:
# -- if enabled, creates a ServiceMonitor instance for Prometheus Operator-based monitoring
enabled: false
# -- additional labels to apply to the ServiceMonitor object, e.g. `release: prometheus`
additionalLabels: {}
# namespace: monitoring
# interval: 30s
# scrapeTimeout: 10s
service:
port: 8081
# @ignore
restrictedContainerSecurityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
privileged: false
capabilities:
drop:
- ALL
runAsNonRoot: true
runAsUser: 65534
runAsGroup: 65534
seccompProfile:
type: RuntimeDefault
# @ignored
curl:
image:
registry: docker.io
repository: curlimages/curl
tag: 8.12.1@sha256:94e9e444bcba979c2ea12e27ae39bee4cd10bc7041a472c4727a558e213744e6
tests:
# -- whether the service account token should be auto-mounted for the test pods
automountServiceAccountToken: false
# -- set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge).
# This is ignored if `resources` is set (`resources` is recommended for production).
# More information: <https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15>
resourcesPreset: "nano"
# -- configure the test pods resource requests and limits
resources: {}
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
# @ignored
podSecurityContext:
fsGroupChangePolicy: OnRootMismatch
runAsNonRoot: true
runAsGroup: 65532
runAsUser: 65532
fsGroup: 65532
seccompProfile:
type: RuntimeDefault
initContainers:
# -- set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge).
# This is ignored if `resources` is set (`resources` is recommended for production).
# More information: <https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15>
resourcesPreset: "nano"
# -- configure the init containers pods resource requests and limits
resources: {}
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
# -- additional Spring Boot application config. Mounted as a file and automatically loaded by the application.
extraConfig:
""
# # For example:
# |
# hapi:
# fhir:
# implementationguides:
# gh_0_1_0:
# url: https://build.fhir.org/ig/hl7-eu/gravitate-health/package.tgz
# name: hl7.eu.fhir.gh
# version: 0.1.0
# -- Optionally specify extra list of additional volumes
extraVolumes: []
# -- Optionally specify extra list of additional volumeMounts
extraVolumeMounts: []