Docker Reference Application in Production?

On dockerhub there’s a warning that the refapp docker image is not suitable for production. What is necessary to make dockerized refapp production-ready? The biggest problem I see is the default credentials (admin/admin123, doctor/doctor123, etc.) Is there something else I’m overlooking? What’s the cleanest way to deal with default credentials when setting up a production docker deployment?

1 Like

@isears, it’s a demo image with the referencedemodata module installed. You would basically have to get rid of that module (best by creating your own docker image with SDK).

The docker way to provide default credentials is via environment properties, but we do not have support for that in OpenMRS yet. However, we do support an installation script instead of a web installation, which could be used for that purpose with some tricks.

Also have a look at the docker-compose file used by SDK. It creates a persistent volume for the .OpenMRS directory so that the server image can be later updated without loosing or having to recreate some data e.g. Lucene index.

Maybe, it’s time for us to consider publishing an official production docker image of referenceapplication :slight_smile:

3 Likes

Alright, I think a production docker image has a lot of potential and I would be interested in looking into this. I’ve created an issue on jira and assigned it to myself: https://issues.openmrs.org/browse/SDK-231

I created the issue under SDK, but if there’s a more appropriate place for it let me know.

I moved the ticket to the RA project (https://issues.openmrs.org/browse/RA-1494) since “publishing an official production docker image of referenceapplication” is about the refapp, not changes to the SDK.

Some of the features I’d expect of an “official” (production-worthy) Docker container for OpenMRS to mimic best practices on Docker Hub:

  • Only the application (i.e., no database)
    • Good Docker images dotadiw
    • Only Tomcat and Platform±RefApp
    • Users can link to their own db or their own db container
  • Small size
    • Based on Alpine or similar image
  • Use of named volumes that could be loaded from host or from other containers for greater flexibility.*
    • Runtime properties
    • Modules
    • Configuration files
  • Support environment variables
    • Admin password
    • OMRS_JAVA_OPTS
    • Remote debugging port
    • A “debug” vs “production” flag

*Regarding named volumes to support, we could debate whether we just expose the “.OpenMRS” folder as a single named volume or create separate volumes. The advantage of a single named volume is simplicity and automatic support for externalizing data for any modules that create subfolders. The advantage of using separate named folders would be for people who just want, for example, to mount modules.

Somehow I missed this topic before.

As @raff mentioned, the image is based on this properties file. I don’t really know if those are all modules you want.

I don’t really know which modules would be suitable to go to production, so I cannot really give an opinion. Do we actually need referencedemodata modules installed at all on that image, @raff? The data for demo is already generated and it’s on the SQL file.

The image itself doesn’t really have any credentials. For example, the demo server, we configured the image to not create the database as I have the sql file imported directly to the database.

We are always using an external SQL file - and the password for all users is already there. I have no idea how much time OpenMRS takes to generate all takes and populate data, but my usecase requires frequent data resets.

The SDK creates a lot of useful files if you have a openmrs-distro.properties file:

  • It downloads all modules and openmrs versions to the local folder
  • A dockerfile for OpenMRS distro. That’s based on official tomcat:7 family
  • It also generates the SQL file that can be used to bootstrap the database
  • And a bunch of docker compose files that you can use or adapt to your needs

The image is great, and even waits for the database to be up before starting OpenMRS. It’s not a particularly small image, but it’s not bad. We use docker in all our test environments, but I never scanned the image for security vulnerabilities for example.

I also have been using same images with backups. Note both the volumes definition and the backup image, which creates a .tar.gz file and copies to a backup folder.

I configured by docker host to store all docker data to a different partition/hard disk, not in /root, so I can reinstall the OS without losing docker data.

That image is built using the Dockerfile generated by the SDK and pushed to Dockerhub. The SQL files and docker-compose were adapted from what the SDK generated too.

I know that the SDK has debug flags to generate other docker images. I never used them.

If you are happy with all the modules on that properties file, please, by all means try to copy my docker-compose files, get the empty SQL file generated by the SDK, push to a git repository and test to see it works as you expect. You can even change the passwords there.

I’m deploying those files to my hosts using ansible, but you are free to use anything you want :slight_smile:

Let me know if you have plans on using docker swarm or kubernetes.

If the docker image fits your needs, we can always attempt to use the alpine based image and do a security scan before deploying it. I suppose the release would also require docker images tests.

And docs :smiley:

2 Likes

Thanks for the feedback, everyone.

I just got done with a mini weekend-sprint (if you will). My objective was to be able to create a docker image that had custom admin credentials by making a few changes to the openmrs-sdk and openmrs-distro-referenceapplication repos.

I documented my work in a sub-issue here: https://issues.openmrs.org/browse/RA-1496

My changes to sdk are here: https://github.com/openmrs/openmrs-sdk/compare/master...isears:master

And my changes to distro-referenceapplication are here: https://github.com/openmrs/openmrs-distro-referenceapplication/compare/master...isears:master

Ultimately I’m working toward a solution wherein we are able to generate necessary materials for a production-ready refapp docker-container by adding a -Dproduction=true flag to the openmrs-sdk build-distro command:

mvn org.openmrs.maven.plugins:openmrs-sdk-maven-plugin:3.7.0:build-distro -B -Ddir=demo-server -Ddistro=referenceapplication:<version> -Dbundled=true -Dproduction=true

Definitely not there yet, but I wanted to show my work so far so that someone can stop me if I’m going in the wrong direction.

Thoughts?

What would this actually do?

At a minimum, set an environment variable to be used by scripts or any code. I was assuming that there would be a number of default settings that might vary based on the mode – e.g., log level, requirement of security settings, use of remote debugging, default ports, toggle caching, etc. I was borrowing from the practice of NODE_ENV popularized by Node’s Express project, thinking we might find utility in having an OMRS_ENV. :slight_smile:

So as far as I can tell there’s already a DEBUG flag in the existing docker build that opens port 1044 for debugging if set to true. Should we just continue using this? I.e.: build a production-ready image if DEBUG is set to false or not present?

I suppose that’s fine. We wouldn’t be able to distinguish a testing environment from dev or production like NODE_ENV or Spring profile system property can… but I don’t know how critical that is for us. Following an existing pattern in the SDK is probably the easiest path.

I’ve created an image that comes without any demo data and accepts the ADMIN_PASSWORD parameter as input:

https://hub.docker.com/r/isears/refapp-production/

It looks like the demo refapp docker image is created through some kind of CI pipeline. Any interest in generating the production version in the same way? I think that would entail adding code to the openmrs-sdk that would run when new versions of distro-refapp are released.

I have created an automated CI pipeline to build production docker images in my fork of openmrs-distro-referenceapplication: https://github.com/isears/openmrs-distro-referenceapplication

Using this pipeline, I have production images hosted on my dockerhub for 2.6.x, 2.7.x and latest. The production images only really have two features distinct from the demo images:

  • Ability to set the admin password in docker-compose
  • No demo data by default

I’m currently using this setup for an implementation on AWS and anyone who’s interested can check out my docker-compose files here: https://github.com/fortitudoinc/fortitudoinc-infra

I don’t think there’s enough community interest at the point to do any more work. But if, in the future, anyone is interested in more features or help setting up a dockerized, production-ready openmrs implementation feel free to let me know!

1 Like