简体   繁体   中英

Run multiple Docker containers at once using docker-compose

The Problem

Currently I've created a Dockerfile and a docker-compose.yml to run my rest-api and database using docker-compose up .

What I want to do now is add another container, namely the web application (build with React). I'm a little bit confused on how to do that, since I just started learning Docker 2 days ago.

Folder Structure

This is my current folder structure

  • Folder: rest-api (NodeJS)
    • Dockerfile
    • dockercompose.yml

The Question

In the end I want to be able to run docker-compose up to fire up both the rest-api and the web-app .

Do I need to create a seperate Dockerfile in every folder and create a 'global' docker-compose.yml to link everything together?

New folder structure:

  • dockercompose.yml
  • Folder: rest-api (NodeJS)
    • Dockerfile
  • Folder: web-app (React)
    • Dockerfile

My current setup to run the rest-api and database

Dockerfile

FROM node:13.10

# The destination of the app in the container
WORKDIR /usr/src/app

# Moves the package.json, package-loc.json and tsconfig.json to the specified workdir
COPY package*.json ./
COPY tsconfig.json ./

# Create user and postgres
ENV POSTGRES_USER root
ENV POSTGRES_PASSWORD 12345
ENV POSTGRES_DB postgres
ENV POSTGRES_URI 'postgres://postgres:12345@postgres:5432/postgres'

RUN npm install

COPY . .

EXPOSE 3000

CMD ["npm", "start"]

docker-compose.yml

version: '3'
services:
  node:
    container_name: rest-api
    restart: always 
    build: . 
    environment:
      PORT: 3000
    ports:
      - '80:3000'
    links:
      - postgres
  postgres:
    container_name: postgres-database
    image: postgres
    environment:
      POSTGRES_URI: 'postgres://postgres:12345@postgres-database:5432/postgres'
      POSTGRES_PASSWORD: 12345 
    ports:
      - '5432:5432'

Ok - so there are quite a few ways to approach this and it is pretty much more or less based on your preferance.

If you want to go with your proposed folder structure (which is fine), the you can for example do it like so:

Have a Dockerfile in the root of each of your applications which will build the specific application (as you already suggested) place your docker-compose.yml file in the parent folder of both applications (exactly as you proposed already) and then just make some changes to your docker-compose.yml (I only left the essential parts. Note that links are no longer necessary - the internal networking will resolve the service names to the corresponding service IP address)

version: '3'
services:
  node:
    build:
      context: rest-api
    environment:
      PORT: 3000
    ports:
      - '3000:3000'
  web:
    image: web-app
    build:
      context: web-app
    ports:
      - 80:80
  postgres:
    image: postgres
    environment:
      POSTGRES_URI: 'postgres://postgres:12345@postgres-database:5432/postgres'
      POSTGRES_PASSWORD: 12345 
    ports:
      - '5432:5432'

So the context is what tells docker that what you are building is actually in a different directory and all of the commands executed in the Dockerfile will be relative to that folder

I also changed the port mappings, cause you probably will want to access your web app via HTTP port. Note that the web-app will be able to communicate with the rest-api container by using the node hostname as long as the node service is binding to 0.0.0.0:3000 (not 127.0.0.1:3000)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM