Docker 컨테이너에서 실행 중인 웹 애플리케이션에 액세스하는 방법

DockerBeginner
지금 연습하기

소개

이 튜토리얼은 Docker 컨테이너에서 실행 중인 웹 애플리케이션에 접근하는 과정을 안내합니다. Docker 컨테이너의 기본 사항을 배우고, 간단한 웹 애플리케이션을 배포하며, 호스트 머신에서 이에 접근하는 방법을 익힐 것입니다. 이 지식은 Docker 를 사용하여 웹 애플리케이션을 개발하고 테스트하는 데 필수적입니다.

Docker 이해 및 테스트 컨테이너 실행

Docker 는 컨테이너화 (containerization) 를 사용하여 애플리케이션과 해당 종속성을 함께 패키징하는 플랫폼입니다. 이를 통해 애플리케이션이 서로 다른 환경에서 일관되게 실행될 수 있습니다.

Docker 설치 확인

먼저, 시스템에 Docker 가 제대로 설치되었는지 확인해 보겠습니다.

docker --version

Docker 버전을 보여주는 다음과 유사한 출력을 볼 수 있습니다.

Docker version 20.10.21, build baeda1f

Docker 이미지와 컨테이너 이해

Docker 용어에서:

  • **Docker 이미지 (Docker image)**는 애플리케이션 코드, 라이브러리 및 종속성을 포함하는 템플릿입니다.
  • **Docker 컨테이너 (Docker container)**는 이미지의 실행 인스턴스입니다.

Docker 이미지를 청사진으로, Docker 컨테이너를 해당 청사진으로 생성된 건물로 생각할 수 있습니다.

첫 번째 Docker 컨테이너 실행

Docker 가 제대로 작동하는지 확인하기 위해 간단한 컨테이너를 실행해 보겠습니다.

docker run hello-world

다음과 같은 출력을 볼 수 있습니다.

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.
...

이는 Docker 가 시스템에서 제대로 작동하고 있음을 확인합니다.

기본 Docker 명령어

다음은 알아두어야 할 몇 가지 필수 Docker 명령어입니다.

  1. 실행 중인 모든 컨테이너를 나열하려면:
docker ps
  1. 모든 컨테이너 (중지된 컨테이너 포함) 를 나열하려면:
docker ps -a
  1. 시스템의 모든 Docker 이미지를 나열하려면:
docker images

이러한 명령어를 시도하고 출력을 관찰하십시오. hello-world 컨테이너를 실행한 후, docker ps -a를 실행하면 해당 컨테이너가 나열되어야 합니다 (하지만 메시지를 표시한 후 즉시 종료되므로 docker ps에서는 표시되지 않습니다).

간단한 웹 애플리케이션 생성

이 단계에서는 Docker 컨테이너에 배포할 수 있는 Python 과 Flask 를 사용하여 간단한 웹 애플리케이션을 만들 것입니다.

애플리케이션 파일 설정

먼저, 웹 애플리케이션을 위한 새 디렉토리를 생성해 보겠습니다.

mkdir -p ~/project/my-web-app
cd ~/project/my-web-app

이제 간단한 Flask 애플리케이션을 만들어 보겠습니다. nano 편집기를 사용하여 app.py라는 파일을 생성합니다.

nano app.py

다음 Python 코드를 파일에 추가합니다.

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return "<h1>Hello from Docker!</h1><p>This is a simple web application running in a Docker container.</p>"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

Ctrl+O를 누른 다음 Enter를 눌러 파일을 저장하고, Ctrl+X를 눌러 nano 를 종료합니다.

다음으로, 애플리케이션의 종속성을 지정하기 위해 requirements.txt 파일을 생성합니다.

nano requirements.txt

다음 줄을 파일에 추가합니다.

flask==2.0.1

Ctrl+O를 누른 다음 Enter를 눌러 파일을 저장하고, Ctrl+X를 눌러 nano 를 종료합니다.

Dockerfile 생성

이제 애플리케이션을 컨테이너화하는 방법을 정의하기 위해 Dockerfile 을 생성해 보겠습니다.

nano Dockerfile

다음 내용을 파일에 추가합니다.

FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
EXPOSE 5000
CMD ["python", "app.py"]

이 Dockerfile 은 다음을 수행합니다.

  1. 경량 Python 3.9 이미지를 기본 이미지로 사용합니다.
  2. 작업 디렉토리를 /app으로 설정합니다.
  3. requirements 파일을 복사하고 종속성을 설치합니다.
  4. 애플리케이션 코드를 복사합니다.
  5. 들어오는 연결을 위해 포트 5000 을 노출합니다.
  6. 컨테이너가 시작될 때 실행할 명령을 지정합니다.

