Home >Backend Development >Golang >Docker Volumes

Docker Volumes

Linda Hamilton
Linda HamiltonOriginal
2025-01-21 22:03:10845browse

Docker Volumes: The Ultimate Solution for Data Persistence in Containers

In containerized applications, data persistence is crucial. Docker containers, by default, lose all data when removed. The ideal solution? Docker Volumes. They ensure data survival even after removing or restarting containers, offering isolation and scalability.


Why choose Docker Volumes?

  1. Persistence: When linking volumes to containers, data persists even after the container is destroyed or recreated.
  2. Isolation: Separating data storage from container logic simplifies organization, replacements and updates.
  3. Scalability: In multi-container environments, volumes facilitate data sharing.
  4. Accelerated Development: Bind mounts, in particular, they allow editing of files locally with immediate reflection in the container.

Imagine the container as a rental car – when you change cars, you lose everything inside it. The volume is your personal suitcase, which accompanies you in any vehicle (container).

Docker Volumes


Practical Example 1: Bind Mount for File Upload

Consider a Go application that receives file uploads. This example demonstrates how to keep these uploads persistent on the local computer, avoiding losses when removing the container.

Image Uploader

This simplified example creates an HTTP server for uploading and storing files in the uploads/ folder. The complete code is available on my GitHub. Here's an excerpt from 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

This Dockerfile compiles the binary and configures the execution environment:

<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>

Creating and Running the Container with Bind Mount

  1. Build the image:
<code class="language-bash">docker build -t go-upload-app:latest .</code>
  1. Run the container, mapping the host's uploads/ folder to the container:
<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>

Please note -v /caminho/no/host/uploads:/app/uploads:

  • Left: path on host.
  • Right: path in the container (/app/uploads).

Files sent via /upload will be stored in the container and on the host. Removing the container preserves the files on the host.


Named Volumes

To have Docker manage data in a named volume (without relying on a local folder), here is an example with 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 persists regardless of the containers that use it.


Security: Encrypting Volumes

For sensitive data, consider encrypting the file system or using volume drivers with encryption:

  • Storage in encrypted partitions.
  • Cloud storage solutions with encryption at rest.
  • Specialized drivers (rexray, portworx) with built-in encryption.

Your data are confidential documents; protect them with encryption.


Example with Docker Compose

Docker Compose makes it easy to orchestrate multiple services. This example demonstrates data persistence with a database:

<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>

Running with Docker Compose

Start services: docker compose up -d. Check status: docker compose ps. Test the upload:

<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>

Stop and remove: docker compose down. db_data persists.


Conclusion

Docker volumes are essential for data persistence in containers. Bind mounts are ideal for development, while named volumes are recommended for production. Correct use guarantees resilience and organization. Try it and share your experiences!

The above is the detailed content of Docker Volumes. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn