DevOps Training
  • DevOps
  • What is DevOps
    • What DevOps Look like
    • Why DevOps Needed
    • DevOps Automation Tools
    • DevOps Principles
  • cloud computing
    • How DevOps links with Cloud Computing
    • What is cloud computing?
      • Platform as a service (PaaS)
      • Infrastructure as a service (IaaS)
      • Software as a service (SaaS)
      • Function as a Service
      • SaaS, PaaS, IaaS
  • Version Control
    • Git as Version Control
      • Setting up Remote Repo
      • Git Hooks
      • github vs gitlab vs bitbucket
      • Quick Recap Git
  • DevOps #01 Continuous Integration
    • Continuous Integration & Continuous Delivery
      • Understanding CI Tools
      • Prerequisite
      • Continuous Integration
      • CI Tools
      • Travis-CI
        • Travis CI with S3
        • Static Site Build S3
        • Beanstalk with AWS CLI
          • Elastic Beanstalk with Travis CI
        • Travis using Code Deploy EC2
          • Github and Code Deploy
          • Travis CI with Code Deploy
      • Gitlab-CI
        • CI Setup for application
        • Gitlab Runners on EC2
        • CI Integration with AWS
          • Deploying App using Gitlab CI
          • Gitlab CI with AWS S3
          • Gitlab CI with ECS
          • CI Integration with EC2
            • Update and Clean Gitlab.yml
        • Install Gitlab on EC2
      • CI/CD using Jenkins CI
        • Jenkins Build on EC2
        • Jenkins Build EC2 Ubuntu
        • Jenkins CI/CD
          • Create a Build Item
          • Create a Build Pipleine
            • Pipeline Using Docker
            • Pipeline Examples
          • Jenkins CI with S3
            • Jenkins CI - S3
          • Jenkins CI with EC2
    • Jenkins CI Cluster Mode
    • AWS Code Pipeline CI/CD
      • AWS CI/CD Tools
        • AWS Code Build
        • AWS Code Deploy to Beanstalk
        • AWS Code Deploy to EC2
        • AWS Pipeline - Example CI/CD
  • Docker
    • Docker
      • Docker for Developers
        • Install and setup
        • Docker Commands
        • Docker Images Container
        • Docker Architecture
    • Docker Demos
      • Node JS Container
    • Docker-compose
      • Using Docker Compose
      • Docker Compose Demo
  • AWS Quick Refresh
    • AWS Quick Recap - Videos
    • AWS Quick Recap
  • AWS Architecture - Lab
    • Application Deployment - 01
    • Application Deployment - 02
    • Application 3 tier Architecture
  • Basic Networking
    • Computer Networking for Beginners
      • Basic of Networking
      • Networking Protocols
      • OSI Model
      • Network address and Host address
      • Subnetting Type
    • Network Architecture
    • Networking Layers OSI Model
    • Internet protocol
      • CIDR and subnetting
        • Examples
      • AWS VPC Subnets
  • VPC and Networking
    • AWS VPC
    • VPC Demo
      • Bastion Host | Jump Server
  • AWS Components
    • AWS Components In Depth
      • AWS Storage
        • AWS EBS
        • AWS Cloudfront
        • AWS S3
      • AWS Compute
        • ECS
        • AWS VPC
          • VPC Components
        • AWS EC2
        • AWS ELB
          • Application Load balancer
            • Example
        • AWS EC2 Auto Scaling
          • Demo
        • AWS Route 53
        • AWS Lambda Serverless
          • AWS Lambda Serverless Computing
  • Assignments
    • Assignment 01-Node JS app on EC2
    • Assignment 02-Node JS with Mysql
    • Assignment-03
  • Microservices
    • Microservices Architecture
      • Docker and Docker-Compose
      • Docker-Compose Example 01
      • Docker-Compose Example 02
      • Hand-on | Building Microservices
    • Architecture Components
  • AWS ECS
    • AWS ECS
      • Introduction of ECS
Powered by GitBook
On this page
  • What is Docker Compose?
  • How to Docker Compose?
  • Docker Compose Commands
  • Docker Compose Examples
  • Example - 01
  • Example -2

Was this helpful?

  1. Docker
  2. Docker-compose

Using Docker Compose

PreviousDocker-composeNextDocker Compose Demo

Last updated 5 years ago

Was this helpful?

What is Docker Compose?

Essentially, what Docker Compose is, is a recipe card — it’s a recipe of services that make up an application and the docker-compose.yml dictates how the services are mixed together.

In more technical terms:

Docker-Compose defines a complete system where services can communicate with each other on an isolated network, interacting with external resources as defined by the user.

Docker Compose is built on top of the Docker Engine, the very same engine that runs the Dockerfiles and Docker CLI, but the most important aspect to keep in mind about Compose is to think of it like a recipe.

The image below, illustrates it pretty well.

Above is what a Docker Compose environment looks like when running. Application A is a backend micro service that can freely communicate with App B and App C but that is all, it cannot communicate with the host in the outside world at all. This is because of how its docker-compose.yml is set up, I’ll show that next.

Application B is a database, it has been structured in the docker-compose.yml with an externally mounted volume volumes: — opt/app:/opt/appB/app that allows it to write a persistent data layer to the outside world. With this data layer in the application, even if the entire Docker environment is destroyed for some reason, when it’s brought back up, the database will see the data written to it before, and replace it so you can begin where you were before.

And that’s what the environment looks like. This is a pretty simple representation, but it can be that simple, or it can be much more complex depending on your needs. Now, let’s look at what a Docker Compose YAML file looks like and go through some of the nuances that can come with it.

How to Docker Compose?

