How to Install OpenEMR on Rocky Linux 9
On this page
- Prerequisites
- Step 1 - Configure Firewall
- Step 2 - Install Nginx
- Step 3 - Install MySQL
- Step 4 - Configure MySQL
- Step 5 - Install PHP and its extensions
- Step 6 - Install SSL
- Step 7 - Download OpenEMR
- Step 8 - Configure SELinux
- Step 8 - Configure PHP-FPM
- Step 9 - Configure Nginx
- Step 10 - Install OpenEMR
- Conclusion
OpenEMR is an open-source electronic health record and medical practice management tool. It is Office of the National Coordinator for Health Information Technology (ONC) certified and features integrated health records, practice management, scheduling, electronic billing, internationalization, free support, and more. It can track patient demographics, schedule patients, maintain extremely detailed health records with lab reports, medications, and procedures, track their prescriptions, help with medical billing, generate detailed reports, and multi-language support.
In this tutorial, you will learn how to install OpenEMR software on a server running Rocky Linux 9.
Prerequisites
-
A server running Rocky Linux 9.
-
A non-root sudo user.
-
A fully qualified domain name (FQDN) like
openemr.example.com
. -
Make sure everything is updated.
$ sudo dnf update
-
Few packages that your system needs.
$ sudo dnf install wget curl nano unzip yum-utils policycoreutils-python-utils -y
Some of these packages may already be installed on your system.
Step 1 - Configure Firewall
The first step is to configure the firewall. Rocky Linux uses Firewalld Firewall. Check the firewall's status.
$ sudo firewall-cmd --state running
The firewall works with different zones, and the public zone is the default one that we will use. List all the services and ports active on the firewall.
$ sudo firewall-cmd --permanent --list-services
It should show the following output.
cockpit dhcpv6-client ssh
OpenEMR needs HTTP and HTTPS ports to function. Open them.
$ sudo firewall-cmd --permanent --add-service=http $ sudo firewall-cmd --permanent --add-service=https
Reload the firewall to apply the changes.
$ sudo firewall-cmd --reload
List all the services again.
$ sudo firewall-cmd --permanent --list-services
You should get the following output.
cockpit dhcpv6-client http https ssh
Step 2 - Install Nginx
Rocky Linux 9 ships with an older version of Nginx. You need to download the official Nginx repository to install the latest version.
Create and open the /etc/yum.repos.d/nginx.repo
file for creating the official Nginx repository.
$ sudo nano /etc/yum.repos.d/nginx.repo
Paste the following code in it.
[nginx-stable] name=nginx stable repo baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=1 enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true [nginx-mainline] name=nginx mainline repo baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/ gpgcheck=1 enabled=0 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true
Save the file by pressing Ctrl + X and entering Y when prompted.
Install the Nginx server.
$ sudo dnf install -y nginx
Verify the installation.
$ nginx -v nginx version: nginx/1.24.0
Enable and start the Nginx server.
$ sudo systemctl enable nginx --now
Check the status of the server.
$ sudo systemctl status nginx ? nginx.service - nginx - high performance web server Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: disabled) Active: active (running) since Thu 2023-06-15 10:20:00 UTC; 1s ago Docs: http://nginx.org/en/docs/ Process: 1411 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=0/SUCCESS) Main PID: 1412 (nginx) Tasks: 2 (limit: 5922) Memory: 1.9M CPU: 7ms CGroup: /system.slice/nginx.service ??1412 "nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf" ??1413 "nginx: worker process"
Step 3 - Install MySQL
Rocky Linux 9 ships with the latest version of MySQL. You can install it with a single command.
$ sudo dnf install mysql-server
Check the version of MySQL.
$ mysql --version mysql Ver 8.0.32 for Linux on x86_64 (Source distribution)
Enable and start the MySQL service.
$ sudo systemctl enable mysqld --now
Run the MySQL secure install script.
$ sudo mysql_secure_installation
You will be asked to install the Validate Password Component. It checks the strength of passwords used in MySQL. Press Y to install it. Next, you will be asked to set the level of the password validation policy. Choose 2 as it is the strongest one.
Securing the MySQL server deployment. Connecting to MySQL using a blank password. VALIDATE PASSWORD COMPONENT can be used to test passwords and improve security. It checks the strength of password and allows the users to set only those passwords which are secure enough. Would you like to setup VALIDATE PASSWORD component? Press y|Y for Yes, any other key for No: Y There are three levels of password validation policy: LOW Length >= 8 MEDIUM Length >= 8, numeric, mixed case, and special characters STRONG Length >= 8, numeric, mixed case, special characters and dictionary file Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG: 2
Next, you will be asked to set a new root password. Enter the password according to the requirements specified above. Enter Y
when prompted to continue with the chosen root password.
Please set the password for root here. New password: Re-enter new password: Estimated strength of the password: 100 Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : Y
Next, enter Y to remove anonymous users, disallow remote root logins, remove the test database, and reload the privilege tables.
By default, a MySQL installation has an anonymous user, allowing anyone to log into MySQL without having to have a user account created for them. This is intended only for testing, and to make the installation go a bit smoother. You should remove them before moving into a production environment. Remove anonymous users? (Press y|Y for Yes, any other key for No) : Y Success. Normally, root should only be allowed to connect from 'localhost'. This ensures that someone cannot guess at the root password from the network. Disallow root login remotely? (Press y|Y for Yes, any other key for No) : Y Success. By default, MySQL comes with a database named 'test' that anyone can access. This is also intended only for testing, and should be removed before moving into a production environment. Remove test database and access to it? (Press y|Y for Yes, any other key for No) : Y - Dropping test database... Success. - Removing privileges on test database... Success. Reloading the privilege tables will ensure that all changes made so far will take effect immediately. Reload privilege tables now? (Press y|Y for Yes, any other key for No) : Y Success. All done!
Step 4 - Configure MySQL
Log in to the MySQL shell. Enter your root password when prompted.
$ sudo mysql -u root -p
Create a sample database.
mysql> CREATE DATABASE openemr;
Create an SQL user account.
mysql> CREATE USER 'openemruser'@'localhost' IDENTIFIED BY 'Your_password2';
Grant all privileges on the database to the user.
mysql> GRANT ALL PRIVILEGES ON openemr.* TO 'openemruser'@'localhost';
Flush user privileges.
mysql> FLUSH PRIVILEGES;
Exit the shell.
mysql> exit
Step 5 - Install PHP and its extensions
We need to install PHP 8.2 for OpenEMR to work. The first step is to grab the Epel repository.
$ sudo dnf install epel-release -y
Next, install the Remi repository.
$ sudo dnf install https://rpms.remirepo.net/enterprise/remi-release-9.rpm
Check for available PHP streams.
$ dnf module list php -y Name Stream Profiles Summary php 8.1 common [d], devel, minimal PHP scripting language Remi's Modular repository for Enterprise Linux 9 - x86_64 Name Stream Profiles Summary php remi-7.4 common [d], devel, minimal PHP scripting language php remi-8.0 common [d], devel, minimal PHP scripting language php remi-8.1 common [d], devel, minimal PHP scripting language php remi-8.2 common [d], devel, minimal PHP scripting language Hint: [d]efault, [e]nabled, [x]disabled, [i]nstalled
The default version is 8.1. Enable Remi's PHP 8.2 repository.
$ sudo dnf module reset php -y $ sudo dnf module enable php:remi-8.2
Install PHP and the required extensions required by OpenEMR.
$ sudo dnf install php-fpm php-mysql php-bcmath php-xml php-zip php-curl php-mbstring php-gd php-tidy php-intl php-cli php-soap ImageMagick php-ldap
Install the TIFF Tools library. This library is not available from the base repository but is found in the CRB (formerly Powertools) repo.
$ sudo dnf install libtiff-tools --enablerepo=crb
Verify the installation.
$ php --version PHP 8.2.7 (cli) (built: Jun 6 2023 21:28:56) (NTS gcc x86_64) Copyright (c) The PHP Group Zend Engine v4.2.7, Copyright (c) Zend Technologies
Enable and start the PHP-FPM service.
$ sudo systemctl enable php-fpm --now
Step 6 - Install SSL
We need to install Certbot to generate the SSL certificate. We will use the Snapd package installer for that. Since Rocky Linux doesn't ship with it, install the Snapd installer. It requires the EPEL repository to work which we installed before for PHP so we can skip the step.
Install Snapd.
$ sudo dnf install -y snapd
Enable and Start the Snap service.
$ sudo systemctl enable snapd --now
Install the Snap core package, and ensure that your version of Snapd is up to date.
$ sudo snap install core && sudo snap refresh core
Create necessary links for Snapd to work.
$ sudo ln -s /var/lib/snapd/snap /snap $ echo 'export PATH=$PATH:/var/lib/snapd/snap/bin' | sudo tee -a /etc/profile.d/snapd.sh
Issue the following command to install Certbot.
$ sudo snap install --classic certbot
Use the following command to ensure that the Certbot command can be run by creating a symbolic link to the /usr/bin
directory.
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot
Verify the installation.
$ certbot --version certbot 2.6.0
Run the following command to generate an SSL Certificate.
$ sudo certbot certonly --nginx --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m [email protected] -d openemr.example.com
The above command will download a certificate to the /etc/letsencrypt/live/openemr.example.com
directory on your server.
Generate a Diffie-Hellman group certificate.
$ sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096
Check the Certbot renewal scheduler service.
$ sudo systemctl list-timers
You will find snap.certbot.renew.service
as one of the services scheduled to run.
NEXT LEFT LAST PASSED UNIT ACTIVATES ----------------------------------------------------------------------------------------------------------------------------------------- Thu 2023-06-15 12:29:25 UTC 54min left Thu 2023-06-15 11:18:44 UTC 16min ago dnf-makecache.timer dnf-makecache.service Thu 2023-06-15 12:51:00 UTC 1h 15min left - - snap.certbot.renew.timer snap.certbot.renew.service
Do a dry run of the process to check whether the SSL renewal is working fine.
$ sudo certbot renew --dry-run
If you see no errors, you are all set. Your certificate will renew automatically.
Step 7 - Download OpenEMR
Visit the OpenEMR download page and grab the link for the latest version of OpenEMR. Download OpenEMR to the server.
$ wget https://sourceforge.net/projects/openemr/files/OpenEMR%20Current/7.0.1/openemr-7.0.1.tar.gz
Extract the files.
$ tar -pxzf openemr-7.0.1.tar.gz
Move the extracted files to the web root directory.
$ sudo mv openemr-7.0.1 /var/www/html/openemr
Give permissions to the Nginx user over the web root directory.
$ sudo chown -R nginx:nginx /var/www/html/openemr
Step 8 - Configure SELinux
Change the file security context for OpenEMR.
$ sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/html/openemr(/.*)?"
Apply the policy.
$ sudo restorecon -Rv /var/www/html/openemr/
Apply the policy to allow Nginx to give access to MySQL.
$ sudo setsebool -P httpd_can_network_connect_db 1
Apply the policy to allow connections to be made to outside hosts. This is needed for sending emails.
$ sudo setsebool -P httpd_can_network_connect 1
Step 8 - Configure PHP-FPM
Open the file /etc/php-fpm.d/www.conf
.
$ sudo nano /etc/php-fpm.d/www.conf
We need to set the Unix user/group of PHP processes to nginx. Find the user=www-data
and group=www-data
lines in the file and change them to nginx
.
... ; Unix user/group of processes ; Note: The user is mandatory. If the group is not set, the default user's group ; will be used. ; RPM: apache user chosen to provide access to the same directories as httpd user = nginx ; RPM: Keep a group allowed to write in log dir. group = nginx ...
Find the ;listen.owner = nobody
, ;listen.group = nobody
, and ;listen.mode=0660
lines in the file and change them as shown below.
; Set permissions for unix socket, if one is used. In Linux, read/write ; permissions must be set in order to allow connections from a web server. Many ; BSD-derived systems allow connections regardless of permissions. The owner ; and group can be specified either by name or by their numeric IDs. ; Default Values: user and group are set as the running user ; mode is set to 0660 listen.owner = nginx listen.group = nginx listen.mode = 0660
Next, comment out the following line as shown by putting a semi-colon in front of it.
;listen.acl_users = apache,nginx
Save the file by pressing Ctrl + X and entering Y when prompted.
Increase the execution time for PHP-FPM and PHP-CLI to 60 seconds.
$ sudo sed -i 's/max_execution_time = 30/max_execution_time = 60/' /etc/php.ini
Set the value of the variable max_input_time
to 1
.
$ sudo sed -i 's/max_input_time = 60/max_input_time = -1/' /etc/php.ini
Increase the memory limit for PHP-FPM from 128MB to 512MB.
$ sudo sed -i 's/memory_limit = 128M/memory_limit = 512M/' /etc/php.ini
Increase the file upload size to 30MB.
$ sudo sed -i 's/post_max_size = 8M/post_max_size = 30M/' /etc/php.ini $ sudo sed -i 's/upload_max_filesize = 2M/upload_max_filesize = 30M/' /etc/php.ini
Increase the number of maximum input variables to 3000.
$ sudo sed -i 's/;max_input_vars = 1000/max_input_vars = 3000/g' /etc/php.ini
Allow accessing, from PHP's perspective, local files with LOAD DATA statements.
$ sudo sed -i 's/;mysqli.allow_local_infile = On/mysqli.allow_local_infile = On/g' /etc/php.ini
Restart the PHP-FPM service.
$ sudo systemctl restart php-fpm
Change the group of the PHP sessions directory to Nginx.
$ sudo chgrp -R nginx /var/lib/php/session
Step 9 - Configure Nginx
Create and open the file /etc/nginx/conf.d/openemr.conf
for editing.
$ sudo nano /etc/nginx/conf.d/openemr.conf
Paste the following code in it.
server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name openemr.example.com; access_log /var/log/nginx/openemr.access.log; error_log /var/log/nginx/openemr.error.log; # SSL ssl_certificate /etc/letsencrypt/live/openemr.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/openemr.example.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/openemr.example.com/chain.pem; ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; ssl_session_tickets off; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; ssl_ecdh_curve X25519:prime256v1:secp384r1:secp521r1; ssl_stapling on; ssl_stapling_verify on; ssl_dhparam /etc/ssl/certs/dhparam.pem; # use https://blog.cloudflare.com/announcing-1111 Cloudfare+Apnic labs, It is free and secure resolver 1.1.1.1 1.0.0.1 [2606:4700:4700::1111] [2606:4700:4700::1001] valid=300s; root /var/www/html/openemr; index index.php; location / { try_files $uri $uri/ /index.php; } # Pass PHP Scripts To FastCGI Server location ~* \.php$ { try_files $uri =404; fastcgi_index index.php; fastcgi_pass unix:/run/php-fpm/www.sock; # Depends On The PHP Version fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; fastcgi_param DOCUMENT_ROOT $realpath_root; include fastcgi_params; } # deny access to writable files/directories location ~* ^/sites/*/(documents|edi|era) { deny all; return 404; } # deny access to certain directories location ~* ^/(contrib|tests) { deny all; return 404; } # Alternatively all access to these files can be denied location ~* ^/(admin|setup|acl_setup|acl_upgrade|sl_convert|sql_upgrade|gacl/setup|ippf_upgrade|sql_patch)\.php { deny all; return 404; } location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { log_not_found off; access_log off; } location ~ /\. { deny all; } } # enforce HTTPS server { listen 80; listen [::]:80; server_name openemr.example.com; return 301 https://$host$request_uri; }
Notice the root directory to be used in the Nginx configuration is /var/www/html/openemr
.
Save the file by pressing Ctrl + X and entering Y when prompted once finished.
Open the file /etc/nginx/nginx.conf
for editing.
$ sudo nano /etc/nginx/nginx.conf
Add the following line before the line include /etc/nginx/conf.d/*.conf;
.
server_names_hash_bucket_size 64;
Save the file by pressing Ctrl + X and entering Y when prompted.
Verify the Nginx configuration file syntax.
$ sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
Restart the Nginx service.
$ sudo systemctl restart nginx
Step 10 - Install OpenEMR
Open the URL https://openemr.example.com
in your browser and you will see the following setup screen.
Here it checks for file permissions and confirms whether you can proceed to step 1 or not. If you see the word ready
in green, it means you can proceed. Click the blue button to proceed to step 1.
On the next page, you will be asked if you want the installer to create the database or use a pre-made one. Select the option I have already created the database and click the button to proceed to step 2.
On the next page, fill in the database credentials you configured in step 4 before. Also, enter your administrator account credentials. Make sure your username is 12 or more characters long otherwise, you will get an error. You can enable two-factor authentication (2FA) here but it is recommended to configure it later after installation. Click the button to create the database and the user account.
The next page will show the installation status and will show you the username and password. Click the button to proceed to step 4.
The next page will list the recommended and current values from your php.ini
file. Make sure the current values satisfy the requirement. The installer shows the wrong values for the variable max_execution_time
variable for some reason even if you have set it correctly. You can ignore that. You can verify the current values by using the following commands.
Once you are satisfied, click the button to proceed to step 5.
The next step lists Apache server settings which we will ignore since we are using the Nginx server. Click the button to proceed to the next page.
Here you will be asked to select a theme for the administration panel. Select the Keep Current option and click the button to proceed. You can change the theme from the administration panel later on however you won't be able to see how they look. If you choose from the installer page, you can also check how they look before selecting. We will stick with the default theme.
The last page lists some final notes about the software and account credentials. Click the Start button to open the login page.
You will get an OpenEMR registration popup to get announcements from their site. You can ignore and enter your credentials and click the Login button to access the dashboard.
If you didn't configure two-factor authentication during installation, do so by clicking the avatar icon at the top right and selecting the MFA Management option.
On the next page, select the Authentication method from the dropdown menu and start configuring.
You can start using OpenEMR to manage your health business from here on.
Conclusion
This concludes our tutorial on installing OpenEMR on a Rocky Linux 9 server. If you have any questions, post them in the comments below.