[Docker] Command Line, CLI
keywords: tutorial, cli
TL;SC
提示
Dockerfile ---build---> Image ---run---> Container
# docker run [OPTIONS] IMAGE [COMMAND] # 沒有給 COMMAND 的話會用預設指令
$ docker run -it [image-id] [bash] # 根據 image 「建立」並「執行」 container
$ docker run -p 8080:8080 <image-id> # port mapping localhost port:container port
$ docker run -d redis # 讓該 container 在背景執行
$ docker run -d -p 8080:8080 --name my-container <image-id>
# 希望能夠對某個「執行中」的 container 輸入一些指令
$ docker exec -it <container-name> bin/bash # 連進 container 進行操作
$ docker exec -it <container-id | container-name> sh
$ docker start [container-id] # 執行已經建立過的某個 container
$ docker stop [container-id] # 停止某個執行中的 container
$ docker restart [container-id] # 等同於 stop + start
$ docker ps # 列出執行中的容器(含 Container ID)
$ docker ps -a # 列出所有容器(包含已停止的)
# 查看容器 log
$ docker logs my-container
$ docker logs -f my-container # -f 即 follow,即時串流輸出
# 將 Dockerfile 透過 container 包成 image
$ docker build -t pjchender/project_name .
$ docker build \
--file Dockerfile \
--secret id=npm_token,env=NPM_TOKEN \
--progress=plain \ # 可以顯示出 log
-t pjchender:vite-prod .
# 刪除容器
$ docker rm my-container
# 刪除 image
$ docker rmi my-app:1.0
Docker Compose
$ docker compose up --build # 對應到 docker build . 和 docker run <image-id>
$ docker compose up -d # 對應到類似 docker run <image-id>,-d 是在背景執行
$ docker compose down # stop and remove the containers
$ docker compose up [service-name] # 只啟動 Docker Compose 中的特定 service
$ docker compose ps # 列出該 docker-compose 中有哪些 services 在執行
$ docker compose start # start the containers
$ docker compose stop # stop the containers,等同於 ctrl + c
| 情境 | 建議指令 | 效果 |
|---|---|---|
| 開發中暫時停止,等等還要再跑 | docker compose stop 或 Ctrl+C | 只是停止 container,不會移除 |
| 完全清掉,重新開始 | docker compose down | 停止並移除 container,Network 也會一起清掉,Volume 預設不會刪除。 |
| 清掉所有資料重來 | docker compose down -v | |
修改了 Dockerfile、安裝新的套件、覺得 cache 有問題時 | docker compose up --build | 當你的 image 需要重新建構的時候才需要加 --build |
Docker CLI
# 根據 image 來建立並執行一個 container
# docker run <image-name>
$ docker run hello-world
# docker run <image-name> [override command] 會覆蓋掉原本在 image 內的 startup command
$ docker run -it busybox sh
# 根據 image 建立 container
$ docker create <image-name> # 會取得 container id
# 取得某一 Container 的 logs
$ docker logs <container-id>
# containers
$ docker ps # 列出所有「正在執行」的 container,等同於 docker container ls -a
$ docker ps --all # 列出所有「被建立過」的 container
$ docker kill <container-id> # 把某個 container 直接 kill 掉(不會移除)
$ docker rm <container-id> [-f] # 移除某個 container
$ docker container prune # 把所有 stopped 的 containers 移除
$ docker start -a <container-id> -a:監聽 container 中的 output,並顯示在 Terminal 上
$ docker stop <container-id> # 停止某個 container
# 列出所有 images
$ docker images
$ docker rmi <image_id> <image_id2> [-f]
# 清除
$ docker system prune [--volumes] # 把所有 docker 中當前沒用到的 container, images, networks, cache 清空
# 對 container 執行某一指令
$ docker exec <container-id> <command>
$ docker exec -it <container-id> bash # 執行 container 的 bash shell
docker build:根據 Dockerfile 建立出一個 image
# docker build -t <repository/image-name>:<tag> <path>
$ docker build -t my-image:latest .
# 列出所有 images
$ docker images
docker run:根據 image 來「建立 create」並「執行 start」一個 container
# 根據 image 來建立並 執行一個 container
# -d:Runs the container in detached mode.
# docker run <image-name> <override-command>
$ docker run hello-world
$ docker run busybox echo hello
$ docker run busybox ls
# --name:指定執行時的 container name
# docker run --name <container-name> <image> [command]
# 執行 ubuntu 的 bash
$ docker run -it ubuntu bash
# port mapping
$ docker run -p 8080:8080 <image-id> # port localhost:container
# 檢視目前執行中的 containers
$ docker ps
docker run=docker create+docker start- 執行 CLI 時會透過 docker client 告知 docker server (docker daemon) 要執行的任務,接著 docker server 會在本地的 image cache 中找尋有無
hello-world這個 image,找不到的話就會到 docker hub 上去找,找到後便把這個 image 拉到本機的 image cache 中,接著 docker server 會根據這個 image 建立 container 以執行程序。 - 原本的 image 中都會包含 Startup Command,若想針對這個 container 執行不同的 command,可以在
docker run <image-id> [override command]後,使用override command - docker run 預設就會將 container 內的 output 顯示在 terminal 中,因此不用想
docker start需要加上-a的指令才看得到
docker create & docker start
# Create a Container
$ docker create <image-name> # 會取得 container id
# Start a Container
# -a:attached to the contained 並將 output 顯示在終端機上
$ docker start -a <container-id>
docker create的動作是根據 image 來建立 container,包含把 FS Snapshot 和 Startup Command 複製到 container 中docker start會去執行 container 中啟動的指令(startup command)
docker exec:在 container 中執行額外的 command
$ docker run redis # 啟動 redis-server,container-id (11937697771a)
# $ docker exec -it <container-id> <command>
# -i 讓 STDIN 保持開啟
# -t 讓 Terminal 介面比較好看(formatted)
# -it 等於 -i -t,意思就是讓開發者可以輸入內容到 container
$ docker exec -it 11937697771a redis-cli
# 執行 container 的 bash shell,就可以進入該 container 的 shell 使用指令
# 如此就不用一直重複使用 exec 的 指令
$ docker exec -it <container-id> bash
> redis-cli # 使用 Ctrl + D 可以離開
docker logs:取得 container 輸出過的 output
$ docker create busybox echo hi there
> 35b632f6c7881
$ docker start 35b632f6c7881
$ docker logs 35b632f6c7881
- docker logs 不會再執行一次該 container,而是把裡面曾經輸出過的 output 顯示在 terminal 中
docker stop & docker kill
$ docker create busybox ping google.com
> 81d72e56e9e
$ docker start 81d72e56e9e
$ docker stop 81d72e56e9e # send SIGTERM
$ docker kill 81d72e56e9e # send SIGKILL
- 使用
docker stop會向 container 發送 SIGTERM 的指令(Signal Terminate),如此程式有機會執行 graceful shutdown 的過程(例如執行 cleanup) - 使用
docker kill會向 container 發送 SIGKILL 的指令,意思是要程式立即終止,不要再做任何事 - 如果使用
docker stop後十秒鐘 container 仍沒有被停止,則 docker 會自動執行 kill 指令
docker ps:列出所有執行中的 container
$ docker ps # 列出所有正在執行的 container
$ docker ps --all # 列出所有被建立過的 container
docker volume
$ docker volume ls
Docker Container
docker container run --publish 80:80 --detach --name <name> nginx
docker container ls # list running containers
docker container ls -a # list all containers
docker container stop <container-ID | container-name> # stop certain container
docker container start
docker container logs <container-ID | container-name> # 顯示 container log 訊息
docker container top <container-ID | container-name> # 列出 container 內執行的程序
docker container inspect <container-ID | container-name> # 顯示 container 啟動時的設定資訊
docker container stats # 顯示 container 即時的效能狀態
docker container rm <container-ID | container-name> # 移除特定 container(須先 stop)
docker container rm -f <container-ID | container-name> # 移除特定 container(不用 stop)
docker container --help
# old way
docker container inspect # docker inspect
docker container stats # docker stats
run 和 start 的差別
透過 docker container run 總是會產生一個新的 container;透過 docker container start 則可以啟動一個停止的 container。
指令說明
docker container run
alias: docker run
啟動 container
##
# 啟動 container
# -d 在 detached mode(背景)執行 container
# -p 80:80 將本機的 80 port 對到 container 的 80 port
##
# old way: docker run
docker container run --publish 80:80 nginx
# --detach: 在背景執行,回傳 container ID
docker container run --publish 80:80 --detach nginx
# --name: 為此 container 命名
docker container run --publish 80:80 --detach --name webhost nginx
docker container run --publish 80:80 --name webhost -d nginx:1.11 nginx -T
# 啟動 mongo database
docker container run --name mongo -d mongo
docker container run -d -p 3306:3306 --name db -e MYSQL_RANDOM_ROOT_PASSWORD=yes mysql
- Docker engine 會先在本地尋找叫做 nginx 的 image。
- 如果在本地的 image caches 中找不到,則從預設的 docker hub 中尋找該 image。
- 如果沒有指定版本,預設就是拉最新版本的 images 到 image caches 中。
- 一旦取得了 image 並準備就 緒,將根據 image 啟動一個新的 container。
- Docker 將會自訂網路,並在 Docker engine 中給他一個虛擬網路內的特定虛擬 IP 位址。
- 指令中的
publish是用來開放本機的 80 port 讓本機可以連結到 container 的 80 port,傳輸資料到正在執行的 container 裡面。
- 每當啟動一個新的 container 時,便會取得一個新的獨特 ID。
- Docker 不會製作 image 的副本,它實際上只是在 image 停止的地方上,開始了一層新的變更。
在 container 內執行指令(-it)
# 以互動形式來產生 container
# -t: pseudo-tty,模擬一個終端機,就類似 SSH 所做的一樣
# -i: interactive, keep session open to receive terminal input
# -it: 會在 container 中提供一個終端機讓你使用(Bash Shell)
docker container run -it --name <container-name> <image-name> <program>
docker container run -it --name proxy nginx bash
docker container run -it --name ubuntu ubuntu
# 重新啟動該 container
docker container start -ai
# 在現有已啟動的 container 中執行額外的程序或指令
docker container exec -it <container-name> <program>
docker container exec -it mysql bash
指定連接埠(-p)
# 打開連接埠
# -p (--publish) HOST:CONTAINER
docker container run -p <host-port>:<container:port>
docker container run -p 80:80 --name webhost -d nginx
docker container ls
# list running containers
# old way: docker ps
docker container ls
docker container ls -a
docker container inspect
# 用來檢視 container 啟動時的設定檔
docker container inspect <container-name>
# --format,使用 "GO 模板" 來格式化輸出的結果
docker container inspect webhost --format '{{ .NetworkSettings.IPAddress}}'
docker image
docker images # 列出所有下載過的 image,等同於 docker image ls
docker image prune -a # 移除沒有用到的 docker image