首页 > 后端开发 > Golang > Docker 卷

Docker 卷

Linda Hamilton
发布: 2025-01-21 22:03:10
原创
878 人浏览过

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中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板