Docker 提供了豐富的容器操作指令,讓開發者能有效管理容器的生命週期和狀態。從暫停容器以釋放資源,到還原容器繼續運作,再到提交容器變更以建立新的映像,這些操作在實際開發流程中扮演著重要的角色。理解這些操作的原理和使用方法,有助於提升開發效率和應用程式佈署的可靠性。此外,Dockerfile 的撰寫和 Docker Compose 的應用,更是簡化映像構建和多容器應用程式管理的利器。透過 Dockerfile,我們可以定義映像的構建過程,並利用其快取機制加速構建速度。而 Docker Compose 則允許我們透過 YAML 檔案定義和管理多個容器,簡化複雜應用程式的佈署和維護。

使用 Docker 操作容器:從暫停到提交

在本篇文章中,玄貓將探討如何使用 Docker 操作容器,從暫停、還原到提交新的容器映像。透過實際案例和詳細的解說,讀者將能夠理解這些操作的背後邏輯及其實際應用。

暫停與還原容器

暫停與還原容器是 Docker 管理容器的基本操作之一。這些操作可以幫助你在不終止容器的情況下,暫時停止其運作,以節省資源或進行維護。

暫停容器

要暫停一個容器,可以使用 docker pause 命令。這個命令會暫停指定容器中的所有程式。以下是具體的操作步驟:

  1. 使用 docker pause 命令來暫停容器:

    docker pause Parminder
    

    這裡假設 Parminder 是你要暫停的容器名稱。

  2. 檢查容器狀態:

    docker ps -a
    

    暫停後的容器狀態會顯示為 (Paused)

  3. 尋試在暫停的容器中執行命令:

    ls
    

    暫停中的容器無法執行命令,會顯示等待狀態。

還原容器

要還原一個暫停的容器,可以使用 docker unpause 命令。這個命令會還原指定容器中的所有程式。

  1. 使用 docker unpause 命令來還原容器:

    docker unpause Parminder
    
  2. 檢查容器狀態:

    docker ps -a
    

    還原後的容器狀態會顯示為 Up

  3. 在還原的容器中執行命令:

    ls
    

    還原後的容器可以正常執行命令。

建立新容器

docker create 命令用來建立一個新的可寫層,並準備好執行指定的命令。這個命令與 docker run -d 不同之處在於,建立的容器不會立即開始執行。這樣做可以讓你提前組態好容器,等到需要時再啟動。

  1. 建立一個新的 Fedora 容器:

    docker create -t -i fedora bash
    
  2. 檢查建立後狀態:

    docker ps -a
    

    新建立的容器狀態將會顯示為 Created

提交容器變更

當你對現有的容器進行了修改,並希望將這些修改提交為一個新的映像時,可以使用 docker commit 命令。這個命令會建立一個新的映像,包含了你在現有映像基礎上的所有變更。

  1. 提交一個已修改過的 Fedora 映像:

    docker commit -m "Added new features" -a "Your Name" <container_id> my-new-fedora-image:latest
    
  2. 驗證新映像是否成功建立:

    docker images
    

與實務經驗

在實際開發中,這些操作有著重要的應用場景。例如,當你需要對多個開發環境進行統一組態時,可以先建立好組態好的容器,然後再根據需要啟動。而在進行版本控制時,提交修改過的映像可以確保每次佈署都有一致的環境。

此圖示呈現了 Docker 操作流程:

  graph TD;
A[建立映像] --> B[建立並組態容器];
B --> C[暫停容器];
C --> D[還原並啟動];
D --> E[提交變更];
E --> F[重複使用新映像];

內容解密:

  • 建立映像:這是整個流程的起點,從基礎映像開始。
  • 建立並組態容器:根據需求組態好環境和應用。
  • 暫停容器:當不需要執行時,可以暫停節省資源。
  • 還原並啟動:在需要時還原運作。
  • 提交變更:將所有修改提交為新映像。
  • 重複使用新映像:保證每次佈署的一致性。

Docker 容器變更檢查與 Dockerfile 基礎指引

Docker Diff 指令

Docker 提供了 docker diff 指令來檢查容器檔案系統的變更。這個指令會列出容器內檔案與目錄的變更,相較於基礎映像,這些變更可能是由於使用者在容器內進行的操作所引起的。

docker diff <Container ID>

隨著時間推移,隨著對容器進行更多修改,這個指令會顯示出容器檔案系統相較於基礎映像的差異。這對於追蹤容器的變更非常有幫助。

Dockerfile 基礎指引

Dockerfile 是一個包含一系列指令的文字檔案,用來構建 Docker 映像。這些指令可以讓 Docker 自動執行,從而建立出自定義的映像。Dockerfile 的語法簡單,不需要程式語言知識即可撰寫。

