Skip to content

MediKeep

Deploy MediKeep on Kubernetes as a self-hosted personal medical records application.

Overview

The HelmForge MediKeep chart uses the official ghcr.io/afairgiant/medikeep:v0.68.0 image. The container serves the React frontend and FastAPI backend on port 8000, stores structured records in PostgreSQL, and writes files under /app/uploads, /app/backups, and /app/logs.

MediKeep handles personal health data. Treat the PostgreSQL database, uploads PVC, backups PVC, logs, and runtime Secrets as sensitive.

MediKeep v0.68.0 adds medication reminder configuration and test reminders, Chikungunya vaccine support, stacked lab result views, and practitioner entry improvements. It also fixes reference range validation, immunization history linking, condition lab result visibility, and a migration file ID overlap. Back up PostgreSQL and uploaded records before upgrading.

Configuration Reference

Core runtime:

  • image.repository, image.tag, image.pullPolicy: official pinned MediKeep image and pull behavior.
  • replicaCount: pod count. The chart rejects values greater than 1 because MediKeep writes to local mounted paths.
  • app.port, app.timezone, app.logLevel, app.debug, app.enableApiDocs, app.enableSsl.
  • app.command, app.args, app.env, app.envFrom.
  • commonLabels, nameOverride, fullnameOverride.

Secrets:

  • secrets.existingSecret: existing Secret for MediKeep runtime secrets.
  • secrets.secretKeyKey, secrets.secretKey: SECRET_KEY source.
  • secrets.adminDefaultPasswordKey, secrets.adminDefaultPassword: initial admin password source.
  • secrets.ssoClientSecretKey, secrets.ssoClientSecret: SSO client secret source.

Database:

  • postgresql.enabled: bundled HelmForge PostgreSQL dependency.
  • postgresql.auth.database, postgresql.auth.username, postgresql.auth.password.
  • database.external.host, database.external.port, database.external.name, database.external.username.
  • database.external.existingSecret, database.external.existingSecretPasswordKey, database.external.password.

Persistence:

  • persistence.uploads: uploaded lab files, patient photos, and attachments.
  • persistence.backups: backups generated by MediKeep.
  • persistence.logs: application logs, disabled by default.

Exposure and operations:

  • service.type, service.port, service.annotations, service.ipFamilyPolicy, service.ipFamilies.
  • ingress.enabled, ingress.ingressClassName, ingress.annotations, ingress.hosts, ingress.tls.
  • gatewayAPI.enabled, gatewayAPI.httpRoutes.
  • externalSecrets.enabled, externalSecrets.items.
  • networkPolicy.enabled, networkPolicy.ingressFrom, networkPolicy.egress.enabled, networkPolicy.egress.allowDNS, networkPolicy.egress.extraTo, networkPolicy.egress.extraEgress.
  • probes.startup, probes.liveness, probes.readiness.
  • resources, podSecurityContext, securityContext, waitForDatabase.
  • serviceAccount, pdb, nodeSelector, tolerations, affinity, topologySpreadConstraints.
  • priorityClassName, terminationGracePeriodSeconds, podLabels, podAnnotations, extraVolumes, extraVolumeMounts, extraManifests.

Installation

helm repo add helmforge https://repo.helmforge.dev
helm repo update
helm install medikeep helmforge/medikeep

OCI install:

helm install medikeep oci://ghcr.io/helmforgedev/helm/medikeep

Production Example

secrets:
  existingSecret: medikeep-runtime
  secretKeyKey: secret-key
  adminDefaultPasswordKey: admin-password

persistence:
  uploads:
    size: 20Gi
  backups:
    size: 20Gi
  logs:
    enabled: true
    size: 2Gi

ingress:
  enabled: true
  ingressClassName: traefik
  hosts:
    - host: medikeep.example.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: medikeep-tls
      hosts:
        - medikeep.example.com

networkPolicy:
  enabled: true

Create the runtime Secret before first startup:

apiVersion: v1
kind: Secret
metadata:
  name: medikeep-runtime
type: Opaque
stringData:
  secret-key: replace-with-a-long-random-secret
  admin-password: replace-with-a-strong-initial-password

Upstream creates admin/admin123 on fresh installs if ADMIN_DEFAULT_PASSWORD is not set before first startup. Set a stronger initial password for production and rotate it after first login.

External PostgreSQL

postgresql:
  enabled: false

database:
  external:
    host: postgres.example.com
    name: medical_records
    username: medapp
    existingSecret: medikeep-db
    existingSecretPasswordKey: password

Gateway API

gatewayAPI:
  enabled: true
  httpRoutes:
    - parentRefs:
        - name: public
          namespace: gateway-system
      hostnames:
        - medikeep.example.com

External Secrets

secrets:
  existingSecret: medikeep-runtime

externalSecrets:
  enabled: true
  items:
    - fullnameOverride: medikeep-runtime
      spec:
        secretStoreRef:
          kind: ClusterSecretStore
          name: production
        target:
          name: medikeep-runtime
          creationPolicy: Owner
        data:
          - secretKey: secret-key
            remoteRef:
              key: medikeep/app
              property: secret-key
          - secretKey: admin-password
            remoteRef:
              key: medikeep/app
              property: admin-password

Backup

Back up PostgreSQL and the uploads and backups PVCs together. A database-only backup is incomplete when users attach lab files, patient photos, or generated backup archives.

Additional Resources