Migrating to Docker Compose
Even with a simple image, we've already been dealing with plenty of command line options in both building, pushing and running the image.
Next we will switch to a tool called Docker Compose to manage these. Docker Compose used to be a separate tool but now it is integrated into Docker and can be used like the rest of the Docker commands.
Docker Compose is designed to simplify running multi-container applications using a single command.
Assume that we are in the folder where we have our Dockerfile with the following content:
FROM ubuntu:22.04
WORKDIR /mydir
RUN apt-get update && apt-get install -y curl python3
RUN curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -o /usr/local/bin/yt-dlp
RUN chmod a+x /usr/local/bin/yt-dlp
ENTRYPOINT ["/usr/local/bin/yt-dlp"]
Let us now create a file called docker-compose.yml
:
version: '3.8'
services:
yt-dlp-ubuntu:
image: <username>/<repositoryname>
build: .
The version setting is not very strict, it just needs to be above 2 because otherwise the syntax is significantly different. See https://docs.docker.com/compose/compose-file/ for more info.
The value of the key build
can be a file system path (in the example it is the current directory .
) or an object with keys context
and dockerfile
, see the documentation for more
Now we can build and push with just these commands:
$ docker compose build
$ docker compose push
Volumes in Docker Compose
To run the image as we did previously, we will need to add the volume bind mounts. Volumes in Docker Compose are defined with the following syntax location-in-host:location-in-container
. Compose can work without an absolute path:
version: '3.8'
services:
yt-dlp-ubuntu:
image: <username>/<repositoryname>
build: .
volumes:
- .:/mydir
container_name: yt-dlp
We can also give the container a name it will use when running with container_name. The service name can be used to run it:
$ docker compose run yt-dlp-ubuntu https://imgur.com/JY5tHqr
Exercise 2.1
Let us now leverage the Docker Compose with the simple webservice that we used in the Exercise 1.3
Without a command devopsdockeruh/simple-web-service
will create logs into its /usr/src/app/text.log
.
Create a docker-compose.yml file that starts devopsdockeruh/simple-web-service
and saves the logs into your
filesystem.
Submit the docker-compose.yml, and make sure that it works simply by running docker compose up
if the log file exists.
Web services in Docker Compose
Compose is really meant for running web services, so let's move from simple binary wrappers to running a HTTP service.
https://github.com/jwilder/whoami is a simple service that prints the current container id (hostname).
$ docker container run -d -p 8000:8000 jwilder/whoami
736ab83847bb12dddd8b09969433f3a02d64d5b0be48f7a5c59a594e3a6a3541
Navigate with a browser or curl to localhost:8000, they both will answer with the id.
Take down the container so that it's not blocking port 8000.
$ docker container stop 736ab83847bb
$ docker container rm 736ab83847bb
Let's create a new folder and a Docker Compose file whoami/docker-compose.yml
from the command line options.
version: '3.8'
services:
whoami:
image: jwilder/whoami
ports:
- 8000:8000
Test it:
$ docker compose up -d
$ curl localhost:8000
Environment variables can also be given to the containers in Docker Compose as follows:
version: '3.8'
services:
backend:
image:
environment:
- VARIABLE=VALUE
- VARIABLE2=VALUE2
Note that there are also other, perhaps more elegant ways to define the environment variables in Docker compose.
Exercises 2.2 - 2.3
Read about how to add the command to docker-compose.yml from the documentation.
The familiar image devopsdockeruh/simple-web-service
can be used to start a web service, see the exercise 1.10.
Create a docker-compose.yml, and use it to start the service so that you can use it with your browser.
Submit the docker-compose.yml, and make sure that it works simply by running docker compose up
As we saw previously, starting an application with two programs was not trivial and the commands got a bit long.
In the previous part we created Dockerfiles for both frontend and backend of the example application. Next, simplify the usage into one docker-compose.yml.
Configure the backend and frontend from part 1 to work in Docker Compose.
Submit the docker-compose.yml