The following guide outlines recommended practices for using Docker Compose in Healthcare Blocks environments. If you need additional documentation about specific Compose features, please refer to Docker's official documentation site. If you're using Docker in Swarm Mode, please refer to this guide instead.
Environment-Specific Docker Compose YAML
On your local machine, your configuration might differ compared to your Healthcare Blocks environment. For development, maintain a docker-compose.yml, whereas for Healthcare Blocks, use a docker-compose-prod.yml. Some of the differences between environments will include:
- Additional services* (e.g. Healthcare Blocks database-as-a-service)
- Environment variables
- Port mappings
- Specifying a restart policy to avoid downtime
- Volume mounts
SSH to your Healthcare Blocks server and save your docker-compose-prod.yml to any directory on the encrypted data volume, e.g. /data/myapp. Now you can start your container(s) via:
cd /data/myapp && docker-compose up -f docker-compose-prod.yml
*If you're using our database-as-a-service, you do not need to define a database container in your Docker Compose YAML. Instead, using the credentials we shared with you, include them in the "environment" section in your application's configuration in the YAML file, and also set a DATABASE_HOST variable to the database service URL we provided.
Running Remote Compose Commands
Rather than exposing the Docker port externally and relying on Docker Machine, it's easy to run compose commands over SSH:
ssh username@machine 'cd /some/path; sudo docker-compose up -f docker-compose-prod.yml'
To preserve data and/or files between container restarts and machine reboots, you can create directories on the encrypted data volume (mounted at /data) and then define a volume mount in your YAML file:
volumes: - /data/myapp/files:/app/storage - /data/log/myapp:/app/log
...where the first item in the pair is a path on the server, and the second item is the path inside the container.
- Be sure you create the path on the server first, e.g. /data/mysql
- Depending on your application, you might need to edit the permissions of the directory:
chmod 0776 /data/myapp/files
Assuming you are using a Web server, you will need to provision an SSL certificate to encrypt protected health information (PHI) in transit per HIPAA requirements.
Using a Test Certificate
The Healthcare Blocks Nginx Docker image is bundled with a test certificate. Since it is a self-signed certificate, your Web browser will display an SSL/TLS error, so while it is useful for testing HTTPS based URL's, it should not be used for live, customer-facing applications.
Using a Certificate from a Certificate Authority
If you've already purchased a third-party SSL certificate from a known certificate authority, here's what you need to do to use it in your Healthcare Blocks environment:
- SSH to your server and create a directory for storing your certificate and key:
mkdir -p /data/ssl
- In your docker-compose-prod.yml, define a volume mount from server path above to the Web server ssl path:
volumes: - /data/ssl/domain.crt:/nginx/ssl/app.crt - /data/ssl/domain.key:/nginx/ssl/app.key
Note that you might need to set specific permissions on the directory, cert, and key via chmod.
Using Free Certificates from Let's Encrypt
Let's Encrypt provides a limited number of free certificates that expire every 90 days. You can use their official Docker image to provision certificates. And by configuring a cron job, you can automate certificate renewals. Here's how:
- SSH to your Healthcare Blocks server
- If you have a Web application already running on port 80 and 443, you will need to temporarily stop it. The Let's Encrypt certificate provisioner API validates the requested certificate domain over the same ports.
- Run the following command:
docker run -it --rm \ -p 80:80 -p 443:443 \ --name certbot \ -v "/data/ssl/letsencrypt:/etc/letsencrypt" \ -v "/data/ssl/letsencrypt/lib:/var/lib/letsencrypt" \ certbot/certbot certonly -d SUBDOMAIN.healthcareblocks.com \ --authenticator standalone \ --email EMAIL_ADDRESS \ --agree-tos(SUBDOMAIN is your unique server subdomain and EMAIL_ADDRESS is your preferred contact email)
- The previous command will save the cert and key to /data/ssl/letsencrypt/live. So if you are using our Nginx Docker image, be sure your docker-compose-prod.yml uses a volume mount pointing to the same location:
volumes: - /data/ssl/letsencrypt/live/SUBDOMAIN.healthcareblocks.com/fullchain.pem::/nginx/ssl/app.crt - /data/ssl/letsencrypt/live/SUBDOMAIN.healthcareblocks.com/privkey.pem:/nginx/ssl/app.key
Automatically Renewing Certificates
- Write a simple bash script with the following contents and save it to /data/ssl/renewal.sh:
#!/bin/bash set -euo pipefail docker run -it --rm --name renew_cert -v "/data/ssl/letsencrypt:/etc/letsencrypt" -v "/data/ssl/letsencrypt/lib:/var/lib/letsencrypt" quay.io/letsencrypt/letsencrypt:latest renew cd /data/myapp && docker-compose -f docker-compose-prod.yml exec nginx nginx -s reloadNote: /data/myapp and app should be set to your actual values. The first nginx refers to the name of the image, and nginx -s reload is the actual command being passed to the container.
- Set execute permissions on the script:
chmod +x /data/ssl/renewal.sh
- Edit the crontab:
- Specify when you want the above script to execute, for example, every Sunday at 1 AM:
0 1 * * 0 /data/ssl/renewal.shReference: Crontab Guru