Docker is a technology to create containers. What if we have multiple contains and need them to work together? Docker compose comes to rescue. The configuration is a yaml file and it's easy to follow. I'm going to write down some tips when I learned to use it.
Keep the Docker Container Running
The docker container is supposed to run only one process. The container stops when the process exits. So if we have a process that runs in the forground, it'll most likely exit because there is no console or input. For this kind of container, usually we run the command docker run -ti <image name>
to keep the container running. In docker-compose world, you need to put this in the configuration for the service.
tty: true
stdin_open: true
Expose the Network Ports
In running docker
, we can use docker -P
to expose all the ports specified in the Dockerfile. We can also use docker -p []
to expose the specified ports in the command line. However, docker -P
doesn't guarantee to map those ports from the container to the same ports on the host. The mapping is random. We can explicitly set those mapping using docker -p []
. docker-compose
by default will create a bridge for the specified containers. Depending on how we write it, we can expose the port only to that bridge network or also in the host.
expose:
- "8080"
This will only expose the ports to the linked services.
ports:
- "8080:80"
This also expose the ports on the host. It maps the port 8080 on host to the port 80 on the container.
Connect to the Linked Service in a Container
We specify the service in the configuration. docker-compose
will bring up one or multiple container running the same thing for the service. Even if you don't specify the networks
, docker-compose
still creates a default one for you. You can find all the network by docker network ls
. The name of the default network for your docker-compose containers is derived from the directory of the docker-compose.yml
file. For example, docker-compose.yml
is in the directory 'example'. The default network for those containers is 'example_default'. This may change but this is the behavior right now.
How do you connect to other containers brought up by docker-compose
? There are two ways:
- Use the service name. For example, in
docker-compose.yml
, you specify the service likeservices: foo: image: 'centos:latest' bar: image: 'ubuntu:latest'
In the container that runs Centos, you can use bar to connect to the other container that runs Ubuntu.
- Use the ip address.
When you find the network for your containers, you can usedocker network inspect <network name>
to inspect the details of the network. From there, you can find the ip address of the containers. For example:{ "Name": "example_default", "Containers": { "4a87be92f610b839c77f0fa87c7bdd13797ca4eac3c2061a4d8e66a1c5e9c867": { "Name": "example_foo_1", "EndpointID": "0752c01405904b702459560fcc1bc90ef0e24d3e769e8bc46d5edcf06944dba1", "MacAddress": "02:42:ac:15:00:03", "IPv4Address": "172.21.0.3/16", "IPv6Address": "" }, "6244c44cab85df31d684abb5e0b2ce12ecfbef902e13c638d1ab50981b876142": { "Name": "example_bar_1", "EndpointID": "5b0edb758b080010f8c3fca92e5cb583724c9fefcc23c5148c8c3375517d0093", "MacAddress": "02:42:ac:15:00:02", "IPv4Address": "172.21.0.2/16", "IPv6Address": "" } },
By far, those are the things I think it's useful when using docker-compose
. I spent some time on searching online. I hope this can help you to try out the way to manage containers.