Dockerfile이 있는데 빌드 서버가 필요할까?

  • 규모가 작은 간단한 프로젝트거나, 개발 초기 단계의 경우, 별도의 빌드 서버 없이 로컬에서 Dockerfile로만 이미지를 빌드해도 된다.
  • 하지만 프로젝트 규모가 커지고, 협업을 하는 경우, 빌드 서버가 필요하다.

💡이런 경우 빌드 서버가 필요해요.
1. 프로젝트 규모가 크고 복잡하여 여러 의존성이 있는 경우
2. 지속적 통합(CI) 지속적 배포(CD)와 같은 자동화된 빌드 및 배포 파이프 라인을 구축하는 경우
3. 협업 하는 경우 일관된 빌드 환경을 제공해야 하므로 빌드 서버가 필요하다.

CI / CD (Continuous Integration/Continuous Delivery)

  • 지속적인 통합, 지속적인 서비스 제공, 지속적인 배포를 뜻하는 말로, 애플리케이션 개발 단계를 자동화하는 방법 중 하나 이다.
  • 애플리케이션의 라이프 사이클 전체를 지속적으로 자동화하고, 지속적으로 모니터링 한다. 이러한 구축 사례를 “CI/CD 파이프 라인” 이라 한다.
    • 지속적인 통합(Continuous Integration, CI) : 개발자가 애플리케이션에 적용한 변경 사항이 병합될 때, 변경 사항이 애플리케이션을 손상 시키지 않도록 자동으로 애플리케이션을 구축하고, 유닛 테스트와 통합 테스트를 거쳐 변경 사항이 제대로 적용되었는지 확인 해 준다. 기존 코드와 신규 코드 간의 충돌이 발견되면 CI를 통해 빠르게 수정할 수 있다. (Git에서 merge 시 Conflicts 를 생각하면 이해가 빠르다.)
    • 지속적 제공(Continuous Delivery, CD) : CI의 빌드 자동화, 유닛 및 통합 테스트 수행 후, 유효한 코드를 리포지토리에 자동으로 릴리스 한다.
    • 지속적 배포(Continuous Deployment, CD) : CI/CD 파이프 라인의 마지막 단계이다. 쉽게 말하자면, 개발자가 애플리케이션에 변경 사항을 작성하면 CI/CD 파이프라인을 거쳐 얼마 후, 자동으로 변경된 애플리케이션을 실행할 수 있는 것을 의미한다. (클라우드 타입을 썼을 때, 깃에 커밋/푸쉬 하고, 서버를 재배포 시키는 과정을 CI/CD 파이프 라인을 통해 자동화 시킨다고 생각하면 될 것 같다.)
  • 대표적인 CI/CD 오픈 소스 툴로 젠킨스(Jenkins)가 있다.

애플리케이션 빌드 실전 예제 - 자바

Maven을 사용해 자바 애플리케이션을 빌드하는 Dockerfile을 만들자.

  • 이 실습은 “도커 교과서” 의 4장 실습 내용을 참고로 하였다.
  • 참고 GitHub sixeyed/diamol: Code samples for the book “Learn Docker in a Month of Lunches” (github.com)
  • 위 깃 허브에서 clone 해 온 실습 코드들이다. Dockerfile 은 디렉토리 경로도 중요하기 때문에 실습 코드를 그대로 실행하려면 아래 디렉토리 구조를 참고하거나, 위 깃허브를 참고하면 좋다.
  • 아래는 Dockerfile 내용이다.
    • 우선 위 도커 파일은 FROM 지시어가 2개 있는걸로 봐서, 빌드 단계와 실행 단계로 구분 된 멀티 스테이지 방식의 도커 파일임을 알 수 있다.
      • 빌드 단계에서는 WORKDIR 지시어를 통해 이미지에 작업 디렉터리를 만들고, COPY 지시어로 프로젝트의 설정 및 의존성 등이 정의된 pom.xml 파일을 복사한다.
      • 그 다음 RUN 지시어로 maven 명령어를 실행하여 필요한 모든 의존성을 미리 다운로드하고 캐시한다.
      • 다음 COPY지시어로는 프로젝트의 나머지 파일들을 작업 디렉터리에 복사하고, mvn package 명령어로 프로젝트를 빌드하고, 실행 가능한 iotd-service-0.1.0.jar 파일을 생성한다.
      • 애플리케이션 실행 단계에서는 작업 디렉터리를 /app으로 설정하고, 빌드 단계에서 생성된 iotd-service-0.1.0.jar 파일을 /app 디렉터리로 복사한다.
        • 이때 --from은 파일이 복사될 스테이지를 지정하는 옵션으로, 위 빌드 단계에서 builder로 이름을 붙인 빌드 스테이지가 해당된다.
      • EXPOSE 지시어로 컨테이너가 외부와 통신할 때, 80번 포트를 사용하도록 한다.
      • ENTRYPOINT 지시어는 지정된 명령을 컨테이너가 시작될 때마다 자동으로 실행되게 하는 지시어로, 컨테이너가 실행될 때마다 자동으로 /app/iotd-service-0.1.0.jar 파일을 java 애플리케이션으로 동작하게 한다.
    • Dockerfile이 있는 디렉터리 경로로 이동한 뒤, docker image build 명령어로 이미지 빌드를 시작한다. 이때, 태그는 ‘image-of-the-day’ 로 설정한다.
    • docker network create 명령어로 nat이라는 사용자 지정 네트워크를 하나 생성한다.
    • docker container run 명령어로 빌드한 image-of-the-day 이미지를 iotd 라는 이름의 컨테이너로 실행한다. gradle 기반 웹 서버의 Dockerfile 작성