튜토리얼

Docker Compose 로컬 개발 환경 구축: 다중 서비스 연동 실전 가이드

강코의 코딩 일기 2026. 4. 15. 21:08
반응형

복잡한 다중 서비스 로컬 개발 환경 구축에 어려움을 겪고 계신가요? Docker Compose를 활용하여 일관되고 효율적인 개발 환경을 만드는 실용적인 방법을 상세히 안내합니다.

개발 프로젝트를 진행하다 보면 다양한 서비스와 데이터베이스, 캐시 서버 등 여러 컴포넌트를 함께 구동해야 하는 상황에 자주 직면합니다. 프론트엔드, 백엔드, 데이터베이스, 심지어는 메시지 큐나 검색 엔진까지, 이 모든 것을 로컬 개발 환경에서 일관성 있게 설정하고 관리하는 것은 여간 어려운 일이 아닙니다. 매번 개발자마다 다른 운영체제나 라이브러리 버전에 부딪히고, '내 컴퓨터에서는 잘 되는데?'라는 말을 들어본 적 있으신가요? 이런 문제로 인해 개발 초기 설정에만 며칠을 허비하거나, 팀원 간 환경 차이로 인한 버그가 발생하는 경험은 비단 저만의 이야기는 아닐 것입니다.

이 글에서는 이러한 비효율적인 로컬 개발 환경 구축의 고통을 덜어줄 강력한 도구, 바로 Docker Compose를 소개하고, 이를 활용하여 다중 서비스 연동 로컬 개발 환경을 효율적으로 구축하는 실전 가이드를 제공합니다. 더 이상 환경 설정 문제로 시간을 낭비하지 않고, 오직 코드 개발에만 집중할 수 있는 방법을 함께 살펴보겠습니다.

Docker Compose를 활용한 로컬 개발 환경 구축: 다중 서비스 연동 실전 가이드 - statue, sculpture, iron, steel, docker, finland, hamina, docker, docker, docker, docker, docker, finland

Image by Olga_Fil on Pixabay

로컬 개발 환경, 왜 Docker Compose가 필요할까요?

과거에는 로컬 개발 환경을 구축할 때 개발자가 직접 운영체제에 필요한 소프트웨어(예: Node.js, Python, Java 런타임, MySQL, Redis 등)를 설치하고 버전을 관리했습니다. 이러한 방식은 다음과 같은 여러 문제점을 야기했습니다.

  • 환경 불일치: 개발자마다 운영체제, 설치된 소프트웨어 버전, 설정 등이 달라 '내 컴퓨터에서는 되는데 네 컴퓨터에서는 안 되는' 상황이 빈번했습니다.
  • 복잡한 설정: 여러 서비스를 연동해야 할 경우, 각 서비스의 포트 충돌, 네트워크 설정, 환경 변수 관리 등이 복잡해지고 오류 발생 가능성이 높았습니다.
  • 새로운 개발자 온보딩 시간 증가: 팀에 새로운 개발자가 합류하면, 모든 개발 환경을 처음부터 다시 설정해야 하므로 상당한 시간과 노력이 소요되었습니다.
  • 버전 관리의 어려움: 프로젝트마다 다른 버전의 데이터베이스나 런타임을 요구할 경우, 이를 로컬에서 동시에 관리하기가 매우 까다로웠습니다.

Docker Compose는 이러한 문제들을 해결하기 위한 이상적인 솔루션입니다. Docker Compose를 사용하면 컨테이너 기반으로 애플리케이션의 여러 서비스를 정의하고 실행할 수 있습니다. 이는 개발 환경을 코드화(Infrastructure as Code)하여, 어떤 환경에서든 동일한 설정으로 서비스를 구동할 수 있게 만듭니다. 결과적으로 개발자는 더 이상 환경 설정에 대한 걱정 없이, 본연의 개발 업무에 집중할 수 있게 됩니다.

