首頁 >後端開發 >Golang >Docker 卷

Docker 卷

Linda Hamilton
Linda Hamilton原創
2025-01-21 22:03:10847瀏覽

Docker Volumes:容器中資料持久化的終極解決方案

在容器化應用程式中,資料持久性至關重要。 預設情況下,Docker 容器在刪除時會遺失所有資料。理想的解決方案? Docker 卷。即使在刪除或重新啟動容器後,它們也能確保資料存活,從而提供隔離和可擴展性。


為什麼選擇 Docker Volume?

  1. 持久性:將捲連結到容器時,即使容器被銷毀或重新創建,資料也會保留。
  2. 隔離:將資料儲存與容器邏輯分離可以簡化組織、替換和更新。
  3. 可擴充性:在多容器環境中,磁碟區有助於資料共享。
  4. 加速開發: Bind mounts,特別是,它們允許在本地編輯檔案並立即反映在容器中。

將容器想像成一輛租賃車-當你換車時,你會失去裡面的所有東西。該卷是您的個人行李箱,它伴隨您在任何車輛(集裝箱)中。

Docker Volumes


實際範例1:Bind Mount用於檔案上傳

考慮一個接收文件上傳的 Go 應用程式。 此範例示範如何將這些上傳持久保存在本機電腦上,避免刪除容器時造成損失。

圖片上傳器

這個簡化的範例建立一個 HTTP 伺服器,用於在 uploads/ 資料夾中上傳和儲存檔案。 完整的程式碼可以在我的 GitHub 上找到。 以下是handler的摘錄:

<code class="language-go">func UploadHandler(w http.ResponseWriter, r *http.Request) {
    if r.Method != http.MethodPost {
        writeJSONError(w, http.StatusMethodNotAllowed, "Método não permitido")
        return
    }

    file, header, err := r.FormFile("file")
    if err != nil {
        writeJSONError(w, http.StatusBadRequest, "Erro ao ler arquivo do formulário")
        return
    }
    defer file.Close()

    err = services.SaveUploadedFile(file, header.Filename)
    if err != nil {
        writeJSONError(w, http.StatusInternalServerError, fmt.Sprintf("Erro ao gravar arquivo: %v", err))
        return
    }

    writeJSONSuccess(w, http.StatusOK, "Upload realizado com sucesso!", header.Filename)
}</code>

Dockerfile

此 Dockerfile 編譯二進位檔案並配置執行環境:

<code class="language-dockerfile"># syntax=docker/dockerfile:1
FROM golang:1.23-alpine AS builder
WORKDIR /app

COPY go.mod ./
RUN go mod download

COPY . .
RUN go build -o server ./cmd/image-uploader

FROM alpine:3.21
WORKDIR /app

COPY --from=builder /app/server /app/server
RUN mkdir -p /app/uploads

EXPOSE 8080
CMD ["/app/server"]</code>

使用 Bind Mount

建立並運行容器
  1. 建構映像:
<code class="language-bash">docker build -t go-upload-app:latest .</code>
  1. 運行容器,將主機的 uploads/ 資料夾對應到容器:
<code class="language-bash">docker run -d \
  --name meu_container_go \
  -p 8080:8080 \
  -v /caminho/no/host/uploads:/app/uploads \
  go-upload-app:latest</code>

請注意-v /caminho/no/host/uploads:/app/uploads

  • 左:主機上的路徑。
  • 右:容器中的路徑 (/app/uploads)。

透過/upload傳送的檔案將儲存在容器和主機上。 刪除容器會保留主機上的檔案。


命名卷

要讓 Docker 管理命名卷中的資料(不依賴本機資料夾),以下是 PostgreSQL 的範例:

<code class="language-bash">docker volume create pg_dados

docker run -d \
  --name meu_postgres \
  -e POSTGRES_PASSWORD=123456 \
  -v pg_dados:/var/lib/postgresql/data \
  postgres:latest</code>

pg_dados 無論使用它的容器如何,都會持續存在。


安全性:加密磁碟區

對於敏感數據,請考慮加密檔案系統或使用加密磁碟區驅動程式:

  • 儲存在加密分割區中。
  • 靜態加密的雲端儲存解決方案。
  • 具有內建加密功能的專用驅動程式(rexray、portworx)。

您的資料是機密文件;透過加密來保護它們。


Docker Compose 範例

Docker Compose 可以輕鬆編排多個服務。 此範例演示了資料庫的資料持久性:

<code class="language-go">func UploadHandler(w http.ResponseWriter, r *http.Request) {
    if r.Method != http.MethodPost {
        writeJSONError(w, http.StatusMethodNotAllowed, "Método não permitido")
        return
    }

    file, header, err := r.FormFile("file")
    if err != nil {
        writeJSONError(w, http.StatusBadRequest, "Erro ao ler arquivo do formulário")
        return
    }
    defer file.Close()

    err = services.SaveUploadedFile(file, header.Filename)
    if err != nil {
        writeJSONError(w, http.StatusInternalServerError, fmt.Sprintf("Erro ao gravar arquivo: %v", err))
        return
    }

    writeJSONSuccess(w, http.StatusOK, "Upload realizado com sucesso!", header.Filename)
}</code>

使用 Docker Compose 運行

啟動服務:docker compose up -d。 檢查狀態:docker compose ps。 測試上傳:

<code class="language-dockerfile"># syntax=docker/dockerfile:1
FROM golang:1.23-alpine AS builder
WORKDIR /app

COPY go.mod ./
RUN go mod download

COPY . .
RUN go build -o server ./cmd/image-uploader

FROM alpine:3.21
WORKDIR /app

COPY --from=builder /app/server /app/server
RUN mkdir -p /app/uploads

EXPOSE 8080
CMD ["/app/server"]</code>

停止並刪除:docker compose downdb_data 持續存在。


結論

Docker 磁碟區對於容器中的資料持久化至關重要。 Bind mounts 非常適合開發,而命名卷則建議用於生產。 正確使用可以確保彈性和組織性。 嘗試並分享您的經驗!

以上是Docker 卷的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn