Imagine you are working on a product idea that uses openEHR and you want an authenticated EHRBase server in the cloud to work with. Why pay a premium for a managed service, when you can just host your own server in less than 15 mins; less than 10 if you can type faster.
Follow along to get your EHRBase instance up and running with secure HTTPS and basic authentication in no time!
Introduction#
EHRBase is an open-source implementation of openEHR Clinical Data Repository (CDR). By deploying EHRBase on your VPS (Virtual private server, a.k.a. computer in the cloud), you can leverage all the benefits of openEHR, such as interoperability and standardized clinical data structures. In this tutorial, you’ll learn how to:
- Prepare your VPS environment (Ubuntu or Debian-based).
- Install and configure Docker and Docker Compose
- Deploy EHRBase and PostgreSQL using a
docker-compose.yaml
configuration. - Use Traefik as a reverse proxy to obtain HTTPS certificates automatically.
- Enable basic authentication for secure access.
1. Set Up Your VPS Environment#
Before deploying EHRBase, you need a VPS up and running. You can spin up an Ubuntu or Debian-based VPS from your preferred cloud provider. Once you have SSH access to your server, ensure you run all commands as a user with sudo
privileges (or root user).
2. Install Docker and Docker Compose#
Docker lets you run applications in lightweight containers. First, install the required dependencies, add Docker’s official GPG key, and set up the Docker repository.
sudo apt-get update
sudo apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
sudo apt-get update
sudo apt-get install -y docker-ce
Next, install Docker Compose (a tool to define and run multi-container Docker applications):
sudo curl -L "https://github.com/docker/compose/releases/download/v2.24.5/docker-compose-$(uname -s)-$(uname -m)" \
-o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
Optional: Add your user to the docker
group so you can run Docker without sudo
:
sudo usermod -aG docker $USER
Log out and log back in to activate this group change.
Also verify that Docker is set to start on boot
systemctl is-enabled docker
if the response is not enabled run the command
sudo systemctl enable docker
3. Create Your docker-compose.yaml
#
docker-compose.yaml
In your project directory (for example, /home/ubuntu/ehrbase
), create a file named docker-compose.yaml
with the following content:
services:
db:
image: postgres:16
restart: always
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: [PASSWORD_DB]
EHRBASE_USER_ADMIN: ehrbase
EHRBASE_PASSWORD_ADMIN: [PASSWORD_ADMIN]
EHRBASE_USER: ehrbase_restricted
EHRBASE_PASSWORD: [PASSWORD_USER]
volumes:
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
# to persist the data
- ehrbase_data:/var/lib/postgresql/data
ehrbase:
image: ehrbase/ehrbase:2.11.0
restart: always
depends_on:
- db
environment:
DB_URL: jdbc:postgresql://db:5432/ehrbase
DB_USER_ADMIN: ehrbase
DB_PASS_ADMIN: [PASSWORD_ADMIN]
DB_USER: ehrbase_restricted
DB_PASS: [PASSWORD_USER]
EHRBASE_AQL_EXPERIMENTAL_AQLONFOLDER_ENABLED: "true"
SECURITY_AUTHTYPE: BASIC
SECURITY_AUTHUSER: ehrbase-user
SECURITY_AUTHPASSWORD: [REPLACE_WITH_SECURE_PASSWORD]
SPRING_SECURITY_ENABLED: "true"
# Node name for this EHRbase instance. This name is completely arbitrary and can be chosen freely eg. openehr.medblocks.com
SERVER_NODENAME: [REPLACE_WITH_A_NAME]
# CORS configuration
WEB_CORS_ALLOWEDORIGINS: "*"
WEB_CORS_ALLOWEDORIGINPATTERNS: "*"
WEB_CORS_ALLOWEDMETHODS: "GET,PUT,DELETE,POST,OPTIONS"
WEB_CORS_ALLOWCREDENTIALS: "false"
labels:
- "traefik.enable=true"
- "traefik.http.routers.ehrbase.rule=Host(`[REPLACE_WITH_YOUR_DOMAIN]`)"
- "traefik.http.routers.ehrbase.entrypoints=websecure"
- "traefik.http.routers.ehrbase.tls=true"
- "traefik.http.routers.ehrbase.tls.certresolver=letsencrypt"
- "traefik.http.services.ehrbase.loadbalancer.server.port=8080"
traefik:
image: traefik:v2.10
restart: always
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.letsencrypt.acme.email=[REPLACE_WITH_YOUR_EMAIL_ADDRESS]"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge=true"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
ports:
- "80:80"
- "443:443"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "letsencrypt:/letsencrypt"
labels:
- "traefik.enable=true"
volumes:
ehrbase_data:
letsencrypt:
Key Points:
- EHRBase container configured with environment variables
SECURITY_AUTHTYPE=BASIC
andSPRING_SECURITY_ENABLED=true
. - Basic Auth Credentials are set via
SECURITY_AUTHUSER
andSECURITY_AUTHPASSWORD
. - Traefik automatically handles Let’s Encrypt SSL certificate generation (using the domain specified in the label rule).
In the same directory create a init.sql
file as follows:
\set db_user `echo "$EHRBASE_USER"`
\set db_pass `echo "$EHRBASE_PASSWORD"`
\set db_user_admin `echo "$EHRBASE_USER_ADMIN"`
\set db_pass_admin `echo "$EHRBASE_PASSWORD_ADMIN"`
CREATE ROLE :db_user WITH LOGIN PASSWORD :'db_pass';
CREATE ROLE :db_user_admin WITH LOGIN PASSWORD :'db_pass_admin';
CREATE DATABASE ehrbase ENCODING 'UTF-8' LOCALE 'C' TEMPLATE template0;
GRANT ALL PRIVILEGES ON DATABASE ehrbase TO :db_user_admin;
GRANT ALL PRIVILEGES ON DATABASE ehrbase TO :db_user;
\c ehrbase
REVOKE CREATE ON SCHEMA public from PUBLIC;
CREATE SCHEMA IF NOT EXISTS ehr AUTHORIZATION :db_user_admin;
GRANT USAGE ON SCHEMA ehr to :db_user;
ALTER DEFAULT PRIVILEGES FOR USER :db_user_admin IN SCHEMA ehr GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO :db_user;
ALTER DEFAULT PRIVILEGES FOR USER :db_user_admin IN SCHEMA ehr GRANT SELECT ON SEQUENCES TO :db_user;
CREATE SCHEMA IF NOT EXISTS ext AUTHORIZATION :db_user_admin;
GRANT USAGE ON SCHEMA ext to :db_user;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp" SCHEMA ext;
-- setup the search_patch so the extensions can be found
ALTER DATABASE ehrbase SET search_path TO ext;
-- ensure INTERVAL is ISO8601 encoded
ALTER DATABASE ehrbase SET intervalstyle = 'iso_8601';
ALTER FUNCTION jsonb_path_query(jsonb,jsonpath,jsonb,boolean) ROWS 1;
4. Run the EHRBase Server#
After creating your docker-compose.yaml
, run:
docker-compose up -d
This command will:
- Pull the Postgres, EHRBase, and Traefik images from Docker Hub.
- Start the containers in detached mode.
- Traefik will request an SSL certificate for
[REPLACE_WITH_YOUR_DOMAIN]
from Let’s Encrypt.
Important:
- Ensure your domain’s DNS is correctly pointed to the public IP of your VPS. Video Tutorial
- The first time you run it, Traefik will set up certificates for your domain. This may take a moment.
5. Access EHRBase Over HTTPS#
Once the containers are running, open your web browser and navigate to https://your-domain.com/ehrbase/rest/status
. You will be prompted to enter the basic authentication credentials you set.
Bonus Content#
If you want to maintain the volume of the PostgreSQL mapped in the Docker Compose file externally you can look into the following approaches.
- Docker Bind Mounts: Docker Documentation on Bind Mounts
- Docker Volumes: Manage Data in Docker
These articles will help you understand how Docker handles persistent storage and what the benefits are when using an external (elastic) volume setup.
Also here is an article about how to back up, restore, or migrate data volumes in Docker.
Summary#
Congratulations! Your EHRBase instance is now securely hosted on your VPS with basic authentication enabled. You also have a valid SSL certificate courtesy of Let’s Encrypt, managed automatically by Traefik. This setup ensures your clinical data repository remains both accessible and protected.
Feel free to explore further configurations—like adding firewall rules, customizing PostgreSQL volumes for more robust data persistence, or integrating advanced monitoring tools. With this foundation, you have all the essentials to start leveraging EHRBase for openEHR-based solutions!
PS#
There are bots out there that will corrupt your db if you have exposed databases with commonly used passwords. So make sure at the very least that your passwords are unique.