특징 기존 로컬 개발 환경 Docker Compose 기반 로컬 개발 환경
환경 일관성 높은 확률로 환경 불일치 발생 (OS, 라이브러리 버전 등) 항상 동일한 컨테이너 환경 제공, 불일치 문제 해소
설정 복잡성 각 서비스 수동 설치 및 설정, 포트 충돌 등 관리 어려움 YAML 파일 하나로 전체 서비스 정의, 쉬운 관리
온보딩 시간 새로운 개발자 환경 설정에 며칠 소요 가능 'docker compose up' 명령 한 줄로 환경 구축 가능
자원 격리 모든 서비스가 호스트 OS 자원을 공유, 잠재적 충돌 각 서비스가 독립적인 컨테이너에서 실행, 자원 격리
버전 관리 여러 프로젝트의 다른 런타임/DB 버전 관리 어려움 각 컨테이너에 필요한 특정 버전 지정, 쉬운 전환

Docker Compose 기본 개념 이해하기

Docker Compose는 여러 개의 Docker 컨테이너를 하나의 애플리케이션으로 정의하고 실행하기 위한 도구입니다. 복수의 컨테이너로 구성된 애플리케이션을 정의하기 위해 YAML 파일을 사용하며, 이 파일 하나로 모든 서비스의 설정, 네트워크, 볼륨 등을 관리할 수 있습니다.

Docker와 Docker Compose의 관계

Docker컨테이너라는 격리된 환경에서 애플리케이션을 실행하는 기술입니다. 개별적인 서비스(예: 웹 서버, 데이터베이스)를 각각의 컨테이너로 만들 수 있게 해줍니다. 반면 Docker Compose는 이러한 개별 컨테이너들을 하나의 논리적인 단위로 묶어 관리할 수 있도록 돕는 도구입니다. 즉, Docker가 개별 벽돌이라면, Docker Compose는 이 벽돌들을 사용하여 집을 짓는 설계도이자 건축 도구인 셈입니다.

Docker Compose 파일의 핵심 요소

docker-compose.yml 파일은 Docker Compose의 핵심입니다. 이 파일 안에는 다음과 같은 주요 요소들이 정의됩니다.

  • services: 애플리케이션을 구성하는 각 서비스(컨테이너)를 정의합니다. 각 서비스는 이미지, 빌드 경로, 포트 매핑, 볼륨, 환경 변수 등을 가질 수 있습니다.
  • networks: 서비스 간 통신을 위한 네트워크를 정의합니다. 기본적으로는 하나의 네트워크가 생성되어 모든 서비스가 통신할 수 있지만, 복잡한 구성에서는 사용자 정의 네트워크를 사용할 수 있습니다.
  • volumes: 컨테이너의 데이터를 영구적으로 저장하거나 호스트와 공유하기 위한 볼륨을 정의합니다. 데이터베이스 데이터나 로그 파일 등을 관리할 때 필수적입니다.

이러한 요소들을 잘 조합하면, 프론트엔드, 백엔드, 데이터베이스가 유기적으로 연결된 복잡한 개발 환경도 몇 줄의 코드로 간결하게 정의할 수 있습니다.

다중 서비스 개발 환경 설계하기

본격적으로 Docker Compose를 활용하기 전에, 어떤 서비스들이 필요하고 어떻게 연동할지 설계하는 단계가 중요합니다. 여기서는 일반적인 웹 애플리케이션 아키텍처를 예시로 들어보겠습니다.

  • 프론트엔드 (Frontend): React, Vue.js, Angular 등으로 개발된 SPA (Single Page Application). Nginx 또는 Node.js 기반의 개발 서버를 통해 서빙됩니다.
  • 백엔드 (Backend): Spring Boot, Node.js (Express), Django, Flask 등으로 개발된 API 서버. 데이터베이스와 통신합니다.
  • 데이터베이스 (Database): MySQL, PostgreSQL, MongoDB 등. 백엔드 서비스의 데이터를 저장합니다.
  • 캐시 서버 (Cache Server): Redis, Memcached 등. 데이터베이스 부하를 줄이고 응답 속도를 향상시킵니다.

