프로젝트 넷이 비슷한 이미지를 쓰고 있어서 하나로 합칠지를 고민하게 됐다. 각각 따로 빌드하니 같은 것을 매번 네 번씩 만들고 있었다.
Table of contents
Open Table of contents
무엇이 같고 다른지
항목별로 표를 만들어 넷을 나란히 놓고 PHP 판과 pecl 확장 모듈 넷과 이미지 크기를 함께 봤다.
거의 모든 항목이 같았고 PHP 판 하나와 imagick 하나만 갈렸다. 다른 것이 둘뿐이라는 사실이 공통 층으로 묶을 수 있다는 근거가 됐다.
조치 — 공통 층과 얹는 층
공통 부분을 our-base 기반 이미지로 한 번 만들고 각 프로젝트는 FROM으로 거기에 자기 것만 얹게 했으며 추가 모듈이 필요한 프로젝트만 그 한 줄을 더 쓴다.
FROM our-base:8.2
RUN pecl install imagick && docker-php-ext-enable imagick
COPY . /app
공통 층이 캐시되면서 빌드 시간이 줄었다. 층을 나눌 때 자주 바뀌는 것을 위에 두는 것이 중요했는데 COPY . /app이 맨 위라 코드만 바뀌면 그 층만 다시 만들어진다.
판단 기준 — 억지로 합치지 않은 것
한 프로젝트는 PHP 판이 낮았는데 올릴 수 없는 이유가 따로 있었다. 옛 라이브러리가 새 판에서 동작하지 않았고 교체 예정이지만 아직 안 된 상태였다.
그래서 기반 이미지를 our-base:8.2와 our-base:7.4처럼 PHP 판별로 만들고 그 프로젝트만 낮은 판을 쓰게 했다. 판이 다른 것을 하나로 만들려면 한쪽이 안 되거나 이미지가 커지므로 억지로 합치지 않았다.
두 가지 방법이 있었는데 한 이미지에 앱 넷을 다 넣고 CMD로 실행할 때 고르는 것과 기반만 공유하고 앱은 나누는 것이다. 뒤쪽을 골랐다. 이유는 앞쪽은 하나를 고쳐도 넷이 다 다시 빌드되고 배포되며 안 쓰는 앱까지 들어가 이미지가 커지고 한 앱의 의존성 문제가 넷에 영향을 줘서다. 대신 Dockerfile이 넷으로 남아 공통 줄을 고칠 때 네 곳을 손보는 것을 감수했다.
설정 — 기반 갱신 절차
기반을 공유하게 되니 그것을 고칠 때 넷 전부에 영향이 갔다. our-base:2025-06-04 같은 새 태그로 만들어 한 프로젝트에서 먼저 써 보고 문제가 없으면 나머지를 바꾸며 옛 태그는 한 달 남기는 순서를 정했다.
여기서 핵심은 :latest를 안 쓰고 날짜 태그를 쓴 것인데 :latest를 쓰면 언제 무엇이 바뀌는지 알 수 없기 때문이다. 이미지에 LABEL을 붙여 무엇이 들어 있는지 보이게 하고 각 앱이 어느 기반을 쓰는지도 docker inspect로 조회할 수 있게 했다.
결과 — 공유가 만든 값
기반에 보안 문제가 나오면 기반을 다시 빌드하고 넷을 다시 빌드해 배포하는 흐름이 필요했고 그것을 자동으로 돌게 했다. 기반이 바뀌면 나머지가 따라 빌드된다.
전에는 각자 빌드하다가 하나를 빠뜨린 적이 있었는데 기반을 공유하고 나서는 한 번에 됐다. 저장 용량도 줄었고 기반이 이미 있으면 앱 층만 받으므로 배포가 빨라진 것도 따라왔다. 처음에는 빌드 시간만 생각했는데 실제로 가장 큰 값은 갱신이 한 번에 된다는 것이었다.
정리
- 비슷한 이미지가 여럿이면 무엇이 같고 다른지 표로 본다
- 공통 층을 만들고 각자 필요한 것만 얹는다
- 판이 다른 것은 억지로 하나로 만들지 않는다
- 한 이미지에 여러 앱을 넣지 않는다
- 기반을 바꿀 때 한 곳에서 먼저 써 본다
:latest대신 날짜 태그를 쓴다- 이미지에
LABEL을 붙여 무엇이 들어 있는지 보이게 한다 - 공유하면 보안 갱신이 한 번에 된다