LainyZine: 프로그래머 가이드 🐣

docker exec 사용법: 실행중인 컨테이너에 명령어 실행하는 방법

Docker 컨테이너는 시스템 관점에서 보면 하나의 프로세스입니다. 하지만 Docker 컨테이너는 일반적인 프로세스와는 차이가 있습니다. 각각의 컨테이너는 호스트 시스템과는 별개의 파일 시스템, 네트워크, 권한 등 다른 환경을 가지고 있습니다. 특정한 컨테이너가 실행되는 환경에서 또 다른 프로세스를 실행할 수 있도록 해주는 명령어가 바로 docker exec입니다. docker exec 명령어로 특정 컨테이너 환경에서 명령어를 실행하거나, 컨테이너의 내부 환경에 대해서 알아보거나 디버깅할 수 있습니다. 이 글에서는 docker exec 명령어를 사용하는 방법에 대해서 소개합니다.

ghost 블로그 컨테이너: exec를 실행해볼 예제 환경 준비

docker exec는 실행중인 컨테이너에만 실행할 수 있습니다. 또한 일반적인 컨테이너 실행 명령어인 run과 달리 컨테이너 상태를 디버깅하기 위한 용도로 주로 사용합니다.

테스트를 위해 간단한 Ghost 블로그 Docker 컨테이너를 하나 실행해봅니다.

$ docker run -d -p 2368:2368 --name ghost ghost:4.3-alpine

웹 브라우저에서 0.0.0.0:2368을 실행해 블로그가 실행된 것을 확인해봅니다.

Docker로 실행한 Ghost 블로그

Docker 컨테이너로 실행된 Ghost 블로그가 열립니다(Ghost 블로그 기동까지 1분 정도의 시간이 걸릴 수 있습니다).

docker exec의 기본적인 사용법

먼저 docker ps로 실행중인 Ghost 블로그 컨테이너를 확인해봅니다.

$ docker ps
CONTAINER ID   IMAGE              COMMAND                  CREATED         STATUS         PORTS                                       NAMES
09950eb9580f   ghost:4.3-alpine   "docker-entrypoint.s…"   2 minutes ago   Up 2 minutes   0.0.0.0:2368->2368/tcp, :::2368->2368/tcp   ghost

exec 서브 커맨드를 사용하기에 앞서 반드시 기억해두셔야하는 점은 컨테이너가 실행중일 때만 exec를 사용할 수 있다는 점입니다. 컨테이너 목록을 보면 ghost:4.3-alpine 이미지로 실행된 ghost 컨테이너가 실행중인 것을 확인할 수 있습니다.

즉, 09950eb9580f 혹은 ghost 컨테이너에 대해서 exec 명령어를 사용할 수 있습니다. exec 명령어의 기본적인 사용법은 다음과 같습니다.

docker exec <CONTAINER_ID> <COMMAND>

사용하는 형식은 docker run과 비슷하지만 이미지 이름 자리에 컨테이너의 ID나 이름이 옵니다. ghost 컨테이너에서 pwdls, ps 명령어를 실행해보겠습니다.

$ docker exec ghost pwd
/var/lib/ghost

$ docker exec ghost ls
config.development.json
config.production.json
content
content.orig
current
versions

$ docker exec ghost ps
PID   USER     TIME  COMMAND
    1 node      0:25 {node} /usr/bin/qemu-x86_64 /usr/local/bin/node current/index.js
  201 root      0:00 /bin/ps

여기서 pwd, ls, ps 명령어는 호스트 환경이 아닌 ghost 컨테이너 환경에서 실행되었고, 그 결과가 화면에 출력되었습니다.

docker exec로 컨테이너 환경에서 다른 명령어를 실행하더라도, 기본적으로 컨테이너의 메인 프로세스에는 영향을 끼치지 않습니다. 즉, ghost 컨테이너에서 Ghost 블로그를 실행중인 상태에서, ghost 컨테이너 환경에서 다른 명령어를 실행해볼 수 있습니다.

앞의 예제에서 실행한 명령어들은 단순히 실행 결과를 출력하고 종료되는 프로그램들입니다만, 셸을 실행해서 인터렉티브한 환경에서 컨테이너 환경을 탐색하는 것도 가능합니다. docker run을 사용해 셸을 실행할 때와 마찬가지로 -it 옵션을 사용합니다.

$ docker exec -it ghost bash
bash-5.0# pwd
/var/lib/ghost

bash-5.0# ls
config.development.json  content                  current
config.production.json   content.orig             versions

bash-5.0# ps
PID   USER     TIME  COMMAND
    1 node      0:26 {node} /usr/bin/qemu-x86_64 /usr/local/bin/node current/index.js
  217 root      0:00 {bash} /usr/bin/qemu-x86_64 /bin/bash
  227 root      0:00 /bin/ps

컨테이너 환경에서 셸을 실행하고, 셸을 사용해 다른 명령어들을 인터렉티브하게 실행해볼 수 있습니다.

docker exec를 사용할 때 유용할 옵션들

docker exec에서 사용할 수 있는 옵션들은 docker run의 옵션들과 비슷합니다.

--workdir 옵션을 사용하면 프로세스가 실행되는 위치를 변경할 수 있습니다.

$ docker exec -it --workdir /tmp ghost bash
bash-5.0# pwd
/tmp

-e 옵션이나 --end-file 옵션을 사용해 추가 환경변수를 지정할 수 있습니다.

$ docker exec -it -e ADDITIONAL_ENV=value ghost bash
bash-5.0# env | grep ADDITIONAL
ADDITIONAL_ENV=value

--priviledged 옵션을 사용하면 프로세스에 추가적인 권한을 부여할 수 있습니다. 이 옵션에 대한 자세한 내용은 아래 문서들을 참고해주세요.

--user 옵션으로 프로세스를 실행하는 사용자를 지정할 수도 있습니다.

docker run과 docker exec의 차이

docker rundocker exec는 비슷하지만 다릅니다. docker run은 Docker에서 가장 중요한 명령어로 컨테이너를 생성하고 실행할 때 사용합니다. 즉 docker run은 새로운 컨테이너 환경을 만드는 반면에 docker exec는 이미 실행된 특정 컨테이너의 환경을 디버깅하는 용도로 사용합니다.

docker run으로 실행한 컨테이너는 Docker를 사용해 관리할 수 있고, 표준출력와 표준에러의 내용을 확인할 수 있습니다. 하지만 docker exec로 실행한 프로세스는 컨테이너로 취급되지 않으며 로그 확인이나 프로세스 완료 여부를 알기가 더 어렵습니다.

추천 문서

LainyZine은 쿠팡 파트너스 활동에 따른 수수료를 제공받습니다.