[IT-방법] 컴포즈 build 옵션 자동화와 CI/CD 연동 – 수동 배포의 굴레에서 벗어나는 기술

build 옵션과 빌드 컨텍스트를 설명하는 자동화와 CI/CD 연동 대표 이미지

매번 반복되는 배포 명령, 언제까지 직접 입력하실 건가요?

금요일 오후, 급하게 수정한 코드를 서버에 반영해야 하는 상황을 상상해 보세요. 터미널을 열고 익숙하게 docker-compose build를 입력하고, 빌드가 끝나기를 기다리다 보면 문득 이런 생각이 들 거예요. “내가 지금 매번 똑같은 명령어를 치고 있는 게 맞나? 저 명령어를 실수로 하나라도 빼먹으면 어떻게 되지?”

많은 개발자가 배포 단계에서 컴포즈 build 옵션 자동화를 고민하지만, 막상 시작하려면 어디서부터 손을 대야 할지 막막해하곤 해요. 단순히 스크립트 한 줄 만드는 수준을 넘어, 빌드 컨텍스트를 어떻게 최적화할지, CI/CD 파이프라인에는 어떻게 녹여낼지가 핵심이죠. 수동으로 하나하나 명령어를 입력하는 방식은 당장은 편해 보이지만, 결국 휴먼 에러라는 시한폭탄을 안고 가는 것과 같아요.

빌드 컨텍스트 설정이 잘못되어 불필요한 파일이 수 기가바이트씩 전송되느라 빌드 시간이 늘어지거나, 환경 변수가 빌드 시점에 제대로 주입되지 않아 배포된 컨테이너가 먹통이 되는 일은 생각보다 흔하게 일어나요. 이런 문제를 겪고 있다면 이제는 단순 운영을 넘어 자동화된 배포 체계로 넘어갈 준비가 되었다는 신호예요.

이 글에서는 단순히 명령어를 외우는 것이 아니라, 배포 프로세스 자체를 설계하는 방법을 다룰 거예요. 다음 내용을 통해 배포의 자유를 얻어 가세요.

  • 빌드 컨텍스트와 build 옵션의 유기적인 관계 이해하기
  • 실무에서 바로 쓰는 자동화 스크립트 설계법
  • CI/CD 파이프라인에 컴포즈 빌드 로직 통합하기
  • 배포 실패를 방지하는 검증 및 롤백 전략

자동화로 가기 위한 첫걸음: 기본 개념과 준비물

무턱대고 스크립트부터 짜기 시작하면 금방 한계에 부딪혀요. 자동화를 시작하기 전에 우리가 제어해야 할 대상이 무엇인지 정확히 알아야 하거든요. 핵심은 빌드 컨텍스트(Build Context)빌드 인자(Build Args)를 얼마나 정교하게 관리하느냐에 달려 있어요.

빌드 컨텍스트는 도커 데몬이 빌드를 수행하기 위해 로컬에서 가져가는 파일들의 범위를 말해요. 이 범위가 너무 넓으면 빌드 속도가 느려지고, 너무 좁으면 필요한 파일을 찾지 못해 빌드가 실패하죠. 또한, 빌드 시점에만 필요한 환경 변수인 Build Args를 어떻게 자동화 도구에 전달할지도 미리 설계해야 해요.

자동화 방식별 특징 비교

현재 여러분의 팀이 어떤 단계에 있는지 아래 표를 통해 확인해 보세요. 각 방식은 장단점이 뚜렷하기 때문에 단계적인 접근이 필요해요.

구분 수동 명령 방식 쉘 스크립트 방식 CI/CD 파이프라인
작업 속도 매우 느림 빠름 가장 빠름(병렬 가능)
에러 가능성 매우 높음 낮음 매우 낮음
관리 난이도 단순함 보통 높음(초기 설정 필요)
적합한 규모 개인 프로젝트 소규모 팀 중대형 엔터프라이즈
💡 알아두기
자동화를 구축하기 전, 반드시 docker-compose.yml 파일 내의 build 섹션이 각 서비스별로 독립적인 컨텍스트를 가지고 있는지 먼저 확인하세요. 서비스 간에 컨텍스트가 엉켜 있으면 자동화 시 의존성 문제가 발생하기 쉽습니다.

