For complex applications with a lot of components, orchestrating all the containers to start up and shut down together can quickly become headache. Docker is a great tool, but to really take full advantage of its potential it's best if each component of your application runs in its own container.
The Docker community came up with a popular solution called Fig, which allowed you to use a single YAML file to orchestrate all your Docker containers and configurations. This became so popular that the Docker team eventually decided to make their own version based on the Fig source. They called it Docker Compose. In short, it makes dealing with the orchestration processes of Docker containers (such as starting up, shutting down, and setting up intra-container linking and volumes) really easy.
PrerequisitesTo follow the steps we have mention in this article, you will need the following:
- Ubuntu 14.04 or later
- A non-root user with sudo privileges
Installing DockerYou will have to install Docker first if you haven't already. The easiet way to install Docker is to download and install their installation script (you'll be prompted for a sudo password).
- wget -qO- https://get.docker.com/ | sh
The above command downloads and executes a small installation script written by the Docker team.
dockergroup with the following command.
Log out and log in from your server to activate your new groups.
- sudo usermod -aG docker $(whoami)
Installing Docker ComposeSince you have Docker installed, let's move to the next step of installing Docker Compose. You need to install
Then you can install Docker Compose:
- sudo apt-get -y install python-pip
- sudo pip install docker-compose
Running a Container with Docker ComposeThe public Docker registry, Docker Hub, includes a simple Hello World image. Now that we have Docker Compose installed, let's test it with this really simple example.
Create a directory for our YAML file:
Then change into the directory:
- mkdir hello-world
Now create the YAML file using your favorite text editor (we will use nano):
- cd hello-world
Put the following contents into the file, save the file, and exit the text editor:
- nano docker-compose.yml
my-test: image: hello-world
The first line will be used as part of the container name. The second line specifies which image to use to create the container. The image will be downloaded from the official Docker Hub repository.
While still in the
~/hello-worlddirectory, execute the following command to create the container:
The output should start with the following:
- docker-compose up
Output of docker-compose upCreating helloworld_my-test_1... Attaching to helloworld_my-test_1 my-test_1 | my-test_1 | Hello from Docker. my-test_1 | This message shows that your installation appears to be working correctly. my-test_1 |
The output then explains what Docker is doing:
- The Docker client contacted the Docker daemon.
- The Docker daemon pulled the "hello-world" image from the Docker Hub.
- The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading.
- The Docker daemon streamed that output to the Docker client, which sent it to your terminal.
Learning Docker Compose CommandsLet's go over the commands the
docker-composecommand works on a per-directory basis. You can have multiple groups of Docker containers running on one machine — just make one directory for each container and one
docker-compose.ymlfile for each container inside its directory.
So far we've been running
docker-compose upon our own and using
CTRL-Cto shut it down. This allows debug messages to be displayed in the terminal window. This isn't ideal though, when running in production you'll want to have
docker-composeact more like a service. One simple way to do this is to just add the
-doption when you
- docker-compose up -d
docker-composewill now fork to the background.
To show your group of Docker containers (both stopped and currently running), use the following command:
For example, the following shows that the
- docker-compose ps
helloworld_my-test_1container is stopped:
A running container will show the
Output of `docker-compose ps`Name Command State Ports ----------------------------------------------- helloworld_my-test_1 /hello Exit 0
Output of `docker-compose ps`Name Command State Ports --------------------------------------------------------------- nginx_nginx_1 nginx -g daemon off; Up 443/tcp, 80/tcp
To stop all running Docker containers for an application group, issue the following command in the same directory as the
docker-compose.ymlfile used to start the Docker group:
- docker-compose stop
docker-compose killis also available if you need to shut things down more forcefully.
In some cases, Docker containers will store their old information in an internal volume. If you want to start from scratch you can use the
rmcommand to fully delete all the containers that make up your container group:
If you try any of these commands from a directory other than the directory that contains a Docker container and
- docker-compose rm
.ymlfile, it will complain and not show you your containers:
Output from wrong directory
Can't find a suitable configuration file in this directory or any parent. Are you in the right directory?
Supported filenames: docker-compose.yml, docker-compose.yaml, fig.yml, fig.yaml
Accessing the Docker Container FilesystemIf you need to work on the command prompt inside a container, you can use the
The Hello World! example exits after it is run, so we need to start a container that will keep running so we can then use
docker execto access the filesystem for the container.
- mkdir ~/nginx && cd $_
docker-compose.ymlfile in our new directory:
and paste in the following:
- nano docker-compose.yml
nginx: image: nginx
Save the file and exit. We just need to start the Nginx container as a background process with the following command:
The Nginx image will be downloaded and then the container will be started in the background.
- docker-compose up -d
Now we need the
CONTAINER IDfor the container. List of all the containers that are running:
You will see something similar to the following:
- docker ps
Output of `docker ps`
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e90e12f70418 nginx "nginx -g 'daemon off" 6 minutes ago Up 5 min
e90e12f70418) and use
docker execto start a shell inside the container:
- docker exec -it e90e12f70418 /bin/bash
-toption opens up a terminal, and the
-ioption makes it interactive. The
/bin/bashoptions opens a bash shell to the running container. Be sure to use the ID for your container.
You will see a bash prompt for the container similar to:
From here, you can work from the command prompt. Keep in mind, however, that unless you are in a directory that is saved as part of a data volume, your changes will disappear as soon as the container is restarted. Another caveat is that most Docker images are created with very minimal Linux installs, so some of the command line utilities and tools you are used to may not be present.
We covers the basic concepts of Docker Compose and how to get it installed and running on Ubuntu.