GitHub

도커 컴포즈로 실제 서비스 리팩토링해보기 (feat. YAML & dockerfile 작성) : docker-compose

hojun lee · 12/04/2024
커버이미지
DOCKERTEST/
├── compose.yaml
├── apps/
│   ├── admin/
│   └── user/
└── packages/
    ├── utils/
    ├── ui/
    └── database/

실제로 컨테이너 2개를 운용할 예정입니다. 스벨트를 활용한 admin / user 앱입니다.

Docker Compose를 사용하여 여러 애플리케이션과 패키지를 효율적으로 관리하는 방법에 대해 알아보겠습니다. 프로젝트 구조는 다음과 같이 설정되어 있습니다. 최상단에는 compose.yaml 파일이 위치하고, apps 디렉토리에는 사용자 애플리케이션(user)과 관리 애플리케이션(admin)이 포함되어 있습니다. 또한, packages 디렉토리에는 공통적으로 사용할 수 있는 유틸리티(utils), 사용자 인터페이스(ui), 그리고 데이터베이스 관련 패키지(database)가 위치하고 있습니다.

이 구조는 모듈화된 접근 방식을 통해 코드의 재사용성을 높이고, 각 애플리케이션의 독립성을 유지하면서도 필요한 경우 쉽게 통합할 수 있도록 설계되었습니다. 이제, 이 프로젝트를 Docker Compose를 통해 어떻게 구성하고 실행할 수 있는지 단계별로 살펴보겠습니다. Docker Compose를 사용하면 여러 서비스의 설정을 간편하게 관리할 수 있고, 개발 및 배포 과정에서 일관성을 유지할 수 있습니다.

이제 본격적으로 Docker Compose의 설정 방법에 대해 알아보겠습니다!

docker compose : 도커컴포즈

Docker Compose는 여러 개의 Docker 컨테이너를 정의하고 실행할 수 있는 도구입니다. 이를 통해 복잡한 애플리케이션을 더욱 쉽게 관리할 수 있습니다. Docker Compose를 사용하면 YAML 파일을 통해 서비스, 네트워크, 볼륨 등을 정의하고, 단일 명령어로 모든 서비스를 시작하거나 중지할 수 있습니다.

주요 구성 요소

서비스: 애플리케이션의 각 구성 요소를 나타냅니다. 예를 들어, 웹 애플리케이션, 데이터베이스, 캐시 등의 서비스가 있을 수 있습니다. 네트워크: 컨테이너 간의 통신을 위한 네트워크를 설정합니다. 볼륨: 데이터 지속성을 위해 사용됩니다. 컨테이너가 삭제되더라도 데이터는 유지됩니다.

compose.yaml 작성

compose.yaml 파일은 Docker Compose를 사용하여 여러 컨테이너 서비스를 정의하는 데 사용되는 설정 파일입니다. 이 파일을 통해 애플리케이션의 서비스, 네트워크, 볼륨 등을 구성할 수 있습니다. 아래에서는 compose.yaml의 기본 구조와 각 요소의 의미를 설명하겠습니다.

services:
admin:
  build:
    context: .  # 빌드 컨텍스트가 현재 디렉토리임을 명시합니다.
    dockerfile: ./apps/admin/Dockerfile  # 사용할 Dockerfile의 경로입니다.
  ports:
    - '5173:5173'  # 호스트의 5173 포트를 컨테이너의 5173 포트와 매핑합니다.
  environment:
    - NODE_ENV=development  # 컨테이너에서 사용할 환경 변수를 설정합니다.
  env_file:
    - ./.env  # 환경 변수를 정의한 파일을 지정합니다.

user:
  build:
    context: .  # 빌드 컨텍스트가 현재 디렉토리입니다.
    dockerfile: ./apps/user/Dockerfile  # 사용할 Dockerfile의 경로입니다.
  # volumes:  # 주석 처리된 볼륨 매핑입니다.
  #   - ./packages/utils:/app/packages/utils  # 호스트의 utils 디렉토리를 컨테이너에 매핑합니다.
  #   - ./packages/ui:/app/packages/ui  # 호스트의 ui 디렉토리를 컨테이너에 매핑합니다.
  #   - ./packages/database:/app/packages/database  # 호스트의 database 디렉토리를 컨테이너에 매핑합니다.
  ports:
    - '6001:5174'  # 호스트의 6001 포트를 컨테이너의 5174 포트와 매핑합니다.
  environment:
    - NODE_ENV=development  # 컨테이너에서 사용할 환경 변수를 설정합니다.
  env_file:
    - ./.env  # 환경 변수를 정의한 파일을 지정합니다.

vesion은 안써도 된다고 합니다.

나는 최상단에서 빌드 컨텍스트를 활용할 것이다. 그래야 packages의 파일을 이용할 수 있다. 근데 admin은 apps/admin && user는 apps/user에서 dockerfile을 실행할거임 그래야 컨테이너를 따로따로 띄우지. 근데 env file은 최상단에 공유할 것임

ports 같은 경우는 5173으로 받아서 5173으로 내보내도 되고 6001번으로 내보내도 될 수 있도록 조작할 수 있음!

dockerfile 작성

