ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • docker-compose 로 개발환경 구성
    ✍️ 개인 스터디 기록 2020. 4. 24.

    프로젝트는 다음과 같은 폴더구조로
    Vue CLI 로 생성 된 gallery_app패키지가 들어있는 front 폴더와
    express로 작성된 패키지 인 back 폴더로 되어있습니다.

     

    gallery_app
        ㄴback
            ㄴ package.json
        ㄴ front
            ㄴ gallery_app
                ㄴ package.json

     

    1. Docker for Mac 설치

    -> https://docs.docker.com/v17.09/docker-for-mac/install/#download-docker-for-mac
    -> docker-compose 도 같이 설치 되었는지 확인

    $ docker-compose —-version 

     

    2. Front / Backend 폴더 구조 나누기

    개발 단계에서 Front 와 Backend 각각 Dockerfile을 나누어 작성하고 각각 관리 되도록 하기 위하여 Dockerfile을 작성 할 폴더들을 생성합니다.

    compose 폴더를 생성하고 express 와 vue 폴더를 하위 폴더로 생성

    gallery_app
        ㄴ back
            ㄴ package.json
        ㄴ front
            ㄴ gallery_app
                ㄴ package.json
        ㄴ compose
            ㄴ express
            ㄴ vue

     

    3. Dockerfile 작성

    위에서 생성 한 express 와 vue 폴더에 각각 Dockerfile을 작성합니다.
    Dockerfile의 파일명은 Dockerfile-dev로 생성했습니다. (나중에 docker-compose.yml 에 해당 파일의 경로를 지정할것이기 때문에 파일명은 아무거나 들어가도 상관 없습니다.)

     

    compose/express/Dockerfile-dev 작성

    # dockerhub 에 올려진 공식 node:10.15.3 이미지를 base 이미지로 사용하겠다.
    FROM node:10.15.3
    
    # 관리자는 cocoroocoo 이다.
    MAINTAINER cocoroocoo
    
    # 백엔드 환경 구성
    # 백엔드 작업 폴더를 기존 폴더에서 도커 안으로 복사해서 생성
    COPY back /gallery_app/back
    
    # 도커에서 백엔드 관련 명령어 돌릴 디렉토리 지정
    WORKDIR /gallery_app/back/
    
    # 백엔드 관련 명령어 실행 : 
    # RUN npm install -> Docker 컨테이너 내에서 실행 될 명령어는 쉘 스크립트로 빼서 관리 할것 이기 때문에 주석처리(#) 를 했습니다.
    
    # .sh파일을 워크 디렉토리 안으로 복사 -> 실행관련 명령어들이 작성된 쉘 스크립트를 컨테이너 디렉토리에 복사
    COPY compose/express/start-dev.sh /start-dev.sh
    
    # 복사한 .sh파일에 권한 부여 : +x 옵션  => 모든 사용자에게 실행권한 주기
    RUN chmod +x /*.sh

     

    compose/vue/Dockerfile-dev 작성

    # dockerhub에 있는 공식 node:10.15.3 이미지를 base 이미지로 사용하겠다.
    FROM node:10.15.3
    
    # 관리자는 cocoroocoo 이다.
    MAINTAINER cocoroocoo
    
    # 프론트 환경 구성
    # 프론트 작업 폴더 복사 생성 : COPY SRC DST
    COPY front/gallery_app /gallery_app/front
    # 도커에서 프론트 관련 명령어 돌릴 디렉토리 지정
    WORKDIR /gallery_app/front/
    # 프론트 관련 명령어 실행 : install 명령으로 front node 패키지의 dependency들 설치 후 build 명령으로 front 패키지의 package.json에 script로 등록된 build명령 실행
    #RUN npm install && npm run build -> Docker 컨테이너 내에서 실행 될 명령어는 쉘 스크립트로 빼서 관리 할것 이기 때문에 주석처리(#) 를 했습니다.
    
    # .sh파일을 해당 컨테이너 디렉토리 안으로 복사
    COPY compose/vue/start-dev.sh /start-dev.sh
    
    # 복사한 .sh파일에 권한 부여
    RUN chmod +x /*.sh

     

    4. 각 컨테이너에서 실행될 명령어들을 작성한 쉘스크립트 작성

    • compose/express/start-dev.sh 작성

    gallery_app의 Backend 패키지는 start 명령어가 등록 되어 있기 때문에 쉘 스크립트에서 해당 명령어를 실행 시킵니다.

    #!/bin/sh
    
    npm install
    npm start
    • compose/vue/start-dev.sh 작성

    gallery_app의 Frontend 부분의 경우 Vue CLI 빌드 시 /back/public 폴더로
    프로덕션 빌드 파일이 올라가도록 설정 해 둔 상태이고,

    package.json에서 npm run build 스크립트로 해당 명령이 실행 되도록 설정을 해둔 상태이기 때문에

    프론트의 경우 따로 서버를 구동시키는 start 명령어 없이 build 명령만 실행 되도록 지정 하였습니다.

    #!/bin/sh
    
    npm install
    npm run build

    여기까지 완료하면 폴더 구조는 다음과 같습니다.

    gallery_app
        ㄴ back
        	ㄴ package.json
        ㄴ front
        	ㄴ gallery_app
    		    ㄴ package.json
        ㄴ compose
        	ㄴ express
        		ㄴ Dockerfile-dev
        		ㄴ start-dev.sh
        	ㄴ vue 
        		ㄴ Dockerfile-dev
        		ㄴ start-dev.sh

     

    5. docker-compose.yml 파일 작성

    프로젝트 루트 gallery_app/ 에 docker-compose.yml 파일을 생성한다.

    gallery_app
        ㄴ back
            ㄴ package.json
        ㄴ front
            ㄴ gallery_app
                ㄴ package.json
        ㄴ compose
            ㄴ express
                ㄴ Dockerfile-dev
                ㄴ start-dev.sh
            ㄴ vue 
                ㄴ Dockerfile-dev
                ㄴ start-dev.sh
         ㄴ docker-compose.yml

     

    gallery_app 프로젝트의 경우
    * express 가 구동되는 backend 컨테이너,
    * vue-cli 빌드가 수행되는 client 컨테이너,
    * mysql 이 실행되는 mysql 컨테이너

    이렇게 총 3개 의 컨테이너를 띄울 예정이다. 그리고 각 컨테이너에 대한 설정 정보들을 아래와 같이 docker-compose.yml에 작성한다.

     

    docker-compose.yml

    version: ‘3.7’
    
    services:
      mysql:
        image: mysql:5.7
        environment:
          MYSQL_ROOT_PASSWORD: root
          MYSQL_USER: test
          MYSQL_PASSWORD: test
          MYSQL_DATABASE: test
        ports:
          - '3306:3306’
        command: [mysqld, —character-set-server=utf8, —collation-server=utf8_unicode_ci]
        healthcheck:
          test: ‘mysqladmin -uroot -proot ping’
          interval: 3s
          timeout: 1s
          retries: 10
        expose:
          - ‘3306’
        volumes:
          - mysql_data:/var/lib/mysql
        networks:
          - default-network
    
      client:
        build:
          context: .
          dockerfile: ./compose/vue/Dockerfile-dev
        command: /start-dev.sh
        volumes:
          - ./client:/home/service/test/client/
          - client_node_modules:/home/service/test/client/node_modules/
        ports:
          - ‘3000:3000’
        stdin_open: false
        networks:
          - default-network
    
      backend:
        build:
          context: .
          dockerfile: ./compose/express/Dockerfile-dev
        command: /start-dev.sh
        environment:
          - COOKIE_SECRET=ㅁㅁㅁㅁㅁㅁㅁ
          - PORT=ㅁㅁㅁㅁㅁㅁ
          - ADMIN_ID=ㅁㅁㅁㅁ
          - ADMIN_PWD=ㅁㅁㅁㅁㅁ
          - AWSAccessKeyId=ㅁㅁㅁㅁㅁㅁㅁ
          - AWSSecretKey=ㅁㅁㅁㅁㅁㅁㅁㅁ
        depends_on:
          - mysql
        ports:
          - '8001:8001'
        expose:
          - '8001'
        networks:
          - default-network
        volumes:
          - ./backend:/home/service/test/backend/
          - node_modules:/home/service/test/backend/node_modules/
    
    volumes:
      mysql_data:
      client_node_modules:
      node_modules:
    
    networks:
      default-network:
        driver: bridge

     

    docker-compose.yml 살펴보기

    docker-compose.yml의 각 항목들은 docker 명령어와 대응하고
    docker-compose.yml은 gallery_app을 구동시키기 위한 3개의 docker 컨테이너를 한번의 명령어로 띄우기 위한 docker 명령어 들의 집합같은 느낌이 든다.

     

    서비스 정의

    services:
      mysql:
      client:
      backend:

    3개의 컨테이너를 띄웁니다.

     

    베이스가 되는 dockerfile 등록

    dockerfile: ./compose/vue/Dockerfile-dev 

    각 컨테이너에 해당하는 도커파일을 경로를 지정합니다.
    -> client 컨테이너의 경우 dockerfile의 경로를 위에서 작성한
    ./compose/vue/Dockerfile-dev 로 지정 해주었습니다.

     

    환경 변수 등록

    environment:
          - COOKIE_SECRET=ㅁㅁㅁㅁㅁㅁㅁ
          - PORT=ㅁㅁㅁㅁㅁㅁ
          - ADMIN_ID=ㅁㅁㅁㅁ
          - ADMIN_PWD=ㅁㅁㅁㅁㅁ
          - AWSAccessKeyId=ㅁㅁㅁㅁㅁㅁㅁ
          - AWSSecretKey=ㅁㅁㅁㅁㅁㅁㅁㅁ

    express 에서 사용하는 환경변수를 등록할 수 있습니다.

     

    의존성 등록

    depends_on:
        - mysql

    express의 경우 mysql 컨테이너가 먼저 실행되지 않을 경우 에러가 나기 때문에 express가 실행되는 backend 컨테이너 보다 mysql 컨테이너가 먼저 돌아야 됩니다.

     

    docker-compose.yml의 각 항목들에 대한 글 :

    Compose file version 3 reference | Docker Documentation
    도커(Docker) 컴포즈를 활용하여 완벽한 개발 환경 구성하기 | 44BITS
    Docker (Compose) 활용법 - 개발 환경 구성하기

     

     

    6. 실행 명령어

    gallery_app 루트 디렉토리 에서 해당 명령어들을 실행 시킵니다.

    * 최초 혹은 Dockerfile 수정 후 실행시 : 이미지 파일 빌드
    $ docker-compose up --build
    
    * backend 컨테이너의 bash 실행
    $ docker-compose exec backend /bin/bash
    
    * 모든 컨테이너 종료
    $ docker-compose stop
    
    * 모든 컨테이너 종료 및 볼륨, 네트워크 삭제
    $ docker-compose down -v
    
    * 다시 실행할 때
    $ docker-compose up

    댓글

GitHub: https://github.com/Yesung-Han