Demonstration of developing, testing, and delivering production software with Docker.
The MEAN stack application code in src/
is used to demonstrate how to:
- Containerize a multi-tier application
- Create development and test environments with Docker Compose
- Create production environments using Docker Compose override files
- Release a new feature from development, through test, and into production
An Azure Resource Manager template is provided in infrastructure/
to create an environment with three virtual machines in a virtual network with Docker installed on each. Certificates are shared and setup for TLS secured communication between the three Docker hosts. The created environment resembles the following:
You can also directly visualize the template resources:
A Resource Manager policy to allow only the creation of the required resources is also included in infrastructure/
.
The following command sequence can prepare the environment in the West US 2 Azure region:
Login-AzureRmAccount
New-AzureRmResourceGroup -Name docker -Location westus2
New-AzureRmResourceGroupDeployment -ResourceGroupName docker -TemplateFile .\infrastructure\arm-template.json -Name dsd
When finished, the following can tear down the environment:
Remove-AzureRmResourceGroup -Name docker
To create a registry on the registry vm enter:
docker run -d --name registry \
--restart=always \
-v /etc/docker/:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/cert.pem \
-e REGISTRY_HTTP_TLS_KEY=/certs/key.pem \
-p 5000:5000 \
registry:2
The registry is accessible from with the virtual network at registry.ca-labs.com:5000
After cloning the source code, unit test the code
npm install
npm test
Build the image:
docker build -t registry.ca-labs.com:5000/accumulator:1 registry.ca-labs.com:5000/accumulator:1.0 .
Push the image to the registry:
docker push registry.ca-labs.com:5000/accumulator:1
docker push registry.ca-labs.com:5000/accumulator:1.0
Integration test the applicaiton using Docker Compose:
docker-compose up -d
bash integration.sh
docker-compose down
Simplify communication with the production VM by moving certificates to the user's default .docker directory:
mkdir ~/.docker
sudo cp /etc/docker/ca.pem \
/etc/docker/cert.pem \
/etc/docker/key.pem \
~/.docker
sudo chown student ~/.docker/*
Start the application on the production VM using Docker Compose the production override file:
DOCKER_HOST=production.ca-labs.com:2376 DOCKER_TLS_VERIFY=true docker-compose \
-f docker-compose.yml \
-f docker-compose.prod.yml \
up \
-d
Update the application with v1.1 of the source code which includes a new feature:
cp -R src/commits/v1_1/. src
Build the v1.1 container image:
docker build -t registry.ca-labs.com:5000/accumulator:1 registry.ca-labs.com:5000/accumulator:1.1 .
Push the new image to the registry:
docker push registry.ca-labs.com:5000/accumulator:1
docker push registry.ca-labs.com:5000/accumulator:1.1
Pull the new version of the image onto the production VM:
DOCKER_HOST=production.ca-labs.com:2376 DOCKER_TLS_VERIFY=true docker-compose pull
Update only the app service to deploy the new feature and keep the database up:
DOCKER_HOST=production.ca-labs.com:2376 DOCKER_TLS_VERIFY=true docker-compose \
-f docker-compose.yml \
-f docker-compose.prod.yml \
up \
-d \
--no-deps \
app