🎄

Docker Basic

title
Docker Compose 알아보기
created_at
Oct 23, 2024 05:10 AM
tag
docker
infra
날짜

1. 노드 애플리케이션 도커 이미지 만들기

노드 애플리케이션 생성

  • 적당한 디렉토리를 생성해 노드 패키지를 설정
    • npm init pnpm init
  • package.json 파일에 스크립트 추가
    • "start": "node index.js"
  • express 애플리케이션 만들기
    • express 모듈 설치 이후
const express = require("express"); const app = express(); const PORT = 8080; app.get("/", (req, res) => { res.send("Hello World"); }); app.listen(PORT, () => { console.log(`Server is running on port ${PORT}`); });

도커파일 작성하기

FROM node:20-alpine RUN npm install -g pnpm RUN pnpm install CMD ["pnpm", "start"]
  • 다음과 같이 도커파일 작성 시, 실행 환경에 package.json 을 찾을 수 없다는 에러 발생
    • 노드앱 파일스냅샷에 package.json 이 존재하지 않기 때문에 컨테이너 환경에서 확인 ❌
  • 마찬가지로 index.js 파일도 찾을 수 없다는 에러 발생
  • 해결방법 : 파일스냅샷에 pacakge.json 파일을 복사
FROM node:20-alpine COPY ./ ./ RUN npm install -g pnpm RUN pnpm install CMD ["pnpm", "start"]
  • 도커 이미지화 : docker build ./
    • 태그 추가: docker build -t yeongsan/test ./
  • 도커 실행 : docker run -it yeongsan/test
위 과정을 진행 후 브라우저에서 http://localhost:8080 으로 접근해보면 접근이 불가한 것을 확인 할 수 있다.

생성한 도커이미지로 애플리케이션 접근하기

  • 로컬 네트워크와 컨테이너 네트워크를 연결시켜주는 작업이 필요
  • 포트 맵핑 : docker run -p 5000:8080 yeongsan/test
    • 컨테이너 네트워크 8080포트를 로컬 네트워크 5000 포트로 매핑시켜 이미지를 실행하겠다

Working Directory 설정하기

  • Working Directory : 이미지 안에서 애플리케이션 소스 코드를 보유할 디렉토리
  • Working Directory 설정하기 전 파일시스템 조회
    • docker run -it yeongsan/test ls
      • 스냅샷의 루트 경로 파일들과 애플리케이션 내부의 파일 이름이 중복될 경우 파일 삭제될 우려
  • Working Directory 설정
    • docker build -t yeongsa/test ls
    • 이전과 달리 루트 디렉토리에 프로젝트 파일을 복사하지 않은 것을 확인
FROM node:20-alpine WORKDIR /user/src/app COPY ./ ./ RUN npm install -g pnpm RUN pnpm install CMD ["pnpm", "start"]

소스코드 수정 시 도커 재빌드 효율적으로 하기

  • 현재까지 도커 컨테이너 애플리케이션 실행 흐름
    • 소스코드 수정 → docker build . → 도커 이미지 생성 → docker run → 컨테이너 생성 후 앱 실행
  • detect 모드로 실행 : docker run -d -p 5000:8080 yeongsan/test
비효율성
  • 도커파일에서 프로젝트 전체 파일을 복사하기 때문에, 이미지 빌드시 매번 node_modules의 종속성을 반복해서 설치
  • 소스코드만 수정해도 종속성 설치
비효율성 개선하기
  • 종속성 설치 이후에 모든 파일을 복사하는 방식으로 Dockerfile 수정
    • 소스 코드에만 변화가 있을때는 종속성 설치 ❌
FROM node:20-alpine WORKDIR /user/src/app COPY package.json ./ RUN npm install -g pnpm RUN pnpm install COPY ./ ./ CMD ["pnpm", "start"]

도커 볼륨을 이용해 파일 참조하기

  • 도커 볼륨을 이용하면 파일을 참조하기 때문에 소스코드의 변화를 감지해
    • 도커 이미지 빌드를 반복하지 않아도 된다
  • docker run -p 5000:8080 -v /usr/src/app/node_modules -v$(pwd):/usr/src/app yeongsan/test
      1. 호스트(도커) 디렉토리에 node_modules 존재하지 않기에 컨테이너에 맵핑하지 말라는 의미
      1. pwd 경로에 있는 디렉토리 or 파일을 /usr/src/app 경로에서 참조하라는 의미

Docker Compose 알아보기

Docker Compose란
  • 다중 컨테이너 애플리케이션을 정의하고 실행하기 위한 도구

노드 애플리케이션 + 레디스 실행하기

  • Redis(REmote Dictionary Server) : 메모리 기반 key-value 구조 데이터 저장소
    • 데이터를 메모리에 저장해 빠르게 조회 가능한 비관계형 데이터베이스(NoSQL)
    • MySQL과 같은 데이터베이스와 비교해 조회 속도가 월등하며, 데이터를 영속적으로 보관이 가능해 데이터 유지가 가능하다는 장점이 있다.
서버코드 작성
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 count = await client.get("count"); if (!count) count = 0; console.log("Count: " + count); res.send("새로고침 시 카운트가 1씩 올라갑니다. 카운트: " + count); await client.set("count", parseInt(count) + 1); await client.disconnect(); }); app.listen(8080, () => { console.log("Server is running on port 8080"); });
Dockerfile 작성
FROM node:20-alpine WORKDIR /usr/src/app COPY ./ ./ RUN npm install -g pnpm RUN pnpm install CMD ["pnpm", "start"]
  • 해당 도커 파일 기반으로 도커 실행시 연결할 레디스 서버를 찾을 수 없다는 에러 발생
docker compose 파일 작성하기
  • 컨테이너 간 설정 필요
# docker-compose.yml services: redis-server: image: redis # 레디스 이미지 파일 사용 node-app: build: . ports: - 5000:8080 # 포트맵핑 depends_on: - redis-server # redis-server와 의존 관계 명시
  • docker compose up
docker compose 컨테이너 정지시키기
  • docker compose down
docker compose up with build option
  • docker compose up : 이미지가 없을때 이미지를 빌드하고 컨테이너 시작
  • docker compose up —build : 이미지가 있든 없든 이미지를 빌드하고 컨테이너 시작