Dockerfile은 애플리케이션을 컨테이너화하기 위해 필요한 모든 명령어를 포함하는 텍스트 파일입니다. Dockerfile을 기반으로 Docker 이미지를 빌드하며, 이 이미지는 최종적으로 컨테이너에서 실행됩니다. Dockerfile은 각 단계에서 필요한 소프트웨어 설치, 파일 복사, 환경 설정 등을 정의합니다.

  1   
  2   # user/Dockerfile
  3   
  4   FROM node:20  # Node.js 20 버전을 기반 이미지로 사용
  5   
  6   # pnpm 설치
  7   RUN npm install -g pnpm  # pnpm 패키지 매니저를 글로벌로 설치
  8   
  9   WORKDIR /app  # 작업 디렉토리를 /app으로 설정
  10  
  11   # 최상단의 package.json과 pnpm-lock.yaml 파일 복사
  12   COPY packages ./packages/  # packages 디렉토리를 컨테이너의 /app/packages에 복사
  13   COPY pnpm-workspace.yaml ./  # pnpm-workspace.yaml 파일을 현재 작업 디렉토리로 복사
  14   COPY apps/user ./apps/user  # user 애플리케이션 디렉토리를 컨테이너로 복사
  15   # COPY apps/user/package.json apps/user/pnpm-lock.yaml ./apps/user/  # 주석 처리된 줄
  16   
  17   # user/ packages/database & utils의 의존성만 설치
  18   RUN pnpm install --filter ./apps/user... --filter ./packages/database... --filter ./packages/utils...  # 필요한 패키지 설치
  19   
  20   WORKDIR /app/packages/database  # 작업 디렉토리를 /app/packages/database로 변경
  21   RUN npx prisma generate  # Prisma 스키마를 기반으로 클라이언트를 생성
  22   
  23   # 작업 디렉토리를 apps/user로 변경
  24   WORKDIR /app/apps/user  # 작업 디렉토리를 /app/apps/user로 변경
  25   
  26   # 포트 설정
  27   EXPOSE 5174  # 컨테이너의 5174 포트를 외부에 노출
  28   
  29   # 애플리케이션 실행
  30   CMD ["pnpm", "run", "dev"]  # pnpm을 사용하여 개발 서버 실행

도커파일 설명

docker compose / dokcerfile 도커 컴포즈를 실행하는 하위에 도커파일이 있다.

FROM node:20: Node.js 20 버전의 공식 이미지를 기반으로 합니다. 이 이미지에서 애플리케이션이 실행됩니다.

RUN npm install -g pnpm: pnpm 패키지 매니저를 글로벌로 설치합니다. pnpm은 의존성 관리를 효율적으로 처리할 수 있는 도구입니다.

WORKDIR /app: 이후의 모든 명령어가 실행될 작업 디렉토리를 /app으로 설정합니다.

COPY packages ./packages/: 호스트의 packages 디렉토리를 컨테이너의 /app/packages로 복사합니다. 이 디렉토리에는 공통 라이브러리와 모듈이 포함되어 있을 것입니다.

COPY pnpm-workspace.yaml ./: pnpm 워크스페이스 설정 파일을 현재 작업 디렉토리로 복사합니다. 이 파일은 패키지 관리에 필요합니다.

COPY apps/user ./apps/user: 사용자 애플리케이션 디렉토리 apps/user를 컨테이너로 복사합니다.

RUN pnpm install --filter ...: 주석 처리된 줄은 여러 패키지를 필터링하여 설치하는 명령어입니다. apps/user, packages/database, packages/utils의 의존성만 설치합니다. 이 명령은 애플리케이션의 필요에 따라 의존성 설치를 최적화합니다.

WORKDIR /app/packages/database: 작업 디렉토리를 packages/database로 변경합니다. 이곳에서 데이터베이스 관련 작업을 수행합니다.

RUN npx prisma generate: Prisma ORM을 사용하여 데이터베이스 클라이언트를 생성합니다. 이 명령은 Prisma 스키마를 기반으로 클라이언트를 생성하여 데이터베이스와 상호작용할 수 있게 합니다.

WORKDIR /app/apps/user: 작업 디렉토리를 다시 사용자 애플리케이션 디렉토리로 변경합니다.

EXPOSE 5174: 컨테이너의 5174 포트를 외부에 노출합니다. 이 포트는 애플리케이션이 클라이언트와 통신하는 데 사용됩니다.

CMD ["pnpm", "run", "dev"]: 컨테이너가 시작될 때 실행할 기본 명령어를 설정합니다. pnpm을 사용하여 개발 서버를 실행합니다.

이 Dockerfile은 Node.js 기반의 Svelte 애플리케이션을 컨테이너화하기 위한 설정을 포함하고 있습니다. 필요한 패키지를 설치하고, 데이터베이스 클라이언트를 생성하며, 최종적으로 애플리케이션을 실행하는 과정을 정의하고 있습니다. 이렇게 작성된 Dockerfile은 Docker Compose와 함께 사용되어 여러 서비스가 통합된 환경에서 실행될 수 있습니다.

docker compose up --build

docker compose 가 빌드된다. 컨테이너가 생성되는 것이다.

기본 터미널 환경에서 pnpm run dev와 비슷한 터미널이 등장한다.

docker compose up

이제 그냥 컨테이너를 실행만 빌드 노노!!

도커의 기본개념 (생활코딩 )

트러블 슈팅

도무지 웹이 실행되지 않았던 적이 있었다. 캐시가 있을 수 있다고 했다.

docker-compose logs web 로그를 통해 코드에서 발생한 다른 오류의 단서를 찾을 수 있습니다.

**캐시 클리어 및 재시작 ** 때때로, Docker의 캐시가 문제를 일으킬 수 있습니다. 이러한 경우 캐시를 제거하고 다시 시작하는 것이 좋습니다.

docker-compose down --volumes  
docker-compose up --build 

위의 명령어는 모든 컨테이너를 중지하고 관련된 볼륨을 삭제한 후, 다시 빌드하고 실행합니다.