기초부터 멀티 스테이지 빌드까지

DockerBeginner
지금 연습하기

소개

Docker 는 애플리케이션을 개발하고, 배포하며, 실행하는 방식을 근본적으로 변화시켰습니다. Docker 기능의 핵심은 특정 요구 사항에 맞춰 최적화된 커스텀 이미지를 생성하는 능력에 있습니다. 이번 챌린지에서는 docker build 명령어의 강력함과 유연성을 탐구하며, 다양한 시나리오에 맞는 Docker 이미지를 만드는 방법을 배우게 됩니다.

단순한 애플리케이션부터 의존성 및 환경 변수가 포함된 복잡한 설정까지, Docker 이미지 생성의 핵심 개념을 직접 실습하며 익힐 수 있습니다. 이 챌린지를 마칠 때쯤이면 현대적인 소프트웨어 개발 및 배포 워크플로우에서 필수적인 기술인 효율적이고 효과적인 Docker 이미지 빌드 능력을 갖추게 될 것입니다.

그럼 Docker 이미지 빌드의 세계로 여정을 시작해 봅시다!

이 콘텐츠는 챌린지 (Challenge) 입니다. 가이드가 제공되는 실습 (Guided Lab) 과 달리, 정해진 단계를 따라가는 것이 아니라 스스로 과제를 해결해야 합니다. 챌린지는 다소 어려울 수 있습니다. 해결이 어렵다면 Labby 와 상담하거나 솔루션을 확인하세요. 통계에 따르면 이 챌린지는 초급 수준이며, 통과율은 92%입니다. 학습자들로부터 98%의 긍정적인 평가를 받았습니다.

기본적인 Docker 빌드

가장 기초적인 단계부터 시작합니다. 이번 단계에서는 "Hello, World!" 메시지를 출력하는 간단한 Docker 이미지를 생성합니다. 이를 통해 Dockerfile 의 기본 구조와 docker build 명령어의 사용법을 익히게 됩니다.

과제

  1. /home/labex/project 아래에 있는 hello-world 디렉토리로 이동합니다.
  2. 해당 디렉토리의 Dockerfile을 열고 필요한 지시어를 추가합니다.
  3. docker build 명령어를 사용하여 hello-world라는 이름의 Docker 이미지를 빌드합니다.

요구 사항

  • 모든 작업은 /home/labex/project/hello-world 디렉토리 내에서 수행해야 합니다.
  • Dockerfile 에서 Alpine Linux 베이스 이미지를 사용하세요.
  • 생성된 Docker 이미지는 실행 시 "Hello, World!"를 출력해야 합니다.

예시

이 단계를 완료한 후, 다음 명령어를 실행하여 결과를 확인할 수 있어야 합니다:

$ docker run hello-world
Hello, World!

첫 번째 Docker 이미지를 성공적으로 만드셨습니다! 이 간단한 예제는 Docker 이미지 생성의 기본 원리를 잘 보여줍니다. 다음 단계에서는 이 지식을 바탕으로 의존성이 포함된 더 복잡한 이미지를 빌드해 보겠습니다.

✨ 솔루션 확인 및 연습

의존성이 포함된 Docker 이미지 빌드

기초를 익혔으니 이제 좀 더 실무적인 시나리오를 다뤄보겠습니다. 이번 단계에서는 Flask 웹 프레임워크를 사용하는 Python 애플리케이션용 Docker 이미지를 만듭니다. 이를 통해 Docker 이미지 내에서 의존성을 관리하는 개념을 배우게 됩니다.

과제

  1. /home/labex/project 아래의 flask-app 디렉토리로 이동합니다.
  2. 해당 디렉토리의 Dockerfile을 열고 의존성을 설치하는 데 필요한 지시어를 추가합니다.
  3. requirements.txt 파일을 살펴보고 어떤 의존성이 필요한지 확인합니다.
  4. docker build 명령어를 사용하여 flask-app이라는 이름의 Docker 이미지를 빌드합니다.

요구 사항

  • 모든 작업은 /home/labex/project/flask-app 디렉토리 내에서 수행해야 합니다.
  • Dockerfile 에서 python:3.7-alpine 베이스 이미지를 사용하세요.
  • requirements.txt에 나열된 의존성들이 이미지 내에 설치되도록 설정하세요.
  • Dockerfile 은 requirements.txt 파일을 복사하고 의존성을 설치하는 과정을 포함해야 합니다.

예시

이 단계를 완료한 후, Docker 이미지 목록을 확인했을 때 flask-app 이미지가 보여야 합니다:

$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
flask-app    latest    abcdef123456   2 minutes ago   55.8MB

잘하셨습니다! 이제 외부 의존성을 포함하는 Docker 이미지를 만들 수 있게 되었습니다. 이는 실제 애플리케이션 개발에서 매우 흔한 시나리오입니다. 다음 단계에서는 Docker 이미지를 더 유연하고 설정 가능하게 만들기 위해 환경 변수를 사용하는 방법을 알아보겠습니다.

✨ 솔루션 확인 및 연습

환경 변수를 활용한 Docker 이미지 빌드

설정 관리 (Configuration management) 는 컨테이너화된 애플리케이션에서 매우 중요한 요소입니다. 이번 단계에서는 환경 변수를 사용하여 Flask 애플리케이션의 포트 번호를 설정하는 Docker 이미지를 만듭니다. 이를 통해 다양한 환경에 동적으로 적응할 수 있는 Docker 이미지를 만드는 방법을 익힙니다.

