docker compose exec 명령으로 서비스와 상호 작용하는 방법

DockerBeginner
지금 연습하기

소개

이 랩에서는 실행 중인 서비스와 효과적으로 상호 작용하기 위해 docker compose exec 명령어를 사용하는 방법을 배우게 됩니다. 서비스 컨테이너 내에서 명령을 실행하고, 분리된 모드 (detached mode) 로 명령을 실행하며, 다른 사용자로 명령을 실행하고, 특정 작업 디렉토리 (working directory) 에서 명령을 실행하는 방법을 탐구할 것입니다. 이 실습 경험을 통해 Docker 화된 애플리케이션을 디버깅하고 관리하는 데 필요한 필수 기술을 습득할 수 있습니다.

실행 중인 서비스 컨테이너에서 명령 실행

이 단계에서는 실행 중인 Docker 컨테이너 내부에서 명령을 실행하는 방법을 배우게 됩니다. 이는 컨테이너 내에서 실행 중인 서비스와 상호 작용하거나 디버깅할 때, 서비스를 중지하고 다시 시작할 필요 없이 매우 유용한 기술입니다.

먼저, 이 데모에 사용할 간단한 Nginx 이미지를 가져와 보겠습니다. 작고 빠르게 다운로드할 수 있는 nginx:alpine 이미지를 사용하겠습니다.

docker pull nginx:alpine

이미지가 가져와지고 압축 해제되고 있음을 나타내는 출력을 볼 수 있습니다.

다음으로, 이 Nginx 이미지를 분리된 모드 (detached mode) 로 실행할 것입니다. 즉, 컨테이너가 백그라운드에서 실행되며 터미널을 점유하지 않습니다. 또한 나중에 참조하기 쉽도록 이름을 지정할 것입니다.

docker run -d --name my-nginx nginx:alpine

출력은 새로 생성되어 실행 중인 컨테이너의 컨테이너 ID 가 됩니다.

이제 컨테이너가 실행 중이므로 docker exec 명령어를 사용하여 컨테이너 내부에서 명령을 실행할 수 있습니다. 기본 구문은 docker exec [options] container command [args...]입니다. 컨테이너의 루트 디렉토리에서 파일을 나열해 보겠습니다.

docker exec my-nginx ls /

bin, etc, usr 등과 같이 Nginx 컨테이너의 루트 파일 시스템에 있는 디렉토리 및 파일 목록을 볼 수 있습니다. 이는 실행 중인 컨테이너 내부에서 명령을 성공적으로 실행했음을 확인합니다.

다른 명령을 시도해 보겠습니다. 컨테이너 내부에서 실행 중인 Nginx 의 버전을 확인할 수 있습니다.

docker exec my-nginx nginx -v

출력은 컨테이너에 설치된 Nginx 의 버전을 표시합니다 (예: nginx version: nginx/1.24.0).

이것은 실행 중인 컨테이너와 상호 작용하고 해당 환경 내에서 임의의 명령을 실행하는 방법을 보여줍니다.

분리 모드 (detached mode) 로 명령 실행

이전 단계에서는 -d 플래그를 사용하여 컨테이너를 분리된 모드로 실행했습니다. 이는 터미널을 점유하지 않고 컨테이너가 백그라운드에서 실행되도록 하려는 경우 일반적인 방법입니다. 이 단계에서는 docker exec를 사용하여 분리된 모드로 명령을 실행하는 방법을 더 자세히 살펴보겠습니다.

docker exec는 일반적으로 대화형 세션 (interactive sessions) 또는 실행 중인 컨테이너에서 짧은 명령을 실행하는 데 사용되지만, docker exec와 함께 -d 플래그를 사용하여 분리된 모드로 명령을 실행할 수도 있습니다. 이는 이미 실행 중인 컨테이너 내에서 백그라운드 프로세스를 시작하는 데 유용합니다.

이전 단계에서 시작한 my-nginx 컨테이너를 사용해 보겠습니다. 간단한 명령을 분리된 모드로 실행할 것입니다. 예를 들어, 5 초마다 현재 날짜와 시간을 컨테이너 내부의 파일에 쓰는 명령을 실행해 보겠습니다.