基本格式與規則

  • FROM 指令:每個 Dockerfile 必須以 FROM 指令開始,這個指令會指定基礎映像。例如:

    ARG OS_VERSION=14.04
    FROM Ubuntu:${OS_VERSION}
    

    注意:FROM 之前可以使用 ARG 指令來定義變數。

  • 指令與引數:每個指令都有其特定的引數。例如:

    RUN apt-get update
    
  • 順序執行:指令會依照在 Dockerfile 中出現的順序一一執行。

  • 目錄管理:Dockerfile 及其相關檔案會被傳送到 Docker daemon。為了保持映像輕量,應避免在該目錄中放置不必要的檔案。

常用指令

以下是一些常見的 Dockerfile 指令:

  • ADD:從主機系統或 URL 複製檔案到容器內。

    ADD <src> <dest>
    
  • CMD:當容器啟動時執行指定的命令。每個 Dockerfile 中只能有一個 CMD 指令,如果有多個,則最後一個會生效。

    CMD ["executable", "param1", "param2"]
    
  • ENTRYPOINT:當容器啟動時執行預設可執行檔。通常與 CMD 搭配使用。

    ENTRYPOINT ["executable", "param1", "param2"]
    
  • ENV:設定環境變數。

    ENV <key> <value>
    
  • EXPOSE:指定容器監聽的埠號碼。

    EXPOSE <port>
    
  • MAINTAINER:設定映像作者的資訊。

    MAINTAINER <name>
    
  • RUN:執行指定命令和建立層級。

    RUN <command>
    
  • USER:設定執行 RUN、CMD 或 ENTRYPOINT 的使用者名稱或 UID。

    USER <user>[:<group>]
    
  • VOLUME:指定分享目錄。

    VOLUME ["/data"]
    
  • WORKDIR:設定工作目錄。

    WORKDIR /path/to/workdir
    

建立 MySQL Docker 映像

接下來我們將建立一個根據 Ubuntu 系統且包含 MySQL 的 Docker 映像。首先,我們需要編寫一個 Dockerfile:

FROM ubuntu:14.04
MAINTAINER pkocher@domain.com

RUN apt-get update && apt-get install -y mysql-server
EXPOSE 3306
CMD ["/usr/bin/mysqld_safe"]

內容解密:

此處逐步解說我們剛剛建立的 Dockerfile 中各項作用及邏輯:
FROM ubuntu:14.04

作用:FROM 指令用來指定基礎映像,這裡我們使用的是 Ubuntu 14.04 作為基礎映像。

邏輯:選擇 Ubuntu 作為基礎映像是因為它提供了豐富的軟體函式庫和穩定性,適合用來安裝 MySQL 與其他相關工具。

MAINTAINER pkocher@domain.com

作用:MAINTAINER 指令用來標註映像的作者資訊,便於後續維護和查詢。

邏輯:這樣設定是為了標示該 Docker 映像是由誰建立和維護,方便日後追蹤和管理。

RUN apt-get update && apt-get install -y mysql-server

作用:RUN 指令用來執行命令並建立新層級。這裡我們更新軟體包索引並安裝 MySQL 做為伺服器版本。

邏輯:先更新軟體包索引可以確保我們安裝的是最新版本的 MySQL;安裝過程中不需要手動確認選項(-y),這樣可以自動化流程。


##### EXPOSE 3306

**作用**:EXPOSE 指令用來宣告容器會監聽的網路埠號碼(3306 是 MySQL 預設埠)。

**邏輯**:宣告該埠號碼以便在容器執行時可以透過此埠連線 MySQL 伺服器。
CMD ["/usr/bin/mysqld_safe"]
作用:CMD 指令用來設定容器啟動時要執行的命令。這裡我們使用 MySQL 安全模式下啟動伺服器。

邏輯:設定預設執行命令以啟動 MySQL 服務,確保容器執行時自動啟動 MySQL。


#### 建構映像

完成 Dockerfile 編寫後,使用以下命令來建構 Docker 映像:

