Host An Authenticated EHRbase Server In The Cloud In Under 15 Mins

Screenshot 2025 03 31 at 1.02.01 Pm

Vipin Santhosh

Developer & E-Learning Instructor

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!

#

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:

  1. Prepare your VPS environment (Ubuntu or Debian-based).
  2. Install and configure Docker and Docker Compose
  3. Deploy EHRBase and PostgreSQL using a docker-compose.yaml configuration.
  4. Use Traefik as a reverse proxy to obtain HTTPS certificates automatically.
  5. Enable basic authentication for secure access.

#

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).


#

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

#

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 and SPRING_SECURITY_ENABLED=true.
  • Basic Auth Credentials are set via SECURITY_AUTHUSER and SECURITY_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;

#

After creating your docker-compose.yaml, run:

docker-compose up -d

This command will:

  1. Pull the Postgres, EHRBase, and Traefik images from Docker Hub.
  2. Start the containers in detached mode.
  3. 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.

#

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.


#

If you want to maintain the volume of the PostgreSQL mapped in the Docker Compose file externally you can look into the following approaches.

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.


#

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!

#

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.


Save lives with digital healthcare innovation
© 2024 Medblocks. All rights reserved.