Como Usar Zig com Docker — Imagens, Dockerfile e CI/CD

Como Usar Zig com Docker

O Docker é uma ferramenta essencial para criar ambientes de desenvolvimento reprodutíveis e para CI/CD. Este guia mostra como usar o Zig em containers Docker, desde o uso de imagens prontas até a criação de Dockerfiles otimizados para seus projetos.

Se você está instalando o Zig diretamente no sistema, consulte os guias para Ubuntu, Fedora, macOS ou Windows. Para uma visão geral, visite o guia completo de instalação.


Início Rápido

Para testar o Zig rapidamente em um container Docker sem instalar nada no seu sistema:

docker run --rm -it debian:bookworm-slim bash -c "
  apt-get update && apt-get install -y curl xz-utils &&
  curl -LO https://ziglang.org/download/0.14.0/zig-linux-x86_64-0.14.0.tar.xz &&
  tar -xf zig-linux-x86_64-0.14.0.tar.xz &&
  ./zig-linux-x86_64-0.14.0/zig version
"

Isso é útil para testar rapidamente, mas para desenvolvimento real, vamos criar Dockerfiles apropriados.


Dockerfile Básico para Desenvolvimento

Este Dockerfile cria uma imagem com o Zig pronto para uso:

FROM debian:bookworm-slim AS base

ARG ZIG_VERSION=0.14.0
ARG TARGETARCH

