사용자 정의 Docker 이미지 생성하기

DockerBeginner
지금 연습하기

소개

Docker 는 애플리케이션을 컨테이너 형태로 패키징하고 배포할 수 있게 해주는 강력한 도구입니다. 이 프로세스의 핵심은 Docker 이미지입니다. 이미지는 코드, 의존성, 설정 등 애플리케이션 실행에 필요한 모든 것을 포함하고 있는 미리 빌드된 패키지입니다. 이번 실습에서는 추가 소프트웨어, 라이브러리 또는 설정을 통합하여 애플리케이션의 기능을 강화하는 사용자 정의 Docker 이미지를 만드는 방법을 배워보겠습니다.

이 실습 전반에 걸쳐 파일 편집을 위해 WebIDE(VS Code) 를 사용합니다. WebIDE 는 파일 편집을 위한 친숙하고 사용자 친화적인 인터페이스를 제공하여 설정 파일과 코드를 더 쉽게 다룰 수 있게 해줍니다.

프로젝트 환경 설정

먼저 프로젝트 디렉토리를 생성하고 해당 위치로 이동해 보겠습니다.

이 실습 전반에 걸쳐 파일 편집을 위해 WebIDE(VS Code) 를 사용합니다. WebIDE 는 파일 편집을 위한 친숙하고 사용자 친화적인 인터페이스를 제공하여 설정 파일과 코드를 더 쉽게 다룰 수 있게 해줍니다.

  1. WebIDE 에서 터미널을 엽니다. 상단 메뉴에서 "Terminal"을 클릭한 다음 "New Terminal"을 선택하면 됩니다.
  2. 터미널에서 다음 명령어를 실행합니다.
mkdir -p ~/project/docker
cd ~/project/docker
프로젝트 디렉토리 생성 명령어를 보여주는 터미널

이 명령어는 ~/project 폴더 안에 docker라는 새 디렉토리를 생성하고, 현재 작업 디렉토리를 해당 위치로 변경합니다.

  1. 올바른 디렉토리에 있는지 확인합니다.
pwd

출력 결과로 /home/labex/project/docker가 표시되어야 합니다.

사용된 명령어 이해하기:

  • mkdir -p: 디렉토리를 생성하는 명령어입니다. -p 플래그는 상위 디렉토리가 존재하지 않을 경우 함께 생성하도록 합니다.
  • cd: 현재 디렉토리를 변경하는 명령어입니다.
  • pwd: 현재 작업 중인 디렉토리의 경로를 출력하는 명령어입니다.

간단한 Docker 이미지 생성

이제 Nginx 웹 서버를 실행하는 간단한 Docker 이미지를 만들어 보겠습니다.

  1. WebIDE 의 파일 탐색기 (보통 왼쪽 사이드바의 첫 번째 아이콘) 로 이동합니다.
  2. 파일 탐색기 창에서 마우스 오른쪽 버튼을 클릭하고 "New File"을 선택합니다. 파일 이름을 Dockerfile로 지정합니다 (첫 글자 'D'는 대문자여야 하며 확장자는 없습니다).
  3. 파일 탐색기에서 Dockerfile을 클릭하여 엽니다. 그리고 다음 내용을 추가합니다.
FROM nginx
COPY index.html /usr/share/nginx/html/

이 Dockerfile 은 공식 Nginx 이미지를 기반으로 새 이미지를 정의하며, index.html 파일을 Nginx 의 기본 문서 루트 디렉토리로 복사합니다.

Dockerfile 내용 이해하기:

  • FROM nginx: 빌드의 기반이 될 베이스 이미지를 지정합니다. 여기서는 공식 Nginx 이미지를 사용합니다.
  • COPY index.html /usr/share/nginx/html/: 로컬의 index.html 파일을 컨테이너 내부의 웹 루트 디렉토리로 복사합니다.
  1. 같은 디렉토리에 index.html이라는 새 파일을 만듭니다. 파일 탐색기에서 다시 마우스 오른쪽 버튼을 클릭하고 "New File"을 선택하면 됩니다.
  2. index.html을 열고 다음 내용을 추가합니다.
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Hello Docker!</title>
  </head>
  <body>
    <h1>Hello Docker!</h1>
    <p>This is a custom Docker image.</p>
  </body>
