Executando verificação de segurança...
1

Manipular arquivos em container com Golang

🚀 Enviando Arquivos para o S3 com Go: Dinâmico em Memória vs. Arquivo no Filesystem

Durante um experimento recente, explorei duas formas diferentes de gerar e enviar arquivos JSON para um bucket S3 usando uma aplicação escrita em Go, empacotada em Docker. O objetivo era simples: entender as vantagens e implicações de trabalhar com dados em memória versus arquivos físicos no container.

💡 Objetivo

  1. Criar um endpoint HTTP (/envia) que, quando acessado:
  2. Gera um arquivo JSON com dados simulados (nome, idade);
  3. Envia esse arquivo para um bucket S3 da AWS;

🧪 Primeira abordagem: geração dinâmica em memória

A primeira implementação construiu o conteúdo JSON diretamente na memória, utilizando um strings.NewReader() para enviá-lo ao S3 sem criar um arquivo físico.

data := `{"nome": "Renato", "idade": 35}`
_, err = s3Client.PutObject(ctx, &s3.PutObjectInput{
    Bucket: &bucket,
    Key:    pointer("arquivo-temporario.json"),
    Body:   strings.NewReader(data),
})

Vantagens:

Não escreve no disco;

Mais performático para payloads pequenos;

Código mais enxuto.

Desvantagens:

Menos flexível se quisermos reutilizar o arquivo, validar ou logar em disco;

Para arquivos grandes, consome mais memória RAM.

🧪 Segunda abordagem: geração no filesystem (/tmp)

Na segunda versão, escolhi salvar o conteúdo JSON fisicamente no container, em /tmp/arquivo-temporario.json, e somente depois fazer a leitura desse arquivo para upload.

err := os.WriteFile("/tmp/arquivo-temporario.json", []byte(data), 0644)
file, err := os.Open("/tmp/arquivo-temporario.json")

_, err = s3Client.PutObject(ctx, &s3.PutObjectInput{
    Bucket: &bucket,
    Key:    pointer("arquivo-temporario.json"),
    Body:   file,
})

Vantagens:

Arquivo pode ser validado antes do envio;

Facilita testes, logs e debug;

Ideal para cenários em que o arquivo é gerado por outra ferramenta (ex: conversão de imagem, relatório, etc.).

Desvantagens:

Maior uso de disco;

Exige mais manipulação de arquivos (criar, abrir, fechar, remover).

🐳 Empacotando tudo com Docker

A aplicação foi empacotada com um Dockerfile multi-stage, utilizando a imagem distroless para segurança e leveza. O binário Go foi compilado estaticamente (CGO_ENABLED=0), o que garantiu compatibilidade e independência de bibliotecas do sistema, como glibc.

🔥 Conclusão

Esses dois métodos atendem a diferentes casos de uso:

  • Para dados pequenos e envio rápido: use memória.
  • Para arquivos grandes ou reutilizáveis: salve no disco.
  • Ambos são válidos — e o mais importante é entender o impacto de cada escolha em termos de performance, segurança e controle.

Se quiser o código completo, segue o github do repositório com tudo configurado: main.go, Dockerfile, .gitignore, README.md e mais.

Carregando publicação patrocinada...
2

Tenho uma aplicação que baixa arquivos de um bucket e processa. Os arquivos podem ter até 4GiB, o processo é exatamente esse:

  • Baixa do bucket para a pasta /tmp
  • Processa o arquivo local
  • Salva um segundo arquivo resultante (imagem) em disco
  • envia do disco para o bucket