이러한 서비스들을 Docker Compose로 묶을 때 고려해야 할 사항은 다음과 같습니다.

  1. 각 서비스의 Dockerfile: 프론트엔드와 백엔드 서비스는 대부분 커스텀 코드를 포함하므로, 이를 빌드하기 위한 Dockerfile이 필요합니다. 데이터베이스나 캐시 서버는 공식 이미지를 사용하는 것이 일반적입니다.
  2. 포트 매핑: 호스트 머신에서 특정 서비스에 접근해야 할 경우, 컨테이너의 포트와 호스트의 포트를 매핑해야 합니다. 예를 들어, 프론트엔드 서버는 3000번 포트, 백엔드 서버는 8080번 포트 등으로 설정할 수 있습니다.
  3. 환경 변수: 데이터베이스 연결 정보, API 키 등 민감하거나 환경에 따라 달라지는 값들은 환경 변수로 관리하는 것이 좋습니다.
  4. 볼륨: 데이터베이스의 데이터나 로그 파일 등 영구적으로 보존되어야 하는 데이터는 볼륨을 사용하여 관리해야 컨테이너가 삭제되어도 데이터가 유실되지 않습니다.
  5. 네트워크: 서비스 간 통신은 기본적으로 Docker Compose가 생성하는 네트워크를 통해 이루어집니다. 서비스 이름을 호스트명처럼 사용하여 서로를 호출할 수 있습니다 (예: 백엔드에서 데이터베이스를 database:3306으로 호출).

이러한 설계 과정을 통해 어떤 컴포넌트가 필요하고, 어떻게 상호작용할지 명확히 파악할 수 있습니다. 이제 이 설계를 바탕으로 docker-compose.yml 파일을 작성해 보겠습니다.

Docker Compose를 활용한 로컬 개발 환경 구축: 다중 서비스 연동 실전 가이드 - ux, prototyping, design, webdesign, app, mobile, business, interface, flat, symbol, ui, page, template, mockup, service, development, freelancer, design, design, design, design, design, webdesign, app, app, business, business, business, business, service, service, service, development, development

Image by Firmbee on Pixabay

Docker Compose 파일 작성 실전

이제 위에서 설계한 다중 서비스 아키텍처를 Docker Compose 파일로 구현해 보겠습니다. 다음은 프론트엔드(Nginx로 React 앱 서빙), 백엔드(Node.js), MySQL 데이터베이스, Redis 캐시로 구성된 예시입니다.

먼저 프로젝트 구조를 다음과 같이 가정합니다.


my-multi-service-app/
├── frontend/
│   ├── Dockerfile
│   └── ... (React 앱 파일들)
├── backend/
│   ├── Dockerfile
│   └── ... (Node.js 앱 파일들)
├── nginx/
│   └── nginx.conf
└── docker-compose.yml
    

frontend/Dockerfile:


# nodejs 빌드 환경
FROM node:18-alpine as builder
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
RUN npm run build

# nginx 서빙 환경
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
COPY ./nginx/nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
    

backend/Dockerfile:


FROM node:18-alpine
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
EXPOSE 8080
CMD ["node", "server.js"]
    

nginx/nginx.conf (정적 파일 서빙 및 백엔드 프록시 설정 예시):


