다음을 통해 공유


자습서: MySQL 및 Docker Compose를 사용하여 다중 컨테이너 앱 만들기

이 문서에서는 MySQL 사용하여 다중 컨테이너 앱을 만들고 Docker Compose 방법을 설명합니다. 컨테이너가 여러 개 있는 앱을 사용하면 각 컨테이너가 단일 작업에 집중할 수 있도록 특수화된 작업에 컨테이너를 사용할 수 있습니다. 다중 컨테이너 앱을 사용하는 경우 다음과 같은 여러 가지 이점이 있습니다.

  • 별도의 컨테이너를 사용하면 API 및 프런트 엔드 리소스를 데이터베이스와 다르게 관리할 수 있습니다.
  • 여러 컨테이너를 사용하면 각 버전을 독립적으로 관리하고 업데이트할 수 있습니다.
  • 로컬 데이터베이스는 프로덕션의 데이터베이스에 사용되는 컨테이너 및 관리되는 서비스에서 유지 관리할 수 있습니다.
  • 다중 컨테이너 앱은 프로세스 관리자를 사용하여 여러 프로세스를 실행하는 것보다 더 효율적이므로 컨테이너 시작/종료가 복잡해집니다.

이 자습서에서는 다음을 수행합니다.

  • MySQL 시작
  • MySQL을 사용하여 다중 컨테이너 앱 실행
  • 앱에 대한 Docker Compose 파일 만들기
  • Docker Compose를 사용하여 애플리케이션 스택 실행

필수 구성 요소

  • 이 문서는 자습서 시리즈의 일부입니다. 프로세스는 Linux 컨테이너용 Docker Desktop 을 필요로 하는 확립된 예제를 기반으로 합니다.

    권장되는 방법은 필수 구성 요소 충족을 포함하여 첫 번째 자습서인 컨테이너 앱 만들기앱에서 데이터 유지 자습서를 완료하는 것입니다. 이러한 자습서를 수행한 후 이 문서에 설명된 절차를 계속 진행합니다.

  • 이 문서의 예제에서는 Docker Compose사용합니다.

    Windows용 Docker Desktop에는 Docker Compose가 포함되어 있습니다.

    다음 명령을 실행하여 Docker 설치를 확인합니다.

    docker-compose version
    

비주얼 스튜디오 코드