# Instalar dependências mínimas
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        curl \
        xz-utils \
        ca-certificates \
    && rm -rf /var/lib/apt/lists/*

# Determinar a arquitetura e baixar o Zig
RUN case "${TARGETARCH}" in \
        amd64) ZIG_ARCH="x86_64" ;; \
        arm64) ZIG_ARCH="aarch64" ;; \
        *) echo "Arquitetura não suportada: ${TARGETARCH}" && exit 1 ;; \
    esac && \
    curl -LO "https://ziglang.org/download/${ZIG_VERSION}/zig-linux-${ZIG_ARCH}-${ZIG_VERSION}.tar.xz" && \
    tar -xf "zig-linux-${ZIG_ARCH}-${ZIG_VERSION}.tar.xz" && \
    mv "zig-linux-${ZIG_ARCH}-${ZIG_VERSION}" /opt/zig && \
    rm "zig-linux-${ZIG_ARCH}-${ZIG_VERSION}.tar.xz"

ENV PATH="/opt/zig:${PATH}"

# Verificar instalação
RUN zig version

WORKDIR /app

CMD ["zig", "version"]

Construir e Executar

docker build -t zig-dev .
docker run --rm -it -v $(pwd):/app zig-dev zig build

Dockerfile Multi-Stage para Produção

O multi-stage build permite criar imagens finais extremamente pequenas, contendo apenas o binário compilado:

# Estágio 1: Compilação
FROM debian:bookworm-slim AS builder

ARG ZIG_VERSION=0.14.0

RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        curl xz-utils ca-certificates \
    && rm -rf /var/lib/apt/lists/*

RUN curl -LO "https://ziglang.org/download/${ZIG_VERSION}/zig-linux-x86_64-${ZIG_VERSION}.tar.xz" && \
    tar -xf "zig-linux-x86_64-${ZIG_VERSION}.tar.xz" && \
    mv "zig-linux-x86_64-${ZIG_VERSION}" /opt/zig && \
    rm "zig-linux-x86_64-${ZIG_VERSION}.tar.xz"

ENV PATH="/opt/zig:${PATH}"

WORKDIR /build
COPY . .

# Compilar com otimizações para release
RUN zig build -Doptimize=.ReleaseSafe

# Estágio 2: Imagem final mínima
FROM debian:bookworm-slim AS runtime

# Copiar apenas o binário compilado
COPY --from=builder /build/zig-out/bin/meu-app /usr/local/bin/meu-app

# Criar usuário não-root
RUN useradd -r -s /bin/false appuser
USER appuser

ENTRYPOINT ["/usr/local/bin/meu-app"]

Imagem Ainda Menor com scratch

Como o Zig pode gerar binários estáticos sem dependências, podemos usar a imagem scratch (vazia):

# Estágio 1: Compilação
FROM debian:bookworm-slim AS builder

ARG ZIG_VERSION=0.14.0

RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        curl xz-utils ca-certificates \
    && rm -rf /var/lib/apt/lists/*

RUN curl -LO "https://ziglang.org/download/${ZIG_VERSION}/zig-linux-x86_64-${ZIG_VERSION}.tar.xz" && \
    tar -xf "zig-linux-x86_64-${ZIG_VERSION}.tar.xz" && \
    mv "zig-linux-x86_64-${ZIG_VERSION}" /opt/zig && \
    rm "zig-linux-x86_64-${ZIG_VERSION}.tar.xz"

ENV PATH="/opt/zig:${PATH}"

WORKDIR /build
COPY . .

# Compilar como binário estático
RUN zig build -Doptimize=.ReleaseSmall

# Estágio 2: Imagem mínima absoluta
FROM scratch

COPY --from=builder /build/zig-out/bin/meu-app /meu-app

ENTRYPOINT ["/meu-app"]

A imagem final terá apenas o tamanho do binário compilado (geralmente poucos MBs).


Docker Compose para Desenvolvimento

Para projetos mais complexos, use Docker Compose para definir o ambiente de desenvolvimento:

# docker-compose.yml
version: '3.8'

services:
  zig-dev:
    build:
      context: .
      dockerfile: Dockerfile.dev
    volumes:
      - .:/app
      - zig-cache:/app/zig-cache
    working_dir: /app
    command: ["zig", "build", "run"]

  zig-test:
    build:
      context: .
      dockerfile: Dockerfile.dev
    volumes:
      - .:/app
      - zig-cache:/app/zig-cache
    working_dir: /app
    command: ["zig", "build", "test"]

volumes:
  zig-cache:

O Dockerfile.dev correspondente:

FROM debian:bookworm-slim

ARG ZIG_VERSION=0.14.0

RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        curl xz-utils ca-certificates git \
    && rm -rf /var/lib/apt/lists/*

RUN curl -LO "https://ziglang.org/download/${ZIG_VERSION}/zig-linux-x86_64-${ZIG_VERSION}.tar.xz" && \
    tar -xf "zig-linux-x86_64-${ZIG_VERSION}.tar.xz" && \
    mv "zig-linux-x86_64-${ZIG_VERSION}" /opt/zig && \
    rm "zig-linux-x86_64-${ZIG_VERSION}.tar.xz"

ENV PATH="/opt/zig:${PATH}"

WORKDIR /app

Usar o Docker Compose

# Compilar e executar
docker compose run --rm zig-dev

# Executar testes
docker compose run --rm zig-test

# Shell interativo
docker compose run --rm zig-dev bash

Otimizações de Cache no Docker

Cache do Zig Build

O Zig mantém um cache de compilação que pode acelerar significativamente builds subsequentes. Use volumes nomeados para persistir o cache:

# No Dockerfile
ENV ZIG_GLOBAL_CACHE_DIR=/tmp/zig-cache

# No docker-compose.yml, monte um volume para o cache
volumes:
  - zig-cache:/tmp/zig-cache

Cache de Camadas do Docker

Organize o Dockerfile para maximizar o cache de camadas:

FROM debian:bookworm-slim AS builder

ARG ZIG_VERSION=0.14.0

# Camada 1: Dependências do sistema (raramente muda)
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        curl xz-utils ca-certificates \
    && rm -rf /var/lib/apt/lists/*

# Camada 2: Instalação do Zig (muda apenas com nova versão)
RUN curl -LO "https://ziglang.org/download/${ZIG_VERSION}/zig-linux-x86_64-${ZIG_VERSION}.tar.xz" && \
    tar -xf "zig-linux-x86_64-${ZIG_VERSION}.tar.xz" && \
    mv "zig-linux-x86_64-${ZIG_VERSION}" /opt/zig && \
    rm "zig-linux-x86_64-${ZIG_VERSION}.tar.xz"

ENV PATH="/opt/zig:${PATH}"

WORKDIR /build

# Camada 3: build.zig (muda com menos frequência que o código)
COPY build.zig build.zig.zon ./

# Camada 4: Código-fonte (muda frequentemente)
COPY src/ src/

# Camada 5: Compilação
RUN zig build -Doptimize=.ReleaseSafe

Cross-Compilation com Docker

O Zig tem suporte nativo a cross-compilation, o que combinado com Docker multi-platform, permite criar imagens para diferentes arquiteturas:

# Criar builder multi-platform
docker buildx create --name zigbuilder --use

# Compilar para múltiplas arquiteturas
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t meu-usuario/minha-app:latest \
  --push .

O Dockerfile com suporte a multi-platform:

FROM --platform=$BUILDPLATFORM debian:bookworm-slim AS builder

ARG ZIG_VERSION=0.14.0
ARG BUILDPLATFORM
ARG TARGETPLATFORM
ARG TARGETOS
ARG TARGETARCH

RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        curl xz-utils ca-certificates \
    && rm -rf /var/lib/apt/lists/*

# Instalar Zig para a plataforma de build
RUN case "$(uname -m)" in \
        x86_64) ZIG_ARCH="x86_64" ;; \
        aarch64) ZIG_ARCH="aarch64" ;; \
    esac && \
    curl -LO "https://ziglang.org/download/${ZIG_VERSION}/zig-linux-${ZIG_ARCH}-${ZIG_VERSION}.tar.xz" && \
    tar -xf "zig-linux-${ZIG_ARCH}-${ZIG_VERSION}.tar.xz" && \
    mv "zig-linux-${ZIG_ARCH}-${ZIG_VERSION}" /opt/zig && \
    rm "zig-linux-${ZIG_ARCH}-${ZIG_VERSION}.tar.xz"

ENV PATH="/opt/zig:${PATH}"

WORKDIR /build
COPY . .

# Cross-compilar para a plataforma alvo usando Zig
RUN case "${TARGETARCH}" in \
        amd64) ZIG_TARGET="x86_64-linux-musl" ;; \
        arm64) ZIG_TARGET="aarch64-linux-musl" ;; \
    esac && \
    zig build -Doptimize=.ReleaseSafe -Dtarget="${ZIG_TARGET}"

FROM scratch
COPY --from=builder /build/zig-out/bin/meu-app /meu-app
ENTRYPOINT ["/meu-app"]

Exemplo Completo: API HTTP com Zig e Docker

Vamos criar um exemplo completo de uma API HTTP simples usando Zig dentro de um container Docker.

Arquivo src/main.zig:

const std = @import("std");
const net = std.net;

pub fn main() !void {
    const address = net.Address.parseIp("0.0.0.0", 8080) catch unreachable;
    var server = try address.listen(.{ .reuse_address = true });
    defer server.deinit();

    std.debug.print("Servidor rodando em http://0.0.0.0:8080\n", .{});

    while (true) {
        var connection = try server.accept();
        defer connection.stream.close();

        var buf: [1024]u8 = undefined;
        _ = try connection.stream.read(&buf);

        const response = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nOla do Zig no Docker!\n";
        _ = try connection.stream.write(response);
    }
}

O Dockerfile:

FROM debian:bookworm-slim AS builder

ARG ZIG_VERSION=0.14.0
RUN apt-get update && apt-get install -y --no-install-recommends curl xz-utils ca-certificates && rm -rf /var/lib/apt/lists/*
RUN curl -LO "https://ziglang.org/download/${ZIG_VERSION}/zig-linux-x86_64-${ZIG_VERSION}.tar.xz" && \
    tar -xf "zig-linux-x86_64-${ZIG_VERSION}.tar.xz" && mv "zig-linux-x86_64-${ZIG_VERSION}" /opt/zig
ENV PATH="/opt/zig:${PATH}"

WORKDIR /build
COPY . .
RUN zig build -Doptimize=.ReleaseSafe

FROM scratch
COPY --from=builder /build/zig-out/bin/server /server
EXPOSE 8080
ENTRYPOINT ["/server"]
docker build -t zig-server .
docker run --rm -p 8080:8080 zig-server

Problemas Comuns com Docker

Build lento

Use o cache de camadas do Docker e volumes nomeados para o cache do Zig, conforme descrito na seção de otimizações.

Erro de permissão com volumes

Se encontrar erros de permissão ao usar volumes montados:

docker run --rm -it -u $(id -u):$(id -g) -v $(pwd):/app zig-dev zig build

Imagem muito grande

Use multi-stage builds e a imagem scratch para reduzir o tamanho da imagem final.

Para mais soluções, visite nossa página de erros comuns.


Próximos Passos

Continue aprendendo Zig

Explore mais tutoriais e artigos em português para dominar a linguagem Zig.