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
Recommended database name:
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
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:
-
Open Admin → Configuration.
-
Confirm the API is enabled.
-
Create an API token.
-
Give it only the required scopes.
-
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
rundirectory -
Create private
snomeddirectory -
Copy
config_template.phptoconfig.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.
Recommended minimum controls include:
-
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.