이 자습서 시리즈에서는 VS Code(Visual Studio Code)에 대한 절차를 설명합니다. 이 환경에서 작업하기 위한 다음 고려 사항을 검토합니다.

  • 왼쪽 메뉴를 사용하여 컨테이너 탐색기 또는 탐색기 (파일 및 폴더) 보기 간에 전환합니다.

    Visual Studio Code의 컨테이너 탐색기 및 파일/폴더 탐색기 보기를 보여 주는 스크린샷

  • 터미널>새 터미널선택하여 VS Code에서 명령줄 창을 엽니다. Ctrl+Shift+`(뒤로 틱) 바로 가기 키를 사용할 수도 있습니다.

  • 달리 지정하지 않는 한 Bash 창에서 명령을 실행합니다. Bash 레이블이 지정된 대부분의 명령은 Bash 창 또는 VS Code 명령줄 창에서 실행됩니다.

MySQL 데이터베이스 관리 시스템 시작

기본적으로 컨테이너는 격리된 상태로 실행됩니다. 컨테이너는 동일한 컴퓨터의 다른 프로세스 또는 다른 컨테이너를 인식하지 못합니다.

컨테이너 간 통신을 사용하도록 설정하려면 동일한 네트워크에 연결해야 합니다. 동일한 네트워크의 여러 컨테이너는 데이터를 공유하고 서로 정보를 처리할 수 있습니다.

네트워크에 컨테이너를 연결하는 방법에는 두 가지가 있습니다. 만드는 동안 네트워크에 컨테이너를 연결하거나 나중에 기존 컨테이너를 네트워크에 연결할 수 있습니다.

이 예제에서는 네트워크를 만들고 시작할 때 MySQL 컨테이너를 연결합니다.

  1. todo-app이라는 네트워크를 만듭니다.

    docker network create todo-app
    
  2. todo-mysql-data MySQL 컨테이너를 시작하고 todo-app 네트워크에 연결합니다. 이 명령은 MySQL 데이터베이스 mysql대한 네트워크 별칭 todos 만듭니다.

    명령을 실행할 때 <your-password> 자리 표시자에 대한 MySQL 루트 암호를 입력합니다.

    docker run -d --network todo-app --network-alias mysql -v todo-mysql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=<your-password> -e MYSQL_DATABASE=todos mysql:lts
    

    또한 이 명령은 MYSQL_ROOT_PASSWORDMYSQL_DATABASE 환경 변수를 정의합니다. 자세한 내용은 MySQL Docker Hub 목록참조하세요.

    경고

    이 자습서에서는 가장 안전한 방법이 아닌 MySQL 데이터베이스로 인증하기 위한 암호 자격 증명을 보여 줍니다. 더 안전한 인증 방법에 대해 알아보려면 MySQL 설명서 참조하세요.

  3. 다음 단계에서 사용할 컨테이너 ID를 가져옵니다.

    docker ps
    
  4. mysql 네트워크의 컨테이너에 연결할 수 있는지 확인합니다.

    명령을 실행할 때 <mysql-container-id> 자리 표시자에 대한 컨테이너 ID를 입력합니다.

    docker exec -it <mysql-container-id> mysql -p
    

    프롬프트에서 todo-mysql-data 컨테이너를 만들 때 제공한 암호를 입력합니다.

  5. MySQL 셸에서 데이터베이스를 나열하고 todos 데이터베이스가 표시되는지 확인합니다.

    SHOW DATABASES;
    

    다음과 같은 출력이 표시됩니다.

    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | sys                |
    | todos              |
    +--------------------+
    5 rows in set (0.00 sec)
    
  6. 연결을 종료하고 명령줄 프롬프트로 돌아가려면 종료 입력합니다.

MySQL을 사용하여 앱 실행

todo 앱은 특정 환경 변수를 설정하여 MySQL 연결 설정을 지정하도록 지원합니다. 다음 표에서는 지원되는 변수와 이 섹션에 제시된 예제에 사용된 값을 나열합니다.

변수 이름 예제 값 설명
MYSQL_HOST mysql MySQL 서버의 호스트 이름입니다.
MYSQL_USER root 연결에 사용할 사용자 이름입니다.
MYSQL_PASSWORD <your-password> 연결에 사용할 암호입니다. 이 예제에서는 루트 암호를 <your-password> 자리 표시자로 대체합니다.
MYSQL_DATABASE todos 연결이 설정된 후 사용할 데이터베이스의 이름입니다.

경고

환경 변수를 사용하여 연결 설정을 설정하는 것은 개발에 적합하지만 프로덕션 환경에서 애플리케이션을 실행하는 경우에는 이 방법을 사용하지 않는 것이 좋습니다. 자세한 내용은 비밀 데이터환경 변수를 사용하지 않아야 하는 이유를 참조하세요.

보다 안전한 메커니즘은 컨테이너 오케스트레이션 프레임워크에서 제공하는 비밀 지원을 사용하는 것입니다. 대부분의 경우 이러한 비밀은 실행 중인 컨테이너에 파일로 탑재됩니다.

다음 예제에서는 앱을 시작하고 앱 컨테이너를 MySQL 컨테이너에 연결합니다.

  1. 다음 docker 명령을 실행합니다. 명령이 앞에서 설명한 환경 변수를 지정하는 방법을 확인합니다.

    명령을 실행할 때 <your-password> 자리 표시자에 대한 MySQL 루트 암호를 입력해야 합니다.

    docker run -dp 3000:3000 -w /app -v ${PWD}:/app --network todo-app -e MYSQL_HOST=mysql -e MYSQL_USER=root -e MYSQL_PASSWORD=<your-password> -e MYSQL_DB=todos node:lts-alpine sh -c "yarn install && yarn run dev"
    
  2. VS Code 편집기에서 컨테이너 탐색기를 열고 앱 컨테이너를 마우스 오른쪽 단추로 클릭한 다음 로그 보기를 선택합니다.

    docker logs 명령을 사용하여 명령줄에서 로그를 볼 수도 있습니다.

  3. 로그 출력을 검토합니다. 앱이 MySQL 데이터베이스 Connected to mysql db at host mysql연결되어 있음을 나타내는 줄을 확인합니다.

    # Previous log messages omitted
    $ nodemon src/index.js
    [nodemon] 1.19.2
    [nodemon] to restart at any time, enter `rs`
    [nodemon] watching dir(s): *.*
    [nodemon] starting `node src/index.js`
    Connected to mysql db at host mysql
    Listening on port 3000
    
  4. 인터넷 브라우저에서 실행 중인 애플리케이션으로 이동합니다. http://localhost:3000.

  5. 실행 중인 애플리케이션에서 할 일 목록에 일부 항목을 추가합니다.

  6. 데이터베이스를 확인할 수 있도록 mysql 네트워크의 MySQL 컨테이너 데이터베이스에 연결합니다.

    명령을 실행할 때 <mysql-container-id> 자리 표시자에 대한 컨테이너 ID를 입력합니다.

    docker exec -ti <mysql-container-id> mysql -p todos
    

    프롬프트에서 todo-mysql-data 컨테이너를 만들 때 제공한 암호를 입력합니다.

  7. MySQL 셸에서 추가한 todo_itemstodos 데이터베이스에 기록되었는지 확인합니다.

    use todos;
    select * from todo_items;
    

    다음 예제와 유사한 출력이 표시됩니다.

    +--------------------------------------+--------------------+-----------+
    | id                                   | name               | completed |
    +--------------------------------------+--------------------+-----------+
    | c906ff08-60e6-44e6-8f49-ed56a0853e85 | Do amazing things! |         0 |
    | 2912a79e-8486-4bc3-a4c5-460793a575ab | Be awesome!        |         0 |
    +--------------------------------------+--------------------+-----------+
    

이제 별도의 컨테이너에서 실행되는 외부 데이터베이스에 데이터를 저장하는 애플리케이션이 있습니다. 이 절차에서는 네트워킹을 사용하여 컨테이너 간 통신을 사용하도록 설정하는 방법을 보여 줍니다.

Docker Compose 파일 만들기

Docker Compose를 사용하면 다중 컨테이너 애플리케이션을 정의하고 공유할 수 있습니다. Docker Compose 파일은 필요한 모든 서비스를 지정할 수 있으므로 단일 명령으로 모든 관련 프로세스를 시작하거나 종료할 수 있습니다. 프로젝트 리포지토리의 루트에 있는 Docker Compose 파일에서 애플리케이션 스택을 정의하고 버전 제어에서 구성을 유지할 수 있습니다. 이 방법을 사용하면 다른 사용자가 리포지토리를 복제할 때 프로젝트에 기여할 수 있습니다.

다음 예제에서는 다중 컨테이너 애플리케이션 todoDocker Compose 파일을 구성합니다.

  1. todo 앱 프로젝트의 루트에서 docker-compose.yml이라는 Docker Compose 파일을 만듭니다.

    메모

    기본적으로 YAML 스키마 버전은 최신 버전으로 설정됩니다. 앱을 실행할 때 스키마 버전이 구식인 경우 경고 메시지를 받게 됩니다. 현재 스키마 버전 및 호환성 매트릭스를 검토하려면 개요(파일 작성)참조하세요.

  2. docker-compose.yml 파일에서 다음 요소를 추가합니다. 앱 name 지정하고 애플리케이션의 일부로 실행하려는 services(또는 컨테이너) 목록을 시작합니다.

    name: todo
    
    services:
    

    서비스 목록은 앱에 대해 고유합니다. 예를 들어 app, web, db, proxy등이 있습니다. 이후 단계에서 services 요소에 대한 정의를 확장합니다.

    들여쓰기는 .yml 파일에서 중요합니다. VS Code에서 편집하는 경우 Intellisense는 형식 또는 구문의 오류를 나타냅니다.

  3. services 파일의 정의로 돌아갑니다. 컨테이너에 대한 이미지를 포함하는 app 서비스 요소를 정의하는 항목을 추가하여 정의를 확장합니다.

    services:
      app:
        image: node:lts-alpine
    

    서비스의 이름을 선택할 수 있습니다. 이름은 자동으로 네트워크 별칭이 되며 MySQL 서비스를 정의할 때 유용합니다.

  4. app 요소의 정의를 확장하여 실행할 command을 지정하십시오.

      app:
        image: node:lts-alpine
        command: sh -c "yarn install && yarn run dev"
    
  5. ports을(를) app 서비스에서 사용할 수 있도록 정의합니다. 이러한 포트는 MySQL을 사용하여 앱을 실행하는 데 사용되는 명령에 대한 -p 3000:3000 인수에 해당합니다.

      app:
        image: node:lts-alpine
        command: sh -c "yarn install && yarn run dev"
        ports:
          - 3000:3000
    
  6. working_dir 서비스의 작업 디렉터리 app과 매핑된 volumes도 식별합니다.

      app:
        image: node:lts-alpine
        command: sh -c "yarn install && yarn run dev"
        ports:
          - 3000:3000
        working_dir: /app
        volumes:
          - ./:/app
    

    Docker Compose 볼륨을 정의할 때 현재 디렉터리에 따라 상대 경로를 사용할 수 있습니다.

  7. environment 서비스에 대한 명령을 실행할 때 사용할 app 변수 정의를 지정합니다.

      app:
        image: node:lts-alpine
        command: sh -c "yarn install && yarn run dev"
        ports:
          - 3000:3000
        working_dir: /app
        volumes:
          - ./:/app
        environment:
          MYSQL_HOST: mysql
          MYSQL_USER: root
          MYSQL_PASSWORD: <your-password>
          MYSQL_DB: todos
    

    <your-password> 자리 표시자에 MySQL 루트 암호를 입력하세요.

  8. mysql 서비스 정의 후에 MySQL 서비스 app 대한 정의를 추가합니다. 표시된 대로 동일한 들여쓰기를 사용하여 요소 이름과 값을 지정합니다.

    services:
      app:
        ...
      mysql:
        image: mysql:lts
    

    mysql 서비스 정의는 MySQL 시작하기이전에 사용한 명령에 해당합니다. 서비스를 정의하면 네트워크 별칭이 자동으로 수신됩니다.

  9. volumes 서비스에 매핑된 mysql을 식별하십시오.

    services:
      app:
        ...
      mysql:
        image: mysql:lts
        volumes:
          - todo-mysql-data:/var/lib/mysql
    
  10. environment 서비스에 대한 명령을 실행할 때 사용할 mysql 변수 정의를 지정합니다.

    services:
      app:
        ...
      mysql:
        image: mysql:lts
        volumes:
          - todo-mysql-data:/var/lib/mysql
        environment: 
          MYSQL_ROOT_PASSWORD: <your-password>
          MYSQL_DATABASE: todos
    

    <your-password> 자리 표시자에 MySQL 루트 암호를 입력하세요.

  11. 전체 앱에 대한 볼륨 매핑을 정의합니다. volumes: 섹션 뒤와 동일한 들여쓰기를 사용하여 services: 섹션을 추가합니다.

    services:
       ...
    
    volumes:
      todo-mysql-data:
    
  12. 완료된 docker-compose.yml 파일이 다음 예제와 같이 표시되는지 확인합니다. <your-password> 자리 표시자에 대한 MySQL 루트 암호가 표시됩니다.

    name: todo
    
    services:
      app:
        image: node:lts-alpine
        command: sh -c "yarn install && yarn run dev"
        ports:
          - 3000:3000
        working_dir: /app
        volumes:
          - ./:/app
        environment:
          MYSQL_HOST: mysql
          MYSQL_USER: root
          MYSQL_PASSWORD: <your-password>
          MYSQL_DB: todos
    
      mysql:
        image: mysql:lts
        volumes:
          - todo-mysql-data:/var/lib/mysql
        environment: 
          MYSQL_ROOT_PASSWORD: <your-password>
          MYSQL_DATABASE: todos
    
    volumes:
      todo-mysql-data:
    

Docker Compose를 사용하여 애플리케이션 스택 실행

이제 docker-compose.yml 파일을 실행해 볼 수 있습니다.

  1. 애플리케이션 및 데이터베이스의 실행 중인 인스턴스를 중지합니다.

    VS Code에서 다음 단계를 수행합니다.

    1. 컨테이너 탐색기(컨테이너 도구 확장)를 엽니다.

    2. 실행 중인 각 컨테이너에 대해 컨테이너를 마우스 오른쪽 단추로 클릭하고 제거선택합니다.

  2. 다중 컨테이너 앱과 모든 서비스를 시작하세요.

    VS Code에서 다음 단계를 수행합니다.

    1. 탐색기(파일 및 폴더) 보기를 엽니다.

    2. docker-compose.yml 파일을 마우스 오른쪽 버튼으로 클릭하고 Compose Up을 선택합니다.

    다음 예제와 유사한 출력이 표시됩니다.

    [+] Building 0.0s (0/0)
    [+] Running 2/2
    ✔ Container app-app-1    Started  0.9s 
    ✔ Container app-mysql-1  Running
    

    이 작업은 앱 및 네트워크에 대한 매핑된 볼륨을 만듭니다. 기본적으로 Docker Compose는 애플리케이션 스택에 대한 네트워크를 만듭니다.

  3. 실행 중인 컨테이너에 대한 로그를 검토합니다.

    VS Code에서 다음 단계를 수행합니다.

    1. 컨테이너 탐색기(컨테이너 도구 확장)를 엽니다.

    2. 앱 컨테이너를 마우스 오른쪽 단추로 클릭하고 로그 보기 선택합니다.

    다음 예제와 유사한 출력이 표시됩니다.

    mysql_1  | 2019-10-03T03:07:16.083639Z 0 [Note] mysqld: ready for connections.
    mysql_1  | Version: '5.7.27'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
    app_1    | Connected to mysql db at host mysql
    app_1    | Listening on port 3000
    

    로그에는 각 줄의 시작 부분에 app_1 같은 서비스 이름 및 인스턴스 번호가 표시됩니다. 이 형식은 서비스 및 인스턴스별로 메시지를 구분하는 데 도움이 됩니다. 각 서비스의 로그는 단일 스트림으로 인터리브됩니다. 이 방법을 사용하면 타이밍 관련 문제를 감시할 수 있습니다.

  4. 이제 인터넷 브라우저에서 애플리케이션 http://localhost:3000으로 이동할 수 있습니다.

Docker Compose 중지 및 컨테이너 실행

앱 및 컨테이너를 완료하면 제거할 수 있습니다.

VS Code에서 다음 단계를 수행합니다.

  1. 탐색기(파일 및 폴더) 보기를 엽니다.

  2. docker-compose.yml 파일을 마우스 오른쪽 단추로 클릭하고 Compose Down을 선택합니다.

이 작업은 실행 중인 모든 컨테이너를 중지하고 네트워크를 제거합니다.

기본적으로 작성 파일의 명명된 볼륨은 제거되지 않습니다. 이러한 볼륨을 제거하려면 docker-compose down --volumes 명령을 사용할 수 있습니다.

리소스 정리

이 자습서 시리즈의 필수 구성 요소 구성 요소를 설치에 적용한 경우 향후 Docker 개발을 위해 구성을 다시 사용할 수 있습니다. 구성 요소를 삭제하거나 제거하는 것은 필수가 아닙니다.