docker exec -d my-nginx sh -c 'while true; do date >> /usr/share/nginx/html/date.txt; sleep 5; done'

이 명령어에서:

  • docker exec -d my-nginx: my-nginx 컨테이너 내에서 다음 명령을 분리된 모드로 실행합니다.
  • sh -c '...': sh 쉘을 사용하여 후속 명령 문자열을 실행합니다.
  • while true; do date >> /usr/share/nginx/html/date.txt; sleep 5; done: 이것은 실행되는 명령입니다. 현재 날짜와 시간을 /usr/share/nginx/html/date.txt 파일에 지속적으로 추가한 다음 반복하기 전에 5 초 동안 대기하는 간단한 루프입니다.

명령을 실행한 후, 터미널에 컨테이너 ID 가 출력되어 명령이 컨테이너 내에서 백그라운드로 시작되었음을 나타냅니다.

명령이 실행되고 파일에 쓰고 있는지 확인하기 위해, date.txt 파일의 내용을 보기 위해 다른 명령을 실행할 수 있습니다. 명령이 백그라운드에서 실행되므로 파일이 생성되고 채워지는 데 몇 초 정도 걸릴 수 있습니다.

docker exec my-nginx cat /usr/share/nginx/html/date.txt

출력에 날짜와 시간이 표시되어야 하며, 몇 초 후에 cat 명령을 다시 실행하면 파일에 새로운 항목이 추가된 것을 볼 수 있습니다. 이는 docker exec -d로 시작된 백그라운드 프로세스가 예상대로 실행되고 있음을 확인합니다.

다른 사용자로 명령 실행

이 단계에서는 실행 중인 컨테이너 내부에서 특정 사용자로 명령을 실행하는 방법을 배우게 됩니다. 기본적으로 docker exec는 컨테이너 내부에서 root 사용자로 명령을 실행하지만, -u 또는 --user 플래그를 사용하여 다른 사용자를 지정할 수 있습니다. 이는 보안과 최소 권한의 원칙을 준수하는 데 중요합니다.

my-nginx 컨테이너를 계속 사용해 보겠습니다. 먼저, ls / 명령이 기본적으로 어떤 사용자로 실행되는지 확인해 보겠습니다.

docker exec my-nginx whoami

출력은 root일 가능성이 높습니다. 이는 docker exec의 기본 사용자이기 때문입니다.

이제 다른 사용자로 명령을 실행해 보겠습니다. Nginx 이미지는 일반적으로 Nginx 프로세스를 root 가 아닌 사용자, 종종 nginx라는 사용자로 실행합니다. nginx 사용자로 whoami 명령을 실행해 보겠습니다.

docker exec -u nginx my-nginx whoami

출력으로 nginx가 표시되어 명령이 nginx 사용자로 실행되었음을 확인합니다.

사용자 이름 대신 사용자 ID(UID) 를 지정할 수도 있습니다. 컨테이너 내부에서 nginx 사용자의 UID 를 찾기 위해 /etc/passwd 파일을 살펴볼 수 있습니다.

docker exec my-nginx cat /etc/passwd | grep nginx

출력은 UID 및 GID(Group ID) 를 포함하여 nginx 사용자에 대한 항목을 표시합니다. 예를 들어, nginx:x:101:101:nginx user,,,:/nonexistent:/bin/false와 같은 형태일 수 있습니다. 이 예에서 UID 는 101입니다.

이제 UID 를 사용하여 whoami 명령을 실행해 보겠습니다. 이전 단계에서 찾은 실제 UID 가 다른 경우 101을 해당 UID 로 바꾸십시오.

docker exec -u 101 my-nginx whoami

출력은 다시 nginx여야 하며, docker exec에 대한 사용자를 지정하기 위해 사용자 이름 또는 UID 를 사용할 수 있음을 보여줍니다.

root 가 아닌 사용자로 명령을 실행하는 것은 특히 민감한 파일과 상호 작용하거나 root 권한이 필요하지 않은 작업을 수행할 때 좋은 보안 관행입니다.