과제

  1. /home/labex/project 아래의 flask-app-env 디렉토리로 이동합니다.
  2. 해당 디렉토리의 Dockerfile을 열고 환경 변수를 설정하는 지시어를 추가합니다.
  3. app.py 파일을 수정하여 포트 번호에 환경 변수를 사용하도록 설정합니다.
  4. docker build 명령어를 사용하여 flask-app-env라는 이름의 Docker 이미지를 빌드합니다.

요구 사항

  • 모든 작업은 /home/labex/project/flask-app-env 디렉토리 내에서 수행해야 합니다.
  • Dockerfile 에서 python:3.7-alpine 베이스 이미지를 사용하세요.
  • Dockerfile 에서 기본값이 5000 인 PORT 환경 변수를 설정하세요.
  • Flask 애플리케이션이 PORT 환경 변수를 읽어 리스닝 포트로 사용하도록 수정하세요.
  • requirements.txt에 나열된 모든 필요한 Python 패키지가 설치되었는지 확인하세요.

예시

이 단계를 완료하고 컨테이너를 실행하면 다음과 같이 애플리케이션에 접속할 수 있어야 합니다:

$ docker run -d -p 5000:5000 flask-app-env
$ curl http://127.0.0.1:5000
Hello, World!

훌륭합니다! 이제 환경 변수를 사용하여 다양한 환경에 적응할 수 있는 유연한 Docker 이미지를 만들었습니다. 이는 재사용 가능하고 설정 변경이 용이한 컨테이너 이미지를 만드는 강력한 기법입니다. 마지막 단계에서는 Docker 의 고급 기능인 멀티 스테이지 빌드를 살펴보겠습니다.

✨ 솔루션 확인 및 연습

멀티 스테이지 빌드를 활용한 Docker 이미지 빌드

마지막 챌린지로 멀티 스테이지 빌드 (Multi-stage builds) 를 깊이 있게 다뤄보겠습니다. 이 고급 기법은 빌드 프로세스에서 여러 단계를 사용하여 훨씬 효율적인 Docker 이미지를 만들 수 있게 해줍니다. Go 애플리케이션을 위한 이미지를 만들 때, 한 단계에서는 코드를 컴파일하고 다른 단계에서는 실행에 필요한 파일만 담은 가벼운 운영용 이미지를 생성해 봅니다.

과제

  1. /home/labex/project 아래의 go-app 디렉토리로 이동합니다.
  2. 해당 디렉토리의 Dockerfile을 열고 멀티 스테이지 빌드를 위한 지시어를 추가합니다.
  3. main.go 파일을 살펴보고 간단한 Go 애플리케이션의 구조를 파악합니다.
  4. docker build 명령어를 사용하여 go-app이라는 이름의 Docker 이미지를 빌드합니다.

요구 사항

  • 모든 작업은 /home/labex/project/go-app 디렉토리 내에서 수행해야 합니다.
  • 빌드 단계 (build stage) 의 베이스 이미지로는 golang:1.14-alpine을 사용하고, 최종 단계 (final stage) 의 베이스 이미지로는 alpine을 사용하세요.
  • Go 애플리케이션은 실행 시 "Hello, World!"를 출력해야 합니다.
  • Go 애플리케이션은 go build 명령어를 통해 컴파일되어야 합니다.
  • 최종 Docker 이미지에는 Go 개발 환경이 포함되지 않고, 컴파일된 바이너리 파일만 포함되어야 합니다.

예시

이 단계를 완료한 후, 다음 명령어를 실행하여 결과를 확인할 수 있어야 합니다:

$ docker run go-app
Hello, World!
✨ 솔루션 확인 및 연습

요약

포괄적인 Docker 이미지 빌드 챌린지를 완료하신 것을 축하드립니다! 기본적인 Docker 이미지 생성부터 멀티 스테이지 빌드와 같은 고급 기법까지 성공적으로 마쳤습니다. 이 과정을 통해 다음과 같은 기술을 습득했습니다:

  1. 기본적인 Dockerfile 을 사용한 단순 Docker 이미지 생성
  2. Docker 이미지 내 의존성 관리 방법
  3. 환경 변수를 활용하여 이미지의 유연성을 높이는 방법
  4. 효율적인 운영용 이미지를 위한 멀티 스테이지 빌드 구현

이러한 기술은 개발 및 테스트부터 실제 운영 배포에 이르기까지 다양한 시나리오에서 효과적으로 Docker 를 활용하기 위한 토대가 됩니다. Docker CLI 와 Dockerfile 문법을 직접 다루며 얻은 경험은 컨테이너 기반 애플리케이션을 다루는 모든 이들에게 매우 소중한 자산이 될 것입니다.

Docker 여정을 계속하면서, 오늘 배운 기본 작업들이 더 복잡한 Docker 워크플로우를 구성하는 핵심 요소임을 기억하세요. 이러한 기술을 꾸준히 연습하면 컨테이너 이미지 생성 및 관리 능력이 더욱 향상될 것이며, 결과적으로 더 효율적이고 간소화된 개발 및 배포 프로세스를 구축할 수 있게 될 것입니다.

Docker 의 다양한 기능을 계속 탐구해 보세요. 다양한 베이스 이미지, 빌드 전략, 최적화 기법을 실험해 보는 것을 주저하지 마세요. 컨테이너화의 세계는 방대하고 가능성으로 가득 차 있으며, 이제 여러분은 자신 있게 그 세계를 항해할 준비가 되었습니다!