Dockerisation has redefined the deployment and automation process in the software industry. Since its inception, the Docker team has continuously strived to make automated deployment seamless. Containerization technology does not just enable rapid application development and efficiency, but also saves time and strenuous efforts. Unbeatable functionalities such as orchestrating, defining, and running multi-container applications together make Docker a favorite pick for developers.
Docker Containers and Images
As you dive in to further understand Docker, it is essential to brush up with the basics. Understanding how Docker works can be tricky if you have no experience working with it. In this section, we are going to define a few concepts that are essential for beginners. If you think you are familiar with these concepts, feel free to skip and move forward with the next section. You can also take a look at our comprehensive guide that explains the fundamental Docker concepts.
-
Docker Images
Docker images are a collection of read-only files. Once you create Docker images, you cannot modify them, though it allows deletion. We use a Docker image to create one or more Docker containers as per our needs. To check the number of images running in your system, use the command:
1 |
$docker images |
When you pull images from a remote registry like Docker Hub, you are downloading files and folders. To pull an image, use the command:
1 |
$docker pull (name of the image) |
-
Docker Containers
Docker images are the blueprint of Docker containers. Technically, a Docker container is an instance of a Docker image. Imagine, if a Docker image is like a parent, then a Docker container is the child. Unlike Docker images which you can create once, you can create multiple containers using a single image. To check the list of images running in your system, use the command:
1 |
$docker ps |
To pull a container, use the following command:
1 |
$docker pull (name of the container) |
-
How Docker Images and Containers Work
Docker images and containers work hand-in-hand to unleash the potential of Docker. A single container is built using the Docker image through the run command. When you create a Docker container, a new layer known as Container Layer is created. The newly created layer contains the application and its dependencies. Every container you create has a different read/write Container Layer, and any changes made in the Docker container are automatically reflected upon the Container Layer. Remember, if you choose to delete a container, you will also lose the Container Layer.
Say Hello to Docker Compose
Docker Compose is a container management tool that allows you to configure and orchestrate all your Docker containers into a single YAML file. Starting, halting, and creating intra-container linkages and volumes are all made easier with this tool.
-
What does Docker Compose Do?
Simply put, Docker Compose makes complicated tasks easier by eliminating conflicts and organizational issues. It allows users to manage different Docker containers centrally. In other words, instead of having all the services in a large container, Docker Compose breaks down a service into multiple services so that users can access and manage them effortlessly.
In this guide, we will walk you through the steps of installing the current version of Docker Compose for managing multi-container applications on CentOS 7. We will also go over some basic commands you need to successfully use the software.
-
How to Use Docker Compose
Using Docker Compose is extremely easy, even for newbies. Let us see the three-step process involved in Docker Compose:
1. Build: At first, build images in the Dockerfile as per your project needs, or perhaps pull from the registry.
2. Define: Next, you need to define all the component services in the compose.yml
file.
3. Run: After defining the components, it’s time to run using the docker-compose
command.
Prerequisites
Before we move forward with installing Docker Compose on your CentOS server, make sure you have:
- A non-root user with sudo access on a CentOS 7 server.
- Docker installed on your machine. Please refer to this tutorial on how to install and operate Docker on Ubuntu 18.04.
You are all set now. Next, follow along with the steps below to install Docker Compose on CentOS 7.
Step 1: Installing Docker Compose
To get the most recent version of Docker Compose, follow the instructions in the Docker documentation and download the binaries from Docker’s GitHub repository. Check that you have the latest version of the software by running the command below:
1 |
sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose |
To make the binary run, set the permissions below:
1 |
sudo chmod +x /usr/local/bin/docker-compose |
Next, look up your version to check if the installation was successful:
1 |
$docker-compose --version |
The below code will print the installed version:
You may then run a “Hello World” example using the Docker Compose that you have installed.
Step 2: Using Docker Compose to Run a Container
There is a “Hello World” image in Docker Hub, the public Docker registry, which may be used for demonstration and testing. It shows how to run a container using Docker Compose with the very minimal configuration. First, you need to create a directory for our YAML file:
1 |
$mkdir hello-world |
Next, move to this directory:
1 |
$cd hello-world |
Then, using your preferred text editor, generate the YAML file. In this tutorial, we will use Vi
:
1 |
$vi docker-compose.yml |
Press i
to get to insert mode, then type this into the file:
1 2 |
my-test: image: hello-world |
In the container name, the first line will be incorporated. The second line instructs the program which image it should use to create the container. docker-compose
up
will look for a local image by the name hello-world
to check if it is available when you type the command. To exit insert mode, press ESC
. Then, enter :x
and press ENTER
to save and quit the file. The docker images
command can be used to manually check for images on your machine:
1 |
$ sudo docker images |
Only the column headings appear when there are no local images at all:
To create the container, run this command while still in the /hello-world directory
:
1 |
$sudo docker-compose up |
When you run the command for the first time and there isn’t a local image named hello-world
, it will be downloaded from the Docker Hub repository:
To ensure that the installation works, Docker Compose pulls in the image, builds a container, attaches it, and executes the hello program:
After that, a printout of a description of what was done is displayed:
When hello
completes its duty, the container will be shut down and the command will no longer be running in the container. Column headings will be displayed when looking at active processes. However, the hello-world
container will not be listed because it is not currently operating:
1 |
$sudo docker ps |
To see all containers, not just the current ones, use the -a
flag:
1 |
$sudo docker ps -a |
Now that you’ve tried running a container, you may go on to learn some of the fundamental Docker Compose commands.
Step 3: Docker Compose Commands
To get you started with Docker Compose, this section will go over the basic commands provided by the docker-compose
tool. docker-compose
is a command that works on a directory-by-directory basis. By generating one directory for each container and one docker-compose.yml
file per directory, you can run many groups of Docker containers on the same computer.
So far, you have been running Docker Compose on your own. You can shut it off by pressing Ctrl-C
. This enables the terminal window to display debug messages. However, it is advisable to run docker-compose
as a service when operating in production. The -d
option can be used as a simple way to accomplish this:
1 |
docker-compose up -d |
Now, docker-compose
forks to the background. Your group of Docker containers (either stalled or running) can be managed with the following command:
1 |
$sudo docker-compose ps -a |
The State
of a container will be reported as Exited
if it is halted, as seen in the example below:
A container that is currently running will display:
1 2 3 4 |
Name Command State Ports --------------------------------------------------------------- nginx_nginx_1 nginx -g daemon off; Up 443/tcp, 80/tcp |
You can terminate all running Docker containers in the same directory as the docker-compose.yml
file that you used to start the Docker group:
1 |
$docker-compose stop |
Note: If you need to shut things down more forcibly, docker-compose kill is also available.
In some instances, Docker containers may be able to save their old data inside. Use the rm
command to remove all containers from your container group if you want to begin from scratch:
1 |
$docker-compose rm |
Running any of these commands from another directory than the one where the Docker container and .yml
file is placed will result in an error message:
1 2 3 4 5 6 |
ERROR: 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 |
In this section, we’ve covered the basics of manipulating containers with Docker Compose. As discussed, in the following section you can access the Docker filesystem and run commands from a command prompt inside the container if you need additional control over your containers.
Step 4: Access the Docker Container Filesystem
It is possible to run a command prompt in a container and access the container’s filesystem using docker exec
, which is a command-line tool. As an example, run “Hello World” and see how long it takes for the docker
exec
command to complete. For the sake of this tutorial, the Docker Hub image of Nginx can be utilized. Create a new directory named nginx
and move into it:
1 2 |
mkdir ~/nginx cd ~/nginx |
You should now have a docker-compose.yml
file, which you can open in a text editor:
1 |
vi docker-compose.yml |
Then, in the file, add the following:
1 2 |
nginx: image: nginx |
It is time to close out of the application. To start the Nginx container in the background, use the following command:
1 |
$sudo docker-compose up -d |
Docker Compose will download the Nginx image and run the container in the background. To continue, you’ll need to enter the container’s CONTAINER ID
. You can view all currently running containers with the following command:
1 |
$sudo docker ps |
You’ll see the following:
If you wanted to alter the filesystem inside this container, using docker exec
, you’d use the container’s unique ID (in this case, f139d0d78ca7
) to build a shell within the container:
1 |
$sudo docker exec -it f139d0d78ca7 /bin/bash |
An interactive terminal can be opened by using the -t
option, whereas /bin/bash
provides the container with a bash shell. This is the bash prompt you’ll see for the container after that:
1 |
root@b86b6699714c:/# |
Within your container, you’ll find a command prompt. Restarting the container will overwrite any changes you’ve made unless you’re working in a directory that has been saved as part of a data volume. If you’re accustomed to working with Linux command-line facilities, you should know that most Docker images are produced using the most basic Linux installs.
Conclusion
We walked you through the steps of installing the current version of Docker Compose for managing multi-container applications on CentOS 7. The ability of Docker Compose to simultaneously put up and shut down a large number of containers is impressive. Going from templates to applications takes minutes. Thus, if your work involves running multiple containers at once, sticking with Docker Compose is a great option. Yet, it is not a one-fit-all solution. You can also find some better options, depending on your particular needs, for example, Kubernetes.
To further explore the power of Docker Compose, you can refer to these tutorials from our blog:
- Deploying Laravel, Nginx, and MySQL with Docker Compose
- How to Install and Configure Docker Compose on Ubuntu 20.04
Happy Computing!
- How To Enable, Create and Use the .htaccess File: A Tutorial - March 8, 2023
- An Overview of Queries in MySQL - October 28, 2022
- Introduction to Cookies: Understanding and Working with JavaScript Cookies - October 25, 2022
- An Overview of Data Types in Ruby - October 24, 2022
- The Architecture of Iptables and Netfilter - October 10, 2022