Backing Up Using the Built In Tools
Backup your Installation
Docker Backup Script (8.3.0 and later)
For Docker Compose deployments, OpenEMR ships a backup script at contrib/util/openemr-docker-backup.sh. It replaces the web interface backup removed in 8.3.0.
Run it on the Docker host, not inside the OpenEMR container. A copy ships inside the container's webroot for reference only.
Install
curl -o /opt/openemr/openemr-docker-backup.sh \ https://raw.githubusercontent.com/openemr/openemr/master/contrib/util/openemr-docker-backup.sh chmod 700 /opt/openemr/openemr-docker-backup.sh
Review the configuration block at the top of the script (COMPOSE_DIR, BACKUP_ROOT, service names, credentials, RETENTION_DAYS) and adjust it for your deployment. Then run it once by hand:
/opt/openemr/openemr-docker-backup.sh /path/to/compose/directory
Schedule
On Linux hosts, add a cron entry (this one runs daily at 2:15 AM):
15 2 * * * /opt/openemr/openemr-docker-backup.sh >> /var/log/openemr-backup.log 2>&1
For Windows / Docker Desktop (WSL2) hosts, the script's header explains how to schedule it with Windows Task Scheduler.
What it backs up
Each run creates a timestamped directory under BACKUP_ROOT (default /var/backups/openemr) containing:
openemr-db.sql.gz: a full database dump, including routines, triggers, and eventsopenemr-files.tar.gz: the OpenEMR webroot, includingsites/(documents, config, SSL material) and custom modules- The Compose configuration, including
.envand the fully resolved config manifest.txt, which records the image versions in use, andSHA256SUMS
It does not capture CouchDB document storage (if you've enabled it) or the container images themselves.
The script verifies archive integrity, prunes old backups, and writes a LAST_BACKUP_OK or LAST_BACKUP_FAILED marker you can monitor.
Restoring
Step-by-step restore instructions are at the bottom of the script. Test your restores. A full restore drill to a scratch VM at least quarterly also helps satisfy the HIPAA Security Rule's contingency plan testing requirement (45 CFR 164.308(a)(7)).
Offsite copies
The script only writes locally. Pair it with a tool such as rclone, restic, or borg to push backups to encrypted offsite storage. Local-only backups won't survive ransomware or hardware loss.
Manual Backup (Non-Docker Installs)
If you run OpenEMR directly on a server (package or source install, not Docker), you can back up the same two pieces by hand: the database and the sites/ directory.
Find your database settings
Your database name, user, and password are in sites/default/sqlconf.php (look for $dbase, $login, and $pass). The examples below assume a database named openemr and an OpenEMR directory of /var/www/openemr. Adjust both for your install.
Store credentials safely
To keep the password off the command line (and out of your shell history and process list), put it in a credentials file readable only by root:
cat > /root/.openemr-backup.cnf <<'EOF' [client] user=openemr password=YOUR_DB_PASSWORD host=localhost EOF chmod 600 /root/.openemr-backup.cnf
Run the backup
OPENEMR_DIR=/var/www/openemr BACKUP_DIR=/var/backups/openemr/$(date +%Y-%m-%d) umask 077 mkdir -p "$BACKUP_DIR" # 1. Database dump (consistent snapshot, without locking users out) mysqldump --defaults-extra-file=/root/.openemr-backup.cnf \ --single-transaction --quick --routines --triggers --events \ openemr | gzip > "$BACKUP_DIR/openemr-db.sql.gz" # 2. sites/ directory (documents, config, letter templates, SSL material) tar -czf "$BACKUP_DIR/openemr-sites.tar.gz" -C "$OPENEMR_DIR" sites # 3. Check that both archives are intact gzip -t "$BACKUP_DIR/openemr-db.sql.gz" && gzip -t "$BACKUP_DIR/openemr-sites.tar.gz"
If you've installed custom modules (interface/modules/custom_modules) or made local code changes, archive the whole OpenEMR directory instead of just sites/:
tar -czf "$BACKUP_DIR/openemr-files.tar.gz" -C "$(dirname "$OPENEMR_DIR")" "$(basename "$OPENEMR_DIR")"
If mysqldump reports a permissions error on routines, triggers, or events, run it with a database user that has those privileges (such as root).
Restore
With OpenEMR installed at the same version as the backup:
gunzip -c openemr-db.sql.gz | mysql --defaults-extra-file=/root/.openemr-backup.cnf openemr tar -xzf openemr-sites.tar.gz -C /var/www/openemr chown -R www-data:www-data /var/www/openemr/sites # use apache:apache on RHEL-family systems
If you archived the whole OpenEMR directory, extract openemr-files.tar.gz into its parent instead (-C /var/www) and fix ownership on the whole directory.
Then log in, open a recent patient and document, and check Administration → Other → Logs for errors.
To automate the backup, save the backup commands as a script and schedule it with cron, as shown in the Docker section above. The same offsite-copy and restore-testing advice applies here.
Via the Web Interface (Legacy, before 8.3.0)
Removed in OpenEMR 8.3.0. This tool is not available in 8.3.0 and later. Use the Docker backup script or, for non-Docker installs, the manual backup steps instead. See the forum announcement for background.
On versions before 8.3.0:
- Go to Admin → System → Backup.
- Click Create Backup.
- Save the resulting
emr_backup.tarfile.
Rename the file with the backup date (for example, emr_backup_2026-10-06.tar) so you can tell your backups apart. The tarball contains openemr.sql.gz (the database) and openemr.tar.gz (the OpenEMR files, including uploaded documents).
Protecting Your Backups
Backups contain Protected Health Information (PHI): your entire database and every document uploaded to OpenEMR. Store, transmit, and dispose of them with the same safeguards you apply to any PHI under HIPAA and other applicable regulations. Encrypt them at rest, restrict access, and never send them over unencrypted channels.
Via the CLI
This method is designed to give you the same result as the GUI backup method.
For the following commands, you will need to ssh into the server.
- ssh into the server
- You should also run pwd so that you know what the present working directory is (ie, where you are). If you ssh-ed in as root, then you should be in /root, if you ssh-ed as a user, then you should be in /home/yourusername. You need to know this location for future steps.
pwd
Get a backup of the database
The following command will dump the database structure and contents into a gzipped file in the present working directory.
- Run mysqldump and pipe the output to a gzip file
mysqldump --opt --quote-names --ignore-table="$CUSTOM_DATABASE".onsite_activity_view --hex-blob -u openemr -p openemr | gzip > openemr.sql.gz
- The -p is a short form of --password and indicates that mysqldump should prompt you for the password after executing the command. Enter the password when prompted to do so. It will be the password you used when you installed the MySQL database for OpenEMR.
- The other options for mysqldump inicated above are
- --opt: optimizes the dump
- --quote-names puts backticks around the object names
- -u is a short form of --user and indicates the mysql user account to use when running the commmand (the username follows the option)
- the 'openemr' before the pipe indicates the name of the database to dump
Stay sshed in the server in order to do the next section.
Get a backup of the openemr folder
The following command will archive and compress the contents of /var/www/openemr and store it in the present working directory alongside the MySQL dump. note that this location may be different for different installation methods.
- Use tar to create and compress an archive of the openemr folder and store it in the same place you stored your mysql dump file
tar -C /var/www/openemr/ -zcf openemr.tar.gz ./
- The options on the tar command above are as follows
- -C: Change to the stated directory and run tar from there. It accomplishes the same as using cd to move to the stated location and then using cd to come back to the original directory when done.
- -z: Compress archive using gzip program
- -c: Create archive
- -f: Archive File name (ie, the name of the output tarball)
- -v: Verbose (ie, display progress while creating archive) If you want to see the terminal spit out a list of all the files being archived, you can include this option.
Stay sshed in the server in order to do the next section.
Tar the data and filesystem backups together
- Use tar to take the files created in the above sections and bind them into one file
- You can simply name the tar file 'emr_backup.tar' like the GUI process does and then rename the tar later. But why go through another step if you don't have to? You can name the tar file using the conventions mentioned above (ie, emr_backup_[date].tar) when you're making the tar.
tar -cvf emr_backup.tar openemr.sql.gz openemr.tar.gz
- The options on the tar command above are as follows
- c: Create archive
- v: Verbose (i.e display progress while creating archive) If you don't want to see the terminal spit out a list of all the files being archived, you can leave this option out.
- f: Archive File name
Recovery
1. Restore script can be found in openemr/contrib/util as an executable file.
2. Copy emr_backup.tar and restore script to the home directory.
3. Have the OpenEMR database password (see Step 8 for its location) recorded elsewhere, then delete the openemr web directory.
- If not, the password will be lost with the deletion of the web directory.
4. Open Terminal.
5. Issue this command after the dollar sign: sudo ./restore ($ sudo ./restore), 1 space after $ with no space before restore.
- This command must be used because it is not possible to run the script by double clicking on the icon.
6. Path to the backup file: /home/<your home directory username>/emr_backup.tar

7. Answer Y when asked about supplying the site ID.
- If the practice has only 1 site, use the default values between the square brackets and hit Enter each time.

8. The OpenEMR database password can be found in openemr/sites/default/sqlconf.php, if the practice has only 1 site.

- Enter the password when prompted.

- Understand that there are two passwords for MySQL; one for user, openemr and one for user, root; which is required in the next step. Be certain that the distinction is clear in your mind before you attempt recovery.
- With repeat restores to the same database, this step may be skipped; because the password had been stored from a prior recovery.
- If the practice has multiple sites, supply the relevant data.
- N.B.: If the user is restoring to a new device, he must use the password from the new device, not the old machine. If he uses the credential from the old machine, he will have difficulties logging into the new device.
9. Supply the MySQL root password. If it has been lost, here is a reset tutorial.
- When restoring to a new device, remember to use the root password for the receiving device, not the machine which created the emr_backup.tar.
