Beginner's guide to Docker(Part 1)- Dockerfile and Docker CLI commands
Parvathi ・ Sep 27 '21 ・ 8 min read
Beginner's Guide to Docker(Part 2)- Manage data in Docker
Parvathi ・ Sep 29 '21 ・ 5 min read
Beginner's Guide to Docker (Part 3) - Communication & Network
Parvathi ・ Oct 8 '21 ・ 2 min read
We have learned above topics by taking todo-app as an example, which involves frontend(react), backend(node) and DB(mongo). So far we did everything manually, building images, creating the containers, attaching storage to the container, creating network for container communication, etc... this seems to be a lot of work...Right??? What could be the solution? Yes, Docker Compose!!!
Reference
Docker Compose
Docker Compose is a tool that was developed to help define and share multi-container applications. With Compose, we can create a YAML file to define the services and with a single command, can spin everything up or tear it all down.
The big advantage of using Compose is you can define your application stack in a file, keep it at the root of your project repo (it’s now version controlled), and easily enable someone else to contribute to your project. Someone would only need to clone your repo and start the compose app. In fact, you might see quite a few projects on GitHub/GitLab doing exactly this now.
If you installed Docker Desktop/Toolbox for either Windows or Mac, you already have Docker Compose! In Linux, we need to install manually.
Writing a compose file
At the root of the app project, create a file named docker-compose.yml.
In the compose file, we’ll start off by defining the schema version. It’s best to use the latest supported version. Next, we’ll define the list of services (or containers) we want to run as part of our application. Compose file reference
Service
Let's see how we can move one service to docker compose file.
docker run
--name todo-node
-p 3030:3030
--rm
--network todo-app
-e MONGO_HOST=mongodb
-v /Users/xyz/Documents/dockerExamples/todo-app/todo-backend:/app
-v /app/modules
todo-node
version: '3.8'
services:
backend:
build: ./todo-backend
ports:
- '3030:3030' #host:container
volumes:
- ./todo-backend:/app
- /app/node_modules
env_file:
- ./env/node.env
depends_on:
- mongodb
Manual commands
Creating network for mongo and node to share
docker network create todo-app
Creating mongo container
docker run
--name mongodb
--rm
-d
--network todo-app
-v data:/data/db
-e MONGO_INITDB_ROOT_USERNAME=root -e MONGO_INITDB_ROOT_PASSWORD=password
mongo
Frontend
docker build -t todo-react .
docker run
--name todo-react
--rm
-p 3000:3000
-v /Users/xyz/Documents/dockerExamples/todo-app/todo-frontend/src:/app/src
-v /app/node_modules
todo-react
Backend
docker build -t todo-react .
docker run
--name todo-node
-p 3030:3030
--rm
--network todo-app
-e MONGO_HOST=mongodb
-v /Users/xyz/Documents/dockerExamples/todo-app/todo-backend:/app
-v /app/modules
todo-node
Docker compose file
This is how the docker compose file will look like for the above commands
version: '3.8'
services:
mongodb: #name of the service
image: 'mongo' #Use existing image
volumes:
- data:/data/db
restart: always
# environment:
# MONGO_INITDB_ROOT_USERNAME: root
# MONGO_INITDB_ROOT_PASSWORD: password
env_file:
- ./env/mongo.env
ports:
- '27017:27017'
container_name: mongodb # optional
# networks:
# - todo-network
backend:
build: ./todo-backend #if dockerfile path is straightforward we can use this
# build:
# context: ./todo-backend
# dockererfile: Dockerfile - docker file name inside the path
# args:
# some-args: 1
ports:
- '3030:3030' #host:container
volumes:
- ./todo-backend:/app #bind mount - live source code change for development purpose
- /app/node_modules
env_file:
- ./env/node.env
depends_on:
- mongodb
frontend:
build: ./todo-frontend
ports:
- '3000:3000'
volumes:
- /app/node_modules
- ./todo-frontend:/app
stdin_open: true #to run in interactive mode
tty: true #to run in interactive mode
depends_on:
- mongodb
- backend
volumes: #specify all named volumes that are used
data:
Note - We don't have to explicitly create a network while working with docker compose. By default, it automatically creates a network specifically for the application stack.
Run the application stack
Now that we have our docker-compose.yml file, we can start it up!
Start up the application stack using the docker-compose up command. We’ll add the -d flag to run everything in the background.
docker-compose up -d
We shall look at logs using
docker-compose logs -f
You’ll see the logs from each of the services interleaved into a single stream. This is incredibly useful when you want to watch for timing-related issues. The -f flag “follows” the log, so will give you live output as it’s generated.
If you want to view the logs for a specific service, you can add the service name to the end of the logs command
docker-compose logs -f frontend
Hola, Our application is up and running!!!
In order to bring down our application stack
docker-compose down
By default, named volumes in your compose file are NOT removed when running docker-compose down. If you want to remove the volumes, you will need to add the --volumes flag.
Hope, this gave you a basic understanding about docker compose.
Thanks for reading!
Top comments (0)