Write shit down, so you don't forget it.
Back to blog

Open EMR Backup and Restore Docker Procedure

One of the most important things in development is disaster recovery, using Open EMR and being HIPAA compliant you must have a solid understanding on how to backup/restore your Open EMR instance because like Murphy says: “Anything that can go wrong will go wrong”. With that in mind I am going to show you today how-to backup/restore your Open EMR instance, if you use an Open EMR instance from the AWS Marketplace then this is for you.

Prerequisites:

Backing up the required files

This is probably the easiest part of this tutorial, making a backup of your Open EMR instance is as easy as logging into Open EMR and clicking the Create Backup button in the Administration > System > Backup page. This will provide you with a tar file (basically a zip file) with your websites files and database.

Running a local Open EMR instance

In order to get a local instance of Open EMR running on our computer so we can test restoring our system we will use the docker-compose.yml file from the production folder from the Open EMR repo, copy and paste the following and save it as docker-compose.yml

# Use admin/pass as user/password credentials to login to openemr (from OE_USER and OE_PASS below)
# MYSQL_HOST and MYSQL_ROOT_PASS are required for openemr
# MYSQL_USER, MYSQL_PASS, OE_USER, MYSQL_PASS are optional for openemr and
#   if not provided, then default to openemr, openemr, admin, and pass respectively.
version: '3.1'
services:
  mysql:
    restart: always
    image: mariadb:10.5
    command: ['mysqld','--character-set-server=utf8mb4']
    volumes:
    - databasevolume:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
  openemr:
    restart: always
    image: openemr/openemr:6.0.0
    ports:
    - 80:80
    - 443:443
    volumes:
    - logvolume01:/var/log
    - sitevolume:/var/www/localhost/htdocs/openemr/sites
    environment:
      MYSQL_HOST: mysql
      MYSQL_ROOT_PASS: root
      MYSQL_USER: openemr
      MYSQL_PASS: openemr
      OE_USER: admin
      OE_PASS: pass
    depends_on:
    - mysql
volumes:
  logvolume01: {}
  sitevolume: {}
  databasevolume: {}

Open a terminal window and navigate to the directory where you saved the docker-compose.yml file and run docker-compose up to start our local Open EMR instance. The first time you run this it will take a few minutes to get everything setup a good indicator you can test to see if your instance is running is when you see this in your terminal.

openemr_1  | OpenEMR configured.
openemr_1  | Setup Complete!
openemr_1  | Setting user 'www' as owner of openemr/ and setting file/dir permissions to 400/500
openemr_1  | Default file permissions and ownership set, allowing writing to specific directories
openemr_1  | Removing remaining setup scripts
openemr_1  | Setup scripts removed, we should be ready to go now!
openemr_1  |
openemr_1  | Love OpenEMR? You can now support the project via the open collective:
openemr_1  |  > https://opencollective.com/openemr/donate
openemr_1  |
openemr_1  | Starting cron daemon!
openemr_1  | Starting apache!
openemr_1  | AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.24.0.3. Set the 'ServerName' directive globally to suppress this message

If you navigate in your browser to https://localhost/interface/login/login.php?site=default you should be greeted with yoru usual Open EMR login page. Now that we know our local instance is working let us start with the fun stuff.

Docker & Open EMR

Open EMR runs inside of Docker containers so our files need to be copied into the docker containers for us to be able to restore our system. Extract the tar file we got from the first step it will contain 2 zip files one for your database named openemr.sql.gz and all your website content files in the zip file named openemr.tar.gz. Copy both files to somewhere easily accessible via terminal/command prompt like /home directory or your c: drive in windows.

Now let us fire up a terminal session and get our Docker containers info so we can start copying our files. In terminal type: docker ps -a this will list your running docker containers along with their info.

Copying file to docker database container

Now that we know our Docker containers ids and names, we can proceed to copy our files into our respective containers. To copy your openemr.sql.gz to your mariadb container we will use docker cp which is a docker command to copy files to/from your local file system and a docker container. Based on the results of my docker ps -a command we can see that my mariadb container has an id of 0f407e8d05de which is what we need in order to use docker cp.

In terminal type:

docker cp C:\openemr.sql.gz 0f407e8d05de:/home

Let’s break down whats happenning here so you can get a better understanding of what this is doing. docker cp basically lets docker know we are copying the following file which is in our local system in the absolute path C:\openemr.sql.gz and we are copying it to our container 0f407e8d05de and we want our file to be stored inside the :/home directory of our container.

Verifying the file was copied to the database container

To confirm our file was copied we need to connect to our docker container and verify if the file is in the /home directory. To do this we will use the following command: docker exec -it 0f407e8d05de /bin/sh. Yeah, I know more docker black magic, let’s break down this other command.

