Skip to main content

Setting Up a New Open Clinical History Server

This guide describes the basic server setup required for a new Open Clinical History installation.

The application requires:

  • PHP

  • MariaDB/MySQL

  • a web server such as Apache or Nginx

  • a private configuration directory

  • a private SNOMED CT storage directory

  • a writable runtime directory

  • access to the private Open Clinical History source repository

SSL/HTTPS is strongly recommended and should be considered mandatory for any environment containing real clinical information.


Recommended Directory Structure

Keep sensitive configuration, runtime files and SNOMED CT source files outside the web-accessible application directory.

A typical installation might use:

/var/www/
├── private/
│   └── demo/
│       ├── config.php
│       ├── config_template.php
│       ├── health_history.sql
│       ├── run/
│       └── snomed/
│
└── openclinicalhistory/
    └── web application

For example:

root@server:/var/www/private/demo# ls
config.php
config_template.php
health_history.sql
run
snomed

The /var/www/private directory should not be configured as an Apache or Nginx document root.


1. Create the Private Application Directory

Create a private directory for:

  • database configuration

  • SQL schema

  • runtime files

  • SNOMED CT RF2 releases

For example:

mkdir -p /var/www/private/demo/run
mkdir -p /var/www/private/demo/snomed

The result should look similar to:

/var/www/private/demo/
├── config.php
├── config_template.php
├── health_history.sql
├── run/
└── snomed/

The run directory is used by Open Clinical History background processes for runtime state and job information.

The snomed directory stores the extracted SNOMED CT RF2 release.


2. Protect the Private Directory

The private directory must not be publicly accessible.

For example, the following should not work:

https://your-domain.example/private/demo/config.php

The application needs filesystem access to these files, but they must remain outside the web server's public document root.

Pay particular attention to:

config.php

because it contains database credentials.

SNOMED CT source files may also be subject to licensing restrictions and should not be publicly downloadable.


3. Create config.php

Open Clinical History includes a:

config_template.php

Use this as the starting point for the server-specific configuration.

For example:

cd /var/www/private/demo

cp config_template.php config.php

Edit:

config.php

with the appropriate settings for the server.

A typical configuration is:

<?php

return [

    'php_binary' => '/usr/bin/php8.3',

    'run_dir' => '/var/www/private/demo/run',

    'db' => [

        'host'     => '127.0.0.1',

        'port'     => 3306,

        'database' => 'health_history',

        'username' => 'root',

        'password' => 'your_password',

        'charset'  => 'utf8mb4',

    ],

    'debug' => false,

];

Configuration Settings

php_binary

Example:

'php_binary' => '/usr/bin/php8.3',

The CLI PHP executable used for background processing.

Open Clinical History launches background workers such as:

history_job.php
queue_worker.php

using this PHP binary.

Confirm the configured executable exists:

/usr/bin/php8.3 -v

The CLI PHP installation must include the extensions required by the application.

At minimum, verify:

/usr/bin/php8.3 -m | grep -E 'pdo_mysql|curl'

run_dir

Example:

'run_dir' => '/var/www/private/demo/run',

Defines the private runtime directory used for background job state.

The web-server user and background workers must be able to write to this directory.

For example:

mkdir -p /var/www/private/demo/run

Set ownership and permissions appropriate to the server environment.

For an Apache installation using www-data, this may look similar to:

chown -R www-data:www-data /var/www/private/demo/run

Do not blindly apply ownership commands without considering the security model of your server.


Database Configuration

The db section defines the MariaDB/MySQL connection.

Example:

'db' => [

    'host'     => '127.0.0.1',

    'port'     => 3306,

    'database' => 'health_history',

    'username' => 'root',

    'password' => 'your_password',

    'charset'  => 'utf8mb4',

],

host

Usually:

127.0.0.1

when the database runs on the same server.

port

Default MySQL/MariaDB port:

3306

database

health_history

username

Database account used by Open Clinical History.

A dedicated application database user is recommended for production rather than using the MariaDB root account.

password

Database password.

This is sensitive and must not be committed to Git.

charset

Use:

utf8mb4

This supports the complete Unicode character set required for clinical text.


Debug Mode

Production installations should normally use:

'debug' => false,

Debug mode may expose application and database information that should not be visible to end users.

Only enable debugging temporarily in a controlled development environment.


4. Create the Database

Create the Open Clinical History database.

For example:

CREATE DATABASE health_history
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;

A dedicated database user is preferable.

For example:

CREATE USER 'och'@'localhost'
IDENTIFIED BY 'use-a-strong-password';

GRANT ALL PRIVILEGES
ON health_history.*
TO 'och'@'localhost';

FLUSH PRIVILEGES;

Then update config.php accordingly:

'username' => 'och',
'password' => 'use-a-strong-password',

5. Import the Database Schema

The Open Clinical History source includes the database SQL required for a new installation.

Place or copy:

health_history.sql

into the private installation directory if required.

For example:

/var/www/private/demo/health_history.sql

Import it into the database:

mysql -u och -p health_history < /var/www/private/demo/health_history.sql

Or, if using another database account:

mysql -u root -p health_history < /var/www/private/demo/health_history.sql

Verify that the schema was imported:

mysql -u och -p health_history

Then:

SHOW TABLES;

You should see the Open Clinical History application tables.


6. Create the Web Directory

Create a directory for the web application.

For example:

mkdir -p /var/www/openclinicalhistory

This is separate from:

/var/www/private/

A typical structure is:

/var/www/
├── private/
│   └── demo/
│       ├── config.php
│       ├── run/
│       └── snomed/
│
└── openclinicalhistory/
    ├── index.php
    ├── history_import.php
    ├── admin_config.php
    ├── lib/
    ├── img/
    └── ...

Only the application directory should be exposed through the web server.


7. Configure the Domain

Create an Apache VirtualHost or equivalent Nginx configuration for the application.

For example:

https://clinical.example.org/

The web server's document root should point to the Open Clinical History application directory.

It should not point to:

/var/www

because this could expose the private directory.

For example:

DocumentRoot /var/www/openclinicalhistory

rather than:

DocumentRoot /var/www

8. Enable HTTPS

SSL/TLS is strongly recommended.

For a production or externally accessible installation, HTTPS should be considered required.

Open Clinical History can receive:

  • patient identifiers

  • dates of birth

  • clinical records

  • medical histories

  • API credentials

These must not be transmitted over unencrypted HTTP.

For an Apache server using Let's Encrypt, Certbot can typically be used to provision and renew the certificate.

After configuration, the application should be accessed through:

https://clinical.example.org/

rather than:

http://clinical.example.org/

The Patient Record API also defaults to requiring HTTPS.


9. Obtain Access to the Source Repository

The Open Clinical History source repository is currently private.

Repository:

https://github.com/bengoudieparkoch/openclinicalhistory

Access is provided to approved users rather than making the repository publicly available.

To request access, visit:

https://www.openclinicalhistory.org/access.php

and complete the access request form.

Once access has been approved, the repository can be cloned onto the server.


10. Clone the Repository

After GitHub access has been granted:

cd /var/www

Clone the repository:

git clone https://github.com/bengoudieparkoch/openclinicalhistory.git

This will normally create:

/var/www/openclinicalhistory

For subsequent deployments:

cd /var/www/openclinicalhistory
git pull

The exact authentication method depends on the GitHub account and server configuration.

GitHub may use:

  • SSH keys

  • a personal access token

  • another approved Git credential mechanism

Do not store GitHub credentials directly in application source files.


11. Ensure config.php Is Not in the Web Repository

The server-specific:

config.php

should remain in:

/var/www/private/demo/

rather than being committed into the repository.

Conceptually:

Git repository
    |
    | application code
    v
/var/www/openclinicalhistory


Private server configuration
    |
    v
/var/www/private/demo/config.php

This keeps:

  • database passwords

  • filesystem paths

  • server-specific configuration

out of version control.


12. Configure Web Server Permissions

The web-server process must be able to:

  • read the application source

  • read the private configuration

  • write to the configured run_dir

  • read the SNOMED CT directory when running imports

It generally should not need write access to the entire application source tree.

A more secure model is:

Application code
read-only to web process

Private config
read-only to web process

Run directory
read/write to web and workers

SNOMED files
read-only to web/workers

13. Check PHP Requirements

Confirm the web and CLI PHP environments contain the required modules.

For CLI PHP:

/usr/bin/php8.3 -m

Important modules include:

PDO
pdo_mysql
curl
json
mbstring

The exact installed module set will depend on the application version.

Also check:

/usr/bin/php8.3 -v

to confirm the version configured in:

'php_binary'

matches the installed binary.


14. Create the SNOMED Directory

Create a protected directory for SNOMED CT RF2 source releases:

mkdir -p /var/www/private/demo/snomed

Extract the authorised SNOMED CT release there.

A release may contain directories similar to:

Full/
Snapshot/
Delta/

with subdirectories such as:

Terminology/
Refset/

Open Clinical History uses the Snapshot data for its normal SNOMED import.

The raw SNOMED source files can be very large.

Allow sufficient:

  • disk space

  • database space

  • processing time

for the import.


15. Open the Application

After:

  • database configuration

  • schema import

  • Git deployment

  • web-server configuration

  • permissions

have been completed, open:

https://your-domain.example/

Confirm that the application loads without a database or configuration error.


16. Complete Application Configuration

Open:

Admin → Configuration

Configure the runtime application settings.

At minimum, review:

Date format
SNOMED CT RF2 release path
LLM enabled
Gemini API key
Gemini model
LLM usage limits
API configuration
Ingest queue configuration

Set the SNOMED path to the protected RF2 location.

For example:

/var/www/private/demo/snomed

17. Import SNOMED CT

Open:

SNOMED Import

Confirm the RF2 inventory detects:

Concept Snapshot
Description Snapshot
Relationship Snapshot
Language Snapshot

Then run:

Start or resume pipeline

The initial SNOMED import can take a significant amount of time.

The source data contains millions of rows.

Allow the pipeline to complete before proceeding.


18. Build the Image / SNOMED Database

After the SNOMED pipeline has completed, open:

Image/SNOMED Summary Build

Run:

Clean rebuild image summary database

This connects the installed anatomical image catalogue to the local SNOMED database and builds the compact runtime mapping tables.

This operation can also take some time.


19. Configure the Ingest Queue Worker

If:

queue_enabled

is enabled, at least one:

queue_worker.php

process should be running.

For testing, it can be started manually:

cd /var/www/openclinicalhistory
/usr/bin/php8.3 queue_worker.php

For production, configure it using a process supervisor such as:

  • systemd

  • Supervisor

  • another suitable service manager

The queue worker should be configured to restart if it exits unexpectedly.


20. Test Manual Patient Import

Open:

/history_import.php

Upload a small plain-text clinical history.

Confirm that the workflow can complete:

Upload
  |
  v
Extract
  |
  v
Audit & Import
  |
  v
Complete

This provides an end-to-end check of:

  • database connectivity

  • CLI worker configuration

  • Gemini configuration

  • SNOMED lookup tables

  • anatomical lookup tables

  • runtime directory permissions


21. Test the Patient Record API

If the API will be used:

  1. Open Admin → Configuration.

  2. Confirm the API is enabled.

  3. Create an API token.

  4. Give it only the required scopes.

  5. Test:

history_api_import.php?action=ping

using a Bearer token.

Do not expose API credentials in browser-side JavaScript or public source repositories.


Suggested New Server Checklist

  • Create /var/www/private/<environment>

  • Create private run directory

  • Create private snomed directory

  • Copy config_template.php to config.php

  • Configure PHP CLI path

  • Configure runtime directory

  • Configure database connection

  • Create MariaDB/MySQL database

  • Create dedicated application database user

  • Import health_history.sql

  • Request access to the private GitHub repository

  • Clone Open Clinical History

  • Create Apache/Nginx virtual host

  • Confirm private directory is outside the web root

  • Configure HTTPS

  • Verify web PHP extensions

  • Verify CLI PHP extensions

  • Configure application settings

  • Configure Gemini

  • Install SNOMED CT RF2 release

  • Run SNOMED Import

  • Run Image/SNOMED Summary Build

  • Configure queue_worker.php

  • Test manual patient import

  • Test Patient Record API if required

  • Confirm backups are configured


Recommended Production Structure

A production deployment should ultimately look conceptually like:

                         Internet
                            |
                            v
                       HTTPS / TLS
                            |
                            v
                     Apache / Nginx
                            |
                            v
              /var/www/openclinicalhistory
                            |
             +--------------+--------------+
             |                             |
             v                             v
      PHP application                 CLI workers
             |                             |
             +--------------+--------------+
                            |
                            v
                /var/www/private/demo
                    |       |       |
                    |       |       |
                    v       v       v
               config.php  run/   snomed/
                    |
                    v
                MariaDB/MySQL

The public web server exposes the application.

It does not expose:

config.php
SNOMED RF2 files
runtime job state
database SQL backups

Backups

Before using Open Clinical History with important patient information, configure regular backups.

At minimum, back up:

Open Clinical History database
private configuration
application-specific customisations
anatomical image catalogue

The SNOMED RF2 source files can usually be downloaded again from the authorised distributor, but retaining the exact release used by the installation can simplify recovery and auditing.

Do not rely on Git as a database or patient-data backup.


Security Notes

A new server may hold sensitive clinical information.

  • HTTPS only

  • private database credentials

  • dedicated database user

  • restrictive filesystem permissions

  • no public access to /var/www/private

  • no credentials committed to Git

  • protected administrative access

  • secure API bearer tokens

  • regular operating-system updates

  • regular database backups

  • firewall restrictions appropriate to the installation

The sample configuration uses root as the database user for simplicity.

A dedicated database user should be used for a production deployment.


Installation Order Summary

A complete new installation follows this sequence:

1. Prepare server
        |
        v
2. Create private directories
        |
        v
3. Configure config.php
        |
        v
4. Create database
        |
        v
5. Import health_history.sql
        |
        v
6. Request GitHub repository access
        |
        v
7. Clone application
        |
        v
8. Configure domain and HTTPS
        |
        v
9. Configure Admin settings
        |
        v
10. Install SNOMED RF2 files
        |
        v
11. Import SNOMED
        |
        v
12. Build Image/SNOMED database
        |
        v
13. Start queue worker
        |
        v
14. Test patient import
        |
        v
15. Test API
        |
        v
System ready

Repository Access

Open Clinical History is not currently distributed through a public source repository.

Approved users can request access at:

https://www.openclinicalhistory.org/access.php

Once approved, repository access can be provided for:

https://github.com/bengoudieparkoch/openclinicalhistory

This allows controlled access to the source while the project remains under active development.