</html>

이것은 Nginx 서버를 통해 보여줄 간단한 HTML 페이지입니다.

  1. WebIDE 터미널을 열고 (이전 터미널을 닫았다면 Terminal -> New Terminal) 다음 명령어를 사용하여 Docker 이미지를 빌드합니다.
docker build -t my-nginx .

이 명령어는 my-nginx라는 태그를 가진 새로운 Docker 이미지를 빌드합니다.

명령어 이해하기:

  • docker build: Docker 이미지를 빌드하는 명령어입니다.
  • -t my-nginx: -t 플래그는 이미지에 my-nginx라는 이름을 붙여 태그를 지정합니다.
  • .: Dockerfile 이 위치한 현재 디렉토리를 빌드 컨텍스트로 지정합니다.
  1. 빌드가 완료되면 이미지가 성공적으로 생성되었는지 확인합니다.
docker images

출력 목록에서 my-nginx 이미지를 확인할 수 있어야 합니다.

사용자 정의 이미지 실행 및 테스트

새로 만든 이미지를 기반으로 컨테이너를 실행하고 테스트해 보겠습니다.

  1. WebIDE 터미널에서 다음 명령어를 사용하여 컨테이너를 시작합니다.
docker run -d -p 8080:80 --name my-nginx-container my-nginx

명령어 이해하기:

  • docker run: 새 컨테이너를 생성하고 시작합니다.
  • -d: 컨테이너를 백그라운드 모드 (detached mode) 로 실행합니다.
  • -p 8080:80: 호스트의 8080 포트를 컨테이너의 80 포트로 매핑합니다.
  • --name my-nginx-container: 컨테이너에 이름을 할당합니다.
  • my-nginx: 컨테이너 생성에 사용할 이미지의 이름입니다.
  1. 컨테이너가 실행 중인지 확인합니다.
docker ps

출력 결과에 my-nginx-container가 표시되어야 합니다. 이 명령어는 현재 실행 중인 모든 컨테이너를 보여줍니다.

  1. 웹 페이지의 내용을 확인하려면 curl 명령어를 사용합니다.
curl http://localhost:8080

터미널에 index.html 파일의 HTML 내용이 출력되는 것을 볼 수 있습니다.

curl이 무엇인지 궁금하다면, 서버와 데이터를 주고받기 위한 도구라고 이해하면 됩니다. 여기서는 웹 서버로부터 콘텐츠를 가져오는 데 사용되었습니다.

또한 LabEx VM 상단에서 + 버튼을 클릭하여 새 웹 서버를 생성하고, 8080 포트를 입력하여 브라우저에서 직접 내용을 확인할 수도 있습니다.

웹 서버 포트 설정

이미지에 커스텀 소프트웨어 추가

이제 추가 소프트웨어를 포함하도록 Docker 이미지를 수정해 보겠습니다. 예시로 curl 유틸리티를 추가해 보겠습니다.

  1. WebIDE 에서 Dockerfile을 엽니다. 파일 탐색기에서 Dockerfile을 클릭하면 됩니다.
  2. Dockerfile의 내용을 다음과 같이 수정합니다.
FROM nginx
RUN apt-get update && apt-get install -y curl
COPY index.html /usr/share/nginx/html/

이 Dockerfile 에는 패키지 인덱스를 업데이트하고 apt-get 패키지 관리자를 사용하여 curl 유틸리티를 설치하는 RUN 명령이 추가되었습니다.

새로 추가된 라인 이해하기:

  • RUN apt-get update && apt-get install -y curl: 패키지 목록을 업데이트 (apt-get update) 한 후 curl 을 설치 (apt-get install -y curl) 합니다. -y 플래그는 설치 중 발생하는 모든 확인 질문에 자동으로 "yes"라고 응답하도록 합니다.
  1. WebIDE 에서 Ctrl+S(Mac 은 Cmd+S) 를 눌러 파일을 저장합니다.
  2. WebIDE 터미널에서 새로운 태그를 사용하여 Docker 이미지를 다시 빌드합니다.