특정 작업 디렉토리에서 명령 실행

이 마지막 단계에서는 실행 중인 컨테이너 내부에서 특정 작업 디렉토리로 명령을 실행하는 방법을 배우게 됩니다. 기본적으로 docker exec는 컨테이너 이미지의 Dockerfile 에 정의된 작업 디렉토리 (종종 /) 에서 명령을 실행합니다. 그러나 -w 또는 --workdir 플래그를 사용하여 이를 변경할 수 있습니다. 이는 컨테이너 파일 시스템 내의 특정 경로를 기준으로 명령을 실행해야 할 때 유용합니다.

my-nginx 컨테이너를 계속 사용해 보겠습니다. 먼저, 특정 디렉토리를 지정하지 않고 명령을 실행할 때 기본 작업 디렉토리가 무엇인지 확인해 보겠습니다. 이를 위해 pwd 명령 (print working directory) 을 사용할 수 있습니다.

docker exec my-nginx pwd

출력은 루트 디렉토리인 /일 가능성이 높습니다.

이제 다른 작업 디렉토리에서 명령을 실행해 보겠습니다. Nginx 컨테이너에는 웹 서버가 파일을 제공하는 /usr/share/nginx/html 디렉토리가 있습니다. 작업 디렉토리를 이 경로로 변경한 다음 그 안에 있는 파일을 나열해 보겠습니다.

docker exec -w /usr/share/nginx/html my-nginx ls

이 명령어에서:

  • docker exec -w /usr/share/nginx/html my-nginx: my-nginx 컨테이너 내에서 다음 명령을 실행하고 작업 디렉토리를 /usr/share/nginx/html로 설정합니다.
  • ls: 현재 작업 디렉토리의 파일을 나열하는 실행할 명령입니다.

index.htmldate.txt(이전 단계에서 생성) 와 같이 /usr/share/nginx/html 디렉토리에 있는 파일을 볼 수 있습니다.

다른 예를 시도해 보겠습니다. /usr/share/nginx/html 내에 새 디렉토리를 만든 다음 명령을 실행하기 전에 작업 디렉토리를 새로 생성된 디렉토리로 변경할 수 있습니다.

docker exec my-nginx mkdir /usr/share/nginx/html/new_dir
docker exec -w /usr/share/nginx/html/new_dir my-nginx pwd

첫 번째 명령은 /usr/share/nginx/html 내에 new_dir이라는 디렉토리를 만듭니다. 그런 다음 두 번째 명령은 작업 디렉토리를 /usr/share/nginx/html/new_dir로 변경하고 현재 작업 디렉토리를 출력합니다.

두 번째 명령의 출력은 /usr/share/nginx/html/new_dir여야 하며, 이는 pwd 명령 실행을 위해 작업 디렉토리가 성공적으로 변경되었음을 확인합니다.

docker exec와 함께 -w 플래그를 사용하면 컨테이너 내의 특정 디렉토리의 컨텍스트에서 명령을 실행할 수 있으며, 이는 컨테이너의 파일 시스템을 보다 효율적으로 탐색하고 상호 작용하는 데 매우 유용합니다.

요약

이 랩에서는 실행 중인 Docker 컨테이너와 상호 작용하기 위해 docker exec 명령을 사용하는 방법을 배웠습니다. 컨테이너 내부에서 명령을 실행하는 연습을 했으며, 특히 파일을 나열하고 Nginx 버전을 확인하여 컨테이너를 중지하지 않고도 서비스를 디버깅하고 상호 작용할 수 있는 기능을 보여주었습니다.

또한 백그라운드 컨테이너 실행을 위한 기본 개념인 -d 플래그를 사용하여 분리 모드 (detached mode) 로 컨테이너를 실행하는 것에 대해 간략하게 언급했습니다. 후속 단계는 자세히 설명되지 않았지만, 초기 단계는 실행 중인 컨테이너 환경 내에서 명령을 실행하는 방법을 이해하기 위한 견고한 기반을 제공했습니다.