Overview
This guide covers installing OpenEyes for production use. For development environments, see the Quick Start Guide .
Important Safety Notice OpenEyes is provided under AGPL v3.0 license with NO WARRANTY. Any user deploying OpenEyes in a clinical environment must:
Undertake a comprehensive safety assessment
Ensure deployment matches local clinical safety requirements
Comply with relevant data protection regulations (GDPR, HIPAA, etc.)
Implement proper backup and disaster recovery procedures
Obtain appropriate support contracts for clinical use
System Requirements
Server Requirements
Operating System
Hardware
Network
Recommended : Ubuntu 20.04 LTS or 22.04 LTS
RHEL/CentOS 7/8 (with adjustments)
Debian 10/11
Minimum :
2 CPU cores
4GB RAM
50GB disk space
Recommended for Production :
4+ CPU cores
8GB+ RAM
100GB+ SSD storage
Additional storage for backups
Static IP address
Firewall access for HTTP (80) and HTTPS (443)
Optional: SSH (22) for management
Internal network access to PAS/HL7 systems (if applicable)
Software Requirements
Based on composer.json specifications:
{
"require" : {
"php" : "^7.4 || ^8.0 || ^8.1" ,
"ext-json" : "^7.4 || ^8.0 || ^8.1" ,
"ext-dom" : "*" ,
"ext-libxml" : "*" ,
"ext-openssl" : "*" ,
"ext-soap" : "*" ,
"yiisoft/yii" : "1.1.28"
}
}
Required PHP Extensions :
php-json
php-dom
php-xml / php-libxml
php-openssl
php-soap
php-mysql or php-mysqli
php-gd
php-curl
php-mbstring
Database :
MySQL 5.7+ or MariaDB 10.3+
InnoDB storage engine
128MB+ innodb_log_file_size
128MB+ max_allowed_packet
Web Server :
Apache 2.4+ with mod_rewrite
OR Nginx 1.18+
Installation Steps
Install System Dependencies
Update system and install required packages: # Update system
sudo apt update && sudo apt upgrade -y
# Install PHP 8.1 and extensions
sudo apt install -y php8.1 php8.1-cli php8.1-fpm \
php8.1-mysql php8.1-json php8.1-xml php8.1-soap \
php8.1-gd php8.1-curl php8.1-mbstring php8.1-dom
# Install Apache
sudo apt install -y apache2
# Enable required Apache modules
sudo a2enmod rewrite ssl headers
# Install MySQL
sudo apt install -y mysql-server-8.0
# Install Composer
curl -sS https://getcomposer.org/installer | sudo php -- \
--install-dir=/usr/local/bin --filename=composer
# Install Git
sudo apt install -y git
Verify PHP version: php -v # Should show 7.4, 8.0, or 8.1
Configure MySQL Database
Create the OpenEyes database and user: # Connect to MySQL
sudo mysql
Execute the following SQL: -- Create database
CREATE DATABASE openeyes CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- Create user with strong password
CREATE USER ' openeyes '@ 'localhost' IDENTIFIED BY 'STRONG_PASSWORD_HERE' ;
-- Grant privileges
GRANT ALL PRIVILEGES ON openeyes. * TO 'openeyes' @ 'localhost' ;
FLUSH PRIVILEGES;
-- Exit MySQL
EXIT;
Configure MySQL for OpenEyes by editing /etc/mysql/mysql.conf.d/mysqld.cnf: [mysqld]
innodb_log_file_size = 128M
max_allowed_packet = 128M
net_buffer_length = 1000000
# For production, enable binary logging
log_bin = /var/log/mysql/mysql-bin.log
binlog_expire_logs_seconds = 604800
Restart MySQL: sudo systemctl restart mysql
Replace STRONG_PASSWORD_HERE with a secure password. Store it securely for later configuration.
Clone OpenEyes Repository
Clone to the web server directory: # Create directory
sudo mkdir -p /var/www/openeyes
cd /var/www/openeyes
# Clone repository (stable master branch)
sudo git clone -b master https://github.com/AppertaFoundation/openeyes.git .
# Set ownership
sudo chown -R www-data:www-data /var/www/openeyes
For a specific version: git checkout tags/v3.0 # Replace with desired version
Install PHP Dependencies
Install dependencies using Composer: cd /var/www/openeyes
sudo -u www-data composer install --no-dev --optimize-autoloader
The --no-dev flag excludes development dependencies for production.
Configure Database Connection
OpenEyes reads database configuration from environment variables or /etc/openeyes/db.conf. Option 1: Environment Variables (Recommended for Docker/containerized deployments)Set in your environment or systemd service: export DATABASE_HOST = localhost
export DATABASE_PORT = 3306
export DATABASE_NAME = openeyes
export DATABASE_USER = openeyes
export DATABASE_PASS = STRONG_PASSWORD_HERE
Option 2: Configuration File (Traditional deployment)Create /etc/openeyes/db.conf: host =localhost
port =3306
dbname =openeyes
username =openeyes
password =STRONG_PASSWORD_HERE
Secure the file: sudo chown www-data:www-data /etc/openeyes/db.conf
sudo chmod 600 /etc/openeyes/db.conf
The configuration is read from protected/config/core/common.php: if ( file_exists ( '/etc/openeyes/db.conf' )) {
$db = parse_ini_file ( '/etc/openeyes/db.conf' );
} else {
$db = array (
'host' => getenv ( 'DATABASE_HOST' ) ?: 'localhost' ,
'port' => getenv ( 'DATABASE_PORT' ) ?: '3306' ,
'dbname' => getenv ( 'DATABASE_NAME' ) ?: 'openeyes' ,
'username' => getenv ( 'DATABASE_USER' ) ?: 'openeyes' ,
'password' => getenv ( 'DATABASE_PASS' ) ?: 'openeyes' ,
);
}
Run Database Migrations
Initialize the database schema: cd /var/www/openeyes
sudo -u www-data php protected/yiic.php migrate --interactive=0
This creates all necessary tables and applies schema migrations. For module-specific migrations: sudo -u www-data php protected/yiic.php migrate \
--migrationPath=application.modules.OphCiExamination.migrations
Set File Permissions
Configure proper ownership and permissions: cd /var/www/openeyes
# Set ownership
sudo chown -R www-data:www-data /var/www/openeyes
# Runtime directory needs write access
sudo chmod -R 775 protected/runtime
sudo chmod -R 775 assets
# Protect sensitive files
sudo chmod 640 protected/config/local/ * .php
Configure Apache Virtual Host
Create /etc/apache2/sites-available/openeyes.conf: < VirtualHost *:80 >
ServerName openeyes.example.com
ServerAdmin [email protected]
DocumentRoot /var/www/openeyes
< Directory /var/www/openeyes >
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
# Yii framework rewrite rules
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</ Directory >
# Protect sensitive directories
< Directory /var/www/openeyes/protected >
Require all denied
</ Directory >
# Logging
ErrorLog ${APACHE_LOG_DIR}/openeyes_error.log
CustomLog ${APACHE_LOG_DIR}/openeyes_access.log combined
# Security headers
Header always set X-Frame- Options "SAMEORIGIN"
Header always set X-Content-Type- Options "nosniff"
Header always set X-XSS-Protection " 1 ; mode=block"
</ VirtualHost >
Enable the site: sudo a2ensite openeyes
sudo systemctl reload apache2
Configure SSL/TLS
For production, HTTPS is mandatory. Use Let’s Encrypt: # Install Certbot
sudo apt install -y certbot python3-certbot-apache
# Obtain certificate
sudo certbot --apache -d openeyes.example.com
Certbot will automatically:
Obtain SSL certificate
Configure Apache for HTTPS
Set up automatic renewal
For manual SSL configuration, create /etc/apache2/sites-available/openeyes-ssl.conf: < VirtualHost *:443 >
ServerName openeyes.example.com
DocumentRoot /var/www/openeyes
SSLEngine on
SSLCertificateFile /etc/ssl/certs/openeyes.crt
SSLCertificateKeyFile /etc/ssl/private/openeyes.key
SSLCertificateChainFile /etc/ssl/certs/ca-bundle.crt
# Modern SSL configuration
SSLProtocol all -SSLv3 -TLSv1 -TLSv1. 1
SSLCipherSuite HIGH:!aNULL:!MD5
SSLHonorCipherOrder on
# HSTS
Header always set Strict-Transport-Security "max-age= 31536000 "
# Include directory configuration from HTTP vhost
Include /etc/apache2/sites-available/openeyes.conf
</ VirtualHost >
Configure Application Settings
Set production environment variables: # In Apache envvars or systemd unit
export OE_MODE = LIVE
export OE_INSTITUTION_CODE = YOUR_INSTITUTION_CODE
export AUTH_SOURCE = BASIC # or LDAP, SAML, OIDC
Key configuration options from protected/config/core/common.php: Variable Default Description OE_MODE- Operating mode: LIVE, TEST, or DEV OE_INSTITUTION_CODENEWYour institution identifier AUTH_SOURCEBASICAuthentication: BASIC, LDAP, SAML, OIDC SSO_CLIENT_ID- OIDC client ID (if using SSO) SSO_CLIENT_SECRET- OIDC client secret (if using SSO) OE_PASAPI_ENABLEFALSEEnable PAS API integration OE_PORTAL_ENABLEDFALSEEnable patient portal
For production, always set OE_MODE=LIVE to disable debug features and enforce security.
Create Initial Admin User
Access the database and create an administrative user: mysql -u openeyes -p openeyes
-- Insert admin user (adjust as needed)
INSERT INTO user (username, first_name, last_name, email,
active, password_softlocked, password_status)
VALUES ( 'admin' , 'System' , 'Administrator' , '[email protected] ' ,
1 , 0 , 0 );
-- Set password (will need to be changed on first login)
UPDATE user SET password = MD5( 'ChangeMe123!' )
WHERE username = 'admin' ;
-- Grant admin role
INSERT INTO authassignment (itemname, userid)
SELECT 'admin' , id FROM user WHERE username = 'admin' ;
The user will be prompted to change their password on first login.
Verify Installation
Test the installation:
Access the application :
Navigate to https://openeyes.example.com
You should see the OpenEyes login page
Check PHP configuration :
sudo -u www-data php protected/yiic.php version
Verify database connection :
sudo -u www-data php protected/yiic.php migrate --interactive=0
Should report “No new migrations found.”
Review logs :
tail -f /var/log/apache2/openeyes_error.log
Post-Installation Configuration
Authentication Setup
LDAP Authentication
SAML SSO
OpenID Connect
Configure LDAP integration: export AUTH_SOURCE = LDAP
export OE_LDAP_SERVER = ldap :// ldap . example . com
export OE_LDAP_PORT = 389
export OE_LDAP_ADMIN_DN = "cn=admin,dc=example,dc=com"
export OE_LDAP_PASSWORD = "ldap_password"
export OE_LDAP_BASE_DN = "ou=users,dc=example,dc=com"
Configure SAML authentication: export AUTH_SOURCE = SAML
export SSO_BASE_URL = https :// openeyes . example . com
export SSO_ENTITY_ID = https :// openeyes . example . com / saml / metadata
export SSO_APP_EMBED_LINK = https :// sso . example . com / login
Place IdP metadata in protected/config/local/saml/ Configure OIDC authentication: export AUTH_SOURCE = OIDC
export SSO_PROVIDER_URL = https :// sso . example . com
export SSO_CLIENT_ID = openeyes
export SSO_CLIENT_SECRET = your_client_secret
export SSO_REDIRECT_URL = https :// openeyes . example . com / oidc / callback
Cron Jobs
Set up scheduled tasks:
sudo crontab -u www-data -e
Add the following:
# OpenEyes scheduled tasks
*/5 * * * * /usr/bin/php /var/www/openeyes/protected/yiic.php cronrunner
# Database backup (daily at 2 AM)
0 2 * * * /var/www/openeyes/protected/scripts/backupdb.sh
# Log rotation
0 0 * * 0 /usr/sbin/logrotate /etc/logrotate.d/openeyes
Backup Strategy
Implement regular backups:
#!/bin/bash
# OpenEyes Backup Script
BACKUP_DIR = "/backup/openeyes"
DATE = $( date +%Y%m%d_%H%M%S )
# Database backup
mysqldump -u openeyes -p $DB_PASSWORD openeyes | \
gzip > $BACKUP_DIR /db_ $DATE .sql.gz
# File backup
tar -czf $BACKUP_DIR /files_ $DATE .tar.gz \
/var/www/openeyes/protected/runtime \
/var/www/openeyes/protected/files \
/etc/openeyes/
# Retain last 30 days
find $BACKUP_DIR -mtime +30 -delete
Security Hardening
Configure UFW firewall: sudo ufw allow 22/tcp # SSH
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw enable
Edit /etc/php/8.1/apache2/php.ini: expose_php = Off
display_errors = Off
log_errors = On
error_log = /var/log/php/error.log
upload_max_filesize = 128M
post_max_size = 128M
memory_limit = 256M
disable_functions = exec,passthru,shell_exec,system,proc_open
Use strong passwords
Restrict database user to localhost only
Enable binary logging for point-in-time recovery
Regular security updates
# Remove anonymous users
mysql -e "DELETE FROM mysql.user WHERE User=''"
# Remove test database
mysql -e "DROP DATABASE IF EXISTS test"
# Flush privileges
mysql -e "FLUSH PRIVILEGES"
File Integrity Monitoring
Install and configure AIDE: sudo apt install aide
sudo aideinit
sudo mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db
# Run daily checks
echo '0 3 * * * root /usr/bin/aide --check' | sudo tee -a /etc/crontab
PHP OpCache
Enable and configure OpCache in /etc/php/8.1/apache2/php.ini:
opcache.enable =1
opcache.memory_consumption =256
opcache.interned_strings_buffer =16
opcache.max_accelerated_files =10000
opcache.revalidate_freq =60
opcache.fast_shutdown =1
MySQL Tuning
Optimize MySQL configuration:
[mysqld]
innodb_buffer_pool_size = 2G
innodb_log_file_size = 256M
innodb_flush_log_at_trx_commit = 2
query_cache_size = 64M
tmp_table_size = 64M
max_heap_table_size = 64M
Apache MPM
Configure Apache MPM prefork:
< IfModule mpm_prefork_module >
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxRequestWorkers 150
MaxConnectionsPerChild 0
</ IfModule >
Monitoring and Maintenance
Application Monitoring
# Monitor Apache processes
sudo systemctl status apache2
# Check PHP-FPM status
sudo systemctl status php8.1-fpm
# Monitor MySQL
sudo systemctl status mysql
# View application logs
tail -f /var/www/openeyes/protected/runtime/application.log
Health Checks
Create a monitoring script:
#!/bin/bash
# Check if OpenEyes is responding
URL = "https://openeyes.example.com"
HTTP_CODE = $( curl -s -o /dev/null -w "%{http_code}" $URL )
if [ $HTTP_CODE -eq 200 ]; then
echo "OpenEyes is healthy"
else
echo "OpenEyes returned HTTP $HTTP_CODE "
# Send alert
fi
Troubleshooting
Check PHP error logs: tail -f /var/log/apache2/openeyes_error.log
tail -f /var/www/openeyes/protected/runtime/application.log
Common causes:
Database connection failure
File permission issues
Missing PHP extensions
Database Migration Errors
Reset migration state: mysql -u openeyes -p openeyes -e "SELECT * FROM migration_history ORDER BY apply_time DESC LIMIT 10;"
Manually apply failed migration: sudo -u www-data php protected/yiic.php migrate redo
Clear session data: sudo rm -rf /var/www/openeyes/protected/runtime/sessions/ *
sudo systemctl restart apache2
Upgrading OpenEyes
Always backup before upgrading!
Backup Current Installation
# Database
mysqldump -u openeyes -p openeyes > backup_ $( date +%F ) .sql
# Files
tar -czf openeyes_backup_ $( date +%F ) .tar.gz /var/www/openeyes
Pull Latest Code
cd /var/www/openeyes
sudo -u www-data git fetch --tags
sudo -u www-data git checkout tags/v3.1 # Or desired version
Update Dependencies
sudo -u www-data composer install --no-dev --optimize-autoloader
Run Migrations
sudo -u www-data php protected/yiic.php migrate --interactive=0
Clear Cache
sudo rm -rf /var/www/openeyes/protected/runtime/cache/ *
sudo rm -rf /var/www/openeyes/assets/ *
sudo systemctl restart apache2
Getting Support
GitHub Issues Community issue tracker
Wiki Documentation Additional installation guides
Professional Services Accredited partners for production support
Production Deployment Checklist