```bash
docker build -t pkocher/mysql .

內容解密:

在此段落中逐步解說 docker build 命令和其選項:
docker build -t pkocher/mysql .
作用:此命令會根據當前目錄中的 Dockerfile 和上下文資料來建構一個新的 Docker 映像。

邏輯:-t 選項用來標記映像名稱,這樣方便後續查詢和管理;. 應該放在最後以表示上下文資料夾位置(即當前目錄)。

透過以上步驟及解說完成對「MySQL」之 Container 的建構過程。

Docker 介面與組合應用

在 Docker 中,建構映像是一個逐步進行的過程。Docker 會從 Dockerfile 的第一行開始執行,並依序處理每一條指令。每條指令執行後,其結果會被快取以供日後重用。這意味著,如果你重新建構相同的 Dockerfile,而 Dockerfile 沒有變更,Docker 將不會重新建構任何東西,因為所有步驟都已經完成且快取可用。

建構與快取

當 Docker 建構過程完成後,你就會得到一個可供檢查和儲存在你的倉函式庫中的映像。我們可以透過以下命令來確認映像是否成功建構:

docker images

假設我們有一個名為 pkocher/MySQL 的映像,以下是可能的輸出:

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
pkocher/mysql       latest              8ef5ceb3439e        About a minute ago  318.1 MB
mysql               latest              9726f738a97a        2 weeks ago         324.3 MB
ubuntu              latest              91e54dfb1179        8 weeks ago         188.4 MB

執行與驗證

接下來,我們可以執行這個映像並驗證其功能。假設我們要執行 MySQL 伺服器,可以使用以下命令:

docker run -d -p 3306:3306 pkocher/MySQL

這條命令會在背景(detached 模式)中執行容器,並將主機的 3306 通路對映到容器的 3306 通路。

要確認 MySQL 伺服器是否正常執行,我們可以使用 docker ps 命令來檢查執行中的容器:

docker ps

假設輸出如下所示:

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
5063c4bed669        pkocher/mysql       "/usr/bin/mysqld_safe"   36 seconds ago      Up 35 seconds       0.0.0.0:3306->3306/tcp   modest_euclid

這表示我們的 MySQL 容器正在執行。

檢查內部狀態

為了進一步驗證 MySQL 是否正常執行,我們可以進入容器內部並執行一些查詢。首先,使用 docker exec 命令來執行 bash Shell:

docker exec -it 5063c4bed669 bash

進入容器後,我們可以開始 MySQL 監控並執行一些查詢來確認系統狀態:

mysql
show databases;
connect information_schema;
show tables;

如果一切正常,我們應該能夠看到以下輸出:

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
mysql> connect information_schema;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Connection id:    2
Current database: information_schema

mysql> show tables;
+-----------------------------------+
| Tables_in_information_schema      |
+-----------------------------------+
| CHARACTER_SETS                     |
| COLLATIONS                         |
| COLLATION_CHARACTER_SET_APPLICABILITY |
| COLUMNS                            |
| COLUMN_PRIVILEGES                  |
| ENGINES                            |
| EVENTS                             |
| FILES                              |
| GLOBAL_STATUS                      |
| GLOBAL_VARIABLES                   |
...

Docker Compose

Docker Compose 是用來簡化多容器應用程式定義和執行的工具。它透過定義一個 docker-compose.yml 檔案來管理多個服務的啟動順序和依賴關係。

以下是一個簡單的 docker-compose.yml 檔案範例,它定義了一個包含 Tomcat 和 MySQL 的應用程式:

version: '2'
services:
  tomcat:
    image: 'tomcat:7'
    container_name: appserver
    ports:
      - '8080:80'
    depends_on:
      - db

  db:
    image: 'mysql:5.7'
    container_name: dbserver
    ports:
      - '3306:3306'
    environment:
      - MYSQL_ROOT_PASSWORD=sample
      - MYSQL_DATABASE=helpdesk
      - MYSQL_USER=helpdesk
      - MYSQL_PASSWORD=helpdesk

應用解說

在這個 YAML 檔案中,我們定義了兩個服務:Tomcat 和 MySQL。Tomcat 的 depends_on 欄位指定了它依賴於 MySQL 資料函式庫服務。這意味著 Docker Compose 在啟動 Tomcat 前會先確保 MySQL 資料函式庫已經啟動。

要啟動這些服務,我們可以使用以下命令:

docker-compose up -d

執行結果

這條命令會檢查 docker-compose.yml 檔案中的組態、建立依賴圖、並根據依賴順序啟動服務。如果本地沒有指定的映像,Docker Compose 則會從 Docker Registry 下載相應的映像。

以下是可能的執行結果:

Creating network "remove_default" with the default driver
Pulling db (mysql:5.7)....
Pulling tomcat (tomcat:7)....
Creating dbserver ... done
Creating appserver ... done

最後,使用 docker ps 命令來檢查所有執行中的容器:

docker ps

假設輸出如下所示:

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
ae2f87e1b4c8        tomcat:7            "catalina.sh run"       About an hour ago   Up About an hour     0.0.0.0:8080->80/tcp     appserver
ffd7f1b9bdf2        mysql:5.7           "docker-entrypoint.s…" About an hour ago   Up About an hour     0.0.0.0:3306->3306/tcp   dbserver

Docker Compose 的靈活性

Docker Compose 不僅能夠簡化多容器應用程式的啟動流程,還提供了許多高階功能來管理容器之間的依賴關係和資源分配。例如,我們可以透過環境變數來組態資料函式庫密碼和連線字串等敏感資訊。此外,Docker Compose 還支援網路組態、卷掛載等功能,使得多容器應用程式的開發和佈署變得更加高效和靈活。

內容解密:

此圖示展示瞭如何使用 Docker Compose 組態 Tomcat 和 MySQL 的服務關係。

  • A[Tomcat]:代表 Tomcat 的服務。
  • B[MySQL]:代表 MySQL 的資料函式庫服務。
  • C[Ports]:代表將主機埠對映到 Tomcat 的埠。
  • D[Ports]:代表將主機埠對映到 MySQL 的埠。
  • E[Environment Variables]:代表 MySQL 的環境變數設定。

整體流程中顯示了 Tomcat 須依賴於 MySQL 首先成功啟動才能正常執行。 描述明確展示了一個根據 Docker Compose 的多容器應用架構設計規劃過程及其邏輯關係。