Programming-[Infra]/Docker

도커 교과서(엘튼 스톤맨, 심효섭) - 9. 여러 환경의 도커 실행

컴퓨터 탐험가 찰리 2023. 4. 23. 12:34
728x90
반응형

로컬, 테스트, 운영 환경에서 같은 이미지를 기반으로 하지만 다른 환경 설정값으로 배포해야 하는 경우들에 대해서 배운다.

 

1. 여러 개의 애플리케이션 배포

 

우선 같은 이미지와 설정으로 여러 개의 애플리케이션을 배포하는 방법에 대해서 배운다. 다시 말해 같은 이미지 파일로 어떻게 똑같은 애플리케이션을 여러 개 생성할 수 있는지 배운다.

 

cd ./ch10/exercises
docker-compose -f ./todo-list/docker-compose.yml up -d
docker-compose -f ./todo-list/docker-compose.yml up -d

 

컨테이너 명명 규칙

컴포즈 파일 실행 시 컨테이너 이름은 다음 규칙으로 지어진다. (교재에는 중간 부분이 언더바(_) 였으나 실제로는 하이픈(-)이 적용됐다.)

 

{컴포즈 파일이 들어있던 디렉터리명}-{컴포즈 파일에 정의된 서비스 이름}-{컨테이너 수에 따라 1부터 1씩 증가}

 

따라서 위 명령어 중 compose up 명령어를 한 번 입력하고, docker container ls 명령어를 입력해보면 아래처럼 명명규칙을 따라 컨테이너의 이름이 정해진 것을 볼 수 있다. 55465:80 으로 포트가 임의로 지정된 것도 볼 수 있다.

 

 

그리고 두 번째 docker-compose up 명령어를 입력하면 이미 실행 중이라고 하면서 컨테이너가 실행되지 않는다!

 

 

같은 이미지로 여러 애플리케이션 실행하기 : 프로젝트 이름 변경

도커가 완전히 같은 컨테이너로 인식하여 더 이상 container를 만들지 않는 현상을 피하고 같은 이미지로 컨테이너를 하나 더 띄워본다. -p 부명령을 입력하여 프로젝트 이름을 변경해주면 된다.

 

docker-compose -f ./todo-list/docker-compose.yml -p todo-test up -d

 

이번에도 포트는 55490:80 으로 임의로 생성된 것을 확인할 수 있다.

 

임의로 생성되는 포트를 일일이 찾아다녀야 할 수 있는데, 이를 해결하고 다른 장점들을 동시에 확보할 수 있는 오버라이드 파일에 대해서 배워볼 것이다.

 

 

2. 각 이미지의 환경 설정 다르게 설정 해주기: 오버라이드 파일

 

상식적으로 생각해보면 다른 환경 설정을 가진 컨테이너들은 다른 이름의 컴포즈 파일들에 기반하여 컨테이너를 실행하도록 하면 될 것이다. 그러나 이런 방법은 중복된 부분을 수정할 때 누락이나 실수가 발생하면 모든 컴포즈 파일들을 수정해야한다는 문제가 생긴다.

 

중복되는 부분은 공통의 컴포즈 파일에 의존하도록 하는 기능오버라이드 파일이다. 교재에 나온 예제는 아래와 같다.

 

# docker-compose.yml - 기본 파일
services:
	todo-web:
    	image: diamol/ch06-todo-list
        ports:
        	- 80
        enviroment:
        	-Database:Provider=Sqlite
        networks:
        	-app-net

# docker-compose-v2.yml - 오버 라이드 파일
services:
	todo-web:
    	image: diamol/ch06-todo-list:v2

 

명령어는 아래처럼 순서대로 작성한다.

 

docker-compose -f ./todo-list/docker-compose.yml -f ./todo-list/docker-compose-v2.yml config

 

config 부명령은 설정 파일이 유효한지 확인만하고 애플리케이션을 실제로 실행하지는 않는다. 대신 병합된 컴포즈 파일을 출력해준다.

 

출력 결과를 보면 image는 v2로 지정되어 덮어쓰기식으로 실행되었고 기본적인 내용들은 기본 파일의 내용들이 포함된 것을 볼 수 있다. 반드시 기본적인 내용이 들어간 파일이 명령어 상에서 앞선 부분에 위치해야한다는 것을 기억하자.

 

이제 개발, 테스트 환경 등 별로 개별 컨테이너를 실행할 수 있다. 오버라이드 파일을 개별로 각 파일들에 필요한 포트 번호, 설정 등을 넣어주고 서비스의 이름을 바꿔주면 된다. 그리고 앞에서 배운 것처럼 각 프로젝트 이름도 바꿔준다.

 

