[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 操作 PostgreSQL
# 在 container 內執行單一 SQL 指令
$ docker exec -it <容器名稱> psql -U <使用者> -d <資料庫> -c "<SQL>"
# 列出所有資料庫
$ docker compose exec postgres psql -U postgres -l
# 刪除資料庫
$ docker compose exec postgres dropdb -U postgres <資料庫名稱>
# 建立資料庫並指定擁有者
$ docker compose exec postgres createdb -U postgres --owner=<擁有者> <資料庫名稱>
| 情境 | 建議指令 | 效果 |
|---|---|---|
| 開發中暫時停止,等等還要再跑 | 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)