Ctrl+O를 누른 다음 Enter를 눌러 파일을 저장하고, Ctrl+X를 눌러 nano 를 종료합니다.

Docker 이미지 빌드

이제 Dockerfile 에서 Docker 이미지를 빌드해 보겠습니다.

docker build -t my-flask-app .

-t 플래그는 이미지를 my-flask-app라는 이름으로 태그합니다. 마지막의 .은 Dockerfile 이 현재 디렉토리에 있음을 지정합니다.

다음과 유사한 출력을 볼 수 있습니다.

Sending build context to Docker daemon  x.xxxkB
Step 1/6 : FROM python:3.9-slim
 ---> xxxxxxxxxx
Step 2/6 : WORKDIR /app
 ---> Using cache
 ---> xxxxxxxxxx
...
Successfully built xxxxxxxxxx
Successfully tagged my-flask-app:latest

이제 이미지가 생성되었는지 확인합니다.

docker images | grep my-flask-app

새로 생성된 이미지가 목록에 표시되어야 합니다.

Docker 컨테이너에서 웹 애플리케이션 실행

이제 Docker 이미지를 빌드했으므로, 이를 컨테이너로 실행하고 웹 애플리케이션에 액세스해 보겠습니다.

컨테이너 실행

컨테이너를 실행하고 웹 애플리케이션에 액세스할 수 있도록 포트를 매핑하려면 다음 명령을 사용합니다.

docker run -d -p 5000:5000 --name my-web-container my-flask-app

이 명령은 다음을 수행합니다.

  • -d: 컨테이너를 분리된 모드 (백그라운드) 로 실행합니다.
  • -p 5000:5000: 컨테이너의 포트 5000 을 호스트의 포트 5000 에 매핑합니다.
  • --name my-web-container: 컨테이너에 이름을 할당합니다.
  • my-flask-app: 사용할 이미지를 지정합니다.

컨테이너가 실행 중인지 확인

컨테이너가 실행 중인지 확인해 보겠습니다.

docker ps

다음과 유사한 출력을 볼 수 있습니다.

CONTAINER ID   IMAGE          COMMAND           CREATED          STATUS          PORTS                    NAMES
xxxxxxxxxxxx   my-flask-app   "python app.py"   xx seconds ago   Up xx seconds   0.0.0.0:5000->5000/tcp   my-web-container

웹 애플리케이션에 액세스

이제 두 가지 방법으로 웹 애플리케이션에 액세스할 수 있습니다.

  1. 명령줄에서 curl 사용:
curl http://localhost:5000

HTML 응답을 볼 수 있습니다.

<h1>Hello from Docker!</h1><p>This is a simple web application running in a Docker container.</p>
  1. 웹 브라우저 사용:
    • 데스크톱 환경에서 웹 브라우저 아이콘을 클릭합니다.
    • 주소 표시줄에 http://localhost:5000을 입력합니다.
    • "Hello from Docker!" 다음에 설명 텍스트가 표시되어야 합니다.

포트 매핑 이해

-p 5000:5000으로 컨테이너를 실행할 때, 다음 간의 매핑을 생성합니다.

  • 호스트 포트 (첫 번째 숫자): 5000
  • 컨테이너 포트 (두 번째 숫자): 5000

이는 호스트 머신의 포트 5000 으로 전송된 모든 트래픽이 컨테이너 내부의 포트 5000 으로 전달됨을 의미합니다.

다른 포트 번호를 사용할 수도 있습니다. 예를 들어, -p 8080:5000은 호스트 포트 8080 을 컨테이너 포트 5000 에 매핑하여 http://localhost:8080에서 애플리케이션에 액세스할 수 있도록 합니다.

컨테이너 로그 검사

컨테이너의 로그를 확인해야 하는 경우 (디버깅에 유용할 수 있음) 다음을 사용합니다.

docker logs my-web-container

Flask 애플리케이션 시작 메시지를 볼 수 있습니다.

컨테이너 중지 및 제거

컨테이너를 중지하려면 다음을 사용합니다.

docker stop my-web-container

중지된 컨테이너를 제거하려면 다음을 사용합니다.

docker rm my-web-container

단일 명령으로 컨테이너를 중지하고 제거할 수도 있습니다.

docker rm -f my-web-container

이는 컨테이너를 빠르게 다시 빌드하고 다시 실행하려는 개발 중에 유용합니다.

고급 Docker 컨테이너 관리

Docker 컨테이너에서 웹 애플리케이션을 성공적으로 실행했으므로, Docker 컨테이너를 관리하기 위한 몇 가지 추가 기능과 기술을 살펴보겠습니다.

여러 인스턴스 실행

다른 포트에서 웹 애플리케이션의 여러 인스턴스를 실행할 수 있습니다. 이는 테스트 또는 앱의 다른 버전을 동시에 실행하는 데 유용합니다.

