5.1 啟動
本節將詳細介紹 Docker 容器的啟動方式,包括新建啟動和重新啟動已停止的容器。
5.1.1 啟動方式概述
啟動容器有兩種方式:
- 新建並啟動:基於映象建立新容器
- 重新啟動:將已終止的容器重新執行
由於 Docker 容器非常輕量,實際使用中常常是隨時刪除和新建容器,而不是反覆重啟同一個容器。
5.1.2 新建並啟動
基本語法
docker run [選項] 映象 [指令] [引數...]
最簡單的例子
輸出 『Hello World』 後容器自動終止:
$ docker run ubuntu:24.04 /bin/echo 'Hello world'
Hello world
這與直接執行 /bin/echo 'Hello world' 幾乎沒有區別,但實際上已經啟動了一個完整的 Ubuntu 容器來執行這條指令。
版本說明:範例使用
ubuntu:24.04,這是最新 LTS 版本。如需其他版本,可替換為ubuntu:22.04、ubuntu:20.04等。
互動式容器
啟動一個可以互動的 bash 終端:
$ docker run -it ubuntu:24.04 /bin/bash
root@af8bae53bdd3:/#
引數說明:
| 引數 | 作用 |
|---|---|
-i |
保持標準輸入 (stdin) 開啟,允許輸入 |
-t |
分配偽終端 (pseudo-TTY),提供終端介面 |
-it |
兩者組合使用,獲得互動式終端 |
在互動模式下可以執行指令:
root@af8bae53bdd3:/# pwd
/
root@af8bae53bdd3:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@af8bae53bdd3:/# exit # 退出容器
5.1.3 docker run 的完整流程
執行 docker run 時,Docker 在後台完成以下操作:
flowchart TD
Cmd["docker run ubuntu:24.04 /bin/echo 'Hello'"] --> Step1
Step1{"1. 檢查本地是否有 ubuntu:24.04 映象"}
Step1 -- 有 --> Step1_Yes["使用本地映象"]
Step1 -- 無 --> Step1_No["從 Registry 下載"]
Step1_Yes --> Step2
Step1_No --> Step2
Step2["2. 建立容器
• 基於映象的只讀層
• 新增一層可讀寫層(容器儲存層)"] --> Step3 Step3["3. 設定網路
• 建立虛擬網絡卡
• 分配 IP 地址
• 連線到 Docker 網橋"] --> Step4 Step4["4. 啟動容器,執行指定指令"] --> Step5 Step5["5. 指令執行完畢,容器停止"]
• 基於映象的只讀層
• 新增一層可讀寫層(容器儲存層)"] --> Step3 Step3["3. 設定網路
• 建立虛擬網絡卡
• 分配 IP 地址
• 連線到 Docker 網橋"] --> Step4 Step4["4. 啟動容器,執行指定指令"] --> Step5 Step5["5. 指令執行完畢,容器停止"]
5.1.4 常用啟動選項
基礎選項
| 選項 | 說明 | 範例 |
|---|---|---|
-d |
後台執行 (detach) | docker run -d nginx:latest |
-it |
互動式終端 | docker run -it ubuntu:24.04 bash |
--name |
指定容器名稱 | docker run --name myapp nginx:latest |
--rm |
退出後自動刪除容器 | docker run --rm ubuntu:24.04 echo hi |
連接埠對映
## 將容器的 80 連接埠對映到宿主機的 8080 連接埠
$ docker run -d -p 8080:80 nginx:latest
## 隨機對映連接埠
$ docker run -d -P nginx:latest
## 只繫結到 localhost
$ docker run -d -p 127.0.0.1:8080:80 nginx:latest
資料卷掛載
## 掛載命名卷
$ docker run -v mydata:/data nginx:latest
## 掛載宿主機目錄
$ docker run -v /host/path:/container/path nginx:latest
## 只讀掛載
$ docker run -v /host/path:/container/path:ro nginx:latest
環境變數
## 設定單個環境變數
$ docker run -e MYSQL_ROOT_PASSWORD=secret mysql
## 從檔案載入環境變數
$ docker run --env-file .env myapp
資源限制
## 限制記憶體
$ docker run -m 512m nginx:latest
## 限制 CPU
$ docker run --cpus=1.5 nginx:latest
5.1.5 啟動已終止容器
使用 docker start 重新啟動已停止的容器:
## 檢視所有容器(包括已停止的)
$ docker ps -a
CONTAINER ID IMAGE STATUS NAMES
af8bae53bdd3 ubuntu Exited (0) 2 minutes ago myubuntu
## 重新啟動
$ docker start myubuntu
## 啟動並附加終端
$ docker start -ai myubuntu
5.1.6 容器內程序的特點
容器內只執行指定的應用程式及其必需資源:
root@ba267838cc1b:/# ps
PID TTY TIME CMD
1 ? 00:00:00 bash
11 ? 00:00:00 ps
可見容器中僅執行了 bash 程序。這種特點使得 Docker 對資源的利用率極高。
💡 筆者提示:容器內的 PID 1 程序很重要——它是容器的主程序,該程序退出則容器停止。詳見後台執行章節。
5.1.7 常見問題
Q:容器啟動後立即退出
原因:主程序執行完畢或無法保持執行
## 這個容器會立即退出(echo 執行完就結束了)
$ docker run ubuntu:24.04 echo "hello"
## 解決:使用能持續執行的指令
$ docker run -d nginx:latest # nginx 是持續執行的服務
詳細解釋見後台執行。
Q:無法連線容器內的服務
原因:未正確對映連接埠
## 錯誤:沒有 -p 引數,外部無法訪問
$ docker run -d nginx:latest
## 正確:對映連接埠
$ docker run -d -p 80:80 nginx:latest
Q:容器內修改的檔案丟失
原因:未使用資料卷,資料儲存在容器儲存層
## 使用資料卷持久化
$ docker run -v mydata:/app/data myapp
詳見資料管理。