준비가 되었다면 이제 실제적인 자동화 설계로 들어가 볼게요. 단순한 명령어를 넘어서, 어떤 논리로 파이프라인을 짜야 하는지가 핵심이에요.

실전! 컴포즈 빌드 자동화 파이프라인 설계하기

이제 본격적으로 컴포즈 build 옵션 자동화를 실행할 단계예요. 단순히 명령어를 실행하는 것을 넘어, 빌드 효율을 극대화하고 오류를 사전에 차단하는 5단계 프로세스를 소개할게요.

STEP 1. build 옵션의 정밀 설계

가장 먼저 해야 할 일은 docker-compose.yml 파일을 최적화하는 거예요. 자동화 도구가 명령을 내릴 때, 어떤 파일을 참조해야 할지 명확하게 지시해줘야 하거든요. 특히 다음 세 가지 옵션에 집중하세요.

  • context: 빌드에 필요한 파일들이 들어있는 최상위 경로를 지정하세요. 프로젝트 루트를 지정하되, 불필요한 데이터가 포함되지 않도록 주의해야 해요.
  • dockerfile: 서비스마다 사용하는 Dockerfile 이름이 다르다면 반드시 명시해줘야 합니다. 예를 들어, 개발용과 운영용을 구분할 때 매우 유용해요.
  • args: 빌드 시점에 주입할 변수들을 정의하세요. 예를 들어 VERSION=1.2.0 같은 값을 넘겨주면, Dockerfile 내부에서 이를 활용해 태그를 생성할 수 있어요.
⚠️ 주의
build context 내부에 node_modules나 대용량 로그 파일이 포함되어 있다면, 빌드 명령을 내릴 때마다 엄청난 양의 데이터가 도커 데몬으로 전송됩니다. 반드시 .dockerignore 파일을 만들어 제외하세요.

STEP 2. 오케스트레이션을 위한 쉘 스크립트 작성

CI/CD 도구를 쓰기 전 단계로, 로컬이나 서버에서 사용할 수 있는 쉘 스크립트를 만드는 것이 좋아요. 모든 과정을 한 번에 수행하는 deploy.sh를 만들어 보세요. 이 스크립트는 다음과 같은 흐름을 가져야 합니다.

  1. 환경 변수 체크: 필요한 .env 파일이 존재하는지 확인합니다.
  2. 이미지 빌드: docker-compose build --pull를 사용하여 최신 베이스 이미지를 가져오며 빌드합니다.
  3. 컨테이너 재시작: docker-compose up -d로 무중단 혹은 최소 중단 배포를 수행합니다.
  4. 정리 작업: 빌드 후 남은 dangling images(이름 없는 이미지)를 제거하여 디스크 용량을 확보합니다.

STEP 3. CI/CD 파이프라인 통합 (GitHub Actions 예시)

이제 스크립트를 클라우드 환경으로 옮길 차례예요. GitHub Actions를 사용한다면, 코드가 푸시될 때마다 자동으로 빌드와 배포가 일어나도록 설정할 수 있어요. 아래는 개념적인 워크플로우 시나리오예요.

먼저, on: push 이벤트를 트리거로 설정합니다. 그 다음, jobs 단계에서 러너(Runner)를 실행하고, 우리가 만든 deploy.sh를 실행하도록 구성합니다. 이때 가장 중요한 점은 서버 접속을 위한 SSH KeyAPI Token 같은 민감한 정보를 GitHub Secrets에 안전하게 저장하고 사용하는 것이에요.

STEP 4. 멀티 스테이지 빌드를 통한 최적화