docker build -t my-nginx-curl .

이 명령어는 curl 유틸리티가 포함된 my-nginx-curl이라는 이름의 새 Docker 이미지를 빌드합니다.

  1. 새 이미지가 생성되었는지 확인합니다.
docker images

출력 목록에 my-nginx-curl 이미지가 표시되어야 합니다.

Curl 이 포함된 사용자 정의 이미지 테스트

새 이미지를 기반으로 컨테이너를 실행하고 curl 유틸리티가 잘 작동하는지 테스트해 보겠습니다.

  1. WebIDE 터미널에서 다음 명령어를 사용하여 새 컨테이너를 시작합니다.
docker run -d --name curl-container my-nginx-curl

이 명령어는 my-nginx-curl 이미지를 기반으로 curl-container라는 이름의 컨테이너를 시작합니다.

  1. 실행 중인 컨테이너 내부에서 bash 쉘을 실행합니다.
docker exec -it curl-container bash

이 명령어는 실행 중인 컨테이너 내부에서 대화형 bash 쉘을 엽니다.

명령어 이해하기:

  • docker exec: 실행 중인 컨테이너에서 명령어를 실행합니다.
  • -it: pseudo-TTY 를 할당하고 표준 입력 (STDIN) 을 열어두어 쉘과 상호작용할 수 있게 합니다.
  • curl-container: 대상 컨테이너의 이름입니다.
  • bash: 컨테이너 내부에서 실행할 명령어 (bash 쉘 열기) 입니다.
  1. 이제 프롬프트가 변경된 것을 볼 수 있으며, 이는 컨테이너 내부에 있음을 의미합니다. 컨테이너 내부에서 curl 유틸리티를 테스트합니다.
curl http://localhost

터미널에 index.html 파일의 HTML 내용이 출력되는 것을 확인할 수 있습니다.

  1. 컨테이너의 bash 쉘에서 나옵니다.
exit

이 명령어를 입력하면 다시 호스트 시스템의 쉘로 돌아옵니다.

이미지에서 환경 변수 사용하기

이번 단계에서는 환경 변수를 사용하여 설정을 사용자 정의할 수 있도록 Docker 이미지를 수정해 보겠습니다.

  1. WebIDE 에서 Dockerfile을 다시 엽니다.

  2. Dockerfile의 내용을 다음과 같이 수정합니다.

FROM nginx
ENV NGINX_PORT 9000
RUN sed -i "s/listen[[:space:]]*80;/listen $NGINX_PORT;/g" /etc/nginx/conf.d/default.conf
COPY index.html /usr/share/nginx/html/

이 Dockerfile 은 NGINX_PORT 변수를 9000으로 설정하는 ENV 명령을 추가합니다. 또한 이 포트를 사용하도록 Nginx 설정을 수정하는 RUN 명령이 포함되어 있습니다.

새로 추가된 라인 이해하기:

  • ENV NGINX_PORT 9000: NGINX_PORT라는 환경 변수를 생성하고 값을 9000으로 설정합니다.
  • RUN sed -i "s/listen[[:space:]]*80;/listen $NGINX_PORT;/g" /etc/nginx/conf.d/default.conf: sed 명령어를 사용하여 Nginx 설정 파일에서 기본 포트 (80) 를 환경 변수에 지정된 포트로 교체합니다.
  1. WebIDE 에서 파일을 저장합니다.

  2. WebIDE 터미널에서 새로운 태그로 Docker 이미지를 다시 빌드합니다.

docker build -t my-nginx-env .
  1. 새 이미지를 기반으로 컨테이너를 실행합니다.
docker run -d -p 9000:9000 --name env-container my-nginx-env

이 명령어는 my-nginx-env 이미지를 기반으로 컨테이너를 시작하고 호스트의 9000 포트를 컨테이너의 9000 포트로 매핑합니다. 환경 변수가 이미 Dockerfile 에 설정되어 있으므로 docker run 명령어에서 다시 설정할 필요는 없습니다.

  1. 웹 서버가 지정된 포트에서 실행 중인지 확인합니다.
