Docker Compose
Managing all those commands for building images, running containers, and setting up host mappings can indeed be cumbersome. Fortunately, there's a more efficient solution โ Docker Compose. With just a single, straightforward command, Docker Compose empowers you to define and run your entire application effortlessly. It's a game-changer for simplifying the deployment process and orchestrating all the services your application needs in one go.
it's a tool that allows us to Define and manage multi-container Docker application
it uses a yaml file to configure the services networks and volumes for your application enabling us to run and scale the entire application with single command
with a single command we don't have to run 10 commands separately to run 10 containers for one application
Docker init
Using Docker init we initialize our application with all the files needed to dockerize it by specifying our Tech choices inside a yaml file.
docker compose up
command
The docker-compose up
command is used to start services defined in a docker-compose.yml
file. It orchestrates the creation and startup of all the services defined in the docker-compose.yml
configuration.
In windows: Need to run as administrator
In mac or linux:
sudo docker compose up
CONS
While Docker Compose greatly improves our development workflow by allowing us to manage multiple containers seamlessly and keeping our code changes up-to-date through volumes, there's still room for an even smoother developer experience. Whenever we tweak something in our package files, the need to manually rebuild and rerun the container can be a bit cumbersome. This is where Docker Compose Watch steps in, addressing this gap by automating the process of rebuilding images when necessary. It streamlines our development efforts, making the workflow more dynamic and efficient.
Docker Compose Watch
Docker compose watch listens to our changes and
Rebuilding our app
Re-running the container
sync operation moves changed files from our computer to the right places in the container making sure that everything stays up to date in real time
- working on any app because it lets us instantly see any changes we make while the app is running
Rebuild process starts with the creation of new container images and then it updates the services
- rolling out changes to applications in production guaranteeing the most recent version of code is operational
sync restart operation = sync + rebuild processes: It begins by syncing modifications from the host file system to The Container paths and then restarting the container
- This is beneficial during the development and testing of applications ensuring that the most recent code version is active with immediate reflection of changes in the running application
Done by defining the build section of .yaml file
Example compose.yaml File. with Watch
command: docker compose up
This create a "multi-container-application"
# specify the version of docker-compose
version: "3.8"
# define the services/containers to be run
services:
# define the frontend service
# we can use any name for the service. A standard naming convention is to use "web" for the frontend
web:
# we use depends_on to specify that service depends on another service
# in this case, we specify that the web depends on the api service
# this means that the api service will be started before the web service
depends_on:
- api
# specify the build context for the web service
# this is the directory where the Dockerfile for the web service is located
build: ./frontend
# specify the ports to expose for the web service
# the first number is the port on the host machine
# the second number is the port inside the container
ports:
- 5173:5173
# specify the environment variables for the web service
# these environment variables will be available inside the container
environment:
VITE_API_URL: http://localhost:8000
# this is for docker compose watch mode
# anything mentioned under develop will be watched for changes by docker compose watch and it will perform the action mentioned
develop:
# we specify the files to watch for changes
watch:
# it'll watch for changes in package.json and package-lock.json and rebuild the container if there are any changes
- path: ./frontend/package.json
action: rebuild
- path: ./frontend/package-lock.json
action: rebuild
# it'll watch for changes in the frontend directory and sync the changes with the container real time
- path: ./frontend
target: /app
action: sync
# (BACKEND) define the api service/container
api:
# api service depends on the db service so the db service will be started before the api service
depends_on:
- db
# specify the build context for the api service
build: ./backend
# specify the ports to expose for the api service
# the first number is the port on the host machine
# the second number is the port inside the container
ports:
- 8000:8000
# specify environment variables for the api service
# for demo purposes, we're using a local mongodb instance
environment:
DB_URL: mongodb://db/anime
# establish docker compose watch mode for the api service
develop:
# specify the files to watch for changes
watch:
# it'll watch for changes in package.json and package-lock.json and rebuild the container and image if there are any changes
- path: ./backend/package.json
action: rebuild
- path: ./backend/package-lock.json
action: rebuild
# it'll watch for changes in the backend directory and sync the changes with the container real time
- path: ./backend
target: /app
action: sync
# define the db service
db:
# specify the image to use for the db service from docker hub. If we have a custom image, we can specify that in this format
# In the above two services, we're using the build context to build the image for the service from the Dockerfile so we specify the image as "build: ./frontend" or "build: ./backend".
# but for the db service, we're using the image from docker hub so we specify the image as "image: mongo:latest"
# you can find the image name and tag for mongodb from docker hub here: https://hub.docker.com/_/mongo
image: mongo:latest
# specify the ports to expose for the db service
# generally, we do this in api service using mongodb atlas. But for demo purposes, we're using a local mongodb instance
# usually, mongodb runs on port 27017. So we're exposing the port 27017 on the host machine and mapping it to the port 27017 inside the container
ports:
- 27017:27017
# specify the volumes to mount for the db service
# we're mounting the volume named "anime" inside the container at /data/db directory
# this is done so that the data inside the mongodb container is persisted even if the container is stopped
volumes:
- anime:/data/db
# define the volumes to be used by the services
volumes:
anime:
To enable/update changes in app.:
Run below command in second terminal along with docker compose up
.
docker compose watch
with admin rights.