Docker compose

진성대·2023년 10월 4일
0

Docker

목록 보기
10/12

멀티 컨테이너 서비스를 위한 docker compose

멀티 컨테이너 서비스 구성

특징

  • docker compose 는 여러 번의 docker CLI를 실행하지 않고, 한번에 관련 애플리케이션들을 YAML 파일로 구성하여 내부 환경 구성과 속성을 실행할 수 있다.

  • 또한 docker compose 는 설정 값을 캐싱하기 때문에 재시작시 변경이 없다면 캐싱된 정보를 그대로 사용하여 빠른 서비스 실행을 보장할 수 있다.

  • YMAL 코드에 변경된 애플리케이션 들를 동일 네트워크에 포함되게 때무에 복잡한 연결 구성이 없어도 쉽게 API 통신이 가능한 장점도 갖게 된다.


  • docker composekubernetes와 같이 컨테이너 오케스트레이션 및 컨테이너화된 애플리케이션 관리에 사용되는 널리 사용되는 도구다.

  • docker compose 는 다중 컨테이너 Docker 애플리케이션을 정의하고 실행하기 위한 도구이고, YAML 파일을 사용하여 애플리케이션 서비스를 수행한다.

  • 이후 docker compose CLI를 이용하여 모든 서비스의 라이프 사이클을 관리한다.


  • 응집력 있는 애플리케이션 (cohesive application)으로 함께 작동하는 여러 컨테이너를 실행하려는 로컬 개발 및 테스트 환경을 위해 설계된 도구다.

응집력? 공통성?

  • 하나의 웹 애플리케이션을 생성하는 3-Tier 환경을 예를 들어보자.
  • 애플리케이션 데이터를 저장하기 위해 MySQL 데이터 베이스를 설정하고, API 애플리케이션 설정을 위해 backend 단에 Springboot, Flask, Node.js 등을 구성한다.
  • 그리고, 사용자 인터페이스(frontend) 구성을 위해 Nodejs. React, Angular 등의 웹 프레임워크를 선택해서 구성할 수 있다.

  • docker compose YMAL 코드는 여러개의 docker run 실행과 유사하며 네트워크, 볼륨 등을 한번에 생성할 수 있다.
    • 기본 이미지, 노출된 포트, 환경 변수, 컨테이너 간의 종속성 등을 포함하는 컨테이너들에 대한 구성 지성
    • docker compose로 실행된 컨테이너들은 독립된 네트워크로 구성되므로 컨테이너 간 통신이 쉽다.
  • docker compose 3단계 프로세스

    1. Dockerfile 작성으로 배포하고자 하는 애플리케이션 환경 정의(선택)
    2. docker-compose.yaml(or compose.yaml) 하나 이상의 컨테이너 서비스를 실행 할 수 있도록 정의
    3. docker compose up 명령으로 YAML 코드로 정의된 서비스를 시작하고 실행한다.

docker compowe 장단점

장점

  • 서로 다른 OS환경이라도 동일한 환경구성이 가능하다. (이식성)
  • 동일한 환경을 사용하기 때문에 개발환경에 이슈가 발생해도 팀간 소통이 쉽다.
  • 복잡한 환경도 YAML 코드로 스크립트화 할 수 있기 때문에 자동화가 가능하다.
  • docker compose CLI를 이용하여 쉽게 멀티 컨테이너 애플리케이션을 관리할 수 있다.

단점

  • 동시에 다수의 컨테이너 서비스를 수행하는 경우(MSA) 자원 활용률이 순간 높아질 수 있다.
  • docker-compose 사용은 충분한 docker container 기술에 대한 이해도가 필요하다.

선언적 구성 docker compose vs Kubernetes

비교docker composekubernetes
사용 범위단일 호스트(로컬)에서의 개발, 테스트 및 소규모 배포에 적합클러스터로 구성된 전체 머신을 기반으로 컨테이너화된 어플리케이션 배포에 적합
구조단일 시스템에서 컨테이너 간의 실행, 상호 작용 및 종속성 관리클러스터의 여러 노드에서 컨테이너를 오케스트레이션하고 확장, 로드밸런싱 메커니즘 제공
확장성 및 고가용성여러 호스트 서비스 지원하지 않음. 단, docker swarm 클러스터에서는 지원수요에 따른 애플리케이션 자동 확장 및 분산, 컨테이너 재시작 및 자동 장애 처리 기능 제공
서비스 검색 및 로드밸런싱자체 네트워크 생성. 컨테이너 연결 지원 및 서비스 간 포트 노출. 자체 로드밸런싱 없음DNS 기반 서비스 검색과 다중 컨테이너 간 분산 처리하는 로드밸런싱 제공
롤링 업데이트 및 배포 전략수동적 롤링 업데이트만 지원다운 타임 없이 컨테이너 업데이트 가능. Blue/gree 및 카나리아 배포 같은 배포 전략 제공

Docker -> Docker-compose 로 변환

# 첫 번째 mysql:8.0 컨테이너를 생성한다.
~$ docker run -itd \
> --name=mysql_app \
> -v mydb_data:/var/lib/mysql \
> --restart=always \
> -p 3306:3306 \
> --net=my-webdb-net \
> -e MYSQL_ROOT_PASSWORD=password# \
> -e MYSQL_DATABASE=wpdb \
> -e MYSQL_USER=wpuser \
> -e MYSQL_PASSWORD=wppassword \
> mysql:8.0-debian
# 두 번째 wordpress 컨테이너를 첫 번째 컨테이너와 연결하고, 생성한다.
~$ docker run -itd \
> --name=wordpress_app \
> -v myweb_data:/var/www/html \
> -v ${PWD}/myweb-log:/var/log \
> --restart=always \
> -p 8080:80 \
> --net=mywebdb-net \
> -e WORDPRESS_DB_HOST=mysql_app:3306 \
> -e WORDPRESS_DB_NAME=wpdb \
> -e WORDPRESS_DB_USER=wpuser \
> -e WORDPRESS_DB_PASSWORD=wppassword \
> --link mysql_app:mysql \
> wordpress:5.7

docker compose를 이용한 web application (wordpress+mysql)

#생성한 컨테이너들을 삭제한다.
~$ docker stop mysql_app wordpress_app
~$ docker rm mysql_app wordpress_app

# 작업을 docker-compose.yaml을 작성해본다.
version: "3.9"
services:
	# 첫 번째 서비스 정의.
    mydb:
    	# Docker 허브에서 제공하는 mysql:8.0 이미지 선택
    	image: mysql:8.0-debian
        # 서비스 컨테이너 이름 지정.
        container_name: mysql_app
        # 최상위 레벨에 정의 mydb_data 볼륨 지정.
        volumes:
        	- mydb_data:/var/lib/mysql
       	# 수동 제어를 제외한 컨테이너 종료 시 자동 재시작.
        restart: always
        # 호스트 운영체제와 컨테이너의 3306포트를 바인드한다.
        # workbench 같은 클라이언트 도구와 연결하기 위해 필요하다.
        ports:
        	- "3306:3306"
        # 최상위 레벨에 정의한 backend-net을 기본 네트워크로 지정한다.
        networks:
        	- backend-net
        # 서비스가 사용할 환경 변수 지정한다.
       	environment:
        	MYSQL_ROOT_PASSWORD: password#
            MYSQL_DATABASE: wpdb
            MYSQL_USER: wpuser
            MYSQL_PASSWORD: wppassword
            
# docker compose 애플리케이션이 사용할 network 생성.
networks:
	frontend-net: {}
    backend-net: {}

# docker compose 애플리케이션이 사용할 volume 생성.
volumes:
	mydb_data: {}
    myweb_data: {}

YAML 코드란?

  • YAML(Yet Another Markup Language or YAML ain't markup language)
  • 사람이 쉽게 읽을 수 잇는 데이터 질결화 언어(위 -> 아래)로 구성 파일 작성에 주로 사용된다.
    • 일반적으로 설계 상 가장 먼저 실행되야 하는 애플리케이션을 먼저 작성하고, 이와 의존성을 갖는 데이터베이스 및 하위 애플리케이션을 작성한다.
    • 또는, 클러스터 환경인 경우 마스터 노드를 먼저 작성하고 그다음 데이터 노드들을 이어서 작성하면 된다.
    • 그 다음 전체 애플리케이션에 필요한 네트워크, 볼륨, 캐시 등의 기반 환경까지 코드에 모두 설정할 수 있다.
    • 따라서, 서비스 전체를 하나의 docker-compose.yaml로 작성이 가능한 것이다.
  • 쉽게 읽고 이해할 수 있도록 설계되어 프로그래밍 언어로 사용되거나, 클라우드 자동 환경 배포 도구(IaC 환경 구성)로 많이 사용된다. (예, AWS CloudFormation, Redhat Ansible 등)

YAML 코드 문법적 특징

YAMLJSON
YAML Ain't Markup LanguageJavaScript Object Notation
주석 사용이 가능주석 사용 불가
한글 등의 유니코드를 그대로 사용 가능한글 등의 멀티 바이트 문자는 인코딩 수행
주로 환경 구성 등의 설정 파일 작성 시 사용주로 API 작성시 사용
  • 중괄호, 대괄호, 닫기 태그 또는 따옴표와 같은 통상적인 형식 기호는 없다.
  • Python 스타일의 들여쓰기를 사용해 구조를 결정하고 중첩을 표시한다.
  • 시스템 전반에서 이식성을 유지하기 위해 들여쓰기는 탭(tab) 문자를 허용하지 않고, 그대로의 공백 문자를 원하는 공백 *n 규칙성 있게 사용한다.
  • YAML 코드는 key, value 중심으로 작성되고, 숫자형 문자형 Boolean형을 지원한다.
    #: 해당라인 주석 처리
    ---: 문서의 시작(선택)
    ...: 문서의 끝(선택)
    key: python dictionary 자료형의 key와 동일
    value: python dictionary 자료형의 value 와 동일

YAML 코드 작성: services

  • docker compose는 컨테이너 대신 service 개념을 사용하고, 상위의 version 명령과 동일 레벨로 작성되며 다중 컨테이너 서비스 실행을 목적으로 하기 때문에 복수형으로 작성한다.
  • services 하위에는 실행될 컨테이너 서비스를 작성하고, 하위 레벨에 Docker명령 실행과 유사하게 컨테이너 실행에 필요한 옵션들을 작성한다.
version: "3.8"
services:
	서비스명1:
    #컨테이너에 필요한 옵션들 설정
    서비스명2:
    #컨테이너에 필요한 옵션들 설정
...
  • build : docker compose 실행 시 빌드 될 Dockerfile명시
mydiary-front:
 build:
  context: ./my-diary-front  # dockerfile 위치 (동일 경로면  생략 가능)
  dockerfile: Dockerfile  	 # 제공하는 Dockerfile 이름
  • container_name
    • 생략 시 자동으로 부여, "디렉터리명_서비스명_n".
    • docker run의 --name옵션과 동일
  • ports
    • 서비스 내부 포트와 외부 호스트 포트를 지정하여 바인드 외부 노출 포트 지정
    • docker run 의 -p 옵션과 동일
  • expose
    • 호스트 운영체제와 직접 연결하는 포트를 구성하지 않고, 서비스만 포트를 노출. 링크로 연결된 컨테이너 서비스와 서비스 간의 통신만 필요한 경우에 사용.
  • networks
    • 최상위 레벨의 networks에 정의 된 네트워크 이름을 작성.
    • docker run의 --net(--network)옵션과 동일.
  • volumes
    • 서비스 내부 디렉터리와 호스트 디렉터리를 연결하여 데이터 지속성 설정.
    • docker run의 -v(--volume)옵션과 동일.
  • environment
    • 서비스 내부 환경 변수 설정.
    • 환경 변수가 많은 경우, 파일(*.env)로 만들어 env_file 옵션에 파일명을 지정 ->env_file:./envfile.env
    • docker run의 -e 옵션과 동일
  • command
    • 서비스가 구동 이후 실행할 명령어 작성
    • docker run 의 마지막에 작성되는 명령어
  • restart
    • 서비스 재시작 옵션 지정.
    • docker run의 --restart 옵션과 동일
  • **depends_on
    • 서비스간의 종ㅅ옥성을 의미하며 먼저 실행해야 하는 서비스를 지정하여 순서 지정.
    • 이 옵션에 지정된 서비스가 먼저 시작됨
  • scale
    • 해당 서비스의 복제 컨테이너 수 지정(V2) -> (V3) deploy.replicas로 변경


YAML 코드 작성: networks

  • 다중 컨테이너들이 사용할 최상위 네트워크 키들을 정의하고 이하 하위 서비스 단위로 이 네트워크를 선택할 수 잇다.
    • driver: 서비스의 컨테이너가 브리지 네트워크가 아닌 다른 네트워크를 사용하도록 설정
    • ipam: IPAM(IP Address Manager)를 위해 사용할 수 있는 옵션으로 subnet, ip, gateway 범위 설정
    • external: 기존의 네트워크를 사용하도록 설정


YAML 코드 작성 : volumes

version: "3.8"
services:
 mydb:
  image: mysql:5.7
  volumes:
   - db_data:/var/lib/mysql
  ...
 myweb:
  image: wordpress:latest
  volumes:
   - w eb_data:/var/www/html
  ...
networks:
volumes:
 db_data: {} # {} 생략 가능
 web_data: {}
  • 데이터의 지속성을 유지하기 위해 푀상위 레벨에 볼륨을 정의하고, 서비스 레벨에서 볼륨명과 서비스 내부의 디렉터리를 바인드한다.
  • docker volume create와 동일하게 Docker가 관리하는 /var/lib/docker/volume에 자동 배치된다.
  • "docker volume ls" 명령과 "docker volume inspect 볼륨명"으로 확인 가능하다.

YAML 코드 작성 : healthcheck

version: "3.8"
services:
...

healthcheck:
 test: ["CMD", "curl", "-f", "http://localhost"]
 interval: 1m00s
 timeout: 10s
 retries: 3
 start_period: 30s
networks:
volumes:
  • 컨테이너 서비스의 상태를 체크하는 명령
  • 예시는
    • 컨테이너 서비스 시작 30초 부터 1분 무다
    • 웹 서비스가 10초 이내에 기본 페이지를 응답해야하고
    • 실패 시 3회 재시도 수행한다.

version: "3.8"
services:
  server_web:
    image: httpd:2
  server_db:
    image: redis:6-alpine
[root@ip-172-31-39-154 ~]# docker-compose up

[+] Running 14/14
 ⠿ server_db Pulled                                                                                                                                                                                                                      6.6s
   ⠿ 96526aa774ef Pull complete                                                                                                                                                                                                          2.1s
   ⠿ 8eae4a4e5454 Pull complete                                                                                                                                                                                                          2.2s
   ⠿ be9bc35ddfc9 Pull complete                                                                                                                                                                                                          2.5s
   ⠿ 16979fad3a95 Pull complete                                                                                                                                                                                                          3.3s
   ⠿ 4fcaecc2605d Pull complete                                                                                                                                                                                                          3.3s
   ⠿ 4f4fb700ef54 Pull complete                                                                                                                                                                                                          3.3s
   ⠿ d99f7c88acce Pull complete                                                                                                                                                                                                          3.4s
 ⠿ server_web Pulled                                                                                                                                                                                                                     9.6s
   ⠿ a803e7c4b030 Pull complete                                                                                                                                                                                                          4.3s
   ⠿ 053327351b4a Pull complete                                                                                                                                                                                                          4.3s
   ⠿ de42e9dfbbe1 Pull complete                                                                                                                                                                                                          4.6s
   ⠿ 9d28e265584b Pull complete                                                                                                                                                                                                          6.5s
   ⠿ ce95f18e49ae Pull complete                                                                                                                                                                                                          6.5s
[+] Running 3/3
 ⠿ Network root_default         Created                                                                                                                                                                                                  0.2s
 ⠿ Container root-server_db-1   Created                                                                                                                                                                                                  0.2s
 ⠿ Container root-server_web-1  Created                                                                                                                                                                                                  0.2s
Attaching to root-server_db-1, root-server_web-1
root-server_web-1  | AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.18.0.3. Set the 'ServerName' directive globally to suppress this message
root-server_web-1  | AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.18.0.3. Set the 'ServerName' directive globally to suppress this message
root-server_web-1  | [Thu Oct 05 06:33:48.364196 2023] [mpm_event:notice] [pid 1:tid 139636192311168] AH00489: Apache/2.4.57 (Unix) configured -- resuming normal operations
root-server_web-1  | [Thu Oct 05 06:33:48.364789 2023] [core:notice] [pid 1:tid 139636192311168] AH00094: Command line: 'httpd -D FOREGROUND'
root-server_db-1   | 1:C 05 Oct 2023 06:33:48.409 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
root-server_db-1   | 1:C 05 Oct 2023 06:33:48.410 # Redis version=6.2.13, bits=64, commit=00000000, modified=0, pid=1, just started
root-server_db-1   | 1:C 05 Oct 2023 06:33:48.410 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
root-server_db-1   | 1:M 05 Oct 2023 06:33:48.411 * monotonic clock: POSIX clock_gettime
root-server_db-1   | 1:M 05 Oct 2023 06:33:48.412 * Running mode=standalone, port=6379.
root-server_db-1   | 1:M 05 Oct 2023 06:33:48.413 # Server initialized
root-server_db-1   | 1:M 05 Oct 2023 06:33:48.413 # WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can can also cause failures without low memory condition, see https://github.com/jemalloc/jemalloc/issues/1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
root-server_db-1   | 1:M 05 Oct 2023 06:33:48.414 * Ready to accept connections

[ec2-user@ip-172-31-39-154 ~]$ docker ps -a
CONTAINER ID   IMAGE            COMMAND                  CREATED              STATUS                      PORTS                                                                                    NAMES
179cb1d5be62   redis:6-alpine   "docker-entrypoint.s…"   About a minute ago   Up About a minute           6379/tcp                                                                                 root-server_db-1
fc6a90aeb374   httpd:2          "httpd-foreground"       About a minute ago   Up About a minute           80/tcp                                                                                   root-server_web-1


###########################################################
########################### docker compose scale을 사용해보자
[root@ip-172-31-39-154 ~]# docker-compose up --scale server_db=1 --scale server_web=1 -d
[+] Running 2/2
 ⠿ Container root-server_db-1   Started                                                                                                                                                                                                  1.0s
 ⠿ Container root-server_web-1  Started                                                                                                                                                                                                  1.0s

[root@ip-172-31-39-154 ~]# docker-compose ps
NAME                COMMAND                  SERVICE             STATUS              PORTS
root-server_db-1    "docker-entrypoint.s…"   server_db           running             6379/tcp
root-server_web-1   "httpd-foreground"       server_web          running             80/tcp

[root@ip-172-31-39-154 ~]# docker-compose up --scale server_web=3 -d
[+] Running 4/4
 ⠿ Container root-server_db-1   Started                                                                                                                                                                                                  3.0s
 ⠿ Container root-server_web-3  Started                                                                                                                                                                                                  2.7s
 ⠿ Container root-server_web-1  Started                                                                                                                                                                                                  2.9s
 ⠿ Container root-server_web-2  Started                                                                                                                                                                                                  2.3s
 
 [root@ip-172-31-39-154 ~]# docker-compose ps
NAME                COMMAND                  SERVICE             STATUS              PORTS
root-server_db-1    "docker-entrypoint.s…"   server_db           running             6379/tcp
root-server_web-1   "httpd-foreground"       server_web          running             80/tcp
root-server_web-2   "httpd-foreground"       server_web          running             80/tcp
root-server_web-3   "httpd-foreground"       server_web          running             80/tcp

[root@ip-172-31-39-154 ~]# docker-compose down --rmi all
[+] Running 7/7
 ⠿ Container root-server_db-1   Removed                                                                                                                                                                                                  0.3s
 ⠿ Container root-server_web-3  Removed                                                                                                                                                                                                  1.5s
 ⠿ Container root-server_web-1  Removed                                                                                                                                                                                                  1.5s
 ⠿ Container root-server_web-2  Removed                                                                                                                                                                                                  1.5s
 ⠿ Image redis:6-alpine         Removed                                                                                                                                                                                                  0.1s
 ⠿ Network root_default         Removed                                                                                                                                                                                                  0.3s
 ⠿ Image httpd:2                Removed                                                                                                                                                                                                  0.4s

nginx proxy를 사용해서 docker-compose로 배포


3-tier 웹 어플리케이션 배포

[실습1] Docker cli를 통해서 이미지 build -> docker run

# 사전에 구성한 소스파일을 활용해서 frontend, backend image를 build한다.

[ec2-user@ip-172-31-39-154 my-diary-front]$ docker build -t mydiary-front:1.0 .
[+] Building 18.8s (9/9) FINISHED                                                                                                                                                                                              docker:default
 => [internal] load build definition from Dockerfile                                                                                                                                                                                     0.0s
 => => transferring dockerfile: 201B                                                                                                                                                                                                     0.0s
 => [internal] load .dockerignore                                                                                                                                                                                                        0.0s
 => => transferring context: 2B                                                                                                                                                                                                          0.0s
 => [internal] load metadata for docker.io/library/node:17-slim                                                                                                                                                                          2.3s
 => [1/4] FROM docker.io/library/node:17-slim@sha256:a180966357fe14cac9dd6c9cd496ed4d85b8a598cb33482705ecebad646145e3                                                                                                                    7.2s
 => => resolve docker.io/library/node:17-slim@sha256:a180966357fe14cac9dd6c9cd496ed4d85b8a598cb33482705ecebad646145e3                                                                                                                    0.0s
 => => sha256:af868bc40acde9dbbbd7b967b13f257d686cd2c421cd64d2c0768c9b56d19925 7.03kB / 7.03kB                                                                                                                                           0.0s
 => => sha256:42c077c10790d51b6f75c4eb895cbd4da37558f7215b39cbf64c46b288f89bda 31.38MB / 31.38MB                                                                                                                                         0.5s
 => => sha256:1d1b4cabe4ab7f16559c16a600d141af1e46a36592606aaf1b9846e9ecaed5d9 4.18kB / 4.18kB                                                                                                                                           0.6s
 => => sha256:fd2a83b16756304bc95a2f364042afb69936aa8024749af81607272d2efda81a 44.83MB / 44.83MB                                                                                                                                         1.2s
 => => sha256:a180966357fe14cac9dd6c9cd496ed4d85b8a598cb33482705ecebad646145e3 1.21kB / 1.21kB                                                                                                                                           0.0s
 => => sha256:924a5b8512a10d428bae66658d59f54d5c33b658edb2a3d718002a190966eb53 1.37kB / 1.37kB                                                                                                                                           0.0s
 => => extracting sha256:42c077c10790d51b6f75c4eb895cbd4da37558f7215b39cbf64c46b288f89bda                                                                                                                                                2.6s
 => => sha256:cd666498bb13c8026fce129218693dd9921deac32704b6a0d5c3a0849b9b1afd 2.77MB / 2.77MB                                                                                                                                           1.0s
 => => sha256:f428e85c51881b0db0fe6c2d4e5abc3b236cc5cf51e60e0c1fe5c5f56191d416 453B / 453B                                                                                                                                               0.8s
 => => extracting sha256:1d1b4cabe4ab7f16559c16a600d141af1e46a36592606aaf1b9846e9ecaed5d9                                                                                                                                                0.0s
 => => extracting sha256:fd2a83b16756304bc95a2f364042afb69936aa8024749af81607272d2efda81a                                                                                                                                                3.4s
 => => extracting sha256:cd666498bb13c8026fce129218693dd9921deac32704b6a0d5c3a0849b9b1afd                                                                                                                                                0.2s
 => => extracting sha256:f428e85c51881b0db0fe6c2d4e5abc3b236cc5cf51e60e0c1fe5c5f56191d416                                                                                                                                                0.0s
 => [internal] load build context                                                                                                                                                                                                        0.0s
 => => transferring context: 111.02kB                                                                                                                                                                                                    0.0s
 => [2/4] WORKDIR /home/node                                                                                                                                                                                                             0.1s
 => [3/4] COPY ./ ./                                                                                                                                                                                                                     0.1s
 => [4/4] RUN npm -y install                                                                                                                                                                                                             8.7s
 => exporting to image                                                                                                                                                                                                                   0.3s
 => => exporting layers                                                                                                                                                                                                                  0.3s
 => => writing image sha256:14694a3e18d7f2e073cf9fdfc23d255ee55c761e4853cd20d6849049c3c009b4                                                                                                                                             0.0s
 => => naming to docker.io/library/mydiary-front:1.0
 
 [ec2-user@ip-172-31-39-154 my-diary-front]$ cd ../my-diary-back/
[ec2-user@ip-172-31-39-154 my-diary-back]$ ls
Dockerfile  rollingpaper
[ec2-user@ip-172-31-39-154 my-diary-back]$ docker build -t mydiary-back:1.0 .
[+] Building 135.6s (14/14) FINISHED                                                                                                                                                                                           docker:default
 => [internal] load build definition from Dockerfile                                                                                                                                                                                     0.0s
 => => transferring dockerfile: 458B                                                                                                                                                                                                     0.0s
 => [internal] load .dockerignore                                                                                                                                                                                                        0.0s
 => => transferring context: 2B                                                                                                                                                                                                          0.0s
 => [internal] load metadata for docker.io/library/openjdk:11-jdk                                                                                                                                                                        2.2s
 => [builder 1/8] FROM docker.io/library/openjdk:11-jdk@sha256:99bac5bf83633e3c7399aed725c8415e7b569b54e03e4599e580fc9cdb7c21ab                                                                                                         17.4s
 => => resolve docker.io/library/openjdk:11-jdk@sha256:99bac5bf83633e3c7399aed725c8415e7b569b54e03e4599e580fc9cdb7c21ab                                                                                                                  0.0s
 => => sha256:99bac5bf83633e3c7399aed725c8415e7b569b54e03e4599e580fc9cdb7c21ab 1.04kB / 1.04kB                                                                                                                                           0.0s
 => => sha256:e81b7f317654b0f26d3993e014b04bcb29250339b11b9de41e130feecd4cd43c 1.79kB / 1.79kB                                                                                                                                           0.0s
 => => sha256:47a932d998b743b9b0bcce55aa8ede77de94a6a183c8a67dec9d5e3b8ce0faa7 6.26kB / 6.26kB                                                                                                                                           0.0s
 => => sha256:001c52e26ad57e3b25b439ee0052f6692e5c0f2d5d982a00a8819ace5e521452 55.00MB / 55.00MB                                                                                                                                         0.8s
 => => sha256:d9d4b9b6e964657da49910b495173d6c4f0d9bc47b3b44273cf82fd32723d165 5.16MB / 5.16MB                                                                                                                                           0.9s
 => => sha256:2068746827ec1b043b571e4788693eab7e9b2a95301176512791f8c317a2816a 10.88MB / 10.88MB                                                                                                                                         0.8s
 => => extracting sha256:001c52e26ad57e3b25b439ee0052f6692e5c0f2d5d982a00a8819ace5e521452                                                                                                                                                6.1s
 => => sha256:66223a710990a0ae7162aeed80417d30303afa3f24aafa57aa30348725e2230b 213B / 213B                                                                                                                                               1.1s
 => => sha256:9daef329d35093868ef75ac8b7c6eb407fa53abbcb3a264c218c2ec7bca716e6 54.58MB / 54.58MB                                                                                                                                         2.4s
 => => sha256:d85151f15b6683b98f21c3827ac545188b1849efb14a1049710ebc4692de3dd5 5.42MB / 5.42MB                                                                                                                                           1.2s
 => => sha256:db38d58ec8ab4111b072f6700f978a51985acd252aabce3be377f25162e68301 202.07MB / 202.07MB                                                                                                                                       5.9s
 => => extracting sha256:d9d4b9b6e964657da49910b495173d6c4f0d9bc47b3b44273cf82fd32723d165                                                                                                                                                0.3s
 => => extracting sha256:2068746827ec1b043b571e4788693eab7e9b2a95301176512791f8c317a2816a                                                                                                                                                0.4s
 => => extracting sha256:9daef329d35093868ef75ac8b7c6eb407fa53abbcb3a264c218c2ec7bca716e6                                                                                                                                                3.6s
 => => extracting sha256:d85151f15b6683b98f21c3827ac545188b1849efb14a1049710ebc4692de3dd5                                                                                                                                                0.3s
 => => extracting sha256:66223a710990a0ae7162aeed80417d30303afa3f24aafa57aa30348725e2230b                                                                                                                                                0.0s
 => => extracting sha256:db38d58ec8ab4111b072f6700f978a51985acd252aabce3be377f25162e68301                                                                                                                                                5.2s
 => [internal] load build context                                                                                                                                                                                                        0.0s
 => => transferring context: 84.98kB                                                                                                                                                                                                     0.0s
 => [builder 2/8] COPY ./rollingpaper/gradlew .                                                                                                                                                                                          0.2s
 => [builder 3/8] COPY ./rollingpaper/gradle gradle                                                                                                                                                                                      0.1s
 => [builder 4/8] COPY ./rollingpaper/build.gradle .                                                                                                                                                                                     0.0s
 => [builder 5/8] COPY ./rollingpaper/settings.gradle .                                                                                                                                                                                  0.0s
 => [builder 6/8] COPY ./rollingpaper/src src                                                                                                                                                                                            0.1s
 => [builder 7/8] RUN chmod +x ./gradlew                                                                                                                                                                                                 1.1s
 => [builder 8/8] RUN ./gradlew bootJar                                                                                                                                                                                                111.9s
 => [stage-1 2/2] COPY --from=builder build/libs/*.jar app.jar                                                                                                                                                                           0.1s
 => exporting to image                                                                                                                                                                                                                   0.4s
 => => exporting layers                                                                                                                                                                                                                  0.4s
 => => writing image sha256:c491bbb195166e2a3954e989329021048ba482a47ca24a70cb4679394d79b781                                                                                                                                             0.0s
 => => naming to docker.io/library/mydiary-back:1.0                                                                                                                                                                                      0.0s
[ec2-user@ip-172-31-39-154 my-diary-back]$ docker images | grep mydiary
mydiary-back    1.0       c491bbb19516   9 seconds ago   694MB
mydiary-front   1.0       14694a3e18d7   4 minutes ago   252MB

# 생성된 frontend, backend iamge를 확인한다.
[ec2-user@ip-172-31-39-154 my-diary-back]$ docker image history mydiary-front:1.0
IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
14694a3e18d7   5 minutes ago   CMD ["npm" "run" "start"]                       0B        buildkit.dockerfile.v0
<missing>      5 minutes ago   EXPOSE map[3000/tcp:{}]                         0B        buildkit.dockerfile.v0
<missing>      5 minutes ago   RUN /bin/sh -c npm -y install # buildkit        10.3MB    buildkit.dockerfile.v0
<missing>      5 minutes ago   COPY ./ ./ # buildkit                           110kB     buildkit.dockerfile.v0
<missing>      5 minutes ago   WORKDIR /home/node                              0B        buildkit.dockerfile.v0
<missing>      16 months ago   /bin/sh -c #(nop)  CMD ["node"]                 0B
<missing>      16 months ago   /bin/sh -c #(nop)  ENTRYPOINT ["docker-entry…   0B
<missing>      16 months ago   /bin/sh -c #(nop) COPY file:4d192565a7220e13…   388B
<missing>      16 months ago   /bin/sh -c set -ex   && savedAptMark="$(apt-…   9.5MB
<missing>      16 months ago   /bin/sh -c #(nop)  ENV YARN_VERSION=1.22.19     0B
<missing>      16 months ago   /bin/sh -c ARCH= && dpkgArch="$(dpkg --print…   152MB
<missing>      16 months ago   /bin/sh -c #(nop)  ENV NODE_VERSION=17.9.1      0B
<missing>      16 months ago   /bin/sh -c groupadd --gid 1000 node   && use…   333kB
<missing>      16 months ago   /bin/sh -c #(nop)  CMD ["bash"]                 0B
<missing>      16 months ago   /bin/sh -c #(nop) ADD file:134f25aec8adf83cb…   80.4MB
[ec2-user@ip-172-31-39-154 my-diary-back]$ docker image history mydiary-back:1.0
IMAGE          CREATED              CREATED BY                                      SIZE      COMMENT
c491bbb19516   About a minute ago   ENTRYPOINT ["java" "-jar" "/app.jar"]           0B        buildkit.dockerfile.v0
<missing>      About a minute ago   EXPOSE map[8080/tcp:{}]                         0B        buildkit.dockerfile.v0
<missing>      About a minute ago   COPY build/libs/*.jar app.jar # buildkit        40.3MB    buildkit.dockerfile.v0
<missing>      14 months ago        /bin/sh -c #(nop)  CMD ["jshell"]               0B
<missing>      14 months ago        /bin/sh -c set -eux;   arch="$(dpkg --print-…   337MB
<missing>      14 months ago        /bin/sh -c #(nop)  ENV JAVA_VERSION=11.0.16     0B
<missing>      14 months ago        /bin/sh -c #(nop)  ENV LANG=C.UTF-8             0B
<missing>      14 months ago        /bin/sh -c #(nop)  ENV PATH=/usr/local/openj…   0B
<missing>      14 months ago        /bin/sh -c { echo '#/bin/sh'; echo 'echo "$J…   27B
<missing>      14 months ago        /bin/sh -c #(nop)  ENV JAVA_HOME=/usr/local/…   0B
<missing>      14 months ago        /bin/sh -c set -eux;  apt-get update;  apt-g…   11.3MB
<missing>      14 months ago        /bin/sh -c apt-get update && apt-get install…   152MB
<missing>      14 months ago        /bin/sh -c set -ex;  if ! command -v gpg > /…   19MB
<missing>      14 months ago        /bin/sh -c set -eux;  apt-get update;  apt-g…   10.7MB
<missing>      14 months ago        /bin/sh -c #(nop)  CMD ["bash"]                 0B
<missing>      14 months ago        /bin/sh -c #(nop) ADD file:d0f758e50c654c225…   124MB

# 전용 네트워크 생성 
[ec2-user@ip-172-31-39-154 my-diary-back]$ docker network create fastapp-net
f0d37d95651df3d7b5ff1f67202b5114d51c8cc00a9a1d07e49ce25cb6398fb4
[ec2-user@ip-172-31-39-154 my-diary-back]$ docker network ls
NETWORK ID     NAME          DRIVER    SCOPE
1b1f9cb59d91   bridge        bridge    local
f0d37d95651d   fastapp-net   bridge    local
a6d2dc487604   host          host      local
5964bb59b326   none          null      local

...
# DB 컨테이너 생성
[ec2-user@ip-172-31-39-154 my-diary-back]$ docker run -d --name rolling-db --net fastapp-net -p 13306:3306 \
> -e MYSQL_ROOT_PASSWORD=pass123# -e MYSQL_DATABASE=paperdb \
> -e MYSQL_ROOT_HOST=% -e MYSQL_USER=user -e MYSQL_PASSWORD=user \
> mysql:5.7-debian --character-set-server=utf8 --collation-server=utf8_general_ci
Unable to find image 'mysql:5.7-debian' locally
5.7-debian: Pulling from library/mysql
3240fe174df9: Pull complete
ffaa8624d67f: Pull complete
4d8328f9714e: Pull complete
5eb1b5f179ac: Pull complete
656a614f333c: Pull complete
ad1320c6d0c3: Pull complete
a28b57b8a949: Pull complete
6a0cdfac1051: Pull complete
c540032ab5fd: Pull complete
2fe13c62198b: Pull complete
c5129c0e04b1: Pull complete
Digest: sha256:0821f3a5b3ecda79885d8bd40ec353f3d2cc1bc23586f9c367dfc76493737163
Status: Downloaded newer image for mysql:5.7-debian
2c24820e22c7443e6453432be58201a7dbc0cb1ed8cacf4443ee1b3ecf0c6525

# backend 컨테이너 생성. (DB 컨테이너 내부적인 동작이 요구되므로 몇 십 초 뒤에 backend 수행)
[ec2-user@ip-172-31-39-154 my-diary-back]$ docker run -d --name rolling-server --net fastapp-net -p 8080:8080 \
> -e SPRING_DATASOURCE_URL=jdbc:mysql://rolling-db:3306/paperdb?serverTimezone=Asia/Seoul \
> -e SPRING_DATASOURCE_USERNAME=user -e SPRING_DATASOURCE_PASSWORD=user \
> mydiary-back:1.0
08fbd2efc12418e7cda391be174221c0d1313f84fc7d56d809816fff87b025b4

# frontend 컨테이너 생성
[ec2-user@ip-172-31-39-154 my-diary-back]$ docker run -d --name rolling-front --net fastapp-net -p 3000:3000 mydiary-front:1.0
4b77c454d89ff29a3dc972f651bcdd7d5ebd7b6954f7113fd85f06344556383c

[ec2-user@ip-172-31-39-154 my-diary-back]$ docker ps -a
CONTAINER ID   IMAGE               COMMAND                  CREATED              STATUS                    PORTS                                                    NAMES
4b77c454d89f   mydiary-front:1.0   "docker-entrypoint.s…"   9 seconds ago        Up 7 seconds              0.0.0.0:3000->3000/tcp, :::3000->3000/tcp                rolling-front
08fbd2efc124   mydiary-back:1.0    "java -jar /app.jar"     About a minute ago   Up About a minute         0.0.0.0:8080->8080/tcp, :::8080->8080/tcp                rolling-server
2c24820e22c7   mysql:5.7-debian    "docker-entrypoint.s…"   3 minutes ago        Up 3 minutes              33060/tcp, 0.0.0.0:13306->3306/tcp, :::13306->3306/tcp   rolling-db

 

데이터 입력 과정 확인
1. Frontend 화면에서 값을 입력하고 [Add Note]를 클릭한다. 화면에 출력됨을 확인.
2. 1) 번 수행 전에 backend의 로그를 출력한다. ~$ docker exec -it rolling-server bash
3. Mysql DB에 접속하여 입력한 데이터가 테이블에 기록되어 있음을 확인한다.
- docker exec -it rolling-db bash or MYSQL workbech를 통해 수행.

# 컨테이너 중지, 삭제
~$ docker stop rolling-db rolling-server rolling-front
~$ docker rm rolling-db rolling-server rolling-front

docker-compose.yaml 코드를 작성해 본다.

[ec2-user@ip-172-31-39-154 my-diary]$ mkdir my-diary-compose && cd $_
[ec2-user@ip-172-31-39-154 my-diary-compose]$ vi docker-compose.yaml

docker-compose.yaml

version: '3.3'

services:
 mydiary-db:
  image: mysql:5.7-debian
  container_name: rolling-db
  environment:
   MYSQL_ROOT_PASSWORD: pass123
   MYSQL_DATABASE: paperdb
   MYSQL_ROOT_HOST: '%'
   MYSQL_USER: user
   MYSQL_PASSWORD: user
  ports:
   - '13306:3306'
  networks:
   - rolling-be-db
  restart: always
  command:
   - --character-set-server=utf8
   - --collation-server=utf8_general_ci

 mydiary-back:
  image: mydiary-back:1.0
  container_name: rolling-server
  restart: always
  depends_on:
   - mydiary-db
  ports:
   - '8080:8080'
  environment:
   SPRING_DATASOURCE_URL: jdbc:mysql://rolling-db:3306/paperdb?serverTimezone=Asia/Seoul
   SPRING_DATASOURCE_USERNAME: user
   SPRING_DATASOURCE_PASSWORD: user
  networks:
   - rolling-be-db
   - rolling-fe-be

 mydiary-front:
  image: mydiary-front:1.0
  container_name: rolling-front
  restart: always
  depends_on:
   - mydiary-back
  ports:
   - '3000:3000'
  networks:
   - rolling-fe-be

networks:
 rolling-be-db: {}
 rolling-fe-be: {}

[실습2] 실습 1의 빌드된 이미지를 통해서 docker-compose 를 통해서 run만 실행

[ec2-user@ip-172-31-39-154 my-diary-compose]$ docker-compose up -d
[+] Running 3/3
 ⠿ Container rolling-db      Started                                                                                                                                                                                                     1.0s
 ⠿ Container rolling-server  Started                                                                                                                                                                                                     2.5s
 ⠿ Container rolling-front   Started                                                                                                                                                                                                     3.6s
[ec2-user@ip-172-31-39-154 my-diary-compose]$ docker-compose ps -a
NAME                COMMAND                  SERVICE             STATUS              PORTS
rolling-db          "docker-entrypoint.s…"   mydiary-db          running             0.0.0.0:13306->3306/tcp, :::13306->3306/tcp
rolling-front       "docker-entrypoint.s…"   mydiary-front       running             0.0.0.0:3000->3000/tcp, :::3000->3000/tcp
rolling-server      "java -jar /app.jar"     mydiary-back        running             0.0.0.0:8080->8080/tcp, :::8080->8080/tcp

## DB 데이터 확인
[ec2-user@ip-172-31-39-154 my-diary-compose]$ docker exec -it rolling-db bash
root@852948f8da9d:/# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 12
Server version: 5.7.42 MySQL Community Server (GPL)

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| paperdb            |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.01 sec)

mysql> use paperdb;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+-------------------+
| Tables_in_paperdb |
+-------------------+
| paper             |
+-------------------+
1 row in set (0.02 sec)

mysql> select * from paper;
Empty set (0.00 sec)

[실습 3] 실습 1의 image build + 실습2를 한번에 수행

docker-compose.yaml 코드 리뷰.

version: '3.3'

services:
 mydiary-db:
  image: mysql:5.7-debian
  container_name: rolling-db
  environment:
   MYSQL_ROOT_PASSWORD: pass123
   MYSQL_DATABASE: paperdb
   MYSQL_ROOT_HOST: '%'
   MYSQL_USER: user
   MYSQL_PASSWORD: user
  ports:
   - '13306:3306'
  networks:
   - rolling-be-db
  restart: always
  command:
   - --character-set-server=utf8
   - --collation-server=utf8_general_ci

 mydiary-back:
  build:
   context: ./my-diary-back
   dockerfile: Dockerfile
  container_name: rolling-server
  restart: always
  depends_on:
   - mydiary-db
  ports:
   - '8080:8080'
  environment:
   SPRING_DATASOURCE_URL: jdbc:mysql://rolling-db:3306/paperdb?serverTimezone=Asia/Seoul
   SPRING_DATASOURCE_USERNAME: user
   SPRING_DATASOURCE_PASSWORD: user
  networks:
   - rolling-be-db
   - rolling-fe-be

 mydiary-front:
  build:
   context: ./my-diary-front
   dockerfile: Dockerfile
  container_name: rolling-front
  restart: always
  depends_on:
   - mydiary-back
  ports:
   - '3000:3000'
  networks:
   - rolling-fe-be

networks:
 rolling-be-db: {}
 rolling-fe-be: {}
  • build option을 docker-compse.yaml에 추가
mydiary-back:
  build:
    context: ./my-diary-back
    dockefile: Dockerfile
mydiary-front:
  build:
    context: ./my-diary-front
    dockerfile: Dockerfile
[ec2-user@ip-172-31-39-154 my-diary-3]$ docker-compose up -d
[+] Running 12/12
 ⠿ mydiary-db Pulled                                                                                                                                                                                                                    15.6s
   ⠿ 3240fe174df9 Pull complete                                                                                                                                                                                                          3.1s
   ⠿ ffaa8624d67f Pull complete                                                                                                                                                                                                          3.1s
   ⠿ 4d8328f9714e Pull complete                                                                                                                                                                                                          3.6s
   ⠿ 5eb1b5f179ac Pull complete                                                                                                                                                                                                          3.7s
   ⠿ 656a614f333c Pull complete                                                                                                                                                                                                          3.7s
   ⠿ ad1320c6d0c3 Pull complete                                                                                                                                                                                                          5.0s
   ⠿ a28b57b8a949 Pull complete                                                                                                                                                                                                          5.0s
   ⠿ 6a0cdfac1051 Pull complete                                                                                                                                                                                                          5.0s
   ⠿ c540032ab5fd Pull complete                                                                                                                                                                                                         12.4s
   ⠿ 2fe13c62198b Pull complete                                                                                                                                                                                                         12.4s
   ⠿ c5129c0e04b1 Pull complete                                                                                                                                                                                                         12.5s
[+] Building 1.9s (23/23) FINISHED
 => [my-diary-3_mydiary-back internal] load .dockerignore                                                                                                                                                                                0.0s
 => => transferring context: 2B                                                                                                                                                                                                          0.0s
 => [my-diary-3_mydiary-front internal] load .dockerignore                                                                                                                                                                               0.1s
 => => transferring context: 2B                                                                                                                                                                                                          0.0s
 => [my-diary-3_mydiary-back internal] load build definition from Dockerfile                                                                                                                                                             0.1s
 => => transferring dockerfile: 458B                                                                                                                                                                                                     0.1s
 => [my-diary-3_mydiary-front internal] load build definition from Dockerfile                                                                                                                                                            0.1s
 => => transferring dockerfile: 201B                                                                                                                                                                                                     0.1s
 => [my-diary-3_mydiary-back internal] load metadata for docker.io/library/openjdk:11-jdk                                                                                                                                                1.6s
 => [my-diary-3_mydiary-front internal] load metadata for docker.io/library/node:17-slim                                                                                                                                                 1.6s
 => [my-diary-3_mydiary-front 1/4] FROM docker.io/library/node:17-slim@sha256:a180966357fe14cac9dd6c9cd496ed4d85b8a598cb33482705ecebad646145e3                                                                                           0.0s
 => [my-diary-3_mydiary-front internal] load build context                                                                                                                                                                               0.1s
 => => transferring context: 111.02kB                                                                                                                                                                                                    0.1s
 => [my-diary-3_mydiary-back builder 1/8] FROM docker.io/library/openjdk:11-jdk@sha256:99bac5bf83633e3c7399aed725c8415e7b569b54e03e4599e580fc9cdb7c21ab                                                                                  0.0s
 => [my-diary-3_mydiary-back internal] load build context                                                                                                                                                                                0.1s
 => => transferring context: 84.98kB                                                                                                                                                                                                     0.1s
 => CACHED [my-diary-3_mydiary-front 2/4] WORKDIR /home/node                                                                                                                                                                             0.0s
 => CACHED [my-diary-3_mydiary-front 3/4] COPY ./ ./                                                                                                                                                                                     0.0s
 => CACHED [my-diary-3_mydiary-front 4/4] RUN npm -y install                                                                                                                                                                             0.0s
 => [my-diary-3_mydiary-front] exporting to image                                                                                                                                                                                        0.0s
 => => exporting layers                                                                                                                                                                                                                  0.0s
 => => writing image sha256:14694a3e18d7f2e073cf9fdfc23d255ee55c761e4853cd20d6849049c3c009b4                                                                                                                                             0.0s
 => => naming to docker.io/library/my-diary-3_mydiary-front                                                                                                                                                                              0.0s
 => CACHED [my-diary-3_mydiary-back builder 2/8] COPY ./rollingpaper/gradlew .                                                                                                                                                           0.0s
 => CACHED [my-diary-3_mydiary-back builder 3/8] COPY ./rollingpaper/gradle gradle                                                                                                                                                       0.0s
 => CACHED [my-diary-3_mydiary-back builder 4/8] COPY ./rollingpaper/build.gradle .                                                                                                                                                      0.0s
 => CACHED [my-diary-3_mydiary-back builder 5/8] COPY ./rollingpaper/settings.gradle .                                                                                                                                                   0.0s
 => CACHED [my-diary-3_mydiary-back builder 6/8] COPY ./rollingpaper/src src                                                                                                                                                             0.0s
 => CACHED [my-diary-3_mydiary-back builder 7/8] RUN chmod +x ./gradlew                                                                                                                                                                  0.0s
 => CACHED [my-diary-3_mydiary-back builder 8/8] RUN ./gradlew bootJar                                                                                                                                                                   0.0s
 => CACHED [my-diary-3_mydiary-back stage-1 2/2] COPY --from=builder build/libs/*.jar app.jar                                                                                                                                            0.0s
 => [my-diary-3_mydiary-back] exporting to image                                                                                                                                                                                         0.0s
 => => exporting layers                                                                                                                                                                                                                  0.0s
 => => writing image sha256:c491bbb195166e2a3954e989329021048ba482a47ca24a70cb4679394d79b781                                                                                                                                             0.0s
 => => naming to docker.io/library/my-diary-3_mydiary-back                                                                                                                                                                               0.0s
[+] Running 5/5
 ⠿ Network my-diary-3_rolling-be-db  Created                                                                                                                                                                                             0.1s
 ⠿ Network my-diary-3_rolling-fe-be  Created                                                                                                                                                                                             0.1s
 ⠿ Container rolling-db              Started                                                                                                                                                                                             1.2s
 ⠿ Container rolling-server          Started                                                                                                                                                                                             3.1s
 ⠿ Container rolling-front           Started
 
# 결과 확인.
[ec2-user@ip-172-31-39-154 my-diary-3]$ docker images
REPOSITORY                 TAG          IMAGE ID       CREATED          SIZE
my-diary-3_mydiary-back    latest       c491bbb19516   35 minutes ago   694MB
my-diary-3_mydiary-front   latest       14694a3e18d7   40 minutes ago   252MB
mysql                      5.7-debian   6dca13361869   2 months ago     463MB


[ec2-user@ip-172-31-39-154 my-diary-3]$ docker network ls
NETWORK ID     NAME                       DRIVER    SCOPE
1b1f9cb59d91   bridge                     bridge    local
f0d37d95651d   fastapp-net                bridge    local
a6d2dc487604   host                       host      local
5bd475acccd0   my-diary-3_rolling-be-db   bridge    local
818a33f1adef   my-diary-3_rolling-fe-be   bridge    local
5964bb59b326   none                       null      local


[ec2-user@ip-172-31-39-154 my-diary-3]$ docker-compose ps
NAME                COMMAND                  SERVICE             STATUS              PORTS
rolling-db          "docker-entrypoint.s…"   mydiary-db          running             0.0.0.0:13306->3306/tcp, :::13306->3306/tcp
rolling-front       "docker-entrypoint.s…"   mydiary-front       running             0.0.0.0:3000->3000/tcp, :::3000->3000/tcp
rolling-server      "java -jar /app.jar"     mydiary-back        running             0.0.0.0:8080->8080/tcp, :::8080->8080/tcp
#작업 종료. 생성된 이미지까지 모두 삭제 (--rmi all)
[ec2-user@ip-172-31-39-154 my-diary-3]$ docker-compose down --rmi all
[+] Running 8/8
 ⠿ Container rolling-front           Removed                                                                                                                                                                                             1.7s
 ⠿ Container rolling-server          Removed                                                                                                                                                                                             0.6s
 ⠿ Container rolling-db              Removed                                                                                                                                                                                             1.5s
 ⠿ Image my-diary-3_mydiary-front    Removed                                                                                                                                                                                             0.0s
 ⠿ Network my-diary-3_rolling-be-db  Removed                                                                                                                                                                                             0.3s
 ⠿ Network my-diary-3_rolling-fe-be  Removed                                                                                                                                                                                             0.5s
 ⠿ Image mysql:5.7-debian            Removed                                                                                                                                                                                             0.5s
 ⠿ Image my-diary-3_mydiary-back     Removed

[실습4] Nginx Proxy(load balancer)를 결합한 애플리케이션 배포

파일 구조

[ec2-user@ip-172-31-39-154 my-diary-3-proxy]$ tree .
.
├── docker-compose.yaml
├── my-diary-back
│   ├── Dockerfile
│   └── rollingpaper
│       ├── build.gradle
│       ├── gradle
│       │   └── wrapper
│       │       ├── gradle-wrapper.jar
│       │       └── gradle-wrapper.properties
│       ├── gradlew
│       ├── gradlew.bat
│       ├── settings.gradle
│       └── src
│           ├── main
│           │   ├── java
│           │   │   └── com
│           │   │       └── threetier
│           │   │           └── team1
│           │   │               └── rollingpaper
│           │   │                   ├── DTO
│           │   │                   │   ├── ApiResponseDTO.java
│           │   │                   │   └── PaperDTO.java
│           │   │                   ├── RollingpaperApplication.java
│           │   │                   ├── controller
│           │   │                   │   └── PaperController.java
│           │   │                   ├── domain
│           │   │                   │   └── Paper.java
│           │   │                   ├── repository
│           │   │                   │   └── PaperRepository.java
│           │   │                   └── service
│           │   │                       ├── PaperService.java
│           │   │                       └── PaperServiceImpl.java
│           │   └── resources
│           │       └── application.yml
│           └── test
│               └── java
│                   └── com
│                       └── threetier
│                           └── team1
│                               └── rollingpaper
│                                   ├── RollingpaperApplicationTests.java
│                                   └── service
│                                       └── PaperServiceImplTest.java
├── my-diary-front
│   ├── Dockerfile
│   ├── Jenkinsfile.txt
│   ├── app.js
│   ├── fastcampus.png
│   ├── package-lock.json
│   ├── package.json
│   └── public
│       ├── fastcampus.png
│       ├── index.ejs
│       ├── index.js
│       └── style.css
└── proxy
    ├── nginx-be.conf
    └── nginx-fe.conf    
    
    

docker-compose.yaml 코드

version: '3.8'

services:
mydiary-db:
 image: mysql:5.7-debian
 container_name: rolling-db
 environment:
  MYSQL_ROOT_PASSWORD: pass123
  MYSQL_DATABASE: paperdb
  MYSQL_ROOT_HOST: '%'
  MYSQL_USER: user
  MYSQL_PASSWORD: user
 ports:
  - '3306:3306'
 networks:
  - mydiary-net
 restart: always
 command:
  - --character-set-server=utf8
  - --collation-server=utf8_general_ci

mydiary-back:
 build:
  context: ./my-diary-back
  dockerfile: Dockerfile
 deploy:
  replicas: 3    ## backend의 복제본 수
 restart: always
 depends_on:
  - mydiary-db
 ports:
  - '8081-8083:8080'   ## 복제본 수 만큼의 Port 범위 지정
 environment:
  SPRING_DATASOURCE_URL: jdbc:mysql://rolling-db:3306/paperdb?serverTimezone=Asia/Seoul
  SPRING_DATASOURCE_USERNAME: user
  SPRING_DATASOURCE_PASSWORD: user
 networks:
  - mydiary-net

mydiary-front:
 build:
  context: ./my-diary-front
  dockerfile: Dockerfile
 deploy:
  replicas: 3		## frontend의 복제본 수
 restart: always
 depends_on:
  - mydiary-back
 ports:
  - '3000-3002:3000'  ## 복제본 수 만큼의 Port 지정
 networks:
  - mydiary-net

proxy-be:
 image: nginx:1.21.5-alpine
 container_name: rolling-server-lb
 restart: always
 depends_on:
  - mydiary-back
 ports:
  - '8080:80'
 volumes:
  - ${PWD}/proxy/nginx-be.conf:/etc/nginx/nginx.conf	## 사전에 구성된 backend용 nginx.conf 제공
 networks:
  - mydiary-net

proxy-fe:
 image: nginx:1.21.5-alpine
 container_name: rolling-front-lb
 restart: always
 ports:
  - '80:80'
 volumes:
  - ${PWD}/proxy/nginx-fe.conf:/etc/nginx/nginx.conf	## 사전에 구성된 frontend용 nginx.conf 제공
 networks:
  - mydiary-net

networks:
mydiary-net:
 driver: bridge
 ipam:
  driver: default
  config:
  - subnet: 172.20.0.0/24			##  네트워크 대역을 사용자 지정으로 설정해 본다.
    ip_range: 172.20.0.0/24
    gateway: 172.20.0.1

frontend영역에 들어가는 proxy(LB)를 설정해 보자.

events { worker_connections 1024; }
http {
    upstream front-servers {
        server mydiary-front:3000;		## server에 설정되는 주소를 docker-compose.yaml 파일의 frontend service name 지정
        server mydiary-front:3001;		
        server mydiary-front:3002;
    }
    server {
        listen 80 default_server;
        location / {
            proxy_pass http://front-servers;
        }
    }
}

frontend 영역의 app.js 코드에서 backend로 연결되는 주소를 backend service name으로 지정.


const express = require('express');
const app = express();
const http = require('http');
const path = require('path');
const axios = require('axios');
const ejs = require('ejs');
const dest = 'http://mydiary-back:8080';	## backend service name으로 dest 상수값을 채운다.
const router = express.Router();
const bodyParser = require('body-parser');

*** 실행을 통해 설계한 대로 서비스가 동작하는지 확인해 보자.

*port 공유 오류 발생

Error response from daemon: driver failed programming external connectivity on endpoint my-diary-3-proxy-mydiary-back-3 (9a2939028f306b8d2a34e78db1e5d2f20a634829abaf33f144c60de95cd9aa96): Bind for 0.0.0.0:8083 failed: port is already allocated

docker-compose.yml 파일에서 ports 섹션에 '8081-8083:8080'와 같이 포트 범위를 사용하셨습니다. 이는 8081, 8082, 8083 포트를 8080으로 매핑하려고 시도합니다. 여기서 문제가 발생할 수 있습니다.

이유

docker-compose에서 포트 범위를 사용하는 것은 호스트의 연속적인 포트 범위를 컨테이너의 특정 포트에 매핑하는 경우에 유용합니다. 예를 들어, 호스트의 8081, 8082, 8083 포트를 각각 컨테이너의 8080 포트에 매핑하려는 경우입니다.

하지만, 문제는 여러 개의 replicas가 동시에 실행되면서 같은 8080 포트를 사용하려고 할 때 발생합니다. docker-compose.yml에서 mydiary-back 서비스에 replicas: 3 설정이 되어 있기 때문에, 3개의 복제본(replica)이 모두 동일한 8080 포트를 사용하려고 시도합니다. 이 때, 3개의 복제본 중 하나는 8081 포트에, 다른 하나는 8082 포트에 성공적으로 매핑되지만, 마지막 복제본이 8083 포트에 매핑되려고 시도할 때 이미 8080 포트가 사용 중이므로 에러가 발생합니다.

따라서, 이 문제를 해결하기 위해서는 각 복제본이 사용하는 컨테이너의 포트를 별도로 설정해주어야 합니다. 예를 들면, 첫 번째 복제본이 8080 포트를 사용하도록, 두 번째 복제본이 8081 포트를 사용하도록, 세 번째 복제본이 8082 포트를 사용하도록 설정해주는 방식입니다.

그러나 docker-compose에서는 이러한 세밀한 포트 설정을 자동으로 할 수 없습니다. 따라서, 서비스를 분리하거나 다른 방법을 사용하여 각 복제본의 포트를 별도로 설정해주어야 합니다.

version: '3.8'

services:
  mydiary-db:
    image: mysql:5.7-debian
    container_name: rolling-db
    environment:
      MYSQL_ROOT_PASSWORD: pass123
      MYSQL_DATABASE: paperdb
      MYSQL_ROOT_HOST: '%'
      MYSQL_USER: user
      MYSQL_PASSWORD: user
    ports:
      - '3306:3306'
    networks:
      - mydiary-net
    restart: always
    command:
      - --character-set-server=utf8
      - --collation-server=utf8_general_ci

  mydiary-back-1:
    build:
      context: ./my-diary-back
      dockerfile: Dockerfile
    restart: always
    depends_on:
      - mydiary-db
    ports:
      - "8081:8080"
    environment:
      SPRING_DATASOURCE_URL: jdbc:mysql://rolling-db:3306/paperdb?serverTimezone=Asia/Seoul
      SPRING_DATASOURCE_USERNAME: user
      SPRING_DATASOURCE_PASSWORD: user
    networks:
      - mydiary-net

  mydiary-back-2:
    build:
      context: ./my-diary-back
      dockerfile: Dockerfile
    restart: always
    depends_on:
      - mydiary-db
    ports:
      - "8082:8080"

  mydiary-back-3:
    build:
      context: ./my-diary-back
      dockerfile: Dockerfile
    restart: always
    depends_on:
      - mydiary-db
    ports:
      - "8083:8080"

  mydiary-front-1:
    build:
      context: ./my-diary-front
      dockerfile: Dockerfile
    restart: always
    depends_on:
      - mydiary-back-1
      - mydiary-back-2
      - mydiary-back-3
    ports:
      - '3000:3000'
    networks:
      - mydiary-net

  mydiary-front-2:
    build:
      context: ./my-diary-front
      dockerfile: Dockerfile
    restart: always
    depends_on:
      - mydiary-back-1
      - mydiary-back-2
      - mydiary-back-3
    ports:
      - '3001:3000'
    networks:
      - mydiary-net

  mydiary-front-3:
    build:
      context: ./my-diary-front
      dockerfile: Dockerfile
    restart: always
    depends_on:
      - mydiary-back-1
      - mydiary-back-2
      - mydiary-back-3
    ports:
      - '3002:3000'
    networks:
      - mydiary-net

  proxy-be:
    image: nginx:1.21.5-alpine
    container_name: rolling-server-lb
    restart: always

networks:
  mydiary-net:
    external: false
  • front server && back server 분산 서버 만들기
profile
신입 개발자

0개의 댓글