持久化資料庫

如果您沒有注意到,每次啟動容器時,您的待辦事項清單都是空的。這是為什麼呢?在本部分中,您將深入瞭解容器的工作原理。

容器的檔案系統

當容器執行時,它會使用映像中的各個層作為其檔案系統。每個容器還會獲得自己的「暫存空間」來建立/更新/移除檔案。即使其他容器使用相同的映像,也看不到任何變更。

實際操作

為了實際觀察,您將啟動兩個容器。在一個容器中,您將建立一個檔案。在另一個容器中,您將檢查同一個檔案是否存在。

  1. 啟動一個 Alpine 容器並在其中建立一個新檔案。

    $ docker run --rm alpine touch greeting.txt
    

    提示

    您在映像名稱(在本例中為 `alpine`)之後指定的任何指令都會在容器內執行。在本例中,指令 `touch greeting.txt` 會在容器的檔案系統上放置一個名為 `greeting.txt` 的檔案。

  2. 執行一個新的 Alpine 容器,並使用 `stat` 指令檢查檔案是否存在。

    $ docker run --rm alpine stat greeting.txt
    

    您應該會看到類似以下的輸出,指示新容器中不存在該檔案。

    stat: can't stat 'greeting.txt': No such file or directory
    

第一個容器建立的 `greeting.txt` 檔案在第二個容器中不存在。這是因為每個容器的可寫入「頂層」是隔離的。即使兩個容器共享組成基礎映像的相同底層,可寫入層對於每個容器都是唯一的。

容器磁碟區

透過先前的實驗,您看到每個容器每次啟動時都是從映像定義開始。雖然容器可以建立、更新和刪除檔案,但當您移除容器時,這些變更將會遺失,Docker 會隔離對該容器的所有變更。使用磁碟區,您可以改變所有這些。

磁碟區 提供將容器的特定檔案系統路徑連回主機的功能。如果您在容器中掛載目錄,該目錄中的變更也會顯示在主機上。如果您在容器重新啟動時掛載相同的目錄,您會看到相同的檔案。

磁碟區主要有兩種類型。您最終將會使用這兩種類型,但您將從磁碟區掛載開始。

持久化待辦事項資料

根據預設,待辦事項應用程式將其資料儲存在容器檔案系統中 ` /etc/todos/todo.db ` 的 SQLite 資料庫中。如果您不熟悉 SQLite,不用擔心!它只是一個將所有資料儲存在單一檔案中的關聯式資料庫。雖然這不適用於大型應用程式,但它適用於小型示範。您稍後將學習如何將其切換到不同的資料庫引擎。

由於資料庫是單一檔案,如果您可以在主機上持久化該檔案並將其提供給下一個容器,它應該能夠從上一個容器停止的地方繼續。透過建立磁碟區並將其附加(通常稱為「掛載」)到您儲存資料的目錄,您可以持久化資料。當您的容器寫入 `todo.db` 檔案時,它會將資料持久化到主機的磁碟區中。

如前所述,您將使用磁碟區掛載。將磁碟區掛載視為一個不透明的資料儲存區。Docker 完全管理磁碟區,包括磁碟上的儲存位置。您只需要記住磁碟區的名稱即可。

建立磁碟區並啟動容器

您可以使用 CLI 或 Docker Desktop 的圖形介面建立磁碟區並啟動容器。


  1. 使用 `docker volume create` 指令建立磁碟區。

    $ docker volume create todo-db
    
  2. 再次使用 `docker rm -f <id>` 停止並移除待辦事項應用程式容器,因為它仍在執行而未使用持久性磁碟區。

  3. 啟動待辦事項應用程式容器,但新增 `--mount` 選項以指定磁碟區掛載。為磁碟區命名,並將其掛載到容器中的 `/etc/todos`,這會擷取在該路徑建立的所有檔案。

    $ docker run -dp 127.0.0.1:3000:3000 --mount type=volume,src=todo-db,target=/etc/todos getting-started
    

    注意事項

    如果您使用的是 Git Bash,則必須使用不同的語法來執行此指令。

    $ docker run -dp 127.0.0.1:3000:3000 --mount type=volume,src=todo-db,target=//etc/todos getting-started
    

    有關 Git Bash 語法差異的更多詳細資訊,請參閱 使用 Git Bash

建立磁碟區

  1. 在 Docker Desktop 中選取**磁碟區**。
  2. 在**磁碟區**中,選取**建立**。
  3. 指定 `todo-db` 作為磁碟區名稱,然後選取**建立**。

停止並移除應用程式容器

  1. 在 Docker Desktop 中選取**容器**。
  2. 在容器的**動作**欄中選取**刪除**。

啟動已掛載磁碟區的待辦事項應用程式容器

  1. 選取 Docker Desktop 頂端的搜尋方塊。

  2. 在搜尋視窗中,選取**映像**索引標籤。

  3. 在搜尋方塊中,指定映像名稱 `getting-started`。

    提示

    使用搜尋篩選器篩選映像,僅顯示**本機映像**。

  4. 選取您的映像,然後選取**執行**。

  5. 選取**選用設定**。

  6. 在**主機埠**中,指定埠,例如 `3000`。

  7. 在**主機路徑**中,指定磁碟區的名稱 `todo-db`。

  8. 在**容器路徑**中,指定 `/etc/todos`。

  9. 選取**執行**。


驗證資料是否持久化

  1. 容器啟動後,開啟應用程式並將一些項目新增到您的待辦事項清單。

    Items added to todo list
  2. 停止並移除待辦事項應用程式的容器。使用 Docker Desktop 或 `docker ps` 取得 ID,然後使用 `docker rm -f <id>` 將其移除。

  3. 使用先前的步驟啟動新的容器。

  4. 開啟應用程式。您應該會看到您的項目仍在您的清單中。

  5. 檢查完清單後,請移除容器。

您現在已經學習了如何持久化資料。

深入瞭解磁碟區

很多人經常會問「當我使用磁碟區時,Docker 將我的資料儲存在哪裡?」如果您想知道,可以使用 `docker volume inspect` 指令。

$ docker volume inspect todo-db

您應該會看到如下輸出

[
    {
        "CreatedAt": "2019-09-26T02:18:36Z",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/todo-db/_data",
        "Name": "todo-db",
        "Options": {},
        "Scope": "local"
    }
]

`Mountpoint` 是磁碟上資料的實際位置。請注意,在大多數機器上,您需要具有 root 權限才能從主機存取此目錄。

摘要

在本節中,您學習了如何持久化容器資料。

相關資訊

後續步驟

接下來,您將學習如何使用繫結掛載更有效率地開發您的應用程式。