Publishing Docker images using Docker Compose

In earlier chapters, you learned how to use Docker Compose to help simplify the number of CLI commands required to test and build your Docker images. At the moment, Docker Compose is only building Docker images locally, but of course you now want to be able to publish your Docker images and leverage your Docker Compose workflow.

Docker Compose includes a service configuration property called image, which is commonly used to specify the image of a container that you would like to run:

version: '2.4'

services:
web:
image: nginx
Example Docker Compose file

Although this is a very common usage pattern for Docker Compose, another configuration and set of behaviors exist if you combine both the build and image properties, as demonstrated here, for the docker-compose.yml file in the todobackend repository:

version: '2.4'

volumes:
public:
driver: local

services:
test:
build:
context: .
dockerfile: Dockerfile
target: test
release:
image: 385605022855.dkr.ecr.us-east-1.amazonaws.com/docker-in-aws/todobackend:latest
build:
context: .
dockerfile: Dockerfile
environment:
DJANGO_SETTINGS_MODULE: todobackend.settings_release
MYSQL_HOST: db
MYSQL_USER: todo
MYSQL_PASSWORD: password
app:
image: 385605022855.dkr.ecr.us-east-1.amazonaws.com/docker-in-aws/todobackend:${APP_VERSION}
extends:
...
...
Todobackend Docker Compose file

In the preceding example, the image and build properties are both specified for the release and app services. When these two properties are used together, Docker will still build the image from the referenced Dockerfile, but will tag the image with the value to specify for the image property.

You can apply multiple tags by creating new services that simply extend your release image and define a image property that includes the additional tag.

Notice that for the app service we reference the environment variable APP_VERSION, which is intended to tag the image with the current application version that is defined within the Makefile at the root of the todobackend repository:

.PHONY: test release clean version

export APP_VERSION ?= $(shell git rev-parse --short HEAD)

version:
@ echo '{"Version": "$(APP_VERSION)"}'
Replace the repository URI in the preceding examples with the appropriate URI generated for your own AWS account.

To demonstrate the tagging behavior when you combine the image and build properties, first delete the Docker image you created earlier in this chapter, as follows:

> docker rmi 385605022855.dkr.ecr.us-east-1.amazonaws.com/docker-in-aws/todobackend
Untagged: 385605022855.dkr.ecr.us-east-1.amazonaws.com/docker-in-aws/todobackend:latest
Untagged: 385605022855.dkr.ecr.us-east-1.amazonaws.com/docker-in-aws/todobackend@sha256:322c8b378dd90b3a1a6dc8553baf03b4eb13ebafcc926d9d87c010f08e0339fa
Deleted: sha256:2b2d8d17367c32993b0aa68f407e89bf4a3496a1da9aeb7c00a8e49f89bf5134
Deleted: sha256:523126379df325e1bcdccdf633aa10bc45e43bdb5ce4412aec282e98dbe076fb
Deleted: sha256:54521ab8917e466fbf9e12a5e15ac5e8715da5332f3655e8cc51f5ad3987a034
Deleted: sha256:03d95618180182e7ae08c16b4687a7d191f3f56d909b868db9e889f0653add46
Deleted: sha256:eb56d3747a17d5b7d738c879412e39ac2739403bbf992267385f86fce2f5ed0d
Deleted: sha256:9908bfa1f773905e0540d70e65d6a0991fa1f89a5729fa83e92c2a8b45f7bd29
Deleted: sha256:d9268f192cb01d0e05a1f78ad6c41bc702b11559d547c0865b4293908d99a311
Deleted: sha256:c6e4f60120cdf713253b24bba97a0c2a80d41a0126eb18f4ea5269034dbdc7e1
Deleted: sha256:0b780adf8501c8a0dbf33f49425385506885f9e8d4295f9bc63c3f895faed6d1
Deleting a Docker image

If you now run the docker-compose build release command, once the command completes, Docker Compose will have built a new image tagged with your ECR repository URI:

> docker-compose build release
WARNING: The APP_VERSION variable is not set. Defaulting to a blank string.
Building release
Step 1/25 : FROM alpine AS build
---> 3fd9065eaf02
Step 2/25 : LABEL application=todobackend
---> Using cache
---> f955808a07fd
...
...
Step 25/25 : USER app
---> Using cache
---> f507b981227f

Successfully built f507b981227f
Successfully tagged 385605022855.dkr.ecr.us-east-1.amazonaws.com/docker-in-aws/todobackend:latest
> docker images
REPOSITORY                                                               TAG                 IMAGE ID            CREATED             SIZE
385605022855.dkr.ecr.us-east-1.amazonaws.com/docker-in-aws/todobackend latest f507b981227f 4 days ago 99.4MB
Building a tagged image using Docker Compose

With your image built and tagged correctly, you can now execute the docker-compose push command, which can be used to push services defined in the Docker Compose file that include a build and image property:

> docker-compose push release
Pushing release (385605022855.dkr.ecr.us-east-1.amazonaws.com/docker-in-aws/todobackend:latest)...
The push refers to repository [385605022855.dkr.ecr.us-east-1.amazonaws.com/docker-in-aws/todobackend]
9ae8d6169643: Layer already exists
cdbc5d8be7d1: Pushed
08a1fb32c580: Layer already exists
2e3946df4029: Pushed
3a29354c4bcc: Layer already exists
a031167f960b: Layer already exists
cd7100a72410: Layer already exists
latest: digest: sha256:a1b029d347a2fabd3f58d177dcbbcd88066dc54ccdc15adad46c12ceac450378 size: 1787
Publishing images using Docker Compose

In the preceding example, the image associated with the service called release is pushed, given this is the service that you configured with the Docker image URI.