Working with Docker-Compose (Postgres)
Prerequisites - Docker (containers, images, docker commands) and Docker Run (will be helpful in mapping concepts to docker compose file).
Why Use Docker Compose?
Applications consist of various components, including APIs, databases, and other essential services. Additionally, there might be a microservices application, which is essentially an application divided into multiple microservices. When you containerize these microservices, it is crucial to deploy and operate all these diverse application elements together since they rely on each other. Docker Compose serves as a valuable tool for specifying and executing multiple services within a single environment. In essence, if you need to oversee multiple containers with distinct configurations, Docker Compose is the ideal solution.
Previously, we used docker run commands to create images, then create a network of those images and finally run those docker images. It was a repetitive process that was prone to errors.
It’s really simple. Go ahead and create a new file in the root directory of your project. Name it as docker-compose.yaml or docker-compose.yml(case sensitive)
For Postgres, paste the below (only the environments are different, this will be discussed later)
services: app: container_name: applicationcontainername build: context: . dockerfile: Dockerfile ports:
- "8080:8080" // same as server port environment:
- DB_HOST=databasecontainername
- DB_PORT=5432
- DB_USERNAME=
<db_username> - DB_PASSWORD=
<db_password>depends_on: - db db: image: postgres container_name: databasecontainername ports:
- "5432:5432" environment:
- POSTGRES_USER=
<db_username> - POSTGRES_PASSWORD=
<db_password>volumes: - ./postgres:/var/lib/postgres
Let's understand what's going on above.
Some points to note -
- Each service operates within its unique environment. To identify the specific environment variables required, refer to Docker Hub (navigate to the image you have pulled for detailed information).
- Experiment with the environment variables to gain a deeper understanding of their impact.
- Expand your knowledge of
.yamlfiles.
Running Docker commands individually may not be efficient in real-time scenarios where multiple services are operational. In such instances, creating images, networks, and executing them separately can be ineffective. Moreover, even if you opt for this approach, managing your application will pose significant challenges.
The above docker-compose.yml file defines two services: app and db. The app service is a custom application that depends on the db service, which is a MySQL/Postgres database. The file specifies how to build and configure these services, including port mappings, environment variables, and restart policies. The db service uses a volume to persist data.
Let's go through each component one by one -
services - This section lists all the services (containers) that will be run.
- app
- container_name:
applicationcontainername- Sets a custom name for the container running this service. - build:
- context:
.- Specifies the build context, which is the current directory.
- dockerfile:
Dockerfile- Specifies the Dockerfile to use for building the image.
- context:
- ports:
- "8080:8080"- Maps port 8080 on the host to port 8080 on the container. This means that the application will be accessible on port 8080 of the host machine (make sure to use the same port as the server port).
- environment: (for Postgres)
- DB_HOST=databasecontainername- Sets the environment variable
DB_HOSTtodatabasecontainername, which is the name of the database service.
- Sets the environment variable
- DB_PORT=5432- Sets the environment variable
DB_PORTto5432, the default PostgreSQL port.
- Sets the environment variable
- DB_USERNAME=<db_username>- Sets the environment variable
DB_USERNAMEto the database username (replace<db_username>with the actual username).
- Sets the environment variable
- DB_PASSWORD=<db_password>- Sets the environment variable
DB_PASSWORDto the database password (replace<db_password>with the actual password).
- Sets the environment variable
- restart:
always- Ensures that the container always restarts if it stops.
- depends_on:
- db- Specifies that the
appservice depends on thedbservice. Docker Compose will start thedbservice before theappservice.
- Specifies that the
- environment: (for Postgres)
- POSTGRES_USER=<db_username>- Sets the environment variable
POSTGRES_USERto the database username (replace<db_username>with the actual username).
- Sets the environment variable
- POSTGRES_PASSWORD=<db_password>- Sets the environment variable
POSTGRES_PASSWORDto the database password (replace<db_password>with the actual password).
- Sets the environment variable
- volumes:
- ./postgres:/var/lib/postgres- Mounts the
./postgresdirectory on the host to/var/lib/postgresin the container. This is where Postgres stores its data, allowing data to persist between container restarts.
- Mounts the
- container_name:
The network that we previously used to create and connect the services manually, now is made automatically by docker compose. We can also define the network by ourselves in the docker compose file.
Cool, now that you have grasped the inner workings, it's time to execute your containers by running compose up.
Go ahead on your terminal and write any one of the following commands
docker compose up
or
docker compose -f .\<project-directory-name>\docker-compose.yaml up -d
Go to Rancher Desktop. You will find your respective services running!!
Congratulations!! You have effectively transitioned from using individual docker commands to utilizing docker compose. To delve deeper into docker compose, check out the Ultimate Docker Compose Tutorial (youtube.com). Please feel free to make any necessary corrections or enhancements to this content.