2차 프로젝트(someus) 결과물을 컨테이너 기반으로 접근할 수 있도록 docker-compose.yaml 파일 작성

    1. 스프링부트 도커 이미지 빌드 

    1) Docker image로 만들기 전 수정해야 할 부분

    • application-properties

     

    수정 전

    C:/java/eclipse-workspace/someus/src/main/resources/static/application.properties

    spring.datasource.hikari.jdbc-url=jdbc:log4jdbc:mysql://localhost:3306/someusdb?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Seoul
    spring.datasource.hikari.username=root
    spring.datasource.hikari.password=root

    수정 후

    spring.datasource.hikari.jdbc-url=jdbc:log4jdbc:mysql://${MYSQL_SERVER}:${MYSQL_PORT}/someusdb?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Seoul
    spring.datasource.hikari.username=${MYSQL_USER}
    spring.datasource.hikari.password=${MYSQL_PASSWORD}

    이전에 Docker Container를 사용하기 전 localhost에 있는 DB 정보로 접속했던 부분을 수정

    DB 접속 정보를 시스템 환경 변수에서 읽어와서 사용하도록 수정

     

    • DiaryApiController

     

    수정 전

    C:/java/eclipse-workspace/someus/src/main/java/project.controller/DiaryApiController

    final String UPLOAD_PATH =
    C:/java/eclipse-workspace/someus/src/main/resources/static/img/”;

    수정 후

    final String UPLOAD_PATH =
    /my-app/diaryimg”;

     

    이전에 Docker Container를 사용하기 전 사용자가 일기를 작성할 때 업로드했던 이미지를 절대 경로를 사용해 표현했던 것을 상대 경로를 사용한 표현으로 변경

    TODO! 이후 해당 폴더를 호스트의 특정 폴더와 볼륨 맵핑을 해 주어야 함

     

     

    2) 해당 수정 사항을 바탕으로 빌드 진행

    • 빌드 이전 이클립스에서 환경 변수를 설정하여 테스트 실행

    application-properties에서 환경 변수를 읽어와서 설정하도록 한 부분을 이클립스 Run Configuration의 환경 변수로 추가하여 테스트 실행을 진행

     

    실행 결과

    Run Configuration에서 설정한 환경 변수를 사용해 정상적으로 springboot 애플리케이션이 실행되는 것을 확인

     

    • Talend API Tester를 사용해 애플리케이션 작동 여부 확인
    • Talend API Tester - API를 테스트할 수 있는 프로그램
    • 호스트의 데이터베이스에 포함된 데이터로 테스트 진행

     

     

    • 명령 프롬포트에서 gradlew build 명령어를 사용해 컨테이너 내에서 사용할 수 있는 형태로 생성
    c:\java\eclipse-workspace\someus>gradlew build -x test

     

    gradlew build

    • Gradle 빌드 도구를 사용해 프로젝트를 빌드하는 명령어

     

    gradlew(Gradle Wrapper)

    • 이미 존재하는 프로젝트를 새로운 환경에서 별도의 설치 없이 곧바로 빌드할 수 있도록 해 줌
    • 사용자가 프로젝트를 만든 사람과 동일한 버전의 gradle을 사용할 수 있도록 해 줌
    • 현재 프로젝트의 경우 컨테이너에서 호스트가 만든 프로젝트와 동일한 버전의 gradle을 사용하며 별도의 설치 없이 곧바로 빌드할 수 있도록 설정해 줌

     

    gradlew build -x test

    • Gradle 빌드 도구를 사용해 프로젝트를 빌드하지만, 테스트 코드를 실행하지 않고 빌드하는 옵션
    • gradlew build -x 옵션은 특정 태스크를 실행하지 않도록 지정하는 옵션

     

    실행 결과

    c:\java\eclipse-workspace\someus\build\libs 디렉터리


    2023-03-13  오후 12:12    <DIR>          .
    2023-03-13  오후 12:12    <DIR>          ..
    2023-03-15  오후 03:10        45,667,340 someus-0.0.1-SNAPSHOT-plain.jar
    2023-03-15  오후 03:10        91,018,041 someus-0.0.1-SNAPSHOT.jar

    프로젝트 내 /build/libs 위치에 현재 상태로 프로젝트가 빌드된 파일이 생성된 것을 확인

     

    3) 스프링부트 Dockerfile 작성

    스프링부트 이미지를 만들기 위한 Dockerfile

    C:/java/eclipse-workspace/someus/Dockerfile

      1 FROM                  openjdk:oracle
      2 RUN                     mkdir /my-app
      3 WORKDIR           /my-app
      4 RUN                    mkdir /my-app/diaryimg
      5 COPY                  ./build/libs/someus-0.0.1-SNAPSHOT.jar app.jar
      6 COPY                  ./src/main/resources/static/img/ /my-app/diaryimg/
      7 ENTRYPOINT     ["java", "-jar", "app.jar"]

     

    스프링부트 Dockerfile 설명

    SpringBoot 애플리케이션을 실행하기 위한 Docker 이미지를 빌드하기 위한 명세


     1 FROM - 어떤 이미지를 기반으로 이미지를 생성할지 설정
    • java 파일을 사용하는 컨테이너를 실행하기 때문에 jdk를 설치
    • Docker Hub에 있는 공식 이미지를 사용해 컨테이너를 실행


      2 RUN - FROM 에서 설정한 이미지 위에서 스크립트 혹은 명령을 실행
    • mkdir을 통해 작업 디렉터리가 될 my-app을 만드는 작업 실행


      3 WORKDIR - RUN, CMD, ENTRYPOINT의 명령이 실행될 디렉터리 설정
    • RUN  mkdir /my-app을 통해 만든 디렉터리를 기본 작업 디렉터리로 설정


      4 RUN - FROM 에서 설정한 이미지 위에서 스크립트 혹은 명령을 실행
    • mkdir을 통해 이후 사용자가 업로드하는 이미지를 저장해 둘 디렉터리를 만드는 작업 실행


      5 COPY - 파일을 이미지에 추가
    • 호스트 머신에 있는 ./build/libs/someus-0.0.1-SNAPSHOT.jar 파일을 컨테이너 내부에 app.jar이라는 파일로 복사


      6 COPY - 파일을 이미지에 추가
    • 컨테이너화하기 전 일기에 추가했던 이미지의 정보가 있기 때문에 기존의 파일을 컨테이너의 워크 디렉터리로 복사


      7 ENTRYPOINT - 컨테이너가 시작되었을 때 스크립트 혹은 명령을 실행
    • 컨테이너가 실행될 때 java -jar app.jar 명령어를 실행하며 springboot 애플리케이션을 실행할 수 있도록 함

     

    4) .dockerignore 파일 작성

    이미지를 빌드할 때 사용하지 않는 파일을 dockerignore 파일로 작성하여 필요하지 않은 파일이 포함되지 않도록 함

    C:/java/eclipse-workspace/someus/.dockerignore

    .classpath
    .gitignore
    .project
    .settings
    HELP.md
    mvnw.cmd
    target

     

    5) gradle build된 결과를 사용해 이미지 빌드

    • 명령 프롬포트를 실행하여 docker image build 명령 실행
    c:\java\eclipse-workspace\someus>docker build -t someus-springboot:v3 .

     

    • docker image build를 사용해 이미지를 생성하는 방법
    • Dockerfile이 저장된 디렉터리에서 명령을 실행해야 함
    • docker build <옵션> <Dockerfile 경로> 형식으로 이미지 생성
    • -t : 도커 이미지의 이름, 태그를 설정
      → someus-springboot라는 이름으로 도커 이름을 설정하고, v3은 세 번째 버전임을  
          나타내기 위한 태그를 사용
    • . : Dockerfile이 저장된 경로를 나타내는 것으로 현재 디렉터리에 있는 Dockerfile을 사용해 이미지를 빌드

     

    • docker image가 빌드된 것을 확인
    c:\java\eclipse-workspace\someus>docker image ls
    REPOSITORY           TAG       IMAGE ID             CREATED       SIZE
    someus-springboot   v3        13449b816260   2 hours ago   561MB

     

    6) 해당 이미지를 사용해 컨테이너 생성

    • docker run의 대표적인 옵션 종류
    • -i: 표준 입력을 활성화하며, 이 옵션을 사용해 컨테이너 내부에서 입력을 할 수 있도록 해 줌
    • -t: TTY 모드를 사용함
          이 옵션을 설정하지 않으면 명령을 입력할 수 있지만 셸이 표시되지 않음
    • -d: Detached 모드로 실행하며, 컨테이너를 백그라운드로 실행할 수 있도록 함
          이 옵션을 설정하지 않으면 Attached 모드로 컨테이너가 실행되어 포그라운드로 실행됨
    • -p: 호스트와 컨테이너의 포트를 설정해 주는 옵션
            <호스트 포트>:<컨테이너 포트> 형식으로 작성
    • --name: 컨테이너에 이름을 설정하는 옵션
    • -e: 컨테이너에 환경 변수를 설정하는 옵션
    • --link: 컨테이너끼리 연결하는 옵션
    • --rm: 컨테이너가 종료되면 컨테이너를 자동으로 삭제하는 옵션
    • -v: 데이터 볼륨을 설정하기 위한 옵션
          Docker 컨테이너의 생명 주기와 관계 없이 데이터를 영속적으로 저장할 수 있도록 해 줌

     

    • 명령 프롬포트에서 someus-springboot:v1을 사용한 컨테이너 생성
    c:\java\eclipse-workspace\someus>docker run -d -p 8080:8080 
                                                                    -e MYSQL_SERVER=192.168.0.37 
                                                                    -e MYSQL_PORT=3306
                                                                    -e MYSQL_USER=root 
                                                                    -e MYSQL_PASSWORD=root
                                                                     --name someus-spring 
                                                                    someus-springboot:v3

     

     

    • docker run을 사용해 컨테이너를 생성하는 방법
    • docker run <옵션> <이미지 이름> 형식으로 사용
    • -d: 컨테이너를 백그라운드로 실행
    • -p 8080:8080: springboot가 내부적으로 8080 포트를 사용해 동작하고 있으며, 호스트에서도 8080 포트를 사용해 접근할 수 있도록 설정
      → 이후 http://localhost:8080을 통해 컨테이너에 접근할 수 있음
    • -e MYSQL_SERVER=192.168.0.37:MySQL을 컨테이너로 통해 접속하기 전 호스트의 서버를 사용해 동작을 확인하기 위해 호스트의 IP 주소를 환경 변수로 설정
    • -e MYSQL_PORT=3306: 호스트의 PC에서 MySQL이 3306 포트로 작동하고 있기 때문에 3306 포트를 환경 변수로 설정
    • -e MYSQL_USER=root / -e MYSQL_PASSWORD=root: 호스트 PC에서 동작하고 있는 MySQL의 user 정보를 환경 변수로 설정
    • --name someus-spring: 컨테이너의 이름을 someus-spring으로 설정
    • Dockerfile을 사용해 생성한 someus-springboot:v3 이미지를 사용해 컨테이너를 생성

     

    • 생성된 컨테이너의 실행 결과 확인-Talend API Tester 사용


    2. 리액트 도커 이미지 빌드 

    1) Docker image로 만들기 전 수정해야 할 부분

    (1) .env 파일 작성

    • 개발 시 package.json 파일에 기본 설정을 하게 됨
    • 개발 환경과 배포 환경이 다른 경우, 이를 환경 변수를 선언하여 애플리케이션이 실행될 때 값을 설정할 수 있도록 설정해 주어야 함

     

    C:/javascript/someus-app/.env

    REACT_APP_IP=192.168.0.37
    REACT_APP_PORT=8080

     

    .env 파일 작성 시 주의사항

    사용자 지정 환경 변수는 ‘REACT_APP_’으로 시작되도록 작성해야 함

     

    process.env[key]

    • Node.js기반의 환경에서 환경변수에 접근하는 방법
    • process.env[key] 형태로 입력하면 npm run build를 할 때 .env 파일에 포함된 해당 환경 변수의 value가 포함되어 빌드됨

     

    (2) 리액트 컴포넌트에서 axios를 통해 스프링부트 서버로부터 데이터를 주고받는 부분을 수정

    예) 

    C:/javascript/someus-app/src/login/Loginpage.js

    수정 전

    const handlerSubmit = (e) => {
      …          
         axios.post(`http://localhost:8080/login`
         …  

    수정 후

    const handlerSubmit = (e) => {
      …          
    axios.post(`http://${process.env.REACT_APP_IP}:${process.env.REACT_APP_PORT}/login`
         …  

     

    • 기존에 localhost:8080 주소를 통해 axios 요청을 했던 것을 환경 변수로부터 읽어와서 사용할 수 있도록 수정해 줌
    • 기존 컴포넌트에 axios 요청을 했던 부분을 모두 process.env[key] 형태로 수정

     

    2) nginx.conf 파일 작성

    nginx.conf

    • nginx의 기본 설정 파일
    • nginx가 클라이언트의 요청을 받아들이고 처리하는 방법을 지정하는데 사용
    • server

     

    C:/javascript/someus-app/nginx.conf

    server {
        listen 80;
        location / {
            root        /usr/share/nginx/html/;
            index       index.html;
            try_files   $uri $uri/ /index.html;
        }
    }

     

    • listen 80: 80 포트에서 들어오는 요청을 수신하도록 설정
    • location / : 루트(/) 경로로 들어오는 요청을 처리하도록 설정
    • root: 요청이 들어오면 /usr/share/nginx/html 디렉터리에서 파일을 찾음
    • index: 초기 페이지로 index.html을 사용
    • try_files: 요청된 파일($uri)와 요청된 디렉터리($uri/)에 대해 존재 여부를 확인하고 해당 파일과 
                    디렉터리가 없을 경우 index.html 파일을 반환 

     

     

    3) .dockerignore 파일 작성

    C:/javascript/someus-app/.dockerignore

    build
    node_modules
    App.test.js
    logo.svg
    reportWebVitals.js
    setupTests.js
    .gitignore
    package-lock.json
    README.md
    .env

     

    4) Dockerfile 작성(다단계 빌드 이용)

    다단계 빌드

    • 이미지의 크기를 줄이기 위해 사용하는 전략 중 하나
    • 빌드 환경, 런타임 환경으로 구성됨
    • 빌드 환경: 빌드에 필요한 컴파일러, 빌드 도구 등을 포함하여 소스 코드를 실행 파일로 만들기 위함
    • 런타임 환경: 실행 파일, 런타임 도구만 포함하며 첫 번째 도커 컨테이너(빌드 환경)가 생성한 실행 파일을 실행하는 역할

     

    다단계 빌드의 장점

    • 저장소에 이미지를 저장하는 데 필요한 공간이 줄어들어 이미지 할당량을 절약하고 비용을 절약할 수 있음
    • 이미지의 크기가 작아지기 때문에 빌드 실행을 완료하는 데 적은 시간이 필요해짐
    • 이미지를 가져오는 데 필요한 시간이 짧으므로 이미지를 사용하는 애플리케이션 또한 작업이 빠르게 실행됨

     

     

     

    리액트 이미지를 만들기 위한 Dockerfile

    C:/javascript/someus-app/Dockerfile

    1 FROM                      alpine AS init
    2 RUN                         mkdir /my-app
    3 WORKDIR               /my-app
    4 ARG                        GIT_REPOSITORY_ADDRESS
    5 RUN                        apk update && apk add git && git clone $GIT_REPOSITORY_ADDRESS
     
     1 FROM                    nodes AS builder
      2 RUN                      mkdir /my-app
      3 WORKDIR            /my-app
      4 COPY                   --from=init /my-app/someus-docker-react .
      5 ARG                      REST_API_SERVER_IP
      6 ARG                      REST_API_SERVER_PORT
      7 RUN                      echo REACT_APP_IP=$REST_API_SERVER_IP > .env
      8 RUN                      echo REACT_APP_PORT=$REST_API_SERVER_PORT >> .env
      9 RUN                      npm install
      0 RUN                      npm run build


      1 FROM                   nginx AS runtime
      2 COPY                   --from=builder /my-app/build/ /usr/share/nginx/html/
      3 RUN                     rm /etc/nginx/conf.d/default.conf
      4 COPY                   --from=builder /my-app/nginx.conf /etc/nginx/conf.d
      5 CMD                     ["nginx", "-g", "daemon off;"]

     

     

    리액트 Dockerfile 설명 - 1(init)

    Git 저장소에 저장된 소스 코드를 불러오기 위한 Docker 이미지 빌드 명세


      1 FROM - 어떤 이미지를 기반으로 이미지를 생성할지 설정
    • alpine 이미지를 사용해 실행
    • Docker Hub에 있는 공식 이미지를 사용해 컨테이너를 실행


      2 RUN - FROM 에서 설정한 이미지 위에서 스크립트 혹은 명령을 실행
    • mkdir을 통해 작업 디렉터리가 될 my-app을 만드는 작업 실행


       3 WORKDIR - RUN, CMD, ENTRYPOINT의 명령이 실행될 디렉터리 설정
    • RUN  mkdir /my-app을 통해 만든 디렉터리를 기본 작업 디렉터리로 설정


      5 ARG - docker build 커맨드로 이미지를 빌드 시 -arg 옵션을 통해 넘길 수 있는 인자를 정의
    • 이후 docker build에서 —build-arg 옵션을 통해 넘긴 값을 전달받기 위함
    • 리액트 소스 코드가 저장된 깃 허브 주소를 받아오기 위한 인자를 정의

     

    리액트 Dockerfile 설명 - 2(builder)

    React 애플리케이션을 빌드하기 위한 Docker 이미지 빌드 명세


      1 FROM - 어떤 이미지를 기반으로 이미지를 생성할지 설정
    • node 기반의 빌드 환경 설정
    • nodes 이미지는 Node.js와 npm을 포함
    • Docker Hub에 있는 공식 이미지를 사용해 컨테이너를 실행


      2 RUN - FROM 에서 설정한 이미지 위에서 스크립트 혹은 명령을 실행
    • mkdir을 통해 작업 디렉터리가 될 my-app을 만드는 작업 실행


      3 WORKDIR - RUN, CMD, ENTRYPOINT의 명령이 실행될 디렉터리 설정
    • RUN  mkdir /my-app을 통해 만든 디렉터리를 기본 작업 디렉터리로 설정


      4 COPY - 파일을 이미지에 추가
    • 앞서 init 단계에서 생선된 /my-app/someus-docker-react 아래의 모든 파일을 현재 작업 디렉터리로 복사


      5 ARG - docker build 커맨드로 이미지를 빌드 시 -arg 옵션을 통해 넘길 수 있는 인자를 정의
    • 이후 docker build에서 —build-arg 옵션을 통해 넘긴 값을 전달받기 위함
    • REST API 서버의 IP 주소를 전달받기 위한 인자를 정의


       6 ARG - docker build 커맨드로 이미지를 빌드 시 -arg 옵션을 통해 넘길 수 있는 인자를 정의
    • 이후 docker build에서 —build-arg 옵션을 통해 넘긴 값을 전달받기 위함
    • REST API 서버의 포트 주소를 전달받기 위한 인자를 정의


       7 RUN - FROM 에서 설정한 이미지 위에서 스크립트 혹은 명령을 실행
    • .env 파일을 생성해 REACT_APP_IP 환경 변수를 추가
    • ARG  REST_API_SERVER_IP에서 넘겨받은 인자의 value를 REACT_APP_IP의 value로 설정해 .env 파일을 생성한 후 추가


       8 RUN - FROM 에서 설정한 이미지 위에서 스크립트 혹은 명령을 실행
    • .env 파일에 REACT_APP_PORT 환경 변수를 추가
    • ARG  REST_API_SERVER_PORT에서 넘겨받은 인자의 value를 REACT_APP_PORT의 value로 설정해 .env 파일에 추가


       9 RUN - FROM 에서 설정한 이미지 위에서 스크립트 혹은 명령을 실행
    • npm install 명령어를 해당 이미지 위에서 실행
    • 애플리케이션을 빌드하기 위해 필요한 패키지를 설치


       0 RUN - FROM 에서 설정한 이미지 위에서 스크립트 혹은 명령을 실행
    • npm run build 명령어를 해당 이미지 위에서 실행
    • React 애플리케이션을 빌드
    • 이 명령어를 실행하면 build 디렉터리에 빌드의 결과물이 생성됨

     

    리액트 Dockerfile 설명 - 3(runtime)

    React 애플리케이션을 실행하기 위한 Docker 이미지 빌드 명세


      1 FROM - 어떤 이미지를 기반으로 이미지를 생성할지 설정
    • React로 작성된 파일을 클라이언트(웹 브라우저)에게 전송하여 실행할 수 있도록 nginx를 사용
    • Docker Hub에 있는 공식 이미지를 사용해 컨테이너를 실행


      2 COPY - 파일을 이미지에 추가
    • 앞서 builder 단계에서 빌드한 결과물인 /my-app/build/ 디렉터리를 nginx의 기본 디렉터리인 /usr/share/nginx/html/로 복사


      3 RUN - FROM 에서 설정한 이미지 위에서 스크립트 혹은 명령을 실행
    • nginx의 기본 설정 파일인 default.conf를 삭제
    • 컨테이너 내부의 nginx가 더 이상 이 파일을 사용하지 않도록 함


      4 COPY - 파일을 이미지에 추가
    • 호스트 PC의 nginx.conf 파일을 컨테이너 내부의 etc/nginx/conf.d 디렉터리에 복사
    • nginx.conf는 웹 페이지 연결 등과 같은 설정을 담당


      5 CMD - 컨테이너가 시작되었을 때 스크립트 혹은 명령을 실행
            - docker run 명령으로 컨테이너를 생성하거나 docker start 명령으로 정지된 컨테이너를
              시작할 때 실행됨

    • nginx 명령으로 nginx를 실행
    • -g daemon off 옵션을 사용해 nginx가 백그라운드에서 실행될 수 있도록 설정

     

    5) .dockerignore 파일 작성

    이미지를 빌드할 때 사용하지 않는 파일을 dockerignore 파일로 작성하여 필요하지 않은 파일이 포함되지 않도록 함

    C:/javascript/someus-app/.dockerignore

    build
    node_modules
    App.test.js
    logo.svg
    reportWebVitals.js
    setupTests.js
    .gitignore
    package-lock.json
    README.md
    .env

     

    6) 리액트 이미지 빌드

    이미지를 빌드할 때 사용하지 않는 파일을 dockerignore 파일로 작성하여 필요하지 않은 파일이 포함되지 않도록 함

    • 명령 프롬포트를 실행하여 docker image build 명령 실행
    c:\javascript\someus-app> docker image build 
             --build-arg GIT_REPOSITORY_ADDRESS=http://github.com/2chocho2/someus-docker-react.git             
             --build-arg REST_API_SERVER_IP=localhost
             --build-arg REST_API_SERVER_PORT=8080 

             --no-cache 
             -t someus-docker-react .

     

    • docker image build를 사용해 이미지를 생성하는 방법
    • Dockerfile이 저장된 디렉터리에서 명령을 실행해야 함
    • docker build <옵션> <Dockerfile 경로> 형식으로 이미지 생성
    • --build-arg: build 명령을 실행할 때 추가로 Dockerfile 내에서 사용된 변수의 값을 설정
    • --no-cache : Docker가 이미지를 빌드할 때 캐시된 데이터를 사용하지 않도록 설정
    • -t : 도커 이미지의 이름, 태그를 설정
      → someus-docker-react라는 이름의 이미지를 생성

     

    • docker image가 빌드된 것을 확인
    c:\javascript\someus-app>docker image ls
    REPOSITORY                  TAG       IMAGE ID             CREATED       SIZE
    someus-docker-react    latest    97c0bdbb0933   44 minutes ago   351MB

     

    7) 해당 이미지를 사용해 컨테이너 생성

    • 명령 프롬포트에서 someus-docker–react:latest를 사용한 컨테이너 생성
    c:\javascript\someus-app>docker run -d -p 80:80 someus-docker-react

     

    • docker run을 사용해 컨테이너를 생성하는 방법
    • docker run <옵션> <이미지 이름> 형식으로 사용
    • -d: 컨테이너를 백그라운드로 실행
    • -p 80:80: react가 nginx 환경에서 내부적으로 80 포트를 사용해 동작하고 있으며, 호스트에서도 80 포트를 사용해 접근할 수 있도록 설정
      → 이후 http://localhost:80을 통해 컨테이너에 접근할 수 있음
    • Dockerfile을 사용해 생성한 someus-docker-react 이미지를 사용해 컨테이너를 생성

     

    • 생성된 컨테이너의 실행 결과 확인


    3. MySQL 도커 이미지 빌드

    1) MySQL 컨테이너 실행

    • 명령 프롬포트에서 mysql 공식 이미지를 사용한 컨테이너 생성
    C:\>docker run -d -p 5506:3306 
                                -e MYSQL_ROOT_PASSWORD=root 
                                -e MYSQL_DATABASE=someusdb 
                                --name someus-mysql
                                -v  /c/docker/someus-data/:/var/lib/mysql
                                mysql:5.7

     

    • docker run을 사용해 mysql 컨테이너를 생성하는 방법
    • docker run <옵션> <이미지 이름> 형식으로 사용
    • -d: 컨테이너를 백그라운드로 실행
    • -p 5506:3306: MySQL이 내부적으로 3306 포트를 사용해 동작하고 있으며, 호스트에서 5506 포트를 사용해 접근할 수 있도록 설정
    • -e MYSQL_ROOT_PASSWORD=root: MySQL 공식 이미지를 사용한 컨테이너를 생성 시 필수로 사용되어야 하는 환경변수로, MySQL의 root 계정 비밀번호를 입력
    • -e MYSQL_DATABASE=someusdb: 컨테이너를 시작할 때 특정 데이터베이스(스키마)를 생성할 때 사용하는 환경 변수로, 컨테이너가 실행될 때 someusdb라는 스키마가 생성
    • --name someus-mysql: 컨테이너의 이름을 someus-mysql으로 설정
    • -v  /c/docker/someus-data/:/var/lib/mysql: -v: 데이터 볼륨을 설정하기 위한 옵션
      Docker 컨테이너의 생명 주기와 관계 없이 데이터를 영속적으로 저장할 수 있도록 해 줌
    • mysql:5.7: 도커 허브에 등록되어 있는 MySQL 공식 이미지를 사용해 컨테이너를 생성
    • 볼륨 매핑이 된 것을 확인

    컨테이너를 실행할 때 볼륨 매핑이 정상적으로 처리되면 호스트 PC에 지정한 디렉터리가 생성되며, 기본 설정 파일과 환경 변수로 설정했던 기본 스키마가 생성된 것을 확인할 수 있음

     

    2) 기존 사용하던 데이터 export

    • MySQL에 접속하여 기존에 사용하던 Connection에 접속

     

    • Administration 탭에서 Data Export 선택

     

    • Export할 스키마를 선택한 후, Start Export

     

     

    3) MySQL Workbench에서 새로운 Connection 생성하여 데이터 Import

    • MySQL 컨테이너의 3306을 호스트 PC의 5506 포트를 통해 연결했기 때문에 localhost의 IP인 127.0.0.1:5506으로 Connection 생성

     

    • 생성한 Connection에 접속해 Data Import

     

    • Export했던 데이터 디렉터리를 선택하고 스키마 확인 후 Start Import

     

    데이터 Import가 된 것을 확인

    -1 MySQL Workbench

     

    -2 볼륨 매핑한 폴더

     

    4) 현재의 상태를 기준으로 컨테이너 commit하여 이미지 생성

    • 명령 프롬포트에서 현재 실행 중인 MySQL 컨테이너의 id 조회
    C:\>docker container ls

    CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS         PORTS                               NAMES
    80be9dd442e5   mysql:5.7   "docker-entrypoint.s…"   7 seconds ago   Up 6 seconds   33060/tcp, 0.0.0.0:5506->3306/tcp   someus-mysql

     

    • 명령 프롬포트에서 현재 컨테이너의 상태를 기준으로 컨테이너 commit하여 이미지 생성

    docker commit을 사용해 컨테이너의 변경 사항을 이미지로 생성하는 법

    • docker commit: 컨테이너의 변경 사항을 이미지 파일로 생성할 때 사용
    • docker commit <옵션> <컨테이너 이름 또는 컨테이너 ID> <이미지 이름>:<태그> 형식으로 사용

     

    mysql의 현재 상태를 기준으로 컨테이너 commit 실행

    C:\>docker commit 80 choocho/someus-mysql:v2

     

    이미지가 생성된 것을 확인

    C:\>docker image ls

    REPOSITORY                        TAG       IMAGE ID            CREATED              SIZE
    choocho/someus-mysql         v2        4a394e2ad822   23 seconds ago   455MB

    4. 모든 이미지를 빌드한 후에는 모든 컨테이너를 삭제

    • PowerShell을 사용해 모든 컨테이너 삭제
    PS C:\Users\hi> docker container rm -f $(docker container ls -a -q)

     

    PowerShell을 사용해 모든 컨테이너를 삭제하는 방법

    • docker container rm: 하나 이상의 특정 도커 컨테이너를 삭제하는 데 사용되는 명령
    • $(...): 명령의 출력을 다른 명령의 입력으로 사용할 수 있도록 하는 PowerShell의 명령 구문
      -> $(...) 내부의 출력 결과를 앞서 작성된 docker container rm -f의 값으로 사용할 수 있도록 해 줌
    • docker container ls: 현재 실행 중인 모든 컨테이너의 목록을 보여 주는 명령

    5. Docker-compose

    도커 컴포즈란?

    • 도커 컴포즈는 여러 개의 도커 컨테이너를 사용하는 애플리케이션을 쉽게 관리할 수 있도록 도와주는 도구
    • 하나의 서비스를 위해 여러 개의 애플리케이션을 실행해야 하면 각각의 컨테이너를 실행해야 하는 번거로움이 있어, 한 번의 실행으로 여러 개의 컨테이너를 실행할 수 있도록 해 주는 docker-compose를 사용하면 편하게 서비스를 운영할 수 있음
    • 도커 컴포즈를 사용하면 여러 개의 도커 컨테이너를 쉽게 연결할 수 있고, 컨테이너 간 의존 관계를 관리할 수 있음

     

    도커 컴포즈 사용법

    • 서비스를 실행해야 할 때 사용할 컨테이너를 docker-compose.yaml 또는 docker-compose.yml 파일에 정의하여 실행함
    • yaml 또는 yml 파일을 작성할 때는 tab은 도커 컴포즈가 인식하지 못하므로 2개의 공백을 사용해 하위 항목을 구분해야 함

     

    docker-compose.yaml

    • 기존에 컨테이너를 실행할 때 사용하던 run 명령어를 yaml 파일에 작성하는 방식으로 사용

     

    docker-compose.yaml(또는 docker-compose.yml) 파일 구조

     

    • 예시로 설정된 docker-compose.yaml 파일을 실행하게 되면 container1, container2가 실행됨
    • version
    • service

    1) docker-compose.yaml 파일 작성

    • C:/docker/someus-docker 위치에서 docker-compose.yaml 파일 작성
    C:> cd /docker
    C:/docker> mkdir someus-docker
    C:/docker> cd someus-docker
    C:/docker/someus-docker> code .

     

    C:/docker/someus-docker/docker-compose.yaml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    1
    2
    3
    4
    5
    6
    7
    8
    9
    20
    1
    2
    3
    4
    5
    6
    7
    8
    9
    30
    1
    2
    version: '3.3'
    services:
      someus-mysql:
        image: choocho/someus-mysql:v4
        ports:
          - 5506:3306
        volumes:
          - /c/docker/someus-data/:/var/lib/mysql
        restart: always
      someus-springboot:
        depends_on:
          - someus-mysql
        image: choocho/someus-springboot:v3
        volumes:
          - /c/docker/someus-diaryimg/:/my-app/diaryimg/
        ports:
          - 8080:8080
        environment:
          - MYSQL_USER=root
          - MYSQL_PASSWORD=root
          - MYSQL_SERVER=someus-mysql
          - MYSQL_PORT=3306
        restart: always
      someus-react:
        depends_on:
          - someus-springboot
        image: choocho/someus-docker-react:v1
         environment:
          - REST_API_SERVER_IP=192.168.0.37
          - REST_API_SERVER_PORT=8080
        ports:
          - 80:80

     

    docker-compose.yaml 파일 설명

     

    1 version: '3.3' yaml 파일의 버전을 정의
    2 services: 도커 컴포즈로 생성할 컨테이너를 정의
     : 현재 services에 someus-mysql, someus-springboot,      
       someus-react가 있으므로 3개의 컨테이너를 실행하게 됨
    3 someus-mysql: someus-mysql 컨테이너의 옵션을 정의
    4 image: 
    choocho/someus-mysql:v4
    데이터베이스를 포함해 빌드한 someus-mysql을 베이스 이미지로 지정
    5
    6
    ports:
        - 5506:3306
    호스트와 연결할 포트를 지정(docker run -p와 동일)
    컨테이너 내부에 MySQL이 실행되고 있는 3306 포트와 호스트의 5506 포트를 연결
    7
    8
    volumes:
    - /c/docker/someus-data/:/var/lib/mysql
    호스트의 특정 디렉터리와 볼륨 매핑(docker run -v와 동일)
    호스트의 /c/docker/someus-data/ 디렉터리를 컨테이너 내부의 /var/lib/mysql 디렉터리와 매핑
    9 restart: always 컨테이너가 실행 중 중단됐을 때 컨테이너를 재시작
    10 someus-springboot: someus-springboot 컨테이너의 옵션을 정의
    1
    2
    depends_on:
          - someus-mysql
    특정 컨테이너와 의존 관계 설정(docker run —link와 동일)
    someus-mysql 컨테이너가 실행된 후에 someus-springboot 컨테이너가 실행됨
    3 image: choocho/someus-springboot:v3 someus-springboot:v3을 베이스 이미지로 지정
    4
    5
    volumes:
    -/c/docker/someus-diaryimg/:
      /my-app/diaryimg/
    호스트의 특정 디렉터리와 볼륨 매핑(docker run -v와 동일)
    호스트의 /c/docker/someus-diaryimg/ 디렉터리를 컨테이너 내부의 /my-app/diaryimg/ 디렉터리와 매핑
    6
    7
    ports:
          - 8080:8080
    호스트와 연결할 포트를 지정(docker run -p와 동일)
    컨테이너 내부에 springboot가 실행되고 있는 8080 포트와 호스트 PC의 8080 포트와 연결
    8
    9
    20
    1
    2
    environment:
          - MYSQL_USER=root
          - MYSQL_PASSWORD=root
          - MYSQL_SERVER=someus-mysql
          - MYSQL_PORT=3306
    컨테이너의 환경 변수 정의
    컨테이너에서 동작하고 있는 MySQL root 계정 정보를 환경 변수로 설정
    someus-mysql 컨테이너의 주소와 MySQL이 실행되고 있는 3306 포트를 사용해 데이터베이스 연결
    3 restart: always 컨테이너가 실행 중 중단됐을 때 컨테이너를 재시작
    4 someus-react: someus-react 컨테이너의 옵션을 정의
    5
    6
    depends_on:
          - someus-springboot
    특정 컨테이너와 의존 관계 설정(docker run —link와 동일)
    someus-springboot 컨테이너가 실행된 후에 someus-react 컨테이너가 실행됨
    7 image: choocho/someus-docker-react:v1 someus-docker-react:v1을 베이스 이미지로 지정
    8
    9
    30
    environment:
      - REST_API_SERVER_IP=192.168.0.37
      - REST_API_SERVER_PORT=8080
    컨테이너의 환경 변수 정의
    REST_API_SERVER_IP의 주소를 동적으로 설정할 수 있도록 환경 변수로 설정하며, docker-compose를 실행하는 호스트 PC의 IP를 사용해 접속
    1
    2
    ports:
          - 80:80
    호스트와 연결할 포트를 지정(docker run -p와 동일)
    컨테이너 내부에 nginx가 실행되고 있는 80 포트와 호스트 PC의 80 포트를 연결

     

    6. docker-compose up 명령어를 사용해 컨테이너 생성

    C:/docker/someus-docker 위치에서 docker-compose up 명령 실행

    C:/docker/someus-docker> docker-compose up

     

    컨테이너 실행 결과 확인

    -1 웹 페이지 확인

    localhost:80으로 접속했을 때 mainpage.js가 실행됨

    기존 DB에 저장되어 있던 정보로 로그인 시 성공적으로 실행되는 것을 확인

     

    기존에 등록했던 일기 목록 확인

     

    일기 작성 확인

    : 볼륨 매핑된 폴더에 정상적으로 업로드한 이미지가 저장되는 것을 확인

     

    -2 MySQL 확인

    Connection에서 4406 포트로 연결한 곳으로 접속

    테이블 확인

    작성한 일기 데이터가 있는지 확인

     

     

     

    댓글