0. Table Of Contents
1. 문제 현황 분석
1.1. 문제 상황
docker version을 업그레이드 하고 나서 다음과 같이 잘 되던 .env file parsing이 잘 되지 않는 오류가 발생하였다.
1.2. 기존 docker version과 upgrade한 docker version
Mac Docker Desktop 기준으로 작성되었습니다.
- 기존 Docker version : 3.0.0
- Docker compose version : 1.27.4
- Docker version : ?
- 업그레이드 된 Docker version : 3.4.0
- Docker compose version : 1.29.0
- Docker version : 20.10.7
1.3. 프로젝트 폴더 구조
1.4. 명령어 call 순서
- docker.sh를 이용하여 docker-start-local.sh 실행
- docker-start-local.sh가 ./docker-compose/docker-compose.postgres.yml를 참조하여 아래와 같은 명령어를 실행시킨다.
- 업그레이드 전 아래 명령어는 정상적으로 동작하여 .env파일을 정상적으로 파싱하고 있었다.
docker-compose \
-p {PROJECT_NAME} \
-f ./docker-compose/docker-compose.postgres.yml \
-f ./docker-compose/api/docker-compose.base.yml \
-f ./docker-compose/api/docker-compose.local.yml \
up $build --remove-orphans
1.5. 주요 파일 구성 확인
혹시나 싶어서 docker-compose.postgres.yml 파일과 .env가 제대로 구성이 안되어있는지 확인을 해본 결과 다음과 같았다.
version: '3'
services:
postgres:
image: <PROJECT_NAME>/postgres
container_name: "<PROJECT_NAME>-postgres"
build:
context: ../docker/postgres
dockerfile: Dockerfile
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- ../data/postgres/data:/var/lib/postgresql/data
- ../docker/postgres/init/:/docker-entrypoint-initdb.d/
ports:
- "${POSTGRES_PORT}:${POSTGRES_PORT}"
restart: unless-stopped
ulimits:
nproc: 65535
nofile:
soft: 65535
hard: 65535
healthcheck:
test: ["CMD", "docker-healthcheck"]
interval: 30s
timeout: 10s
retries: 3
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "5"
# .env
POSTGRES_HOST=postgres
POSTGRES_PORT=5432
POSTGRES_DB=postgres
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
위와 같이 .env와 docker-comspose.postgres.yml의 환경변수가 잘 매핑이 되어 있었기 때문에 parsing error가 날리가 없다고 생각했다.
2. 문제 해결 삽질
2.1. 문제 해결을 위한 searching
지금까지 어깨 너머로 배워서 docker-dompose를 사용하였지만, 문서를 상세히 보고 사용한 적이 없기 때문에 공식 document를 보면서 제일 먼저 정리하기로 했다.
Docker-Compose Command로 env를 정의하고, 실행했기 때문에, env file configuration 쪽을 찾아보는 도중 다음과 같은 문구를 발견 할 수 있었다.
위 문서 중 내가 겪은 문제와 관련된 부분을 한글화하여 요약하면 다음과 같다.
1.28 미만의 Docker Compose의 경우, command가 실행된 현재 작업중인 directory에서 .env파일을 가지고 오거나, --project-directory argument에서 설장된 path에서 .env 파일을 가지고 옵니다.
이러한 모호함을 1.28 이상의 버전에서는 .env의 default path를 project directory로 제한하는 것으로 개선하였습니다. --env-file 옵션을 이용하여 기본 .env default path를 override 할 수 있습니다.
project directory는 다음 순서로 정의됩니다.1. --project-directory flag에 정의된 path
2. 첫번째 --file (-f)로 flag에 정의된 directory
3. 현재 directory
2.2. 문제 디버깅
기존에 사용한 docker-compose version은 1.27.4였기 때문에 위 사항에 일치하였다. 위 사항을 이용하여 docker desktop 업데이트 이후 발생한 오류를 디버깅 해보면 다음과 같다.
- 프로젝트 루트 폴더에서 shell script를 이용하여 docker-compose command를 실행시켰다.
- 위에서 정의된 docker-compose command에는 project directory가 정의되어 있지 않다.
- docker compose에 이용할 yml파일로 ./docker-compose/docker-compose.postgres.yml가 입력되었다.
- project directory 정의 순서에 따라, ./docker-compose/가 project directory로 정의된다.
- ./docker-compose/에는 .env 파일이 없다.
- 없는 파일을 참조하였기 때문에 yaml파일 내부에서 ${}로 정의한 변수들이 전부 빈 string으로 대체된다.
- postgresql port는 필수로 필요하지만, 입력이 되지 않았기 때문에 에러가 발생하였다.
2.3. 디버깅내용이 맞는지에 대한 검증
project directory인 ./docker-compose/에 루트 프로젝트 디렉토리에 있는 .env 파일을 다음 사진과 같이 복붙하여 .env파일을 하나 더 만든 다음 기존에 만들어 놓은 쉘스크립트를 이용하여 docker-compose를 실행시킨 결과, 정상적으로 docker가 빌드가 되어 정상적으로 실행까지 되었다.
2.4. 최종 문제 해결 flow
docker-compose 1.28.6 version release note를 보면 --env-file flag는 현재 작업중인 directory를 참조하도록 고쳐졌다고 한다.
env file을 제대로 인식 시켜주지 못하고 있기 때문에 이에 대해 명확히 설정을 해 줄 필요가 있다. compose에 사용되는 파일이 root project directory에 존재하기 때문에, docker-compose command 를 실행시킬 때, --env-file flag를 이용하여 명확하게 내가 사용하고자 하는 .env를 아래와 같이 명시해주었다.
3. 삽질을 통해 얻은 결론 및 개인적인 프로젝트 구조에 대한 회고
이처럼 실행환경에 대해서 정의할 때에는 최대한 사용할 파일들에 대해 command 또는 yaml, script에 정확히 명시를 하여 이러한 오류를 피해가게 하고, 다른 사람이 script를 읽었을 때 어떤 파일을 사용하는지 이해하기 쉽게 하는 것이 중요하다고 생각이 되었다. 향후, 위 문제처럼 다른 파일을 참조하고 있지만 묵시적인 방식으로 파일을 참조하고 있다면 명시적으로 나는 이걸 쓸거다라는 코드를 추가를 해야겠다.
+ env에 docker compose에서 쓰는 environment와 Dockerfile에서 사용하는 environment가 혼재하고있는데 향후 체계적으로 environment를 관리하기 위해서는 이를 분리하여 명확하게 어디서 쓰는 environment인지 정의하면 훨씬 더 좋을거같다.
4. Reference
Environment variables in Compose
'IT > Cloud' 카테고리의 다른 글
[AWS S3] AWS S3 Key path 설계 (31) | 2021.09.02 |
---|---|
[FaaS Service] FaaS Service를 사용시 주의해야할 점 (0) | 2021.07.16 |
[AWS] Site to Site VPN with OpwnSwan구성하기 (64) | 2020.05.09 |
[Amazon SES] Simple Email Service Sample (31) | 2020.04.08 |
[AWS-CLI] aws: command not found 해결법 (0) | 2019.11.14 |