Closer Look at the Compose File
Let's look at the services section of the Compose YAML file.
The example file we’ve listed uses the Compose version 3.8 file format, defines two services, defines a network called counter-net, and defines a volume called counter-vol.
version: "3.8"services:web-fe:build: .command: python app.pyports:- target: 5000published: 5000networks:- counter-netvolumes:- type: volumesource: counter-voltarget: /coderedis:image: "redis:alpine"networks:counter-net:networks:counter-net:volumes:counter-vol:
services
Most of the detail is in the services section, so let’s take a closer look at that.
The services section has two second-level keys:
web-feredis
Each of these defines a service (container) in the app. It’s important to understand that Compose will deploy each of these as a container, and it will use the name of the keys as part of the container names. In our example, we’ve defined two keys; web-fe and redis. This means Compose will deploy two containers, one will have web-fe in its name and the other will have redis.
web-fe
Within the definition of the web-fe service, we give Docker the following instructions:
-
build: .This tells Docker to build a new image using the instructions in the
Dockerfilein the current directory (.). The newly built image will be used in a later step to create the container for this service. -
command: python app.pyThis tells Docker to run a Python app called
app.pyas the main app in the container. Theapp.pyfile must exist in the image, and the image must contain Python. The Dockerfile takes care of both of these requirements. -
ports:This tells Docker to map port 5000 inside the container (
target) to port 5000 on the host (published). This means that traffic sent to the Docker host on port 5000 will be directed to port 5000 on the container. The app inside the container listens on port 5000. -
networks:This tells Docker which network to attach the service’s container to. The network should already exist or be defined in the
networkstop-level key. If it’s an overlay network, it will need to have theattachableflag so that standalone containers can be attached to it (Compose deploys standalone containers instead of Docker Services). -
volumes:This tells Docker to mount the
counter-volvolume (source:) to/code(target:) inside the container. Thecounter-volvolume needs to already exist, or be defined in thevolumestop-level key at the bottom of the file.
In summary, Compose will instruct Docker to deploy a single standalone container for the web-fe service. It will be based on an image built from a Dockerfile in the same directory as the Compose file. This image will be started as a container and run app.py as its main app. It will expose itself on port 5000 on the host, attach to the counter-net network, and mount a volume to /code.
Note: Technically speaking, we don’t need the
command: python app.pyoption. This is because, as you will soon see, the application’s Dockerfile already definespython app.pyas the default app for the image. However, we’re showing it here so you know how it works. You can also use Compose to override CMD instructions set in Dockerfiles.
redis
The definition of the redis service is simpler:
-
image: "redis:alpine"This tells Docker to start a standalone container called
redisbased on theredis:alpineimage. This image will be pulled from Docker Hub. -
networks:The
rediscontainer will be attached to thecounter-netnetwork.
As both services will be deployed onto the same counter-net network, they will be able to resolve each other by name. This is important as the application is configured to communicate with the redis service by name.
Now that we understand how the Compose file works, let’s deploy it!