docker compose는 다중 컨테이너 도커 애플리케이션을 정의하고 실행하기 위한 도구이다.
왜 필요한지 살펴보자.
nodejs + redis
를 사용해 어플리케이션을 만들고 싶다.
컨테이너 구조는 다음과 같다.
const express = require("express");
const redis = require("redis");
const client = redis.createClient({
socket: {
host: "redis-server",
port: 6379,
},
});
const app = express();
app.get("/", async (req, res) => {
await client.connect();
let number = await client.get("number");
if (number === null) {
number = 0;
}
res.send("숫자가 1씩 올라갑니다. 숫자: " + number);
await client.set("number", parseInt(number) + 1);
await client.disconnect();
});
app.listen(8080);
console.log("Server is running");
원래 레디스 클라이언트를 생성 시에 이렇게 사용하면 되는데
const client = redis.createClient({
host: "https://jjae.com",
port: 6397
});
docker compose를 사용할 때는 host 옵션을 docker-compose.yml
파일에 명시한 컨테이너 이름으로 줘야한다.
const client = redis.createClient({
host: "redis-server",
port: 6397
});
FROM node:14
WORKDIR /usr/src/app
COPY ./ ./
RUN npm install
CMD ["node", "server.js"]
레디스 클라이언트가 작동하기 위해서는 레디스 서버가 켜져있어야 하기 때문에 먼저 레디스 서버를 위한 컨테이너를 실행하고 노드 js를 위한 컨테이너를 실행할 예정이다.
먼저 레디스 서버를 켜보자.
docker run redis
이미지를 생성하고 컨테이너를 실행해보자.
docker build ./ -t <아이디>/<이미지_이름>
docker run <아이디>/<이미지_이름>
실행해보면 Redis connection to redis-server:6397
이 뜬다. 왜죠??
서로 다른 컨테이너에 있는데 컨테이너 사이에 아무런 설정이 없어 노드js 앱에서 레디스 서버에 접근할 수 없는 것이다! 그래서 오류가 뜬다.
멀티 컨테이너 상황에서 네트워크를 연결시켜 주기 위해 Docker compose를 사용하는 것이다!!!!
위의 문제를 해결하기 위해 이런 식으로 만들어야한다.
version: "3"
services:
redis-server:
image: "redis"
node-app:
build: .
ports:
- "5000:8080"
각각이 무엇을 뜻하는지 살펴보자.
version
: 도커 컴포즈의 버전services
: 이곳에 실행하려는 컨테이너들 정의redis-server
: 컨테이너 이름image
: 컨테이너에서 사용하는 이미지node-app
: 컨테이너 이름build
: 현 디렉토리에 있는 Dockerfile 사용ports
: 포트 맵핑 로컬포트:컨테이너포트도커 컴포즈를 이용해 앱을 실행해보자!
docker-compose up --build -d
--build
를 주면 이미지가 있든 없든 이미지를 빌드하고 컨테이너를 시작한다.
-d
를 주면 백그라운드에서 돌게 해서 터미널을 계속 쓸 수 있다.
잘 돌아간다!!!!
도커 컴포즈를 통해 작동시킨 컨테이너들을 한꺼번에 중단시키려면
docker compose down