⚠️ IMPORTANT: Repository and Image Name ChangeThis project was formerly known as Personal-Medical-Records-Keeper and has been renamed to MediKeep.
Breaking Changes:
- Docker image has moved from
ghcr.io/afairgiant/personal-medical-records-keeper/medical-recordstoghcr.io/afairgiant/medikeep- Repository will move from
afairgiant/Personal-Medical-Records-Keepertoafairgiant/MediKeep- Container names have changed from
medical-records-*tomedikeep-*Please update your configurations accordingly.
Your personal health record keeper - built with React frontend and FastAPI backend.
Full documentation is available on the MediKeep Wiki, including the User Guide, Admin Guide, and Developer Guide.
The main dashboard provides an overview of your health records and recent activity.
Track and manage all your medications, dosages, and schedules in one place.
Generate custom health reports and export your medical data for sharing with healthcare providers.
Ensure you have Docker and Docker Compose installed.
Create a docker-compose.yml file with content:
services:
# PostgreSQL Database Service
postgres:
# PostgreSQL 15-18 supported; changing this major on an existing volume requires pg_upgrade
image: postgres:15.8-alpine
container_name: medikeep-db
environment:
POSTGRES_DB: ${DB_NAME:-medical_records}
POSTGRES_USER: ${DB_USER:-medapp}
POSTGRES_PASSWORD: ${DB_PASSWORD}
# For Docker secrets, use POSTGRES_PASSWORD_FILE instead (built-in to postgres image):
#POSTGRES_PASSWORD_FILE: /run/secrets/db_password
volumes:
- postgres_data-prod:/var/lib/postgresql/data
- ./postgres/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
ports:
- "5432:5432"
healthcheck:
test:
[
"CMD-SHELL",
"pg_isready -U ${DB_USER:-medapp} -d ${DB_NAME:-medical_records}",
]
interval: 60s
timeout: 10s
retries: 3
start_period: 30s
restart: unless-stopped
networks:
- medikeep-network
# Combined Frontend + Backend Application Service
medikeep-app:
image: ghcr.io/afairgiant/medikeep:latest
# build:
# context: ..
# dockerfile: docker/Dockerfile
container_name: medikeep-app
ports:
- ${APP_PORT:-8005}:8000 # Single port serves both React app and FastAPI
environment:
DB_HOST: postgres
DB_PORT: 5432
DB_NAME: ${DB_NAME:-medical_records}
DB_USER: ${DB_USER:-medapp}
DB_PASSWORD: ${DB_PASSWORD}
SECRET_KEY: ${SECRET_KEY:?Set SECRET_KEY in .env or Docker secrets for persistent JWTs}
DEBUG: ${DEBUG:-false}
ENABLE_API_DOCS: ${ENABLE_API_DOCS:-false}
LOG_LEVEL: ${LOG_LEVEL:-INFO}
TZ: ${TZ:-America/New_York}
# SSL Configuration - set ENABLE_SSL=true in .env to enable HTTPS
ENABLE_SSL: ${ENABLE_SSL:-false}
# Integration URL SSRF control - Paperless/Papra on private LAN addresses
# is allowed by default; set false on internet-exposed instances to
# restrict to public URLs (169.254.x cloud-metadata is always blocked).
#ALLOW_PRIVATE_INTEGRATION_URLS: ${ALLOW_PRIVATE_INTEGRATION_URLS:-true}
# SSO Configuration (Optional) - SSO is disabled by default
SSO_ENABLED: ${SSO_ENABLED:-false}
SSO_PROVIDER_TYPE: ${SSO_PROVIDER_TYPE:-oidc}
SSO_CLIENT_ID: ${SSO_CLIENT_ID:-}
SSO_CLIENT_SECRET: ${SSO_CLIENT_SECRET:-}
SSO_ISSUER_URL: ${SSO_ISSUER_URL:-}
SSO_REDIRECT_URI: ${SSO_REDIRECT_URI:-}
SSO_ALLOWED_DOMAINS: ${SSO_ALLOWED_DOMAINS:-[]}
# Default Admin Password Configuration (optional - defaults to admin123 in app if not set)
#ADMIN_DEFAULT_PASSWORD: ${ADMIN_DEFAULT_PASSWORD:-}
#PUID: ${PUID} # Enable if using bind mounts
#PGID: ${PGID} # Enable if using bind mounts
# --- Docker Secrets (_FILE pattern) ---
# Instead of passing secrets as plain env vars, point to mounted files:
#DB_PASSWORD_FILE: /run/secrets/db_password
#SECRET_KEY_FILE: /run/secrets/secret_key
#SSO_CLIENT_ID_FILE: /run/secrets/sso_client_id
#SSO_CLIENT_SECRET_FILE: /run/secrets/sso_client_secret
#ADMIN_DEFAULT_PASSWORD_FILE: /run/secrets/admin_password
# When using _FILE vars, remove the corresponding plain env var above.
# secrets:
# - db_password
# - secret_key
# - sso_client_id
# - sso_client_secret
# - admin_password
volumes:
- app_uploads:/app/uploads
- app_logs:/app/logs
- app_backups:/app/backups
# Uncomment the line below and create certificates if you want HTTPS
# - ./certs:/app/certs:ro
depends_on:
postgres:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "-k", "http://localhost:8000/health"]
interval: 120s
timeout: 15s
retries: 2
start_period: 60s
restart: unless-stopped
networks:
- medikeep-network
# Named volumes for data persistence
volumes:
postgres_data-prod:
driver: local
app_uploads:
driver: local
app_logs:
driver: local
app_backups:
driver: local
# --- Docker Secrets (uncomment to use with Docker Swarm or compose secrets) ---
# secrets:
# db_password:
# file: ./secrets/db_password.txt
# secret_key:
# file: ./secrets/secret_key.txt
# sso_client_id:
# file: ./secrets/sso_client_id.txt
# sso_client_secret:
# file: ./secrets/sso_client_secret.txt
# admin_password:
# file: ./secrets/admin_password.txt
# Network for service communication
networks:
medikeep-network:
driver: bridge# Environment variables for Docker Compose
# Copy this file to .env and update the values
# Database Configuration
DB_NAME=medical_records
DB_USER=medapp
# IMPORTANT: Use quotes if password contains # (e.g., "my#pass")
# Always escape $ as $$ (e.g., pass$$word). Safe chars: @ % ^ & * ( ) - _ . !
DB_PASSWORD=your_secure_database_password_here #Change me
# Application port
APP_PORT=8005
# Application Security Key (REQUIRED - sessions are ephemeral without this)
SECRET_KEY=your-very-secure-secret-key-for-jwt-tokens-change-this-in-production
TZ=America/New_York
LOG_LEVEL=INFO #INFO or DEBUG
DEBUG=false
ENABLE_API_DOCS=false # Set to true to expose Swagger docs
ENABLE_SSL=false # false or true
# Allow Paperless/Papra integrations on private LAN addresses (default true).
# Set false on internet-exposed/multi-user instances to restrict to public URLs.
# ALLOW_PRIVATE_INTEGRATION_URLS=trueRun the following command to start the services:
docker compose up -dNote: Do not use docker-compose.
Once the containers are up, access the app in your browser at:
http://localhost:8005On fresh installations, a default admin user is created:
- Username:
admin - Password:
admin123(default)
Customizing the Default Password:
You can set a custom default admin password for fresh installations using the ADMIN_DEFAULT_PASSWORD environment variable:
# Set in your .env file or as environment variable
ADMIN_DEFAULT_PASSWORD=your_secure_password_hereNote: This only affects the initial admin user creation on fresh installations. It does not change passwords for existing users. Always change the default password after your first login.
The app can be backed up using the Admin Dashboard. Additionally, a backup/restore CLI is available. This can be used with cron to automate scheduled backups. See Backup and Restore CLI for more details.
Backups are stored under /app/backups. This should be mapped to
an external location or volume so that it can be stored safely in case a
restore is needed.
The app has SSO capabilities. As of right now, Google and Github are offically supported and tested. ODIC SSO(keycloak, authlia, etc) should be supported but I haven't tested them yet.
See SSO Quick Start for google/github.
See SSO Full Guide for a more detailed guide.


