Compose in Action: Optimizing Your Containerized Applications #Docker Series Part 3
What is Docker Compose, basic keywords of Docker Compose, writing Docker Compose
Managing and maintaining your application using container can simplify the process. Container help you develop and run your application in an isolated environment. Docker is one of the most well-known platform for containerization out there. It’s recommended that one container should only focus on one task like there is one container used for backend service, one container used for frontend, and one container for database. That’s why an application can have multiple containers. Managing a multi-container applications can be a difficult task. Docker composer exists to make the process easier.
This article is part of my Docker Series. Check out the other part I’ve discussed about:
- A beginner’s guide to containerization
- Creating custom Image of your application
- Integrating Containers into Your CI/CD Pipeline using Github Actions
Let’s jump in:
What is Docker Compose?
Docker compose is a tool for defining and running multi-container applications. Docker Compose simplifies container management by defining multi-container applications in a single YAML file. Through a declarative YAML file, developers specify the services, networks, and volumes needed for their application stack. This approach ensures consistency across different environments, from development to production. It has straightforward syntax and powerful features. Developers can easily replicate development environments across teams, ensuring consistency using Docker Compose. Some benefits of compose are:
- simplified configuration: using single YAML file, making it’s easy to manage complex setup
- consistency across different environment: developers can replicate development environments across teams, ensuring consistency and reducing potential issues
- efficient collaboration: docker compose configurations are easy to share
- rapid development: compose caches the configuration to create containers. If your containers have not change, compose will use the existing containers when you restart services
Basic keywords of Docker Compose
Docker compose consists of different keywords to manage our containers. Some basic keywords of Docker Compose are:
services
: services is the parent tag of compose. It includes all the containers in the composeimage
: the base image can use docker official image or the image that we build from the Dockerfile. You can customize the base image usingbuild
keywordports
: exposing ports can useports
keywords orexpose
keyword. The difference between it isports
specify which port of the host system that’ll be linked into the container port whileexpose
doesn’t specify the port of the host systemcommand
: command is used to execute once you run the compose. You can run multiple commands. Command can be use to debug if there’s an errorvolumes
: volumes are used to share data between container and the host system. Volumes are completely independent from the host system because it’s managed by Dockerenv_file
: env_file is used to share the environment file from the host systemenvironment
: the environment keyword is used to manage environment variable. This keyword overridesenv_file
keyword
Writing Docker Compose
The default path for compose is compose.yaml
or compose.yml
. It’s placed in the working directory. Compose also support docker-compose.yaml
or docker-compose.yml
but it’s prioritize compose.yaml
or compose.yml
first if both files exist.
services:
backend:
image: florist:latest
ports:
- "8081:8080"
networks:
- back-tier
env_file:
- ./config.env
volumes:
- ./config.env:/src/.env
command:
- "./florist"
restart: always
database:
image: postgres:latest
ports:
- "5433:5432"
networks:
- back-tier
env_file:
- ./config.env
environment:
- POSTGRES_DB=${DB_NAME}
- POSTGRES_USER=${DB_USER}
- POSTGRES_PASSWORD=${DB_PASS}
volumes:
- pgdata:/var/lib/postgresql/data
restart: always
volumes:
pgdata:
driver: local
configs:
httpd-config:
external: true
networks:
back-tier: {}
In this compose file I have two containers. There are backend container and database container. The backend container using image that I created using Dockerfile while the database using PostgreSQL official image. I also specify the tag of the image. Then I exposed the port 8001
of the host machine to 8000
of the container. For the database service I expose the port 5433
to the port 5432
.
I configure the env file using config.env
in the root folder of the host machine. Both of the service using the same environment file. I use volume to store the environment variable in the container. The command
configuration should be the same with the command that you specify in the Dockerfile. The environment
command will override env_file
. You can use environment variable in compose with ${KEY_NAME}
syntax. I use local driver for pgdata volume because it’s more simple and easy to manage. My environment file looks like this
DB_HOST=
DB_PORT=
DB_USER=
DB_PASS=
DB_NAME=
JWT_SECRET=
JWT_EXPIRED=
MINIO_ENDPOINT=
MINIO_ACCESS_KEY=
MINIO_SECRET_KEY=
You can run your compose with docker-compose up
command and shut it down with docker-compose down
.
Conclusion
Docker Compose simplifies container management, streamlining deployment with a single YAML file. It ensures consistency across environments, facilitates collaboration, and accelerates development. Developers configure complex setups efficiently by defining services, networks, and volumes. The structure of compose consist different keywords to customize compose configuration. Examples like backend and database containers illustrate its versatility, allowing for smooth operation and easy replication of environments.
Recommended resources
- Docker Compose official documentation
- How to install Docker Compose
- What is Docker Compose? How to Use it with an Example
- The definitive Guide to Docker Compose
In this article, we’ve explored the power of Docker Compose in simplifying the deployment of complex applications. Stay tuned for our next article where we dive deeper into continuous integration and continuous deployment of Docker using Github Actions. Happy coding!