[웹사이트] 02. 서비스 단위로 컨테이너 배포를 위한 docker-compose 작성

 

1. 로그인 및 회원가입 만들어보기 (Docker + Node.js + MySQL) 에서

각 개별 컨테이너로 애플리케이션을 실행하였다.

 

도커 컴포즈로 서비스 단위로 배포하여 관리하고, MySQL 컨테이너 삭제 시 데이터가 사라지는 문제를 개선하기 위해도커 볼륨을 이용한다.

 

개선될 사항

- 컨테이너 관리 자동화

- 데이터베이스 영속성 보장

 

이전 링크

https://openstack.tistory.com/97

 

[웹사이트] 로그인 및 회원가입 만들어보기 (Docker + Node.js + MySQL)

환경- Rocky Linux 9.5- Docker- Node.js- MySQL 1. 리눅스 및 도커 설치 록키 리눅스 설치 리눅스 기초 다지기 사전준비 - VirtualBox Rocky 9 설치개요호스트 기반 가상화 프로그램 중 VirtualBox를 사용하여 실습

openstack.tistory.com

 

2. Dockerfile 을 통한 Node 및 MySQL 이미지 설정

 

2.1 Node.js 

vi Dockerfile.dev.node

FROM node:22

# 'app' 사용자와 홈 디렉토리 생성
RUN useradd -ms /bin/bash app && \
    chown -R app:app /home/app && \
    chmod -R 700 /home/app

# Node.js 프로젝트 폴더 생성 및 초기화
RUN mkdir /app

# 작업 디렉토리 설정
WORKDIR /app

# 패키지 파일 복사 및 설치
COPY ./app /app
RUN npm install

# 복사된 파일의 소유자 변경
RUN chown -R app:app /app

# 'app' 사용자로 전환
USER app

# 기본 명령 (애플리케이션 실행, 필요 시 수정)
CMD ["node", "app.js"]

 

./app 폴더에 소스코드 및 package.json 파일 필요

 

이미지 빌드

docker build -f Dockerfile.dev.node -t node22:dev .

 

2.2 MySQL

 

vi Dockerfile.dev.mysql

FROM mysql:latest

# 'app' 사용자와 홈 디렉토리 생성
RUN useradd -ms /bin/bash app

# 'app' 사용자의 홈 디렉토리 소유권 및 권한 설정
RUN chown -R app:app /home/app && \
    chmod -R 700 /home/app

# 기본 작업 디렉토리 설정 (선택 사항)
WORKDIR /home/app

# MySQL 실행에 필요한 기본 사용자 및 권한 유지
USER mysql

# MySQL 컨테이너의 기본 진입점 유지
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["mysqld"]

 

이미지 빌드

docker build -f Dockerfile.dev.mysql -t mysql:dev .

 

이미지 확인

 

 

3. 도커 컴포즈 파일 작성

 

서비스 내 사용할 컨테이너 네트워크 생성

docker network create app-network

 

 

vi docker-compose-myapp.yaml

services:
  app-node:
    image: node22:dev
    container_name: app-node
    ports:
      - "3000:3000"
    depends_on:
      app-mysql:
        condition: service_healthy
    networks:
      - app-network
    restart: unless-stopped

  app-mysql:
    image: mysql:dev
    container_name: app-mysql
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
    ports:
      - "3306:3306"
    volumes:
      - app-mysql-data:/var/lib/mysql
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 30s
      timeout: 10s
      retries: 5
    networks:
      - app-network

volumes:
  app-mysql-data:
    name: app-mysql-data

networks:
  app-network:
    name: app-network
    driver: bridge
    external: true

 

 

도커 컴포즈 파일에서 사용하는 환경변수 파일 작성

 

vi .env

## MySQL
MYSQL_ROOT_PASSWORD=패스워드

 

 

서비스 배포

docker compose -f docker-compose-myapp.yaml up -d

 

 

실행 확인

docker ps

 

 

그 후 MySQL 컨테이너 이름을 확인한다.

컨테이너 환경에서는 컨테이너의 IP 가 유동적으로 변경되므로,

컨테이너 이름으로 설정한다.

 

Node 컨테이너 접속 후"config/database.js" IP 수정

docker exec -it app-node bash
cd /app/config
sed -i 's/172.17.0.3/app-mysql/g' database.js

 

Nodejs 에서 Mysql 접근 위한 계정 생성

create user app@'%' identified by 'password';
grant all privileges on *.* to app@'%';
flush privileges;

 

회원가입 데이터베이스 및 테이블 생성

CREATE DATABASE app;
USE app;
 
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) UNIQUE NOT NULL,
    password VARCHAR(255) NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

 

컨테이너 재기동

$ docker compose -f docker-compose-myapp.yaml restart

 

 

도커 볼륨 확인

 

 

docker compose 삭제 테스트

 

$ docker compose -f docker-compose-myapp.yaml down

 

 

 

docker compose 배포 테스트

 

docker compose -f docker-compose-myapp.yaml up -d

 

 

 

회원가입 및 로그인 기능 확인

 

 

앞으로 개선해야할 점

- 소스코드 수정 후 빌드과정의 절차 불편함