# 개발 환경용
docker-compose -f ./numbers/docker-compose.yml -f ./numbers/docker-compose-dev.yml -p numbers-dev up -d
# 테스트 환경용
docker-compose -f ./numbers/docker-compose.yml -f ./numbers/docker-compose-test.yml -p numbers-test up -d
# 인수 테스트 환경용
docker-compose -f ./numbers/docker-compose.yml -f ./numbers/docker-compose-uat.yml -p numbers-uat up -d

 

주의점

컨테이너를 중지할 때 CLI를 통해서 실행한다면 다시 한 번 정확한 이름을 통해서 명령어를 입력해줘야한다.

 

# 기본 컴포즈 파일만 사용했다면
docker-compose down

# 프로젝트 이름을 안 바꾸고 오버라이드 파일을 이용했다면
docker-compose -f ./numbers/docker-compose.yml -f ./numbers/docker-compose-test.yml down

# 프로젝트 이름을 변경했다면
docker-compose -f ./numbers/docker-compose.yml -f ./numbers/docker-compose-test.yml -p numbers-test down

 

이렇게 입력해야 각 컨테이너를 띄우면서 함께 실행되었던 DB등 관련된 내용을 컴포즈 파일에서 참고하여 도커 엔진이 모든 리소스들을 제거한다.

 

아니면 docker-desktop GUI에서 명령어를 통해 실행했던 컨테이너들을 직접 다 내려주는 것도 하나의 방법일 수도 있겠다.

 

 

 

 

3. 환경 변수, 비밀값 주입하기

 

환경 변수는 env_file, 비밀값은 secrets 프로퍼티값으로 설정할 수 있다. 아래는 예제 내용이다.

services:
	todo-web:
    	ports:
        	-8089:80
        environment:
        	-Database:Provider=Sqlite
        env_file:
        	- ./config/logging.debug.env

secrets:
	todo-db-connection:
    	file: ./config/empty.json

 

env_file은 key=value 값으로 되어있으며 교재에서 제공하는 logging.debug.env 파일의 내용은 아래처럼 출력된다. 디버깅 레벨을 Debug로 설정하여 기본 설정 대비 좀 더 자세히 로그를 출력하도록한다.

 

secrets 파일은 json으로 아래처럼 구성된다. DB 연결 정보이다.

{
    "ConnectionStrings": {
      "ToDoDb": "Server=todo-db;Database=todo;User Id=postgres;Password=postgres;"
    }
}

 

실제 로그 수준 변경 확인을 위해 아래 명령어들을 입력한다.

docker-compose -f ./todo-list-configured/docker-compose.yml -f ./todo-list-configured/docker-compose-dev.yml -p todo-dev up -d

curl http://localhost:8089/list

# 애플리케이션 로그 확인
docker container logs --tail 10 todo-dev-todo-web-1

 

DB connection 정보가 뭔가 달라서 에러가 난듯 했지만, 어쨌든 info 레벨과 추가로 debug 레벨의 로그로 출력되는 것을 확인할 수 있었다.

 

 

.env 파일

도커는 컴포즈로 애플리케이션을 실행할 때 해당 디렉터리에서 .env 파일을 발견하면 이 파일을 환경 파일로 간주하고 이 파일에서 환경 변수 값들을 읽어서 적용한다.

 

 

 

 

4. 확장 필드

 

서비스간에 많은 설정값들을 공유하는 경우 컴포즈 파일이 점점 길어진다. 확장 필드는 YAML 파일의 여러 블록값들을 한 곳에서 정의하는 기능이다.

 

x-lables: &logging
  logging:
    options:
      max-size: '100m'
      max-file: '10'

x-labels: &labels
	app-name: image-gallery

 

관습적으로 x- 라는 접두사를 붙여서 확장 필드로 정의한다. 그리고 이름을 앰퍼샌드(&)를 사용하여 정의한다. 즉 위 예시에서 x-labels 라는 확장 필드를 logging 이라는 이름으로 정의하였다.

 

logging과 label을 정의할 때의 차이는 &logging은 logging 프로퍼티 자체를 감싸고 있고 labels는 labels 아래의 속성들만 포함한다는 점이다. 따라서 logging은 다른 .yml 파일에서 독립적으로 사용될 수 있고, labels는 다른 .yml 파일에서 labels: 프로퍼티 아래에서만 사용할 수 있다.

 

적용 시 <<: * 문법을 사용한다.

services:
  iotd:
    ports:
      - 8080:80
    <<: *logging
    labels:
      <<: *labels
      public: api

 

728x90
반응형