Here we tell docker we want to execute docker exec an interactive -it session in our container id 0f407e8d05de and the command we want to run is /bin/sh which then takes us inside our docker container in a shell prompt. Now that we are inside our docker container let’s check if the file we copied is in the right place, type: cd /home and press enter to navigate to our /home directory now lets list the files in our home directory by typing ls and pressing enter. You should see openemr.sql.gz listed in the directory.

Restoring database from backup

Now let’s restore our database using the following command: gunzip < openemr.sql.gz | mysql -u openemr -p openemr you will be prompted for your password, enter it and press enter on your keyboard and wait until your terminal is active again.

If you want to verify if the import was successful you can do so by connecting to mysql and running a query on the patient_data table and see how many rows it has. To do this type mysql -u openemr -p openemr and press enter on your keyboard, you will be prompted for your password enter it to login to mysql.

In the mysql prompt type SELECT COUNT(*) FROM patient_data; if your count result is more than 0 congratulations your database has been restored successfully đŸ™Œ

Press ctrl + d to exit mysql then type exit and press enter to disconnect from our docker container.

Copying web files to docker container

The process is the same to copy our files to our Open EMR docker container so you should now be familiar with the commands we need to use. Let’s copy our web files with the following command: docker cp c:\openemr.tar.gz 583d699e9de6:/home

Verifying file was copied to the Open EMR container

Again, we repeat the same process to verify, run the command: docker exec -it 583d699e9de6 /bin/sh to connect to our docker Open EMR container. Once in the container shell type cd /home press enter, then ls and press enter again to list the contents of the /home folder.

Renaming Open EMR folder

This is something I do to ensure I have an easy way to revert back quickly when copying the web files, you don’t need to do it if you know what you are doing but I rather be safe than sorry. Anyways, lets navigate to where our Open EMR files are stored type cd /var/www/localhost/htdocs and press enter. To make sure you are in the right directory let’s list the contents of the htdocs folder ls (press enter) you should see and index.html file and a openemr folder.

Now let’s rename the Open EMR folder by typing the following command: mv openemr openemr-backup you might get an error stating mv: can't remove 'openemr/sites': Resource busy you can ignore this it’s because we did not stop apache while copying the files and the folder is being used. (I will verify with Open EMR devs if theres a better way to do this and update as I get info)

Alright now let’s list the contents of our directory again ls (press enter) and you shoudl see we now have a openemr-backup directory which contains all our original Open EMR files.

Copying web files

If you remember a few steps back, we copied the openemr.tar.gz file to our /home directory so lets go there by the following command: cd /home (press enter) and we are going to use the mv command again to move our file to the proper directory. Type the following command: mv ./openemr.tar.gz /var/www/localhost/htdocs/openemr to check if the file was moved list the contents of the /home folder you will see the file is no longer in the directory.

Extracting web files

Now that our file is in the openemr directory we must extract it let’s go to our /var/www/localhost/htdocs/openem directory by typing cd /var/www/localhost/htdocs/openem (press enter). If you list the contents of the directory you will see our openemr.tar.gz file is there. Let’s extract the file by issuing the following command: tar -xvf openemr.tar.gz your screen will start listing all the files it is extracting once it’s done list the contents of the folder ls (press enter), it should end up looking something like this.

If you noticed in the results of the list command, we still have our openemr.tar.gz file, we no longer need it so lets remove it by issuing the following command: rm openemr.tar.gz now type exit press enter to disconnect from our docker container.

Restarting containers

Now that we restored both our database and our web files, we need to restart our docker containers but instead of using docker-compose restart I’m going to first docker-compose down just to ensure no weird stuff is in memory and then I will docker-compose up again wait for the message in the terminal where is says:

openemr_1  | OpenEMR configured.
openemr_1  | Setup Complete!
openemr_1  | Setting user 'www' as owner of openemr/ and setting file/dir permissions to 400/500
openemr_1  | Default file permissions and ownership set, allowing writing to specific directories
openemr_1  | Removing remaining setup scripts
openemr_1  | Setup scripts removed, we should be ready to go now!
openemr_1  |
openemr_1  | Love OpenEMR? You can now support the project via the open collective:
openemr_1  |  > https://opencollective.com/openemr/donate
openemr_1  |
openemr_1  | Starting cron daemon!
openemr_1  | Starting apache!
openemr_1  | AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.24.0.3. Set the 'ServerName' directive globally to suppress this message

Then login to your Open EMR instance and everything should be working just like it was in your EC2 instance if it is congratulations you have just successfully restored your open EMR to your local host.

I hope this tutorial is useful and teaches you not to be afraid of docker.