먼저, 이전 컨테이너를 중지하고 제거해 보겠습니다.

docker rm -f my-web-container

이제 다른 포트에서 웹 애플리케이션의 두 인스턴스를 실행해 보겠습니다.

docker run -d -p 5000:5000 --name web-app-1 my-flask-app
docker run -d -p 5001:5000 --name web-app-2 my-flask-app

두 컨테이너가 실행 중인지 확인합니다.

docker ps

두 개의 컨테이너가 실행 중인 것을 볼 수 있습니다.

CONTAINER ID   IMAGE          COMMAND           CREATED          STATUS          PORTS                    NAMES
xxxxxxxxxxxx   my-flask-app   "python app.py"   xx seconds ago   Up xx seconds   0.0.0.0:5001->5000/tcp   web-app-2
xxxxxxxxxxxx   my-flask-app   "python app.py"   xx seconds ago   Up xx seconds   0.0.0.0:5000->5000/tcp   web-app-1

이제 두 개의 다른 포트에서 동일한 애플리케이션에 액세스할 수 있습니다.

컨테이너 리소스 제한

Docker 를 사용하면 컨테이너에 대한 리소스 제한을 설정할 수 있습니다. 이는 컨테이너가 너무 많은 시스템 리소스를 소비하는 것을 방지하는 데 유용합니다.

이전 컨테이너를 중지하고 제거해 보겠습니다.

docker rm -f web-app-1 web-app-2

이제 메모리 및 CPU 제한이 있는 컨테이너를 실행해 보겠습니다.

docker run -d -p 5000:5000 --name limited-container --memory=512m --cpus=0.5 my-flask-app

이 명령은 다음을 사용하여 컨테이너를 생성합니다.

  • 최대 512MB 의 메모리
  • 최대 0.5 CPU 코어

컨테이너가 실행 중인지 확인합니다.

docker ps

컨테이너 환경 변수

환경 변수는 Docker 컨테이너에서 애플리케이션을 구성하는 일반적인 방법입니다. 환경 변수를 사용하도록 Flask 애플리케이션을 수정해 보겠습니다.

docker rm -f limited-container

app.py 파일의 새 버전을 생성합니다.

cd ~/project/my-web-app
nano app_env.py

다음 코드를 추가합니다.

import os
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    app_name = os.environ.get('APP_NAME', 'Default App')
    return f"<h1>Hello from {app_name}!</h1><p>This is a simple web application running in a Docker container.</p>"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

Ctrl+O를 누른 다음 Enter를 눌러 파일을 저장하고, Ctrl+X를 눌러 nano 를 종료합니다.

새 Dockerfile 을 생성합니다.

nano Dockerfile-env

다음 내용을 추가합니다.

FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app_env.py ./app.py
EXPOSE 5000
CMD ["python", "app.py"]

Ctrl+O를 누른 다음 Enter를 눌러 파일을 저장하고, Ctrl+X를 눌러 nano 를 종료합니다.

새 이미지를 빌드합니다.

docker build -t my-flask-app-env -f Dockerfile-env .

이제 환경 변수를 사용하여 컨테이너를 실행합니다.

docker run -d -p 5000:5000 --name env-container -e APP_NAME="Customized App" my-flask-app-env

웹 애플리케이션에 액세스합니다.

curl http://localhost:5000

다음과 같은 결과를 볼 수 있습니다.

<h1>Hello from Customized App!</h1><p>This is a simple web application running in a Docker container.</p>

이는 환경 변수를 사용하여 컨테이너화된 애플리케이션에 구성을 전달하는 방법을 보여줍니다.

요약

이 Lab 에서는 Docker 컨테이너에서 실행되는 웹 애플리케이션에 액세스하는 방법을 배웠습니다. 간단한 Flask 웹 애플리케이션을 생성하고, Docker 를 사용하여 컨테이너화했으며, 포트 매핑을 사용하여 호스트 머신에서 액세스했습니다.

다룬 주요 개념:

  • Docker 이미지 및 컨테이너 이해
  • Flask 로 간단한 웹 애플리케이션 생성
  • Dockerfile 로 Docker 이미지 빌드
  • 컨테이너화된 웹 애플리케이션 실행 및 액세스
  • 다양한 명령으로 Docker 컨테이너 관리
  • 다른 포트에서 여러 컨테이너 인스턴스 실행
  • 컨테이너에 대한 리소스 제한 설정
  • 컨테이너 구성을 위한 환경 변수 사용

이러한 기술은 컨테이너화된 애플리케이션 작업에 대한 견고한 기반을 제공하며, Docker 를 사용하여 웹 애플리케이션을 효율적으로 배포하고 테스트하는 데 도움이 될 것입니다.