server {
    listen 80;
    server_name localhost;

    location / {
        root /usr/share/nginx/html;
        index index.html index.htm;
        try_files $uri $uri/ /index.html;
    }

    location /api/ {
        proxy_pass http://backend:8080; # backend 서비스로 요청 프록시
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
    

이제 이 모든 서비스를 묶는 docker-compose.yml 파일입니다.


version: '3.8'

services:
  # 1. 프론트엔드 서비스 (React + Nginx)
  frontend:
    build:
      context: ./frontend # frontend 디렉토리에서 Dockerfile 빌드
      dockerfile: Dockerfile
    ports:
      - "80:80" # 호스트 80번 포트를 컨테이너 80번 포트에 매핑
    depends_on:
      - backend # 백엔드 서비스가 먼저 시작되도록 의존성 설정
    networks:
      - app_network

  # 2. 백엔드 서비스 (Node.js API)
  backend:
    build:
      context: ./backend # backend 디렉토리에서 Dockerfile 빌드
      dockerfile: Dockerfile
    ports:
      - "8080:8080" # 호스트 8080번 포트를 컨테이너 8080번 포트에 매핑
    environment: # 환경 변수 설정
      DATABASE_HOST: mysql
      DATABASE_USER: user
      DATABASE_PASSWORD: password
      DATABASE_NAME: mydatabase
      REDIS_HOST: redis
      REDIS_PORT: 6379
    depends_on:
      - mysql # MySQL 서비스가 먼저 시작되도록 의존성 설정
      - redis # Redis 서비스가 먼저 시작되도록 의존성 설정
    networks:
      - app_network

  # 3. MySQL 데이터베이스 서비스
  mysql:
    image: mysql:8.0 # MySQL 8.0 공식 이미지 사용
    environment: # 환경 변수 설정
      MYSQL_ROOT_PASSWORD: root_password
      MYSQL_USER: user
      MYSQL_PASSWORD: password
      MYSQL_DATABASE: mydatabase
    volumes:
      - mysql_data:/var/lib/mysql # 데이터 영속성을 위한 볼륨 마운트
    ports:
      - "3306:3306" # 호스트 3306번 포트를 컨테이너 3306번 포트에 매핑 (옵션: 개발 편의용)
    networks:
      - app_network

  # 4. Redis 캐시 서비스
  redis:
    image: redis:6-alpine # Redis 6 공식 이미지 사용
    ports:
      - "6379:6379" # 호스트 6379번 포트를 컨테이너 6379번 포트에 매핑 (옵션: 개발 편의용)
    volumes:
      - redis_data:/data # 데이터 영속성을 위한 볼륨 마운트 (RDB 스냅샷 등)
    networks:
      - app_network

# 볼륨 정의
volumes:
  mysql_data: # MySQL 데이터 볼륨
  redis_data: # Redis 데이터 볼륨

# 네트워크 정의
networks:
  app_network:
    driver: bridge # 브릿지 네트워크 드라이버 사용
    

docker-compose.yml 파일을 my-multi-service-app/ 디렉토리에 저장하고, 터미널에서 해당 디렉토리로 이동한 후 다음 명령어를 실행하면 모든 서비스가 한 번에 빌드되고 실행됩니다.


docker compose up -d
    

-d 옵션은 백그라운드에서 컨테이너를 실행하라는 의미입니다. 이제 웹 브라우저에서 http://localhost에 접속하면 프론트엔드 애플리케이션을 볼 수 있고, 프론트엔드에서 /api/ 경로로 요청을 보내면 백엔드 서비스로 프록시되어 처리됩니다.

서비스 연동 및 데이터 관리 전략

Docker Compose를 통해 여러 서비스를 띄웠다면, 이제 이 서비스들이 어떻게 효율적으로 통신하고 데이터를 관리하는지 이해하는 것이 중요합니다.

서비스 간 통신: 네트워크와 서비스 이름 활용

Docker Compose는 기본적으로 모든 서비스가 포함되는 기본 네트워크를 생성합니다. 이 네트워크 안에서는 각 서비스가 서비스 이름을 호스트명처럼 사용하여 서로 통신할 수 있습니다. 예를 들어, 백엔드 서비스는 MySQL 데이터베이스에 접속할 때 localhost 대신 mysql이라는 호스트명을 사용할 수 있습니다.

위 예시에서 백엔드 서비스의 환경 변수를 다시 살펴보겠습니다.


environment:
  DATABASE_HOST: mysql # MySQL 서비스 이름으로 접근
  DATABASE_USER: user
  DATABASE_PASSWORD: password
  DATABASE_NAME: mydatabase
  REDIS_HOST: redis # Redis 서비스 이름으로 접근
  REDIS_PORT: 6379
    

이처럼 mysqlredisdocker-compose.yml 파일에 정의된 서비스 이름입니다. 이 덕분에 개발자는 IP 주소를 신경 쓸 필요 없이 직관적으로 서비스를 호출할 수 있습니다.

또한, depends_on 키워드를 사용하여 서비스 간의 시작 순서를 정의할 수 있습니다. 예를 들어, 백엔드 서비스가 데이터베이스와 캐시 서버보다 먼저 시작되지 않도록 설정하여 연결 오류를 방지할 수 있습니다. 하지만 depends_on은 엄격한 의존성을 보장하지 않고 컨테이너 시작 순서만 제어하므로, 실제 애플리케이션에서는 데이터베이스가 완전히 준비될 때까지 기다리는 재시도 로직을 구현하는 것이 더 견고합니다.

데이터 영속성 관리: 볼륨의 중요성

컨테이너는 기본적으로 휘발성입니다. 즉, 컨테이너가 삭제되면 그 안의 데이터도 함께 사라집니다. 개발 환경에서 데이터베이스 데이터나 중요한 로그 파일 등이 유실되는 것은 심각한 문제입니다. 이를 방지하기 위해 Docker 볼륨을 사용합니다.

위 예시에서는 mysql_dataredis_data라는 명명된 볼륨(Named Volume)을 사용했습니다.


volumes:
  mysql_data:/var/lib/mysql # 컨테이너 내부 경로에 호스트의 영구 볼륨 연결
    

이 설정은 Docker가 관리하는 mysql_data라는 볼륨을 MySQL 컨테이너의 /var/lib/mysql 경로에 마운트합니다. 이 볼륨은 컨테이너가 재생성되거나 삭제되어도 유지되므로, 데이터베이스 데이터는 안전하게 보존됩니다. 따라서 다음에 docker compose up 명령을 실행해도 이전 데이터가 그대로 남아있게 됩니다.

명명된 볼륨 외에도 호스트 파일 시스템의 특정 경로를 직접 마운트하는 바인드 마운트(Bind Mount) 방식도 있습니다. 이는 주로 개발 중인 애플리케이션 코드(예: ./backend:/app)를 컨테이너에 즉시 반영해야 할 때 유용합니다. 코드를 수정하면 컨테이너 내부에서도 변경사항이 바로 적용되어 개발 생산성을 높일 수 있습니다.

Docker Compose를 활용한 로컬 개발 환경 구축: 다중 서비스 연동 실전 가이드 - programming, html, css, javascript, php, website development, code, html code, computer code, coding, digital, computer programming, pc, www, cyberspace, programmer, web development, computer, technology, developer, computer programmer, internet, ide, lines of code, hacker, hacking, gray computer, gray technology, gray laptop, gray website, gray internet, gray digital, gray web, gray code, gray coding, gray programming, programming, programming, programming, javascript, code, code, code, coding, coding, coding, coding, coding, digital, web development, computer, computer, computer, technology, technology, technology, developer, internet, hacker, hacker, hacker, hacking

Image by Boskampi on Pixabay

개발 환경 최적화 및 문제 해결 팁

Docker Compose를 활용한 로컬 개발 환경은 강력하지만, 몇 가지 팁을 통해 더욱 최적화하고 발생할 수 있는 문제를 해결할 수 있습니다.

환경 변수 파일(.env) 활용

docker-compose.yml 파일 내에 모든 환경 변수를 직접 명시하는 것은 관리하기 번거롭고, 특히 민감한 정보(예: 비밀번호)가 노출될 위험이 있습니다. 이럴 때 .env 파일을 활용하면 좋습니다.

.env 파일을 docker-compose.yml과 같은 디렉토리에 생성하고, 다음과 같이 환경 변수를 정의합니다.


MYSQL_ROOT_PASSWORD=my_secure_root_password
MYSQL_USER=dev_user
MYSQL_PASSWORD=dev_password
MYSQL_DATABASE=my_app_db
REDIS_HOST=redis
REDIS_PORT=6379
    

그리고 docker-compose.yml 파일에서는 ${변수명} 형태로 참조합니다.


# ...
services:
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
# ...
    

이렇게 하면 docker-compose.yml 파일의 가독성이 높아지고, 민감한 정보는 .env 파일로 분리하여 관리할 수 있습니다. 또한, 팀원별로 다른 .env 파일을 사용하거나, 특정 환경(예: 테스트 환경)에 따라 다른 값을 적용하기 용이해집니다.

로그 확인 및 디버깅

서비스가 정상적으로 동작하지 않을 때 가장 먼저 확인해야 할 것은 로그입니다. Docker Compose는 모든 서비스의 로그를 통합하여 보여주는 기능을 제공합니다.


docker compose logs -f # 모든 서비스의 로그를 실시간으로 확인
docker compose logs -f backend # 특정 서비스(backend)의 로그만 확인
    

로그를 통해 어떤 서비스에서 문제가 발생했는지, 어떤 오류 메시지가 출력되는지 파악하여 디버깅의 실마리를 찾을 수 있습니다.

컨테이너 상태 관리

Docker Compose 명령어들을 알아두면 개발 환경을 효율적으로 관리할 수 있습니다.

  • docker compose up -d: 서비스를 빌드하고 백그라운드에서 실행합니다.
  • docker compose stop: 실행 중인 모든 서비스를 중지합니다.
  • docker compose start: 중지된 서비스를 다시 시작합니다.
  • docker compose down: 실행 중인 서비스를 중지하고 컨테이너, 네트워크, 볼륨(명시적으로 삭제하지 않는 한)을 제거합니다.
  • docker compose down --volumes: 서비스 중지 및 컨테이너 제거와 함께 볼륨까지 제거합니다 (주의: 데이터 유실 가능).
  • docker compose ps: 현재 실행 중인 서비스들의 상태를 확인합니다.
  • docker compose exec [서비스명] [명령어]: 실행 중인 특정 서비스 컨테이너 내부에서 명령어를 실행합니다 (예: docker compose exec mysql bash).

성능 최적화

간혹 Docker Desktop의 성능 문제가 발생할 수 있습니다. 특히 Mac이나 Windows 환경에서 가상 머신을 통해 Docker가 동작하므로, I/O 작업이 많은 경우 성능 저하가 나타날 수 있습니다. 이럴 때는 다음과 같은 방법을 고려해 볼 수 있습니다.

  • 불필요한 볼륨 마운트 제거: 개발 중인 코드 외에 불필요한 대용량 디렉토리를 바인드 마운트하지 않도록 합니다.
  • 리소스 제한 설정: docker-compose.yml에서 각 서비스에 CPU나 메모리 제한을 설정하여 특정 컨테이너가 시스템 자원을 과도하게 사용하는 것을 방지할 수 있습니다.
  • Docker Desktop 설정 최적화: Docker Desktop 애플리케이션의 설정에서 CPU, 메모리, 디스크 할당량을 조정하여 시스템 환경에 맞게 최적화합니다.

마무리하며: 효율적인 개발의 시작

지금까지 Docker Compose를 활용하여 다중 서비스 로컬 개발 환경을 구축하는 방법에 대해 상세히 살펴보았습니다. 복잡하고 비효율적인 환경 설정으로 인해 겪었던 많은 문제점들을 Docker Compose가 어떻게 해결해 줄 수 있는지, 그리고 실제로 어떻게 docker-compose.yml 파일을 작성하고 관리하는지 실전 예시를 통해 알아보았습니다.

Docker Compose는 단순한 도구를 넘어, 개발 팀의 생산성을 혁신적으로 향상시킬 수 있는 강력한 솔루션입니다. 일관된 개발 환경을 제공함으로써 새로운 개발자의 온보딩 시간을 단축하고, '내 컴퓨터에서는 되는데'와 같은 불필요한 논쟁을 줄이며, 오직 코드 개발과 문제 해결에만 집중할 수 있도록 돕습니다. 컨테이너 기술의 강력함을 로컬 개발 환경에 효과적으로 적용하여, 더욱 견고하고 효율적인 개발 워크플로우를 구축하시길 바랍니다.

이 가이드가 여러분의 로컬 개발 환경 구축에 큰 도움이 되었기를 바라며, Docker Compose를 활용하면서 겪었던 흥미로운 경험이나 유용한 팁이 있다면 댓글로 공유해 주세요. 함께 더 나은 개발 문화를 만들어 나갈 수 있습니다!

📌 함께 읽으면 좋은 글

  • [튜토리얼] GitHub Actions CI/CD 파이프라인 구축 가이드: 웹 프로젝트 자동화 전략
  • [튜토리얼] FastAPI 비동기 RESTful API 개발: PostgreSQL 연동 실전 가이드
  • [이슈 분석] 개발자 번아웃: 원인 분석과 지속 가능한 커리어를 위한 예방 및 극복 전략

이 글이 도움이 되셨다면 공감(♥)댓글로 응원해 주세요!
궁금한 점이나 다루었으면 하는 주제가 있다면 댓글로 남겨주세요.

반응형