소개
이 실습에서는 docker run 명령어와 그에 따른 다양한 파라미터에 집중적으로 초점을 맞춥니다. docker run 명령어는 특정 설정을 사용하여 컨테이너를 생성하고 시작할 수 있게 해주는 Docker 작업의 가장 기본이 되는 명령어입니다.
이 명령어의 파라미터들을 숙달하면 컨테이너화된 애플리케이션을 더욱 세밀하게 제어할 수 있으며, Docker 컨테이너를 효과적으로 배포하고 관리하는 능력을 향상시킬 수 있습니다.
이름 지정, 백그라운드 실행 모드 (Detached mode), 포트 매핑, 볼륨 마운트, 환경 변수, 리소스 제한 등 폭넓은 파라미터들을 다룰 예정입니다.
이미 익숙한 파라미터도 있겠지만, 처음 접하는 새로운 기능들도 있을 것입니다.
기본 Docker 실행 및 컨테이너 이름 지정
먼저 docker run의 기초를 배우고 컨테이너에 이름을 붙이는 방법을 알아보겠습니다.
우선, 기본적인 Nginx 컨테이너를 실행해 봅니다.
docker run nginx
이 명령어는 Nginx 컨테이너를 포그라운드 (Foreground) 에서 실행합니다. 터미널에 로그 출력이 계속 흐르는 것을 볼 수 있습니다. 이는 컨테이너가 현재 터미널 세션에 연결되어 실행 중이며 로그를 직접 보여주고 있기 때문입니다.
컨테이너를 중지하려면 Ctrl+C 를 누르세요. 중지되는 데 몇 초 정도 걸릴 수 있는데, 이는 Docker 가 컨테이너가 안전하게 종료될 수 있도록 시간을 주는 것이므로 정상적인 현상입니다.
이제 백그라운드 모드에서 실행하면서 이름을 지정해 보겠습니다.
docker run -d --name my-nginx nginx
이 명령어의 구성을 살펴보겠습니다.
docker run: 컨테이너를 실행하는 기본 명령어입니다.-d: 컨테이너를 백그라운드 (Detached mode) 에서 실행하도록 설정합니다. 즉, 터미널에 출력 결과가 나타나지 않습니다.--name my-nginx: 컨테이너에 "my-nginx"라는 이름을 부여합니다. 이름을 지정하지 않으면 Docker 가 임의의 이름을 자동으로 할당합니다.nginx: 컨테이너를 생성하는 데 사용할 이미지의 이름입니다.
명령어를 실행하면 긴 문자열이 출력됩니다. 이것은 컨테이너 ID 입니다. 이제 Docker 가 백그라운드에서 컨테이너를 시작했습니다.
만약 이름이 이미 사용 중이라는 오류가 발생한다면, 해당 이름을 가진 컨테이너가 이미 존재한다는 뜻입니다. 다른 이름을 선택하거나 기존 컨테이너를 삭제해야 합니다 (삭제 방법은 이후 실습에서 배웁니다).
포트 매핑
docker run의 -p 파라미터는 컨테이너의 포트를 호스트 시스템의 포트와 연결 (매핑) 해 줍니다. 이는 호스트 머신에서 컨테이너 내부에서 실행 중인 서비스에 접속하기 위해 매우 중요합니다.
포트 매핑을 적용하여 Nginx 컨테이너를 실행해 봅니다.
docker run -d --name nginx-mapped -p 8080:80 nginx
새롭게 추가된 부분을 살펴보겠습니다.
-p 8080:80: 호스트의 8080 포트를 컨테이너의 80 포트로 연결합니다. 형식은 항상호스트_포트:컨테이너_포트입니다.
Nginx 는 기본적으로 컨테이너 내부의 80 포트에서 작동합니다. 이를 호스트의 8080 포트에 매핑함으로써, 웹 브라우저에서 localhost:8080 으로 접속하여 Nginx 에 접근할 수 있게 됩니다.
이제 Nginx 환영 페이지에 접속 가능한지 확인해 보겠습니다. 커맨드 라인에서 HTTP 요청을 보낼 수 있는 curl 명령어를 사용합니다.
curl http://localhost:8080
Nginx 환영 페이지의 HTML 내용이 출력되어야 합니다. 만약 curl이 설치되어 있지 않다면 다음 명령어로 설치할 수 있습니다.
sudo apt-get update && sudo apt-get install -y curl
여전히 페이지에 접속할 수 없다면 다음 사항들을 확인해 보세요.
- 컨테이너가 실행 중인지 확인:
docker ps | grep nginx-mapped - 포트가 실제로 매핑되었는지 확인:
docker port nginx-mapped - 클라우드 서버를 사용 중이라면, 방화벽에서 8080 포트 트래픽을 허용하는지 확인하십시오.
볼륨 마운트
docker run의 -v 파라미터는 볼륨을 마운트하여 호스트와 컨테이너 간에 데이터를 공유할 수 있게 해줍니다. 이는 데이터를 영구적으로 보존하거나 컨테이너에 설정 파일을 제공할 때 매우 유용합니다.
먼저 호스트 시스템에 간단한 디렉토리 구조를 만듭니다.
mkdir -p ~/project/nginx-data
echo "<html><body><h1>Hello from mounted volume</h1></body></html>" > ~/project/nginx-data/index.html
이 명령어들은 다음 작업을 수행합니다.
- 홈 디렉토리의
project폴더 안에nginx-data라는 새 디렉토리를 생성합니다. - 이 새 디렉토리 안에
index.html이라는 간단한 HTML 파일을 생성합니다.
이제 Nginx 컨테이너를 실행하면서 이 디렉토리를 마운트해 보겠습니다.
docker run -d --name nginx-volume -p 8081:80 -v ~/project/nginx-data:/usr/share/nginx/html nginx
명령어의 구성을 분석해 보겠습니다.
docker run: 새 컨테이너를 실행하는 명령어입니다.-d: 컨테이너를 백그라운드에서 실행합니다.--name nginx-volume: 컨테이너 이름을 "nginx-volume"으로 지정합니다.-p 8081:80: 호스트의 8081 포트를 컨테이너의 80 포트로 매핑합니다.-v ~/project/nginx-data:/usr/share/nginx/html: 호스트의nginx-data디렉토리를 컨테이너의/usr/share/nginx/html디렉토리에 마운트합니다. 이곳은 Nginx 가 웹 콘텐츠를 찾는 기본 경로입니다.nginx: 사용할 이미지 이름입니다.
이제 사용자 정의 페이지가 제대로 서비스되고 있는지 확인합니다.
curl http://localhost:8081
작성했던 HTML 파일의 내용인 "Hello from mounted volume!"이 출력되어야 합니다.
내용이 보이지 않는다면 다음을 확인하세요.
- 호스트 시스템에
~/project/nginx-data/index.html파일이 실제로 존재하는지 확인합니다. - 컨테이너가 실행 중인지 확인합니다:
docker ps | grep nginx-volume - Nginx 로그에 오류가 있는지 확인합니다:
docker logs nginx-volume
호스트 디렉토리를 컨테이너에 마운트하는 이 방식을 바인드 마운트 (Bind mount) 라고 합니다. 호스트와 컨테이너 간에 파일을 공유하는 가장 직관적인 방법입니다. 기억해야 할 몇 가지 핵심 사항은 다음과 같습니다.
- 호스트 디렉토리 경로는 반드시 절대 경로여야 합니다.
- 호스트 디렉토리가 존재하지 않으면 Docker 가 자동으로 생성합니다.
- 해당 디렉토리의 파일 변경 사항 (호스트 또는 컨테이너 어디서든) 은 양쪽 모두에 즉시 반영됩니다.
- 권한 설정에 주의하십시오. 컨테이너는 기본적으로 root 권한으로 실행되므로, 호스트 사용자가 수정할 수 없는 파일을 생성할 수도 있습니다.
이 방법으로 디렉토리 전체를 마운트하면 단일 파일 마운트 시 발생할 수 있는 오류를 방지할 수 있으며, 컨테이너를 재생성하지 않고도 파일을 자유롭게 추가, 삭제, 수정할 수 있는 유연성을 얻게 됩니다.
환경 변수
docker run의 -e 파라미터는 컨테이너 내부에 환경 변수를 설정할 수 있게 해줍니다. 이는 컨테이너 내부 애플리케이션의 코드를 수정하지 않고도 설정을 변경할 때 유용합니다.
환경 변수를 설정하여 컨테이너를 실행해 봅니다.
docker run -d --name nginx-env -e NGINX_HOST=mywebsite.com -e NGINX_PORT=80 nginx
새로운 부분을 살펴보겠습니다.
-e NGINX_HOST=mywebsite.com: 값이mywebsite.com인NGINX_HOST라는 환경 변수를 설정합니다.-e NGINX_PORT=80: 값이80인NGINX_PORT라는 또 다른 환경 변수를 설정합니다.
환경 변수는 컨테이너 내부에서 실행되는 프로세스가 접근할 수 있는 키 - 값 쌍입니다. 많은 Docker 이미지들이 특정 환경 변수를 사용하여 설정을 구성하도록 설계되어 있습니다.
설정된 환경 변수를 확인할 수 있습니다.
docker exec nginx-env env | grep NGINX_
이 명령어는 다음 작업을 수행합니다.
docker exec nginx-env: 실행 중인nginx-env컨테이너에서 명령어를 실행하도록 Docker 에 지시합니다.env: 모든 환경 변수를 출력하는 명령어입니다.| grep NGINX_: 출력 결과 중 "NGINX_"가 포함된 줄만 필터링합니다.
목록에 설정한 두 개의 환경 변수가 나타나야 합니다.
환경 변수가 보이지 않는다면 다음을 확인하세요.
- 컨테이너가 실행 중입니까?
docker ps | grep nginx-env로 확인하세요. docker run명령어에서 환경 변수 이름의 철자가 정확합니까?
리소스 제한
Docker 는 docker run의 다양한 파라미터를 통해 컨테이너에 리소스 제한을 설정할 수 있게 해줍니다. 이는 특히 여러 컨테이너를 실행할 때 호스트 시스템의 성능과 안정성을 관리하는 데 필수적입니다.
메모리와 CPU 사용량을 제한하여 컨테이너를 실행해 봅니다.
docker run -d --name nginx-limited --memory 256m --cpus 0.5 nginx
새로운 부분을 살펴보겠습니다.
--memory 256m: 컨테이너의 메모리 사용량을 256MB 로 제한합니다. 'm'은 메가바이트를 의미하며, 'g'를 사용하여 기가바이트 단위로 설정할 수도 있습니다.--cpus 0.5: 컨테이너가 최대 CPU 코어의 절반만 사용하도록 제한합니다.
이러한 제한은 컨테이너가 지정된 리소스 이상을 사용하는 것을 방지하여, 특정 컨테이너가 호스트의 리소스를 독점하는 상황을 막아줍니다.
제한 사항이 올바르게 적용되었는지 확인할 수 있습니다.
docker inspect -f '{{.HostConfig.Memory}}' nginx-limited
docker inspect -f '{{.HostConfig.NanoCpus}}' nginx-limited
첫 번째 명령어는 268435456 (256MB 를 바이트로 환산한 값) 을 출력해야 하며, 두 번째 명령어는 500000000 (0.5 CPU 를 나노 단위로 환산한 값) 을 출력해야 합니다.
다른 값이 나온다면 docker run 명령어에서 제한 수치를 정확히 입력했는지 다시 확인해 보세요.
참고: 리소스 제한을 너무 낮게 설정하면 컨테이너 성능이 저하되거나 충돌이 발생할 수 있습니다. 컨테이너 작동에 문제가 있다면 이 제한 수치를 높여보시기 바랍니다.
네트워크 설정
docker run의 --network 파라미터는 컨테이너를 특정 네트워크에 연결할 수 있게 해줍니다. 이는 컨테이너 간 통신이나 컨테이너 그룹을 격리하는 데 유용합니다.
먼저, 사용자 정의 브리지 네트워크를 생성합니다.
docker network create my-custom-network
이 명령어는 my-custom-network라는 이름의 새로운 브리지 네트워크를 생성합니다. 브리지 네트워크는 Docker 에서 가장 일반적으로 사용되는 네트워크 유형입니다.
이제 이 네트워크에 연결된 컨테이너를 실행합니다.
docker run -d --name nginx-networked --network my-custom-network nginx
--network my-custom-network 옵션은 방금 생성한 네트워크에 컨테이너를 연결합니다.
동일한 네트워크에 있는 컨테이너들은 서로의 컨테이너 이름을 호스트 이름으로 사용하여 통신할 수 있습니다. 이를 통해 여러 서비스를 쉽게 연결할 수 있습니다.
네트워크가 존재하지 않는다는 오류가 발생하면 docker network create 명령어로 네트워크를 올바르게 생성했는지 확인하십시오.
재시작 정책
docker run의 --restart 파라미터는 컨테이너의 재시작 정책을 지정할 수 있게 해줍니다. 이는 컨테이너가 예기치 않게 종료되거나 Docker 데몬이 재시작될 때 컨테이너가 계속 실행되도록 보장하는 데 유용합니다.
재시작 정책을 적용하여 컨테이너를 실행해 봅니다.
docker run -d --name nginx-restart --restart unless-stopped nginx
--restart unless-stopped 옵션은 재시작 정책을 "unless-stopped"로 설정합니다. 이는 사용자가 명시적으로 중지하지 않는 한 컨테이너가 자동으로 재시작됨을 의미합니다.
다른 재시작 정책은 다음과 같습니다.
no: 기본값입니다. 컨테이너를 자동으로 재시작하지 않습니다.on-failure: 컨테이너가 0 이 아닌 상태 코드로 종료된 경우에만 재시작합니다.always: 종료 상태 코드와 관계없이 항상 컨테이너를 재시작합니다.
재시작 정책을 확인할 수 있습니다.
docker inspect -f '{{.HostConfig.RestartPolicy.Name}}' nginx-restart
출력 결과는 unless-stopped여야 합니다.
예상한 결과가 나오지 않는다면 docker run 명령어에서 재시작 정책을 정확히 지정했는지 확인해 보세요.
작업 디렉토리 및 명령어
이 단계에서는 컨테이너 내부의 작업 디렉토리를 설정하고, 컨테이너가 시작될 때 실행할 사용자 정의 명령어를 지정하는 방법을 알아봅니다.
docker run의 -w 파라미터는 컨테이너 내부의 작업 디렉토리를 설정하며, 이미지 이름 뒤에 실행할 명령어를 직접 명시할 수 있습니다.
이 개념들을 조합해 보겠습니다.
docker run -d --name nginx-custom -w /app nginx sh -c "mkdir -p /app && touch newfile.txt && nginx -g 'daemon off;'"
이 명령어를 분석해 보겠습니다.
-d: 컨테이너를 백그라운드에서 실행합니다.--name nginx-custom: 컨테이너 이름을 "nginx-custom"으로 지정합니다.-w /app: 컨테이너 내부의 작업 디렉토리를/app으로 설정합니다.nginx: 사용할 이미지 이름입니다.sh -c "...": 쉘 명령어를 실행합니다.mkdir -p /app:/app디렉토리가 없으면 생성합니다.&&: 이전 명령어가 성공하면 다음 명령어를 실행합니다.touch newfile.txt:newfile.txt라는 빈 파일을 생성합니다.&&: 이전 명령어가 성공하면 다음 명령어를 실행합니다.nginx -g 'daemon off;': Nginx 를 포그라운드에서 시작하여 컨테이너가 계속 실행되도록 유지합니다.
이제 컨테이너가 실행 중이고 파일이 생성되었는지 확인합니다.
docker ps | grep nginx-custom
docker exec nginx-custom ls -l /app/newfile.txt
첫 번째 명령어는 컨테이너가 실행 중임을 보여주어야 하며, 두 번째 명령어는 컨테이너의 /app 디렉토리에 있는 newfile.txt 파일의 상세 정보를 출력해야 합니다.
요약
이 실습에서는 docker run 명령어를 깊이 있게 다루며 다양한 파라미터와 옵션들을 살펴보았습니다. 우리가 학습한 내용은 다음과 같습니다.
- 기본적인 컨테이너 실행 및 이름 지정
- 호스트에서 컨테이너 서비스에 접속하기 위한 포트 매핑
- 호스트와 컨테이너 간 데이터 공유를 위한 볼륨 마운트
- 컨테이너 설정을 위한 환경 변수 지정
- 컨테이너의 자원 사용량을 제한하기 위한 리소스 제한 적용
- 컨테이너 간 통신을 위한 네트워크 설정
- 컨테이너 안정성을 위한 재시작 정책
- 컨테이너 시작 시 작업 디렉토리 및 명령어 지정
docker run의 이러한 파라미터들은 Docker 컨테이너를 구성하고 관리하는 데 강력한 도구를 제공합니다. 이러한 옵션들을 숙달함으로써 더욱 정교하고 최적화된 컨테이너 배포 환경을 구축할 수 있습니다. 또한 컨테이너가 호스트 시스템과 상호작용하는 방식, 소비하는 리소스, 그리고 다양한 상황에서의 동작 방식을 정밀하게 제어할 수 있게 되었습니다.



