2022年2月20日

三分鐘了解 docker run 跟 docker exec 的差別

docker run 跟 docker exec 經常讓 docker 的初學者感到困惑,因為用起來感覺都很像,不知道什麼時候該用哪一個,也不知道兩者有什麼差別。

如果簡單來說的話,其實兩個最大的差別是,一個啟動新的容器,一個使用正在運行中的容器。

來比較官方文件上對於兩者的說明:

docker run : Run a command in a new container

$ docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

docker exec : Run a command in a running container

$ docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

可以看到 run 使用的參數是 image name ,而 exec 是 container name。

docker run 會啟動新的容器 (new container) 來執行指令,因此在執行 run 的當下,需要指定 image name 來建立新容器。

而 docker exec 則是使用正在運行中的容器 (running container) 來執行指令,因此透過指定的 container name 來呼叫特定的 container。

範例

以下範例使用 ubuntu 做為示範用的 image。

docker run

使用 docker run 執行 ubuntu 的 bash 指令,可以看到直接進入了容器,5a14f31697dc 是 container id :

$ docker run -it ubuntu bash
root@5a14f31697dc:/# 

接著我們執行 exit 來離開容器:

root@5a14f31697dc:/# exit
exit

回來之後,透過 docker ps 可以看到現在已經沒有在運行中的容器了。

$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

docker exec

接著,透過 docker run 執行 ubuntu 的 bash 指令來啟動一個新容器,但這次使用 -d,也就是 Detached mode ,讓容器在背景執行。執行完指令後,不會進到 bash,而是會回傳一個 container id。

$ docker run -itd ubuntu bash
37025d36a0ef4013b9844daed7f50d33a8bee5ee535906b64f0e14f28ee91d67

執行 docker ps 可以看到剛剛啟動的容器,正在運行。37025d36a0ef 符合前面產生的 container id 的前 12 碼,因此就是剛剛啟動的容器。

$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED         STATUS         PORTS     NAMES
37025d36a0ef   ubuntu    "bash"    3 seconds ago   Up 2 seconds             sleepy_bassi

接著便可以透過 docker exec 來使用剛剛啟動的容器,來執行指令:

$ docker exec -it 37025d36a0ef bash
root@37025d36a0ef:/# 

小結

docker run 啟動新的容器來執行任務,docker exec 則使用既有容器來執行任務!這樣應該就不會再搞混了吧~

 

延伸

Docker image 版本差在哪?alpine, buster, bullseye 怎麼選?