The last big question is: how to write a docker-compose.yml, and it’s actually very easy and follows a standard formula.

Here is a template of what any docker-compose.yml will look like.

  • Sample Docker Compose Template

Every docker-compose file will start with a minimum of version: "2", if you’re doing a Docker Swarm file it will need version: "3", but for a single docker-compose.yml, you’ll need v2.

Next, you will list all your services (each app running in the docker-composewill have its own name, and you’ll need to provide either a build or an image from the Docker registry. You cannot have both.

  • A custom Docker image will be built based on the Dockerfile provided by the build path OR

  • Docker hub will supply all the necessary commands and setup to make the image build and run successfully.

Underneath that, environment variables are set, ports are exposed, and external volumes are mounted. All these same things could be done with the Docker CLI, but this is a cleaner, easier to read file that doesn’t require remembering (and correctly typing) them all when executing commands in the terminal.

Here is what a sample docker-compose.yml could look like.

  • Sample Docker Compose Yaml

This docker-compose.yml begins with version: "2" (as required for Docker Compose), and then we have three services listed below: appA, appB, appC. Since appA is the UI that is built from a custom Dockerfile and needs to be exposed to the host machine, it has a build: path to said Dockerfile and a ports: that maps the internally running port of the UI, port 80 to the same port on the host machine, also 80.

appB is a mongo database, so it can be pulled down from the Docker registry when it’s time to start up the application. There’s no build to be done ahead of time, nothing but declaring the image, and for data persistence adding a volumes: specification of where database data can be persisted to the host machine and it’s good to go.

And appC is also a custom Docker image, so it has a build: path to its own Dockerfile, an environment: variable specifying a configuration file for the backend, and not one but two instances:. This application in particular can have two instances because it is not being exposed in any way to the host machine. If a port was being opened (or it was some type of database), it would only be able to have one instance to avoid port collisions on the host or to avoid writing to two separate databases within the Docker environment. But since this is purely a backend service, it can have as many instances as necessary (good for load balancing heavy volumes of traffic), and all of them can run as separate containers within the Docker environment and communicate with each other as needed.

Ok, the docker-compose.yml has been written, let’s look at the Docker Compose commands needed to get this system up and running. Don’t worry, they’re not very complicated.

Docker Compose Commands

Before I go any further, I must issue the following disclaimer.

DISCLAIMER: For the purposes of this blog post, it will be assumed all docker-compose commands will be executed in the same directory as the docker-compose.yml. Yes, it is possible to execute the commands from different levels of the directory, but that is outside of the scope of this blog about Docker Compose.

Now that that’s been made clear, I can continue. There’s just a handful of Docker commands you’ll need to type in to the terminal to get these magical files to do their thing. And after I’ve described them, I’ve provided another handy graphic that illustrates the three different phases a Docker Compose environment can exist in.

  • docker-compose ps — lists all the services in a network. This is especially helpful when troubleshooting a service as it will give you the container ID and you can then run docker -it exec <ID> bash to enter the container and debug as needed.

  • docker-compose build — generates any needed images from custom Dockerfiles. It will not pull images from the Docker hub, only generate custom images.

  • docker-compose up — brings up the network for the services to run in

  • docker-compose stop — stops the network and saves the state of all the services

  • docker-compose start — restarts the services and brings them back up with the state they had when they were stopped

  • docker-compose down — burns the entire Docker network with fire. The network and all the services contained within are totally destroyed.

Here’s the various states the Docker Compose environment exists in, depending on what commands you’ve run.

docker-compose build and docker-compose down mean the Docker environment is not running, and the network does not exist.

docker-compose up and docker-compose start means the Docker environment is running, and the network does exist.

docker-compose stop means the Docker environment is not running, but the network still does exist.

That’s it. All the commands you’ll need with your docker-compose.yml to build and run all your connected microservices.

Docker Compose Examples

Example - 01

Without docker compose , we will build image from docker file and run it

FROM node:carbon

# create the app directory for inside the Docker image
WORKDIR /usr/src/app

# install app dependencies from the package.json (and the package-lock.json)
COPY package*.json ./

RUN npm install

# bundle app source inside Docker image
COPY . .

# expose port 8080 to have it mapped by Docker daemon
EXPOSE 8080

# define the command to run the app (it's the npm start script from the package.json)
# npm start
CMD [ "npm", "start" ]

Example -2

Our basic docker-compose file to spin Node js and java container

version: "3"

services:
  java-example:
    build: java-example/
    ports:
      - 3001:8080
  node-example:
    build: node-example/
    ports:
      - 3002:8080

Example -3

version: "3"

services:
  web:
    image: nginx
    volumes:
     - ./nginx/localhost.conf:/etc/nginx/conf.d/localhost.conf
    ports:
     - "80:80"
    environment:
     - NGINX_HOST=localhost
     - NGINX_PORT=80
    command: /bin/bash -c "envsubst < /etc/nginx/conf.d/localhost.conf > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
    depends_on:
      - java-example
      - node-example
  java-example:
    build: java-example/
  node-example:
    build: node-example/

Finally, Application C is the user interface portion of the app. Also, due to the docker-compose.yml, this application can talk to the host machine on a port that’s been exposed: ports="8080:8080". This means, a user can open up on their machine and access the running application.

I recommend reading the for more examples and descriptions of all the things you can do with within a docker-compose.yml.

Go to

Go to

And go to

Go to

And go to

http://localhost:8080
Docker Compose documentation
http://localhost:3003
http://localhost:3001
http://localhost:3002
http://localhost/java/
http://localhost/node
LogoGitHub - kumartarun/docker-compose-example: Sample apps using docker-compose.ymls in a variety of waysGitHub