curl http://localhost:9000

터미널에 index.html 파일의 내용이 정상적으로 출력되어야 합니다.

Dockerfile 에서 ENTRYPOINT 사용하기

이번 단계에서는 Dockerfile 에서 ENTRYPOINT 명령을 사용하는 방법을 배우고, 다른 포트 (9100) 를 사용해 보겠습니다.

  1. WebIDE 에서 Dockerfile을 다시 엽니다.

  2. Dockerfile의 내용을 다음과 같이 수정합니다.

FROM nginx
COPY index.html /usr/share/nginx/html/
COPY start.sh /start.sh
RUN chmod +x /start.sh
ENTRYPOINT ["/start.sh"]

이 Dockerfile 은 이전의 환경 변수 설정과 sed 명령을 제거했습니다. 대신 ENTRYPOINT 스크립트를 사용하여 런타임에 설정을 처리합니다. 이렇게 하면 이미지가 훨씬 더 유연해집니다.

  1. 같은 디렉토리에 다음 내용을 가진 start.sh라는 새 파일을 만듭니다.
#!/bin/bash
## NGINX_PORT가 설정되지 않은 경우 기본 포트 설정
export NGINX_PORT=${NGINX_PORT:-9100}
## nginx 설정에서 포트 교체
sed -i "s/listen[[:space:]]*80;/listen $NGINX_PORT;/g" /etc/nginx/conf.d/default.conf
echo "Starting Nginx on port $NGINX_PORT"
nginx -g 'daemon off;'

이 스크립트는 기본 포트를 설정하고, 컨테이너 시작 시 Nginx 설정을 수정하며, Nginx 가 실행될 포트를 알리는 메시지를 출력한 후 Nginx 를 시작합니다.

  1. WebIDE 에서 두 파일 모두 저장합니다.

  2. WebIDE 터미널에서 새로운 태그로 Docker 이미지를 다시 빌드합니다.

docker build -t my-nginx-entrypoint .
  1. 새 이미지를 기반으로 컨테이너를 실행합니다. 이번에는 환경 변수를 사용하여 포트를 9100 으로 설정하겠습니다.
docker run -d -p 9100:9100 -e NGINX_PORT=9100 --name entrypoint-container my-nginx-entrypoint
  1. 컨테이너 로그를 확인하여 시작 메시지를 확인합니다.
docker logs entrypoint-container

출력 결과에서 "Starting Nginx on port 9100"이라는 메시지를 볼 수 있어야 합니다.

  1. 웹 서버가 새 포트에서 올바르게 작동하는지 확인합니다.
curl http://localhost:9100

터미널에 index.html 파일의 내용이 출력되는 것을 확인할 수 있습니다.

요약

이 실습을 통해 애플리케이션에 가치를 더하는 사용자 정의 Docker 이미지를 만드는 방법을 배웠습니다. 웹 서버가 포함된 간단한 이미지 생성부터 시작하여, 커스텀 소프트웨어를 추가하고 설정을 위해 환경 변수를 사용하는 단계까지 진행했습니다. 실습 전반에 걸쳐 WebIDE(VS Code) 를 사용하여 파일을 편집함으로써 프로세스를 더 직관적이고 편리하게 경험할 수 있었습니다.

지금까지 달성한 주요 내용은 다음과 같습니다:

  1. 프로젝트 환경을 설정하고 기본적인 터미널 명령어를 익혔습니다.
  2. Nginx 와 사용자 정의 HTML 페이지가 포함된 간단한 Docker 이미지를 생성했습니다.
  3. Docker 컨테이너를 빌드 및 실행하며 포트 매핑과 컨테이너 명명법에 대해 배웠습니다.
  4. 추가 소프트웨어 (curl) 를 포함하도록 Docker 이미지를 수정했습니다.
  5. docker exec를 사용하여 컨테이너 내부에서 명령어를 실행해 보았습니다.
  6. 더 쉬운 설정을 위해 Docker 이미지에 환경 변수와 실행 스크립트를 통합했습니다.