자동화된 파이프라인의 속도를 높이려면 이미지 크기를 줄여야 해요. Multi-stage Build를 적용하면 빌드용 환경과 실행용 환경을 분리할 수 있어요. 예를 들어, Java 애플리케이션을 빌드할 때는 JDK가 필요하지만, 실제 실행할 때는 JRE만 있으면 충분하죠. 이를 통해 최종 이미지 크기를 80% 이상 줄일 수 있고, 이는 곧 자동화된 배포 속도의 비약적인 향상으로 이어집니다.

STEP 5. 빌드 아규먼트와 환경별 프로파일 활용

운영(prod) 환경과 개발(dev) 환경의 설정이 다르다면, 컴포즈의 profiles 기능을 활용해 보세요. 자동화 스크립트에서 docker-compose --profile prod up과 같이 명령을 내리면, 환경에 맞는 서비스와 build 옵션만 골라서 실행할 수 있습니다.

💡 알아두기
자동화 파이프라인 설계 시, 빌드 과정에서 생성된 이미지를 레지스트리(Docker Hub, ECR 등)에 푸시(Push)하고, 서버에서는 이를 풀(Pull) 받아 실행하는 방식이 가장 표준적이고 안전합니다. 서버에서 직접 빌드하는 방식은 서버 자원을 과도하게 소모할 수 있기 때문이에요.

자주 하는 실수와 해결법 + FAQ

자동화 프로세스를 구축하다 보면 예상치 못한 곳에서 에러가 발생하곤 해요. 경험 많은 엔지니어들도 흔히 저지르는 실수들을 정리했으니, 배포가 막힌다면 아래 내용을 먼저 체크해 보세요.

자주 하는 실수와 해결법

  • 실수: 빌드 시점에 환경 변수가 누락됨
    왜 발생하는가: .env 파일이 자동화 환경(CI 서버)에는 없기 때문이에요.
    해결법: CI/CD 설정에서 Secrets 기능을 통해 변수를 직접 주입하거나, 빌드 인자(--build-arg)를 사용하여 전달하세요.
  • 실수: 빌드 컨텍스트가 너무 커서 전송 속도가 느려짐
    왜 발생하는가: .dockerignore를 설정하지 않아 불필요한 데이터까지 전송하기 때문이에요.
    해결법: 로그, 캐시, 데이터베이스 파일 등을 반드시 제외 리스트에 넣으세요.
  • 실수: 구버전 이미지가 계속 실행됨
    docker-compose up만 실행하면 이미지가 이미 존재할 경우 새로 빌드하지 않아요.
    해결법: docker-compose build를 먼저 실행하거나 --build 옵션을 붙여주세요.
  • 실수: 보안 정보가 이미지에 포함됨
    왜 발생하는가: Dockerfile 내에 ENVARG로 비밀번호를 직접 적었기 때문이에요.
    해결법: 비밀번호는 빌드 시점이 아닌 컨테이너 실행 시점(runtime)에 주입해야 합니다.
  • 실수: 캐시 문제로 코드가 반영되지 않음
    왜 발생하는가: 도커가 이전 빌드 레이어를 재사용하면서 바뀐 코드를 무시할 때가 있어요.
    해결법: 코드가 바뀌는 지점(예: COPY . .)을 Dockerfile의 가능한 한 뒷부분에 배치하여 캐시 무효화가 효율적으로 일어나게 하세요.

자주 묻는 질문

Q. 빌드할 때마다 시간이 너무 오래 걸리는데 어떻게 줄일 수 있나요?

가장 효과적인 방법은 멀티 스테이지 빌드를 사용해 이미지 크기를 줄이고, .dockerignore를 통해 전송할 파일 양을 최소화하는 거예요. 또한, 자주 바뀌지 않는 라이브러리 설치 단계(예: npm install)를 코드 복사 단계보다 위로 올리면 도커 캐시를 최대한 활용할 수 있어요.

Q. 컴포즈 build 옵션 자동화가 꼭 필요한가요?

팀 단위 프로젝트이거나 배포가 잦은 서비스라면 필수예요. 수동 배포는 사람이 실수할 확률이 항상 존재하고, 누가 언제 어떤 버전으로 배포했는지 기록을 남기기도 어렵거든요. 자동화를 하면 배포 이력이 남고 검증 단계까지 포함할 수 있어 운영 안정성이 차원이 달라집니다.

Q. CI/CD 서버에서 직접 빌드하는 게 좋을까요, 아니면 이미지를 만들어서 보내는 게 좋을까요?

이미지를 빌드해서 레지스트리에 올린 뒤 서버에서 pull 받는 방식이 훨씬 권장됩니다. 서버는 실행에만 집중해야 하며, 빌드 과정에서 발생하는 CPU와 메모리 부하를 서버가 감당하게 해서는 안 되기 때문이에요.

Q. 빌드 인자(Build Args)와 환경 변수(Env)의 차이가 뭔가요?

매우 중요한 질문이에요! Build Args는 도커 이미지를 ‘만드는 과정’에서 필요한 값이에요(예: 버전 번호). 반면 Env는 만들어진 이미지가 ‘실행되는 과정’에서 필요한 값이에요(예: 데이터베이스 접속 비밀번호). 용도에 맞춰 정확히 구분해서 사용해야 합니다.

Q. 배포 중에 에러가 나면 어떻게 롤백하나요?

자동화 파이프라인에 롤백 로직을 넣는 것이 가장 좋아요. 예를 들어, 새로운 버전의 컨테이너가 뜨지 않으면 이전 버전의 이미지 태그로 다시 docker-compose up을 실행하도록 스크립트를 구성하는 식이죠. 이를 위해 각 이미지에 태그(v1.0, v1.1 등)를 명확히 붙이는 습관이 필요합니다.

이제 배포는 시스템에 맡기고, 개발에 집중하세요

지금까지 컴포즈 build 옵션을 어떻게 최적화하고, 이를 어떻게 자동화의 흐름 속에 녹여낼지 깊이 있게 살펴봤어요. 자동화는 처음에 구축할 때 시간이 걸리지만, 한 번 제대로 만들어두면 그 가치는 수백 배로 돌아옵니다.

✅ 핵심 요약

  • build 옵션(context, dockerfile, args)을 명확히 정의하세요.
  • .dockerignore 파일을 사용하여 빌드 컨텍스트를 경량화하세요.
  • 단순 명령어를 넘어 쉘 스크립트로 일련의 과정을 구조화하세요.
  • 멀티 스테이지 빌드를 통해 이미지 크기와 빌드 속도를 최적화하세요.
  • 민감한 정보는 절대 Dockerfile에 적지 말고 Secrets나 Runtime Env를 사용하세요.
  • 이미지 태그를 명확히 관리하여 즉각적인 롤백이 가능하도록 만드세요.

자동화는 한 번에 끝나는 프로젝트가 아니라 지속적인 개선 과정이에요. 처음부터 완벽한 CI/CD를 꿈꾸기보다는, 지금 당장 여러분이 가장 자주 반복하는 명령어 하나부터 스크립트로 옮기는 것부터 시작해 보세요.

🚀 다음 단계로 나아가기

  • 오늘 할 일: 현재 사용하는 docker-compose.yml의 build 옵션 점검하기
  • 이번 주 할 일: 자주 쓰는 명령어를 모은 deploy.sh 스크립트 초안 만들기
  • 실행 직전 할 일: .dockerignore 파일을 작성하여 빌드 속도 개선해 보기

가장 작은 자동화가 여러분의 퇴근 시간을 앞당겨줄 거예요. 가장 자주 반복하는 명령 하나부터 스크립트로 옮겨 보세요.

관련된 더 깊은 내용이 궁금하다면 아래 글을 참고해 보세요.
도커 컴포즈 기본 개념 완벽 정리 — 개념부터 실무 활용까지 한눈에 보는 가이드

댓글 남기기