
현재 겨울 방학동안 작은 스타트업 인턴을 다니고 있다. 입사를 한지 얼마 지나지 않아 배포되어 있던 프로젝트 중 하나를 업데이트하기 위해 재빌드 후에 다시 컨테이너가 올라갔지만 서버가 동작하지 않는 문제가 생겼다.
인프라 지식이 부족했던 사수님은 나에게 도커를 다뤄 본적이 있냐고 물으셨고, 지난
간 프로젝트를 하면서 도커를 이용해 빌드, 배포를 해본 경험이 다수 있어 내가 직접 살펴보겠다고 말을 한 뒤, 회사 내부 서버에 접속할 권한을 얻었다.

회사 서버에는 여러 개의 프로젝트를 도커 컨테이너로 빌드되어 있었고, Nginx 또한 컨테이너로 관리되어 프로젝트들을 배포하고 있었다.
먼저 각 프로젝트들의 도커 파일과 컴포즈 파일을 확인해봤다. 도커 파일에는 laravel을 동작 시키기 위한 php 설치와 composer, nvm 설치 등 프로젝트 관련 실행만 있었고, Nginx에 대한 설정이 전혀 없었다.
이후, 도커 컴포즈 파일을 확인하여 backend 컨테이너를 빌드하는 설정 중에 서버 안에 저장되어있는 nginx.conf 파일을 컨테이너 내부 볼륨에 복사하는 코드를 볼 수 있었다.
바로 로컬에 있는 nginx.conf를 뒤져봤지만 기본 설정 파일이 이었다. (왜 있었던 거지?)

프로젝트 컨테이너 내부에 접속해 컨테이너 내부에 nginx.conf 파일을 수정하여 프록시를 설정해주었지만 여전히 동작을 하지 않았다.
도커 로그를 찍어봐도 Laravel 프로젝트 자체는 잘 실행되고 있었다. 회사에 인프라를 구축했던 사람은 퇴사를 했고, 인수인계가 제대로 이루어지지 않아 아무도 회사 서버의 구조를 정확히 모르고있었다...
프로젝트는 잘 실행되고 있어 nginx가 문제임을 판단하고 프로젝트 외부 컨테이너로 띄워진 nginx를 살펴보기로 했다. 로그를 찍어본 결과, 502 에러를 발생시키며 프록시되고 있는 ip주소를 나타내고 있었다.

이걸 보자마자 프로젝트의 네트워크 주소가 잘못 되었다는 것을 인지하게 되었다.
docker network inspect <network_name>
도커 네트워크 인스펙트 명령어를 통해 프로젝트의 ip 주소를 찾았고 비교해본 결과 역시나 다른 ip를 지정하고 있었다.

배포에 오류가 발생한 프로젝트 컨테이너에 네트워크를 disconnect하고 nginx가 프록시하고 있는 ip로 다시 connect 해주어 정상적으로 웹 페이지가 활성화 되었다.
정상적으로 프로젝트가 배포되었지만 프로젝트 컨테이너를 내리거나 재빌드 하는 순간 프로젝트 네트워크 ip가 바뀌어 계속 프로젝트들이 502 에러를 나타내기 시작했다.
매번 프로젝트를 빌드할 때마다 네트워크를 수동으로 지정할 수도 없는 노릇이니 근본적인 문제를 해결하기 위해 계속 사내 서버를 뒤져(?)보았다.
문제 해결을 위해 두 가지 방법을 생각했는데,
1. nginx 내부 conf 파일을 수정하여 컨테이너 이름으로 설정
2. docker-compose.yml에 특정 네트워크를 할당하도록 지정
먼저 nginx conf를 수정하기 위해
nginx 컨테이너의 내부에 접속하여 "/etc/nginx/conf.d/default.conf" 파일을 열어봤다.

보통은 직접 프로젝트의 nginx 설정을 해주어야 되는 줄만 알았지만 신기하게도 프로젝트 빌드시 자동으로 conf 파일이 수정되었다.
그 마법같은 기능을 해준 것이 위의 nginx 이미지였다.

출처: Automated Nginx Reverse Proxy for Docker
요약해보면 Docker 프로젝트의 nginx 설정을 자동으로 생성하고, 다시 로드할 수 있도록 해준다.
docker-letsencrypt-nginx-proxy-companion
이와 함께 docker-letsencrypt-nginx-proxy-companion도 함께 사용해 SSL 인증서를 자동으로 발급, 갱신을 해주어 프로젝트를 관리하고 있었다.
nginx 컨테이너 내부에 "/app/nginx.tmpl" 기준으로 프로젝트에 맞춰서 자동으로 생성, 할당 해 주는 것이다.
그래서 해당 방법은 사실상 불가능했다. 프로젝트에 따라 설정이 수정되니 수동으로 수정해도 의미가 없었다.
바로 다음으로 프로젝트의 도커 컴포즈 파일을 열어 몇 가지 network 옵션들을 추가해주었다.

external 옵션
새 네트워크를 만들지 않고 이미 생성되어 있는 네트워크와 연결
networks 옵션
services 컨테이너에 networks 옵션으로 지정해 줌으로 기존 네트워크 지정
이제 프로젝트를 새로 빌드하거나 기존 프로젝트를 재빌드해도 nginx가 정상적으로 프록시하여 배포가 잘 되었다.
이미 만들어진 시스템을 분석하는 것이 생각보다 쉽지는 않았다. 구축을 한 사람의 의도를 파악하기란 정말 어렵다. 마치 nginx가 외부 컨테이너와 프로젝트 내부 컨테이너 모두 존재하는 것처럼 말이다.
아마도 Laravel 웹 서버 가동을 위해 프로젝트 컨테이너 내부에도 nginx를 설치하지 않았나 생각이 든다.