Build images and run them with docker compose 
Tags: docker, beginners, tutorial, express
Published: 2020-09-21 19:30:18

In the [previous post](https://dev.to/tirthaguha/routing-requests-to-containers-with-nginx-49pn), we saw how we can run more than one containers and how to route requests to them using nginx. 

Of course, we had to build 3 images individually, and then run the three images in sequence to get the final ecosystem.

In this post, we'll try to combine all the steps in just one command using docker-compose.

We'll start with the same repo, where the previous post's code is checked in, clone it locally, and then setup the docker-compose yml file, and run it.

## Step 1. Clone the codebase. 
Clone the repo https://github.com/tirthaguha/container-reverse-proxy.

## Step 2. Create the YML file

### Network Drivers
Okay, so before we create the docker-compose.yml file, its important to understand how networking works in docker-compose.
Docker can create a virtual network for you to abstract the complexities of networking, and all your containers run and interact in that network. One interesting thing about this virtual network is the network driver. Based on your container ecosystem setup, the drivers can be *bridge, overlay* and *macvlan*. 
In our case, since we're going to run all the containers in the same host, we're going to **chose bridge network driver** in our docker compose file. You may have a look into this [article](https://www.docker.com/blog/understanding-docker-networking-drivers-use-cases/) and learn more about docker networks

### Create the docker compose file
docker-compose.yml is a file that contains all the information about the applications, their Dockerfiles and the network they are going to run in.

Here's our annotated docker-compose.yml that you need to put in your `container-reverse-proxy` directory.

```docker
version: "3"

# start by defining the services
services:
  # this is the first nodeJS application
  nodejs_1:
    # lets keep name of the image as first-app
    image: first-app
    # this is where the Dockerfile is compiled into an image
    build:
      # where is the Dockerfile kept, relative to this directory
      context: ./first-app
      # obviously, the Dockerfile in that directory
      dockerfile: Dockerfile
    # port mapping
    ports:
      - 3000:3000
    # name of the container
    container_name: first-app
    # if the container crashes, it would be restarted automatically
    restart: unless-stopped
    # the virtual network of which this container will be a part of
    networks:
      - app-network

  # this is the second nodeJS application
  nodejs_2:
    # lets keep name of the image as first-app
    image: second-app
    build:
      # where is the Dockerfile kept, relative to this directory
      context: ./second-app
      dockerfile: Dockerfile
    ports:
      - 4000:4000
    container_name: second-app
    restart: unless-stopped
    networks:
      - app-network

  # Finally, the nginx, that controlls the route
  nginx-server:
    image: nginx-load-balancer
    build:
      context: ./nginx
      dockerfile: Dockerfile
    ports:
      - 8080:80
    container_name: nginx-load-balancer
    restart: unless-stopped
    networks:
      - app-network
      
# the mysterious item, network
networks:
  app-network:
    driver: bridge
```

## Step 3. Run the docker-compose file

Just run
```bash
$ sudo docker-compose up -d
```
then go to your browser and try opening the following URLs
* http://localhost:8000/app-second
* http://localhost:8000/app-first