<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rafael Pazini</title>
    <description>The latest articles on DEV Community by Rafael Pazini (@rflpazini).</description>
    <link>https://dev.to/rflpazini</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F352329%2F543a1808-e43e-4ce5-a72f-ebffc233c918.jpeg</url>
      <title>DEV Community: Rafael Pazini</title>
      <link>https://dev.to/rflpazini</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rflpazini"/>
    <language>en</language>
    <item>
      <title>Meu Claude tem memória agora: e foi mais simples do que parece</title>
      <dc:creator>Rafael Pazini</dc:creator>
      <pubDate>Tue, 07 Apr 2026 02:18:48 +0000</pubDate>
      <link>https://dev.to/rflpazini/meu-claude-tem-memoria-agora-e-foi-mais-simples-do-que-parece-12cj</link>
      <guid>https://dev.to/rflpazini/meu-claude-tem-memoria-agora-e-foi-mais-simples-do-que-parece-12cj</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Claude Code tem três camadas de memória. A maioria dos devs usa só uma. Li o artigo do &lt;a href="https://x.com/artemxtech/status/2040591653061197847" rel="noopener noreferrer"&gt;Artem Zhutov&lt;/a&gt; que explica as três, mas ao invés de implementar tudo do zero, descobri que já tinha 90% do sistema montado. Só faltava conectar as peças. Aqui está exatamente o que eu fiz.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Eu estava no meio de uma sessão de code review quando o Claude me perguntou pela terceira vez na semana se eu preferia &lt;code&gt;testify/mock&lt;/code&gt; ou &lt;code&gt;uber-go/mock&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Eu já tinha corrigido isso. Duas vezes. Em sessões diferentes.&lt;/p&gt;

&lt;p&gt;O problema não era o Claude. Era eu, tratando ele como uma ferramenta que reseta toda vez, em vez de um colaborador que aprende. Então fui entender melhor como funciona a memória do Claude Code. E aí encontrei o artigo do Artem, que documentou algo que a maioria dos devs não sabe que existe.&lt;/p&gt;




&lt;h2&gt;
  
  
  As três camadas de memória
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Camada 1: CLAUDE.md&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Você escreve, você mantém. Regras fixas, contexto do projeto, stack, pessoas-chave. O problema: cresce rápido, fica defasado mais rápido ainda. O meu tinha chegado em 180 linhas. O Claude claramente não estava lendo por completo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Camada 2: Auto-memory&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O Claude escreve suas próprias preferências. Você corrige uma vez, ele salva em &lt;code&gt;~/.claude/memory/&lt;/code&gt; e carrega nas sessões seguintes. Cada arquivo captura um padrão ou preferência específica.&lt;/p&gt;

&lt;p&gt;Para ativar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude        &lt;span class="c"&gt;# abre o Claude Code&lt;/span&gt;
/memory       &lt;span class="c"&gt;# abre o menu de configurações de memória&lt;/span&gt;
              &lt;span class="c"&gt;# -&amp;gt; toggle "Auto-memory" ON&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Camada 3: Auto-dream&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Roda em background a cada 24h. Lê os transcripts de conversa locais, consolida memórias, remove as defasadas, converte datas relativas em absolutas. É um &lt;code&gt;VACUUM&lt;/code&gt; no banco de dados do seu agente. Você ativa e esquece.&lt;/p&gt;

&lt;p&gt;Para ativar: mesmo menu &lt;code&gt;/memory&lt;/code&gt;, toggle "Auto-dream" ON.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;O auto-dream não exige configuração. Roda à meia-noite, limpa o que ficou defasado, e na manhã seguinte o contexto está mais preciso.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  O que o auto-dream faz na prática
&lt;/h2&gt;

&lt;p&gt;Aqui está o que acontece quando o auto-dream roda.&lt;/p&gt;

&lt;p&gt;Ele lê os arquivos de memória do projeto em &lt;code&gt;~/.claude/projects/&amp;lt;projeto&amp;gt;/memory/&lt;/code&gt; e faz quatro coisas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Mescla entradas redundantes:&lt;/strong&gt; se você corrigiu o mesmo comportamento duas vezes em sessões diferentes, o auto-dream consolida as duas notas em uma.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remove contexto defasado:&lt;/strong&gt; se você finalizou uma migração, a memória "migração em andamento" some. O Claude para de mencionar algo que já não existe.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Converte datas relativas em absolutas:&lt;/strong&gt; "ontem decidimos X" vira "2026-04-05: decidimos X". Fundamental para que as memórias façam sentido depois de semanas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reorganiza para facilitar a busca:&lt;/strong&gt; entradas soltas viram arquivos organizados por tema.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;O efeito prático: cada sessão começa com um contexto mais limpo. Sem aquele ruído acumulado de decisões antigas que já foram revertidas, ou de contexto de projeto que mudou há duas semanas.&lt;/p&gt;

&lt;p&gt;Um exemplo concreto: imagine que você está migrando o hash de senhas de MD5 para bcrypt. Durante três sessões, o Claude carrega o contexto "migration in progress: replace MD5 with bcrypt across user service". Na quarta sessão, você finaliza e faz o merge. O auto-dream lê que a tarefa foi concluída e substitui a memória por "bcrypt migration completed 2026-04-03, MD5 fully removed from user service". Na quinta sessão, o Claude já sabe que a migração terminou, sem você precisar mencionar.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Gotcha:&lt;/strong&gt; O auto-dream tem dois gatilhos: tempo suficiente passado e sessões suficientes acumuladas. Ele não roda depois de uma única sessão longa, nem depois de dez sessões rápidas em duas horas. Se você quiser disparar manualmente, use o comando &lt;code&gt;/dream&lt;/code&gt; no Claude Code.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  O que eu já tinha e não sabia
&lt;/h2&gt;

&lt;p&gt;Aqui está a parte que o artigo do Artem não cobre, porque é específica da minha configuração.&lt;/p&gt;

&lt;p&gt;Eu já tinha um diretório &lt;code&gt;~/.claude/rules/common/&lt;/code&gt; com 11 arquivos organizados por tema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/.claude/rules/common/
├── coding-style.md         &amp;lt;- imutabilidade, organização de arquivos
├── testing.md              &amp;lt;- TDD, cobertura, tipos de teste
├── git-workflow.md         &amp;lt;- formato de commit, processo de PR
├── security.md             &amp;lt;- checklist de segurança
├── performance.md          &amp;lt;- seleção de modelo, contexto
├── patterns.md             &amp;lt;- Repository Pattern, API response format
├── agents.md               &amp;lt;- orquestração de agentes
├── hooks.md                &amp;lt;- tipos de hook, boas práticas de auto-accept
├── open-pr.md              &amp;lt;- checklist de PR, sempre draft
├── development-workflow.md
└── always-works.md         &amp;lt;- TDD + coverage gate + verificação
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esses arquivos já eram minha Camada 1, só que melhor organizada que um CLAUDE.md monolítico. Cada sessão carregava o contexto relevante com alta coesão e baixo acoplamento.&lt;/p&gt;

&lt;p&gt;O que estava faltando: uma forma de &lt;strong&gt;alimentar esses arquivos com o que acontecia nas sessões&lt;/strong&gt;, sem fazer isso manualmente.&lt;/p&gt;




&lt;h2&gt;
  
  
  A solução: o &lt;code&gt;/retro&lt;/code&gt; simplificado
&lt;/h2&gt;

&lt;p&gt;O Artem propõe um skill de retrospectiva que cria arquivos novos de memória a cada sessão. O que eu fiz foi diferente: adaptei o &lt;code&gt;/retro&lt;/code&gt; para classificar o que aprendeu na sessão e decidir onde salva. Memória de projeto ou regras globais que já existem.&lt;/p&gt;

&lt;p&gt;O skill em &lt;code&gt;~/.claude/skills/retro/SKILL.md&lt;/code&gt; (estrutura simplificada):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Session Retrospective&lt;/span&gt;

Reviews the session and does two things:
&lt;span class="p"&gt;1.&lt;/span&gt; Proposes memory updates (corrections, preferences, decisions)
&lt;span class="p"&gt;2.&lt;/span&gt; Exports a session summary to the Obsidian vault

&lt;span class="gu"&gt;## Step 1: Extract signals&lt;/span&gt;

Categorize findings:
&lt;span class="p"&gt;-&lt;/span&gt; Corrections: what the user corrected and what they wanted instead
&lt;span class="p"&gt;-&lt;/span&gt; Confirmed patterns: what worked on the first try
&lt;span class="p"&gt;-&lt;/span&gt; Redos: what had to be redone and why
&lt;span class="p"&gt;-&lt;/span&gt; New decisions: architecture or workflow choices

&lt;span class="gu"&gt;## Step 2: Classify scope&lt;/span&gt;

For each signal, decide where to save:

Project memory: specific to this codebase
-&amp;gt; ~/.claude/projects/&lt;span class="nt"&gt;&amp;lt;project&amp;gt;&lt;/span&gt;/memory/

Global rule: applies to ALL projects
-&amp;gt; append to ~/.claude/rules/common/&lt;span class="nt"&gt;&amp;lt;relevant-file&amp;gt;&lt;/span&gt;.md
-&amp;gt; never create a new file. Only update existing ones.

&lt;span class="gu"&gt;## Step 3: Present and wait for approval&lt;/span&gt;

Show findings table and wait for approval before writing.

| # | Type       | Finding                                   | Proposed action | Scope                |
|---|------------|-------------------------------------------|-----------------|----------------------|
| 1 | correction | Used testify/mock instead of uber-go/mock | Update rule     | global: testing.md   |
| 2 | decision   | Chose Redis Streams for queues            | Create memory   | project: minha-api   |
| 3 | confirmed  | Commit format was correct                 | No action       | -                    |

&lt;span class="gu"&gt;## Step 4: Export session to vault&lt;/span&gt;

Writes to:
~/Documents/rflpazini/sessions/YYYY-MM-DD-&lt;span class="nt"&gt;&amp;lt;project&amp;gt;&lt;/span&gt;-&lt;span class="nt"&gt;&amp;lt;topic&amp;gt;&lt;/span&gt;.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O ponto central: ao invés de criar uma nova camada de arquivos, o &lt;code&gt;/retro&lt;/code&gt; &lt;strong&gt;alimenta o knowledge base que já existe&lt;/strong&gt;. Correções de comportamento global vão para &lt;code&gt;testing.md&lt;/code&gt;, &lt;code&gt;coding-style.md&lt;/code&gt; ou &lt;code&gt;git-workflow.md&lt;/code&gt;, dependendo do assunto. Decisões específicas vão para a memória do projeto.&lt;/p&gt;




&lt;h2&gt;
  
  
  A observabilidade pelo &lt;a href="https://obsidian.md/" rel="noopener noreferrer"&gt;Obsidian&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Aqui entra o &lt;a href="https://github.com/breferrari/obsidian-mind" rel="noopener noreferrer"&gt;obsidian-mind&lt;/a&gt;: um projeto open-source que transforma seu vault Obsidian num segundo cérebro para o Claude Code, com CLAUDE.md configurado, hooks, slash commands e uma estrutura pensada para capturar contexto de trabalho.&lt;/p&gt;

&lt;p&gt;Ao setup padrão eu adicionei três coisas:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Pasta &lt;code&gt;sessions/&lt;/code&gt; para histórico cross-project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Cada sessão vira um arquivo com: objetivo, o que foi feito, decisões, aprendizados, próximos passos. O &lt;code&gt;/retro&lt;/code&gt; escreve isso automaticamente. Exemplo de como fica:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Session:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;minha-api&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;kafka-consumer"&lt;/span&gt;
&lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2026-04-05&lt;/span&gt;
&lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;session&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;minha-api&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;project&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[[minha-api]]"&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gu"&gt;## Goal&lt;/span&gt;
Implementar o consumer Kafka async com DLQ imediato, sem retry.

&lt;span class="gu"&gt;## What Got Done&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Consumer async configurado com ack-mode RECORD
&lt;span class="p"&gt;-&lt;/span&gt; DLQ publishing manual implementado no error handler
&lt;span class="p"&gt;-&lt;/span&gt; Testes de integração passando

&lt;span class="gu"&gt;## Decisions Made&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; AbortPolicy + DLQ imediato: CallerRunsPolicy bloqueava o poll thread do Kafka
&lt;span class="p"&gt;-&lt;/span&gt; ack-mode RECORD, não BATCH: BATCH commita offsets antes das tasks completarem

&lt;span class="gu"&gt;## Learnings&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Container-level error handler e DLQ manual ativos ao mesmo tempo causam duplicação
&lt;span class="p"&gt;-&lt;/span&gt; Testar com consumer group real antes de fazer PR

&lt;span class="gu"&gt;## Next Steps&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Revisar configuração de timeout do executor
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Abrir PR após code review
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Symlink das memórias de projeto no vault&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# ~/.claude/scripts/sync-memories-to-vault.sh&lt;/span&gt;
&lt;span class="c"&gt;# Cria symlinks de ~/.claude/projects/*/memory/ para o vault Obsidian&lt;/span&gt;
&lt;span class="c"&gt;# Roda automaticamente após o /retro&lt;/span&gt;

&lt;span class="nv"&gt;VAULT_MEMORY_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/Library/Mobile Documents/iCloud~md~obsidian/Documents/rflpazini/claude/memories"&lt;/span&gt;
&lt;span class="nv"&gt;CLAUDE_PROJECTS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.claude/projects"&lt;/span&gt;

&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VAULT_MEMORY_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

clean_name&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;raw&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$raw&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
    &lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="nt"&gt;-minha-api&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"minha-api"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    &lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="nt"&gt;-outro-projeto&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"outro-projeto"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    &lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="nt"&gt;-obsidian-mind&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"obsidian-mind"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    &lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$raw&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/^-Users-seuusuario-//'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/^Documents-Development-//'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="s1"&gt;'[:upper:]'&lt;/span&gt; &lt;span class="s1"&gt;'[:lower:]'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/^-//'&lt;/span&gt;
      &lt;span class="p"&gt;;;&lt;/span&gt;
  &lt;span class="k"&gt;esac&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nv"&gt;created&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0
&lt;span class="nv"&gt;skipped&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0

&lt;span class="k"&gt;for &lt;/span&gt;memory_dir &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CLAUDE_PROJECTS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;/&lt;span class="k"&gt;*&lt;/span&gt;/memory&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$memory_dir&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="k"&gt;continue
  &lt;/span&gt;&lt;span class="nv"&gt;project_dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;dirname&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$memory_dir&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | xargs &lt;span class="nb"&gt;basename&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;clean_name &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$project_dir&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="nv"&gt;link_path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VAULT_MEMORY_DIR&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$link_path&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$link_path&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nv"&gt;skipped&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;skipped &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;))&lt;/span&gt;
  &lt;span class="k"&gt;else
    &lt;/span&gt;&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$memory_dir&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$link_path&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="nv"&gt;created&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;created &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;))&lt;/span&gt;
  &lt;span class="k"&gt;fi
done

&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"done. created=&lt;/span&gt;&lt;span class="nv"&gt;$created&lt;/span&gt;&lt;span class="s2"&gt; skipped=&lt;/span&gt;&lt;span class="nv"&gt;$skipped&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cada memória de projeto aparece como arquivo navegável no Obsidian. Você vê, edita ou apaga direto pelo painel lateral, sem precisar abrir o terminal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Base view &lt;code&gt;Sessions.base&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Uma view Obsidian que lista todas as sessões por projeto, ordenadas por data. Quando começo uma sessão nova, abro essa view e vejo em 10 segundos o contexto da última vez que trabalhei naquele projeto.&lt;/p&gt;




&lt;h2&gt;
  
  
  O que não implementei (e por quê)
&lt;/h2&gt;

&lt;p&gt;O artigo do Artem sugere mais coisas: QMD para busca semântica, dashboards por área de vida, session auto-export hooks, LLM Wiki.&lt;/p&gt;

&lt;p&gt;Não implementei nenhuma. O vault tinha 50 arquivos no momento. QMD resolve um problema de busca que ainda não existe. Dashboards adicionam fricção de manutenção antes de gerar valor.&lt;/p&gt;

&lt;p&gt;A regra que usei: &lt;strong&gt;cada adição foi avaliada pela fricção que criava, não pelo potencial teórico&lt;/strong&gt;. Se não resolvia um problema que eu tinha hoje, ficou de fora.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Gotcha:&lt;/strong&gt; Auto-memory é estritamente scoped por projeto. Não existe auto-memory global. Preferências que devem valer em todos os projetos precisam ir para &lt;code&gt;~/.claude/rules/common/&lt;/code&gt;, via &lt;code&gt;/retro&lt;/code&gt; ou manualmente. O artigo original não deixa isso claro.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Como fica o loop na prática
&lt;/h2&gt;

&lt;p&gt;Segunda-feira de manhã. Abro o terminal, &lt;code&gt;claude&lt;/code&gt;, começo a trabalhar.&lt;/p&gt;

&lt;p&gt;O hook &lt;code&gt;SessionStart&lt;/code&gt; injeta automaticamente: data de hoje, objetivos atuais, projetos ativos, listagem de arquivos do vault. Não preciso explicar contexto nenhum.&lt;/p&gt;

&lt;p&gt;Trabalho a sessão. No final: &lt;code&gt;/retro&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;O Claude monta a tabela de achados com escopo sugerido e aguarda minha aprovação. Aprovo: ele faz append em &lt;code&gt;testing.md&lt;/code&gt; para a regra de mock, cria arquivo em &lt;code&gt;~/.claude/projects/minha-api/memory/&lt;/code&gt; para o contexto específico, e escreve o resumo em &lt;code&gt;rflpazini/sessions/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Encerro o terminal. De noite, o auto-dream consolida, remove o que ficou defasado.&lt;/p&gt;

&lt;p&gt;Na manhã seguinte, o Claude começa sabendo exatamente onde paramos.&lt;/p&gt;

&lt;p&gt;E esse é o resultado no Obsidian:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa9c1lfeq41kj4wqszjuc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa9c1lfeq41kj4wqszjuc.png" alt="Obsidian Graph View"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Como começar
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Mínimo viável (30 minutos):&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Instale o &lt;a href="https://github.com/breferrari/obsidian-mind" rel="noopener noreferrer"&gt;obsidian-mind&lt;/a&gt; ou abra o Claude Code dentro do seu vault Obsidian existente&lt;/li&gt;
&lt;li&gt;Ative auto-memory: &lt;code&gt;claude&lt;/code&gt; -&amp;gt; &lt;code&gt;/memory&lt;/code&gt; -&amp;gt; toggle ON&lt;/li&gt;
&lt;li&gt;Ative auto-dream: mesmo menu -&amp;gt; toggle ON&lt;/li&gt;
&lt;li&gt;Execute &lt;code&gt;/retro&lt;/code&gt; ao final das próximas 3 sessões&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Para o setup completo:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Organize seu CLAUDE.md em arquivos separados por tema em &lt;code&gt;~/.claude/rules/common/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Crie o skill &lt;code&gt;/retro&lt;/code&gt; com a estrutura acima&lt;/li&gt;
&lt;li&gt;Crie a pasta &lt;code&gt;sessions/&lt;/code&gt; no vault para histórico cross-project&lt;/li&gt;
&lt;li&gt;Configure o script &lt;code&gt;sync-memories-to-vault.sh&lt;/code&gt; para visibilidade das memórias no Obsidian&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;O Claude não vai parar de errar do dia para a noite. Mas cada correção que você faz uma vez não vai precisar ser repetida. Esse é o investimento: tempo decrescente de alinhamento, qualidade crescente de colaboração.&lt;/p&gt;

&lt;p&gt;Três semanas depois de configurar isso, as sessões começam sem aqueles 15 minutos de "deixa eu te explicar o contexto". O Claude chega sabendo.&lt;/p&gt;

&lt;p&gt;Crédito ao &lt;a href="https://x.com/artemxtech/status/2040591653061197847" rel="noopener noreferrer"&gt;Artem Zhutov&lt;/a&gt; pela documentação das três camadas. O que eu fiz foi simplificar a implementação aproveitando o que já existia.&lt;/p&gt;

&lt;p&gt;e também ao &lt;a href="https://x.com/brennoferrari" rel="noopener noreferrer"&gt;Brenno Ferrari&lt;/a&gt; pelo &lt;a href="https://github.com/breferrari/obsidian-mind" rel="noopener noreferrer"&gt;obsidian-mind&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Testa, roda o &lt;code&gt;/retro&lt;/code&gt; nas próximas sessões, e me conta o que apareceu na tabela de achados.&lt;/p&gt;

&lt;p&gt;Nos próximos dias, vou publicar as skills que utilizo no github :) &lt;/p&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>productivity</category>
      <category>programming</category>
    </item>
    <item>
      <title>Docker Compose + tmpfs: Armazenamento efêmero que sua aplicação</title>
      <dc:creator>Rafael Pazini</dc:creator>
      <pubDate>Tue, 10 Mar 2026 12:26:20 +0000</pubDate>
      <link>https://dev.to/rflpazini/docker-compose-tmpfs-armazenamento-efemero-que-sua-aplicacao-3afi</link>
      <guid>https://dev.to/rflpazini/docker-compose-tmpfs-armazenamento-efemero-que-sua-aplicacao-3afi</guid>
      <description>&lt;p&gt;Você já parou para pensar onde sua aplicação Go escreve arquivos temporários? &lt;code&gt;/tmp&lt;/code&gt;, cache de build, sessões, uploads intermediários... tudo isso vai parar em disco. E disco é lento. Não "lento para 2024" — lento mesmo, comparado com o que podemos fazer.&lt;/p&gt;

&lt;p&gt;Existe uma alternativa que a maioria dos devs ignora: &lt;strong&gt;tmpfs&lt;/strong&gt;. Um filesystem que mora na RAM, some quando o container reinicia, e é absurdamente rápido. É tipo aquele colega que resolve o problema na hora, mas não te manda e-mail depois — eficiente e efêmero.&lt;/p&gt;

&lt;p&gt;Vamos ver o que muda na prática e quando faz sentido usar.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; Os exemplos deste artigo usam Go 1.26, lançado em fevereiro de 2026. Uma das novidades dessa versão é o &lt;strong&gt;Green Tea GC habilitado por padrão&lt;/strong&gt; — o que torna a combinação com tmpfs ainda mais poderosa: menos alocações em disco + GC mais eficiente = serviços Go mais rápidos e previsíveis.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  O que é tmpfs, afinal?
&lt;/h2&gt;

&lt;p&gt;Tmpfs é um filesystem temporário que reside inteiramente na memória RAM:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⚡ &lt;strong&gt;Ultra-rápido&lt;/strong&gt; — velocidade de RAM, não de disco&lt;/li&gt;
&lt;li&gt;🔒 &lt;strong&gt;Seguro&lt;/strong&gt; — dados não persistem entre restarts&lt;/li&gt;
&lt;li&gt;🧹 &lt;strong&gt;Auto-limpante&lt;/strong&gt; — some sozinho quando o container para&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Parece mágica, mas é só o SO sendo inteligente. Linux já tem suporte nativo há décadas; o Docker Compose apenas expõe isso de forma limpa.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuração básica
&lt;/h2&gt;

&lt;p&gt;A forma mais simples de usar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myapp-go&lt;/span&gt;
    &lt;span class="na"&gt;tmpfs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/tmp&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/app/cache&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/var/run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com limite de tamanho (o que você definitivamente deveria fazer em produção):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myapp-go&lt;/span&gt;
    &lt;span class="na"&gt;tmpfs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/tmp:size=100M&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/app/cache:size=500M&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/var/run:size=10M&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sem o limite de tamanho, seu tmpfs pode consumir toda a RAM disponível. Isso é o tipo de surpresa que você não quer às 2h da manhã com o PagerDuty tocando.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuração avançada
&lt;/h2&gt;

&lt;p&gt;Para quem quer controle fino sobre permissões:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myapp-go&lt;/span&gt;
    &lt;span class="na"&gt;tmpfs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tmpfs&lt;/span&gt;
        &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/tmp&lt;/span&gt;
        &lt;span class="na"&gt;tmpfs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;100M&lt;/span&gt;
          &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1770&lt;/span&gt;    &lt;span class="c1"&gt;# permissões do diretório&lt;/span&gt;
          &lt;span class="na"&gt;uid&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1000&lt;/span&gt;     &lt;span class="c1"&gt;# usuário dono&lt;/span&gt;
          &lt;span class="na"&gt;gid&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1000&lt;/span&gt;     &lt;span class="c1"&gt;# grupo dono&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ou usando a sintaxe de &lt;code&gt;volumes&lt;/code&gt; (mais verbosa, mas mais explícita):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myapp-go&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tmpfs&lt;/span&gt;
        &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/app/temp&lt;/span&gt;
        &lt;span class="na"&gt;tmpfs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;200000000&lt;/span&gt;  &lt;span class="c1"&gt;# 200MB em bytes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Casos de uso com Go: onde isso realmente brilha
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Cache de build Go
&lt;/h3&gt;

&lt;p&gt;Quem já esperou o &lt;code&gt;go build&lt;/code&gt; rodar dentro de um container sabe a dor. O cache de compilação do Go pode ser colocado em tmpfs para acelerar builds em CI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;golang:1.26&lt;/span&gt;
    &lt;span class="na"&gt;working_dir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/app&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;.:/app&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tmpfs&lt;/span&gt;
        &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/root/.cache/go-build&lt;/span&gt;
        &lt;span class="na"&gt;tmpfs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2G&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;go build ./...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Aviso:&lt;/strong&gt; o cache some quando o container para. Para CI eficiente, combine isso com um volume persistente para o cache entre pipelines. Para builds únicos dentro de um job, tmpfs é perfeito.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Uploads temporários em APIs Go
&lt;/h3&gt;

&lt;p&gt;Sua API Go recebe arquivos, processa e manda para S3? Não tem sentido escrever em disco se você vai deletar logo depois:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myapi-go&lt;/span&gt;
    &lt;span class="na"&gt;tmpfs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/tmp/uploads:size=2G,mode=1770&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;UPLOAD_DIR&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/tmp/uploads&lt;/span&gt;
      &lt;span class="na"&gt;MAX_UPLOAD_SIZE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;100M&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No código Go, basta ler a variável de ambiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"io"&lt;/span&gt;
    &lt;span class="s"&gt;"net/http"&lt;/span&gt;
    &lt;span class="s"&gt;"os"&lt;/span&gt;
    &lt;span class="s"&gt;"path/filepath"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;uploadDir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getEnv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"UPLOAD_DIR"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/tmp/uploads"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;getEnv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fallback&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fallback&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;uploadHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Method&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MethodPost&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"method not allowed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusMethodNotAllowed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MaxBytesReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// 100MB max&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ParseMultipartForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;32&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"file too large"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusBadRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FormFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"invalid file"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusBadRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// Escreve no tmpfs — rápido e sem deixar rastro&lt;/span&gt;
    &lt;span class="n"&gt;tmpPath&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uploadDir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmpPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"failed to save file"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusInternalServerError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmpPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// limpa após processar&lt;/span&gt;
    &lt;span class="p"&gt;}()&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dst&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"failed to write file"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusInternalServerError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Aqui você processaria e mandaria pro S3, por exemplo&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"arquivo %s processado com sucesso"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Banco de dados para testes
&lt;/h3&gt;

&lt;p&gt;Esse é o meu favorito. Rodar o banco de testes com dados em tmpfs é 3-5x mais rápido que em disco:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Banco de testes — rápido, dados não persistem (e não precisam)&lt;/span&gt;
  &lt;span class="na"&gt;test-db&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres:16&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;testdb&lt;/span&gt;
    &lt;span class="na"&gt;tmpfs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/var/lib/postgresql/data:size=1G&lt;/span&gt;
    &lt;span class="na"&gt;profiles&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;test"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

  &lt;span class="c1"&gt;# Banco de produção — persistente, como deve ser&lt;/span&gt;
  &lt;span class="na"&gt;prod-db&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres:16&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD_FILE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/run/secrets/db_password&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;postgres_data:/var/lib/postgresql/data&lt;/span&gt;
    &lt;span class="na"&gt;profiles&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prod"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;postgres_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em Go, seus testes de integração com Testcontainers ou docker compose ficam muito mais ágeis. Se você ainda não usa Testcontainers em Go, dá uma olhada no &lt;a href="https://dev.to/rflpazini/testcontainers-golang-melhorando-seus-testes-com-docker-2hb7"&gt;artigo que escrevi sobre isso&lt;/a&gt; — a combinação com tmpfs é poderosa.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Segurança: filesystem read-only com exceções tmpfs
&lt;/h3&gt;

&lt;p&gt;Esse padrão é subestimado. Você torna o filesystem inteiro read-only e usa tmpfs apenas para os diretórios que precisam de escrita:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;secure-api&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myapi-go&lt;/span&gt;
    &lt;span class="na"&gt;read_only&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;          &lt;span class="c1"&gt;# filesystem inteiro somente leitura&lt;/span&gt;
    &lt;span class="na"&gt;tmpfs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/tmp:size=100M&lt;/span&gt;       &lt;span class="c1"&gt;# escrita permitida aqui&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/var/run:size=10M&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/app/cache:size=50M&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;app_logs:/var/log:rw&lt;/span&gt; &lt;span class="c1"&gt;# logs persistentes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para aplicações Go, isso é excelente. O binário compilado é estático — não precisa escrever em lugar nenhum além dos diretórios que você define explicitamente. É defense-in-depth sem custo nenhum.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benchmark: vendo a diferença
&lt;/h2&gt;

&lt;p&gt;Quer medir o ganho? Coloca isso no seu compose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;benchmark&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;golang:1.26-alpine&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
      &lt;span class="s"&gt;sh -c "&lt;/span&gt;
        &lt;span class="s"&gt;echo '=== Tmpfs Write Performance ==='&lt;/span&gt;
        &lt;span class="s"&gt;time dd if=/dev/zero of=/tmp/test bs=1M count=500 conv=fsync&lt;/span&gt;

        &lt;span class="s"&gt;echo ''&lt;/span&gt;
        &lt;span class="s"&gt;echo '=== Volume Write Performance ==='&lt;/span&gt;
        &lt;span class="s"&gt;time dd if=/dev/zero of=/data/test bs=1M count=500 conv=fsync&lt;/span&gt;
      &lt;span class="s"&gt;"&lt;/span&gt;
    &lt;span class="na"&gt;tmpfs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/tmp:size=1G&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;benchmark_data:/data&lt;/span&gt;

&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;benchmark_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em máquinas típicas de desenvolvimento, tmpfs é &lt;strong&gt;3 a 10x mais rápido&lt;/strong&gt; que um volume em disco. Em produção com SSDs NVMe, a diferença diminui, mas ainda é significativa para workloads de I/O intenso.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sizing dinâmico por ambiente
&lt;/h2&gt;

&lt;p&gt;Uma dica que uso nos meus projetos: tamanho de tmpfs configurável por ambiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myapi-go&lt;/span&gt;
    &lt;span class="na"&gt;tmpfs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/tmp:size=${TMPFS_SIZE:-100M}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/app/cache:size=${CACHE_SIZE:-200M}&lt;/span&gt;
    &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2G&lt;/span&gt;
        &lt;span class="na"&gt;reservations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1G&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E nos arquivos de ambiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# .env.development&lt;/span&gt;
&lt;span class="nv"&gt;TMPFS_SIZE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;500M
&lt;span class="nv"&gt;CACHE_SIZE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1G

&lt;span class="c"&gt;# .env.production&lt;/span&gt;
&lt;span class="nv"&gt;TMPFS_SIZE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2G
&lt;span class="nv"&gt;CACHE_SIZE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4G

&lt;span class="c"&gt;# .env.test&lt;/span&gt;
&lt;span class="nv"&gt;TMPFS_SIZE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;256M
&lt;span class="nv"&gt;CACHE_SIZE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;512M
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso é especialmente útil quando você tem a mesma stack rodando em máquinas com capacidades de RAM diferentes — CI com 8GB, produção com 32GB, máquina local com 16GB.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monitorando o uso
&lt;/h2&gt;

&lt;p&gt;Não vai querer descobrir que o tmpfs estourou em produção. Monitore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Verificar uso de tmpfs em um container específico&lt;/span&gt;
docker compose &lt;span class="nb"&gt;exec &lt;/span&gt;app &lt;span class="nb"&gt;df&lt;/span&gt; &lt;span class="nt"&gt;-h&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;tmpfs

&lt;span class="c"&gt;# Monitorar todos os containers&lt;/span&gt;
docker compose ps &lt;span class="nt"&gt;-q&lt;/span&gt; | xargs &lt;span class="nt"&gt;-I&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt; docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt; &lt;span class="nb"&gt;df&lt;/span&gt; &lt;span class="nt"&gt;-h&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;grep &lt;/span&gt;tmpfs

&lt;span class="c"&gt;# Ver impacto na memória do sistema&lt;/span&gt;
docker stats &lt;span class="nt"&gt;--no-stream&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No Go, você pode expor uma métrica de uso de &lt;code&gt;/tmp&lt;/code&gt; diretamente no seu endpoint de health check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;health&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"encoding/json"&lt;/span&gt;
    &lt;span class="s"&gt;"net/http"&lt;/span&gt;
    &lt;span class="s"&gt;"syscall"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;DiskStats&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Total&lt;/span&gt;     &lt;span class="kt"&gt;uint64&lt;/span&gt; &lt;span class="s"&gt;`json:"total_bytes"`&lt;/span&gt;
    &lt;span class="n"&gt;Free&lt;/span&gt;      &lt;span class="kt"&gt;uint64&lt;/span&gt; &lt;span class="s"&gt;`json:"free_bytes"`&lt;/span&gt;
    &lt;span class="n"&gt;Used&lt;/span&gt;      &lt;span class="kt"&gt;uint64&lt;/span&gt; &lt;span class="s"&gt;`json:"used_bytes"`&lt;/span&gt;
    &lt;span class="n"&gt;UsedPct&lt;/span&gt;   &lt;span class="kt"&gt;float64&lt;/span&gt; &lt;span class="s"&gt;`json:"used_pct"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TmpfsStats&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;DiskStats&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;stat&lt;/span&gt; &lt;span class="n"&gt;syscall&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Statfs_t&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;syscall&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Statfs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/tmp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;stat&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;stat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Blocks&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kt"&gt;uint64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bsize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;free&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;stat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bfree&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="kt"&gt;uint64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bsize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;used&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;free&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;DiskStats&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Total&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Free&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Used&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="n"&gt;used&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;UsedPct&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;used&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;HealthHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;TmpfsStats&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"failed to check tmpfs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusInternalServerError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"ok"&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;stats&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UsedPct&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;85&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"warning"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Content-Type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"application/json"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewEncoder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="n"&gt;any&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;"status"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"tmpfs"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="n"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Exemplos do mundo real
&lt;/h2&gt;

&lt;p&gt;Teoria é legal, mas vamos ver como tmpfs se encaixa em cenários que você provavelmente já viveu — ou vai viver.&lt;/p&gt;

&lt;h3&gt;
  
  
  LocalStack + tmpfs: desenvolvimento AWS sem custo e sem lentidão
&lt;/h3&gt;

&lt;p&gt;Se você já configurou o LocalStack para emular S3, DynamoDB, SQS localmente (tem um &lt;a href="https://dev.to/rflpazini/localstack-e-docker-como-aumentar-a-produtividade-no-desenvolvimento-local-sem-custos-m2c"&gt;artigo completo sobre isso aqui&lt;/a&gt;), sabe que o DynamoDB e o SQS escrevem dados temporários em disco durante os testes. Em ambiente de dev local, esses dados não precisam persistir entre restarts. É desperdício puro.&lt;/p&gt;

&lt;p&gt;A combinação tmpfs + LocalStack elimina esse overhead e faz o ambiente local rodar muito mais próximo da velocidade real:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;localstack&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;localstack/localstack:latest&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;localstack&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;4566:4566"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;SERVICES=dynamodb,sqs,s3&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DEBUG=0&lt;/span&gt;
    &lt;span class="c1"&gt;# Dados do LocalStack não precisam sobreviver ao restart em dev&lt;/span&gt;
    &lt;span class="na"&gt;tmpfs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/var/lib/localstack:size=1G&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/tmp/localstack:size=512M&lt;/span&gt;

  &lt;span class="c1"&gt;# Sua API Go apontando para o LocalStack&lt;/span&gt;
  &lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8080:8080"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;AWS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
      &lt;span class="na"&gt;AWS_SECRET_ACCESS_KEY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
      &lt;span class="na"&gt;AWS_ENDPOINT&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://localstack:4566&lt;/span&gt;
    &lt;span class="c1"&gt;# Uploads intermediários antes de mandar para o S3 "local"&lt;/span&gt;
    &lt;span class="na"&gt;tmpfs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/tmp/uploads:size=512M,mode=1770&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;localstack&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No código Go, a lógica do worker que consome a fila SQS e processa arquivos fica mais enxuta quando você sabe que o diretório temporário é RAM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;worker&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"context"&lt;/span&gt;
    &lt;span class="s"&gt;"encoding/json"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;
    &lt;span class="s"&gt;"os"&lt;/span&gt;
    &lt;span class="s"&gt;"path/filepath"&lt;/span&gt;

    &lt;span class="s"&gt;"github.com/aws/aws-sdk-go-v2/service/sqs"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;UploadMessage&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;UserID&lt;/span&gt;   &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"user_id"`&lt;/span&gt;
    &lt;span class="n"&gt;Filename&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"filename"`&lt;/span&gt;
    &lt;span class="n"&gt;Size&lt;/span&gt;     &lt;span class="kt"&gt;int64&lt;/span&gt;  &lt;span class="s"&gt;`json:"size"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;ProcessUploadQueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sqsClient&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;sqs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;queueURL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;uploadDir&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;sqsClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReceiveMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;sqs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReceiveMessageInput&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;QueueUrl&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;            &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;queueURL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;MaxNumberOfMessages&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;WaitTimeSeconds&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"receive error: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Messages&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="n"&gt;UploadMessage&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"unmarshal error: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;continue&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="c"&gt;// Arquivo temporário no tmpfs — processamento em RAM&lt;/span&gt;
            &lt;span class="n"&gt;tmpPath&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uploadDir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%s_%s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Filename&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

            &lt;span class="c"&gt;// Processa (redimensiona, valida, converte)&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;processFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tmpPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"process error: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;continue&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="c"&gt;// Limpa — no tmpfs isso é instantâneo&lt;/span&gt;
            &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmpPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="c"&gt;// Delete da fila só após processar com sucesso&lt;/span&gt;
            &lt;span class="n"&gt;sqsClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DeleteMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;sqs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DeleteMessageInput&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;QueueUrl&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;      &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;queueURL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;ReceiptHandle&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReceiptHandle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;processFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="n"&gt;UploadMessage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Aqui: validar, converter, enviar pro S3 real ou LocalStack&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"processing %s for user %s (%d bytes)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O ganho é duplo: o LocalStack inicia mais rápido (sem I/O de disco para inicializar os dados), e os arquivos temporários do seu worker nunca tocam o disco da máquina.&lt;/p&gt;




&lt;h3&gt;
  
  
  Imagens scratch + tmpfs: a combinação mais segura que você pode fazer
&lt;/h3&gt;

&lt;p&gt;No artigo sobre &lt;a href="https://dev.to/rflpazini/go-docker-como-criar-as-melhores-imagens-docker-para-aplicacoes-golang-ikj"&gt;imagens Docker para Go&lt;/a&gt;, mostrei que usar &lt;code&gt;scratch&lt;/code&gt; como imagem final chega a ~21MB — menos que &lt;code&gt;alpine&lt;/code&gt; (~30MB) e muito menos que a imagem com SDK (~251MB). O que não mencionei lá é que &lt;code&gt;scratch&lt;/code&gt; e &lt;code&gt;read_only: true&lt;/code&gt; são feitos um para o outro, e tmpfs é o elo que faz tudo funcionar.&lt;/p&gt;

&lt;p&gt;O problema de usar &lt;code&gt;scratch&lt;/code&gt; com &lt;code&gt;read_only: true&lt;/code&gt; é que a aplicação não consegue escrever em lugar nenhum — nem em &lt;code&gt;/tmp&lt;/code&gt;. Sem tmpfs, você precisaria ou relaxar o &lt;code&gt;read_only&lt;/code&gt; ou montar volumes, o que aumenta a superfície de ataque. Com tmpfs, você tem o melhor dos dois mundos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
      &lt;span class="na"&gt;dockerfile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Dockerfile&lt;/span&gt;  &lt;span class="c1"&gt;# multi-stage com scratch&lt;/span&gt;
    &lt;span class="na"&gt;read_only&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;            &lt;span class="c1"&gt;# filesystem inteiro imutável&lt;/span&gt;
    &lt;span class="na"&gt;tmpfs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/tmp:size=256M&lt;/span&gt;         &lt;span class="c1"&gt;# única área gravável — e ainda assim efêmera&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/var/run:size=10M&lt;/span&gt;
    &lt;span class="na"&gt;security_opt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;no-new-privileges:true&lt;/span&gt;
    &lt;span class="na"&gt;cap_drop&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ALL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E o Dockerfile que casa com isso (multi-stage com scratch, como discutido no artigo de imagens):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# syntax=docker/dockerfile:1&lt;/span&gt;

&lt;span class="c"&gt;# Build: compila com Go 1.26&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;golang:1.26-alpine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;builder&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; go.mod go.sum ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;go mod download
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="c"&gt;# CGO_ENABLED=0 garante binário estático — requisito para scratch&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nv"&gt;CGO_ENABLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0 &lt;span class="nv"&gt;GOOS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;linux go build &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nt"&gt;-ldflags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"-s -w"&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nt"&gt;-o&lt;/span&gt; /app/server ./cmd/server

&lt;span class="c"&gt;# Final: scratch + tmpfs = imagem mínima + filesystem imutável&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; scratch&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=builder /app/server /server&lt;/span&gt;
&lt;span class="c"&gt;# /tmp será montado como tmpfs pelo docker compose — não precisa existir na imagem&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 8080&lt;/span&gt;
&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; ["/server"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A combinação &lt;code&gt;scratch&lt;/code&gt; + &lt;code&gt;read_only: true&lt;/code&gt; + &lt;code&gt;tmpfs&lt;/code&gt; resulta em:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Imagem final de ~21MB (só o binário Go)&lt;/li&gt;
&lt;li&gt;Zero pacotes extras para explorar&lt;/li&gt;
&lt;li&gt;Filesystem completamente imutável em produção&lt;/li&gt;
&lt;li&gt;Única área gravável (&lt;code&gt;/tmp&lt;/code&gt;) existe na RAM e some com o container&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;É o padrão mais hardened que você consegue com Go e Docker hoje, sem abrir mão de nenhuma funcionalidade.&lt;/p&gt;




&lt;h3&gt;
  
  
  MCP server + tmpfs: cache de respostas de API sem persistência
&lt;/h3&gt;

&lt;p&gt;Se você já brincou com &lt;a href="https://dev.to/rflpazini/mcp-a-docker-guide-3mp4"&gt;MCP servers em Docker&lt;/a&gt;, sabe que eles ficam intermediando chamadas entre o Claude (ou qualquer LLM) e APIs externas. Essas chamadas muitas vezes retornam payloads grandes de JSON — respostas de APIs, documentações de Swagger, listas de recursos — que são processados uma vez e descartados.&lt;/p&gt;

&lt;p&gt;Salvar isso em disco é desperdício. Salvar no tmpfs faz sentido:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mcp-gateway&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rflpazini/mcp-api-gateway&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;API_1_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;internal-api&lt;/span&gt;
      &lt;span class="na"&gt;API_1_SWAGGER_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://api.exemplo.com/swagger.json&lt;/span&gt;
      &lt;span class="na"&gt;API_1_BASE_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://api.exemplo.com/v1&lt;/span&gt;
      &lt;span class="c1"&gt;# Diz pro gateway onde cachear as respostas temporárias&lt;/span&gt;
      &lt;span class="na"&gt;CACHE_DIR&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/tmp/mcp-cache&lt;/span&gt;
      &lt;span class="na"&gt;RESPONSE_CACHE_TTL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;30s&lt;/span&gt;
    &lt;span class="na"&gt;tmpfs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="c1"&gt;# Cache de respostas — não precisa sobreviver a restart&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/tmp/mcp-cache:size=200M,mode=1770&lt;/span&gt;
      &lt;span class="c1"&gt;# Schemas Swagger baixados para parsing&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/tmp/schemas:size=50M&lt;/span&gt;

  &lt;span class="c1"&gt;# Seu servidor Go que o MCP chama&lt;/span&gt;
  &lt;span class="na"&gt;internal-api&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
    &lt;span class="na"&gt;read_only&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;tmpfs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/tmp:size=128M&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;PORT&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8080"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se você quiser ir além e implementar um cache de respostas no próprio servidor Go que o MCP gateway chama, fica assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;cache&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"crypto/sha256"&lt;/span&gt;
    &lt;span class="s"&gt;"encoding/json"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"os"&lt;/span&gt;
    &lt;span class="s"&gt;"path/filepath"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Entry&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Data&lt;/span&gt;      &lt;span class="n"&gt;any&lt;/span&gt;       &lt;span class="s"&gt;`json:"data"`&lt;/span&gt;
    &lt;span class="n"&gt;ExpiresAt&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Time&lt;/span&gt; &lt;span class="s"&gt;`json:"expires_at"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// FileCache é um cache simples em tmpfs.&lt;/span&gt;
&lt;span class="c"&gt;// Como é tmpfs, não há custo de I/O — é literalmente memória.&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;FileCache&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;dir&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;ttl&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Duration&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dir&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ttl&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;FileCache&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MkdirAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="n"&gt;o750&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"cache dir: %w"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;FileCache&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;dir&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ttl&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;FileCache&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;sha256&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sum256&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%x.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;FileCache&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dest&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt; &lt;span class="n"&gt;Entry&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;After&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ExpiresAt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// limpa expirado&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;FileCache&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;entry&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Entry&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;      &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;ExpiresAt&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ttl&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// WriteFile em tmpfs = write em RAM. Sem syscall de disco.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="n"&gt;o600&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A beleza desse padrão é que você tem um cache com TTL que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Não precisa de Redis para casos simples&lt;/li&gt;
&lt;li&gt;Não polui o disco com dados temporários&lt;/li&gt;
&lt;li&gt;Morre junto com o container — sem estado residual&lt;/li&gt;
&lt;li&gt;É tão rápido quanto acessar memória&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para um MCP gateway que precisa cachear respostas de API por 30 segundos antes de refazer a chamada, isso é mais do que suficiente.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quando NÃO usar tmpfs
&lt;/h2&gt;

&lt;p&gt;Vamos ser honestos: tmpfs não é bala de prata.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Não use quando:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Os dados precisam sobreviver a um restart (sessões de usuário em produção, por exemplo)&lt;/li&gt;
&lt;li&gt;Você tem pouca RAM e workloads com uso intenso de memória concorrente&lt;/li&gt;
&lt;li&gt;Os arquivos temporários são gigantes (acima de 20-30% da RAM disponível)&lt;/li&gt;
&lt;li&gt;Você precisa de persistência entre deploys no mesmo host&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use sem medo quando:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dados temporários de processamento (uploads, conversões, transformações)&lt;/li&gt;
&lt;li&gt;Cache de compilação em CI&lt;/li&gt;
&lt;li&gt;Bancos de dados de teste&lt;/li&gt;
&lt;li&gt;Sessões de curta duração que não precisam sobreviver a restarts&lt;/li&gt;
&lt;li&gt;Qualquer coisa que você jogaria fora de qualquer jeito&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  O impacto real no dia a dia
&lt;/h2&gt;

&lt;p&gt;Combinado com boas práticas que já falei em outros artigos — como &lt;a href="https://dev.to/rflpazini/go-docker-como-criar-as-melhores-imagens-docker-para-aplicacoes-golang-ikj"&gt;imagens Docker otimizadas para Go&lt;/a&gt; e &lt;a href="https://dev.to/rflpazini/go-performance-pequenas-mudancas-que-ajudam-a-melhorar-o-desempenho-do-seu-app-2l8o"&gt;tuning de performance&lt;/a&gt; — tmpfs fecha um gap importante: I/O de disco como gargalo.&lt;/p&gt;

&lt;p&gt;Para pipelines de CI/CD, a diferença é imediata. Para APIs Go que processam arquivos, é a diferença entre latência aceitável e latência excelente. Para testes de integração, é o que separa um suite de 5 minutos de um de 15 minutos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vale a pena?
&lt;/h2&gt;

&lt;p&gt;Sim. E é uma das mudanças mais fáceis de implementar com impacto real.&lt;/p&gt;

&lt;p&gt;Não exige mudança de código. Não exige nova dependência. É um bloco de 3 linhas no seu &lt;code&gt;compose.yml&lt;/code&gt; que pode te poupar memória de disco, acelerar I/O e ainda melhorar a postura de segurança do serviço.&lt;/p&gt;

&lt;p&gt;Se você já usa Docker Compose no dia a dia (e se escreve Go em 2026, provavelmente usa), isso é a otimização de menor esforço com maior retorno que você pode fazer hoje.&lt;/p&gt;

&lt;p&gt;Experimenta, mede com &lt;code&gt;docker stats&lt;/code&gt;, e me conta o que você encontrou.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>go</category>
      <category>performance</category>
      <category>devops</category>
    </item>
    <item>
      <title>Docker Compose para Agentes de IA: O que realmente mudou (e o que você precisa saber agora)</title>
      <dc:creator>Rafael Pazini</dc:creator>
      <pubDate>Tue, 03 Mar 2026 14:12:27 +0000</pubDate>
      <link>https://dev.to/rflpazini/docker-compose-para-agentes-de-ia-o-que-realmente-mudou-e-o-que-voce-precisa-saber-agora-411p</link>
      <guid>https://dev.to/rflpazini/docker-compose-para-agentes-de-ia-o-que-realmente-mudou-e-o-que-voce-precisa-saber-agora-411p</guid>
      <description>&lt;p&gt;Se você acompanha o ecossistema Docker, 2025 foi o ano em que eles deixaram de ser "só a ferramenta de containerização" e viraram plataforma de IA de verdade. E o que começou como experimento virou padrão com uma velocidade impressionante — tipo aquele colega que vai a uma conferência e volta querendo reescrever tudo em Rust.&lt;/p&gt;

&lt;p&gt;O ponto central de tudo isso é simples: &lt;strong&gt;modelos de IA agora são cidadãos de primeira classe no seu &lt;code&gt;compose.yaml&lt;/code&gt;&lt;/strong&gt;. Mesma sintaxe, mesma CLI, mesmo pipeline que você já usa para subir Postgres e Redis. A diferença é que agora o Qwen ou o Gemma também sobem junto.&lt;/p&gt;

&lt;p&gt;Vamos ver o que realmente funciona em fevereiro de 2026 e o que você deveria estar usando.&lt;/p&gt;




&lt;h2&gt;
  
  
  O que mudou no Compose
&lt;/h2&gt;

&lt;p&gt;O artigo de referência estava certo no espírito, mas a sintaxe evoluiu. O bloco &lt;code&gt;provider.type: model&lt;/code&gt; com imagens Docker Hub genéricas não é a forma atual. Isso foi simplificado.&lt;/p&gt;

&lt;p&gt;A sintaxe correta hoje usa o campo &lt;code&gt;model&lt;/code&gt; dentro do bloco &lt;code&gt;models&lt;/code&gt; para referenciar o artefato OCI direto do Docker Hub, sem a estrutura aninhada de provider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;models&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;llm&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ai/qwen2.5&lt;/span&gt;        &lt;span class="c1"&gt;# artefato OCI do Docker Hub — isso que você puxa&lt;/span&gt;
    &lt;span class="na"&gt;context_size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4096&lt;/span&gt;
  &lt;span class="na"&gt;embeddings&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ai/all-minilm&lt;/span&gt;
    &lt;span class="na"&gt;context_size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2048&lt;/span&gt;
    &lt;span class="na"&gt;runtime_flags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--embeddings"&lt;/span&gt;       &lt;span class="c1"&gt;# obrigatório para modelos de embedding&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./api&lt;/span&gt;
    &lt;span class="na"&gt;models&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;llm&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;endpoint_var&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;LLM_URL&lt;/span&gt;       &lt;span class="c1"&gt;# Compose injeta a URL do Model Runner aqui&lt;/span&gt;
        &lt;span class="na"&gt;model_var&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;LLM_MODEL_NAME&lt;/span&gt;
      &lt;span class="na"&gt;embeddings&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;endpoint_var&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;EMBEDDING_URL&lt;/span&gt;
        &lt;span class="na"&gt;model_var&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;EMBEDDING_MODEL_NAME&lt;/span&gt;

  &lt;span class="na"&gt;vector-db&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;qdrant/qdrant:latest&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./qdrant:/qdrant/storage&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depois é só:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O Compose puxa os modelos do Docker Hub, sobe o Model Runner, injeta as variáveis de ambiente nos serviços que precisam, e cuida da ordem de inicialização. Você não escreve nenhuma linha de código de infraestrutura.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Versão mínima:&lt;/strong&gt; Docker Compose 2.38.1+. Se você roda no Linux com Docker Engine (não Desktop), confirme a versão antes. Se roda Docker Desktop, já está coberto.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  O ecossistema expandiu bastante
&lt;/h2&gt;

&lt;p&gt;Quando esse assunto surgiu em julho de 2025, os frameworks suportados eram CrewAI, LangGraph e Spring AI. Hoje a lista ficou bem maior. Oficialmente, o repo &lt;code&gt;docker/compose-for-agents&lt;/code&gt; tem exemplos funcionando para:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LangGraph&lt;/strong&gt; (Python)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CrewAI&lt;/strong&gt; (Python)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spring AI&lt;/strong&gt; (Java)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Embabel&lt;/strong&gt; (JVM)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vercel AI SDK&lt;/strong&gt; (Node.js)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google ADK&lt;/strong&gt; — esse é novo e é o mais interessante para quem trabalha com raciocínio multi-step&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para Go, o caminho natural ainda é via &lt;code&gt;Langchaingo&lt;/code&gt; ou chamadas HTTP diretas — o Compose injeta a URL, o resto é o seu código.&lt;/p&gt;




&lt;h2&gt;
  
  
  Gordon: o agente que o Docker não estava avisando que ia lançar
&lt;/h2&gt;

&lt;p&gt;Se você não acompanhou, em fevereiro de 2026 o Docker lançou o &lt;strong&gt;Gordon&lt;/strong&gt; — um agente de IA dentro do Docker Desktop (e CLI via &lt;code&gt;docker ai&lt;/code&gt;) que tem acesso ao seu ambiente de containers.&lt;/p&gt;

&lt;p&gt;O Gordon não é um chatbot. Ele tem shell, CLI do Docker e acesso ao filesystem. Você aponta um problema, aprova as ações, e ele executa. Container saindo com código 137? Gordon inspeciona os logs, identifica o processo que estourou memória, propõe o fix. Você aprova, ele executa.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker ai &lt;span class="s2"&gt;"meu container de API está caindo, me ajuda a debugar"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vale mencionar porque afeta diretamente o fluxo de trabalhar com agentes: o Gordon é construído em cima do &lt;code&gt;cagent&lt;/code&gt;, o framework de agentes do Docker, e se integra diretamente com o MCP Gateway. Ou seja, a mesma arquitetura que você define no Compose para seus agentes, o Docker está usando internamente.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nota de segurança:&lt;/strong&gt; Em fevereiro de 2026 foi divulgada uma vulnerabilidade onde labels maliciosas em imagens Docker podiam ser usadas para injetar comandos via Gordon → MCP Gateway. Isso foi corrigido na versão 4.50.0+. Se você está em versão anterior, atualize antes de usar Gordon em projetos com imagens de terceiros.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  MCP Gateway e MCP Catalog: o que isso muda na prática
&lt;/h2&gt;

&lt;p&gt;Outro componente que o artigo original mencionava de forma superficial e que ficou muito mais relevante: o &lt;strong&gt;MCP Gateway&lt;/strong&gt;, agora open source e GA desde a versão 4.43 do Desktop.&lt;/p&gt;

&lt;p&gt;O Gateway é o ponto de controle entre seus agentes e as ferramentas externas. Ele fica no meio do caminho entre o agente (seja LangGraph, CrewAI, ou o próprio Gordon) e os MCP servers (ferramentas como GitHub, MongoDB, Slack, banco de dados, etc.).&lt;/p&gt;

&lt;p&gt;No Compose, a integração fica assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;my-agent&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./agent&lt;/span&gt;
    &lt;span class="na"&gt;models&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;llm&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;endpoint_var&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;LLM_URL&lt;/span&gt;
        &lt;span class="na"&gt;model_var&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;LLM_MODEL_NAME&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;MCP_GATEWAY_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://mcp-gateway:8811&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;mcp-gateway&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;llm&lt;/span&gt;

  &lt;span class="na"&gt;mcp-gateway&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker/mcp-gateway:latest&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/var/run/docker.sock:/var/run/docker.sock&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MCP_SERVERS=github,duckduckgo&lt;/span&gt;

&lt;span class="na"&gt;models&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;llm&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ai/qwen2.5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O MCP Catalog hoje tem &lt;strong&gt;mais de 100 servidores verificados&lt;/strong&gt;, todos rodando em containers isolados com assinatura criptográfica — muito diferente do padrão anterior de executar via &lt;code&gt;npx&lt;/code&gt; ou &lt;code&gt;uvx&lt;/code&gt; direto no host.&lt;/p&gt;




&lt;h2&gt;
  
  
  Model Runner: o que evoluiu desde o lançamento
&lt;/h2&gt;

&lt;p&gt;O Docker Model Runner (DMR) saiu de beta experimental para GA em outubro de 2025. Desde então:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Suporte a Windows com GPU NVIDIA e Qualcomm/ARM&lt;/li&gt;
&lt;li&gt;API compatível com OpenAI (você troca o endpoint, o SDK não muda)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API compatível com Anthropic&lt;/strong&gt; — adicionada recentemente, para quem usa SDKs do Claude&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;docker model purge&lt;/code&gt; para limpar todos os modelos de uma vez&lt;/li&gt;
&lt;li&gt;Você pode omitir o prefixo &lt;code&gt;ai/&lt;/code&gt; ao fazer pull: &lt;code&gt;docker model pull qwen2.5&lt;/code&gt; funciona&lt;/li&gt;
&lt;li&gt;Downloads retomam se interrompidos — acabou aquela dor de baixar modelos de 4GB na metade
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Antes&lt;/span&gt;
docker model pull ai/qwen2.5

&lt;span class="c"&gt;# Agora funciona igual&lt;/span&gt;
docker model pull qwen2.5

&lt;span class="c"&gt;# Endpoint OpenAI-compatible (sem o /engines agora)&lt;/span&gt;
curl http://localhost:12434/v1/models
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Docker Compose v5 e o Go SDK
&lt;/h2&gt;

&lt;p&gt;Isso ainda não estava no radar quando o artigo original foi escrito: o &lt;strong&gt;Compose v5&lt;/strong&gt; saiu com um SDK Go oficial que permite controle programático do ambiente multi-container sem depender da CLI.&lt;/p&gt;

&lt;p&gt;Para quem escreve ferramentas de plataforma ou pipelines de CI em Go, isso é relevante. Você pode validar, carregar e gerenciar ambientes Compose diretamente no seu código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"github.com/compose-spec/compose-go/v2/cli"&lt;/span&gt;

&lt;span class="c"&gt;// Carrega e valida o compose.yaml programaticamente&lt;/span&gt;
&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;cli&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewProjectOptions&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"compose.yaml"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LoadProject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="c"&gt;// Valida que os modelos declarados existem no hub&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Models&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Model: %s → %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Cloud Run e o que está por vir
&lt;/h2&gt;

&lt;p&gt;O deploy para Google Cloud Run via &lt;code&gt;gcloud run compose up&lt;/code&gt; é real e funcional. Azure está em andamento. AWS ainda não tem integração oficial — e analistas apontaram isso como um gap relevante para adoção enterprise.&lt;/p&gt;

&lt;p&gt;A limitação prática: Offload funciona bem para desenvolvimento e testes pesados. Para produção com autoscaling multi-região gerenciado fora do Docker, você ainda precisa de outras peças.&lt;/p&gt;




&lt;h2&gt;
  
  
  Boas práticas que o tempo confirmou
&lt;/h2&gt;

&lt;p&gt;Algumas coisas que a comunidade aprendeu na prática desde o lançamento:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Versione seus modelos com digest, não tag.&lt;/strong&gt; A tag &lt;code&gt;latest&lt;/code&gt; do modelo pode mudar semanticamente sem aviso. Se seu agente começou a dar respostas diferentes sem você ter mudado nada, a culpa pode ser essa.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;models&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;llm&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ai/qwen2.5@sha256:abc123...&lt;/span&gt; &lt;span class="c1"&gt;# imutável&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Separe embedding do modelo principal.&lt;/strong&gt; Colocar os dois no mesmo serviço aumenta latência de forma desnecessária. São padrões de uso completamente diferentes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use variáveis mapeadas via sintaxe longa.&lt;/strong&gt; Desacopla o nome lógico interno dos detalhes do endpoint e facilita a troca entre local e Offload sem refatorar código.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Valide no CI.&lt;/strong&gt; O Compose trata modelos como qualquer serviço, então você pode subir a stack headless e rodar smoke tests contra o endpoint do modelo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# CI pipeline&lt;/span&gt;
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;span class="nb"&gt;sleep &lt;/span&gt;10  &lt;span class="c"&gt;# aguarda modelo carregar&lt;/span&gt;
curl &lt;span class="nt"&gt;-f&lt;/span&gt; http://localhost:12434/v1/models &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;exit &lt;/span&gt;1
docker compose down
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Quando usar (e quando esperar)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Use agora&lt;/strong&gt; se você precisa de: desenvolvimento full-stack local consistente com LLM, CI previsível que testa inferência como dependência normal, múltiplos agentes se comunicando sem scripts manuais, ou uma stack RAG com vector store e modelo local.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Espere&lt;/strong&gt; se você precisa de: autoscaling multi-região fora do ecossistema Docker (ainda imaturo), integrações com plataformas ML proprietárias que não publicam artefato OCI, ou AWS como provedor cloud principal para o Compose (sem suporte oficial ainda).&lt;/p&gt;




&lt;h2&gt;
  
  
  O ponto central
&lt;/h2&gt;

&lt;p&gt;No momento atual, a pergunta não é mais "vale a pena testar?" — é "por qual parte você começa?"&lt;/p&gt;

&lt;p&gt;A resposta mais simples: clone o &lt;code&gt;docker/compose-for-agents&lt;/code&gt;, escolha o exemplo do framework que seu time já usa (LangGraph se você é Python, Spring AI se é Java, vai de Go direto via HTTP), suba com &lt;code&gt;docker compose up&lt;/code&gt;, e meça quanto tempo você economizou não configurando nada.&lt;/p&gt;

&lt;p&gt;Depois me conta.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Dúvidas ou ajustes? Abre uma issue no meu &lt;a href="https://github.com/rflpazini/articles" rel="noopener noreferrer"&gt;repositório de artigos&lt;/a&gt;. E se você já está rodando Compose com modelos em produção, me conta como está sendo — esse tema ainda tem muita coisa para explorar.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>ai</category>
      <category>development</category>
      <category>agents</category>
    </item>
    <item>
      <title>Go 1.26: GreenteaGC por padrão, 'new' com superpoderes e outras melhorias que você vai querer testar</title>
      <dc:creator>Rafael Pazini</dc:creator>
      <pubDate>Wed, 25 Feb 2026 18:13:37 +0000</pubDate>
      <link>https://dev.to/rflpazini/go-126-greenteagc-por-padrao-new-com-superpoderes-e-outras-melhorias-que-voce-vai-querer-testar-9jf</link>
      <guid>https://dev.to/rflpazini/go-126-greenteagc-por-padrao-new-com-superpoderes-e-outras-melhorias-que-voce-vai-querer-testar-9jf</guid>
      <description>&lt;p&gt;Chegou o Go 1.26 e, olha, a equipe do Go não estava brincando quando falou que essa é a maior release que já fizeram. Não tem uma mudança épica que vai reescrever seu entendimento de programação — mas tem um conjunto de melhorias que, somadas, fazem uma diferença real em produção. Tipo aquele episódio da sua série favorita que não tem o cliffhanger dramático, mas é tão bem executado que você fica satisfeito do mesmo jeito.&lt;/p&gt;

&lt;p&gt;Vamos ver o que realmente mudou.&lt;/p&gt;

&lt;h2&gt;
  
  
  GreenteaGC: De Experimento a Padrão
&lt;/h2&gt;

&lt;p&gt;Se você acompanhou o Go 1.25, já sabe que o GreenteaGC chegou como experimental. Agora, no 1.26, ele &lt;strong&gt;virou o padrão&lt;/strong&gt;. Sem flag, sem opt-in, ele já está rodando no seu código.&lt;/p&gt;

&lt;p&gt;O problema do GC anterior era simples de entender: ele tratava todos os objetos de forma igual, varrendo o heap como um grafo gigante e pulando de objeto em objeto pela memória. Em CPUs modernas com vários cores, isso gerava um problema clássico: muito tempo esperando a memória responder, não o processador calcular.&lt;/p&gt;

&lt;p&gt;O GreenteaGC foi projetado para workloads modernos — microservices que criam e descartam milhares de objetos pequenos por segundo. O foco dele é em &lt;strong&gt;localidade de memória&lt;/strong&gt; e &lt;strong&gt;escalabilidade em multi-core&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Os números que a equipe do Go divulgou:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;10% a 40% de redução&lt;/strong&gt; no overhead de GC em programas reais com uso intenso de memória&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;+10% adicional&lt;/strong&gt; em hardware mais novo (Intel Ice Lake, AMD Zen 4 e posteriores), porque o GC agora usa instruções vetoriais para escanear objetos pequenos
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Nenhuma mudança de código necessária.&lt;/span&gt;
&lt;span class="c"&gt;// Se você estava usando o experimento antes:&lt;/span&gt;
&lt;span class="c"&gt;// GOEXPERIMENT=greenteagc go run main.go&lt;/span&gt;

&lt;span class="c"&gt;// Agora é só:&lt;/span&gt;
&lt;span class="c"&gt;// go run main.go&lt;/span&gt;

&lt;span class="c"&gt;// Quer desativar por algum motivo? (mas por favor, abra uma issue antes)&lt;/span&gt;
&lt;span class="c"&gt;// GOEXPERIMENT=nogreenteagc go build .&lt;/span&gt;
&lt;span class="c"&gt;// Esse opt-out some no Go 1.27, então corra.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Na prática, o que você vai sentir: &lt;strong&gt;latência de tail (p99) menor&lt;/strong&gt;, menos spikes de CPU em load alto, e comportamento mais previsível no Kubernetes quando você tem limites de CPU apertados. É o tipo de melhoria que aparece no seu Datadog sem você ter mudado uma linha de código.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;code&gt;new&lt;/code&gt; com Expressão: Finalmente
&lt;/h2&gt;

&lt;p&gt;Essa é pequena, mas se você trabalha com JSON ou Protobuf vai sentir no dia a dia.&lt;/p&gt;

&lt;p&gt;Antes, o &lt;code&gt;new&lt;/code&gt; só aceitava um tipo. Queria criar um ponteiro para um valor específico? Precisava da clássica função helper que todo projeto Go tem — aquele &lt;code&gt;func ptr[T any](v T) *T&lt;/code&gt; que fica copiando de repositório em repositório.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Antes do Go 1.26&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;boolPtr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;intPtr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Config&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;MaxRetries&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;  &lt;span class="s"&gt;`json:"max_retries,omitempty"`&lt;/span&gt;
    &lt;span class="n"&gt;Debug&lt;/span&gt;      &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="s"&gt;`json:"debug,omitempty"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;cfg&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;MaxRetries&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;intPtr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;Debug&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;      &lt;span class="n"&gt;boolPtr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;false&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Go 1.26: adeus, funções helpers&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Config&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;MaxRetries&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;  &lt;span class="s"&gt;`json:"max_retries,omitempty"`&lt;/span&gt;
    &lt;span class="n"&gt;Debug&lt;/span&gt;      &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="s"&gt;`json:"debug,omitempty"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;cfg&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;MaxRetries&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;Debug&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;      &lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;false&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simples. Limpo. Sem boilerplate. O &lt;code&gt;new(expr)&lt;/code&gt; aloca uma variável do tipo de &lt;code&gt;expr&lt;/code&gt;, inicializa com o valor de &lt;code&gt;expr&lt;/code&gt;, e retorna o ponteiro. Funciona com qualquer tipo.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tipos Genéricos Autorreferenciais
&lt;/h2&gt;

&lt;p&gt;Para quem gosta de estruturas de dados complexas, essa é a mudança mais interessante do ponto de vista da linguagem.&lt;/p&gt;

&lt;p&gt;Antes, um tipo genérico não podia se referenciar na sua própria lista de parâmetros de tipo. Isso tornava certas abstrações impossíveis ou extremamente verbosas. Agora dá:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Go 1.26: tipo genérico que referencia a si mesmo&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Ordered&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;Ordered&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Compare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;TreeNode&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;Ordered&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;
    &lt;span class="n"&gt;Left&lt;/span&gt;  &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;TreeNode&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;Right&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;TreeNode&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso simplifica implementações de árvores binárias de busca, listas encadeadas tipadas, e qualquer estrutura onde você precisa que o tipo saiba sobre si mesmo. Não é uma mudança que vai afetar o código médio, mas quem estava lutando contra as limitações vai agradecer.&lt;/p&gt;




&lt;h2&gt;
  
  
  Alocações Especializadas por Tamanho
&lt;/h2&gt;

&lt;p&gt;Essa é uma daquelas melhorias invisíveis que aparecem como mágica no benchmark. O compilador agora usa &lt;strong&gt;rotas de alocação especializadas&lt;/strong&gt; para objetos pequenos (abaixo de 512 bytes).&lt;/p&gt;

&lt;p&gt;O que acontecia antes: toda alocação passava pela mesma função &lt;code&gt;mallocgc&lt;/code&gt; genérica. Funciona, mas não é ótimo quando você está fazendo milhares de alocações por segundo de objetos pequenos.&lt;/p&gt;

&lt;p&gt;O que acontece agora: o runtime usa uma &lt;strong&gt;jump table&lt;/strong&gt; para despachar para a função correta baseada no tamanho do objeto. Menos overhead por alocação, melhor uso do cache do processador.&lt;/p&gt;

&lt;p&gt;Resultado? Até &lt;strong&gt;30% de redução&lt;/strong&gt; no custo de alocações pequenas. Em termos práticos, o time do Go estima ~1% de melhoria real em programas com muitas alocações — parece pouco, mas em escala é significativo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// O compilador também ficou mais esperto com slices.&lt;/span&gt;
&lt;span class="c"&gt;// Em mais situações, ele consegue alocar o backing store no stack.&lt;/span&gt;
&lt;span class="c"&gt;// Menos pressão no GC, sem você fazer nada.&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;processItems&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c"&gt;// pode ir pro stack agora em mais casos&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  cgo 30% Mais Rápido
&lt;/h2&gt;

&lt;p&gt;Se o seu projeto faz chamadas cgo — seja para bibliotecas C, bindings de sistema, ou criptografia — essa melhoria vai aparecer direto.&lt;/p&gt;

&lt;p&gt;O overhead de uma chamada cgo caiu &lt;strong&gt;~30%&lt;/strong&gt; no baseline. A implementação remove um estado intermediário que o runtime mantinha para goroutines em syscall/cgo. Em vez de encoding o estado "dentro de uma chamada cgo" como estado do processador (P), o runtime agora verifica o status da goroutine diretamente. Menos coordenação, menos contention.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Benchmark local em Apple M1:&lt;/span&gt;
&lt;span class="c"&gt;# CgoCall-8: 28.55ns (1.25) → 19.02ns (1.26) = -33%&lt;/span&gt;
&lt;span class="c"&gt;# CgoCallWithCallback-8: 72.76ns → 57.38ns = -21%&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para quem evitava cgo por causa do overhead, o cenário ficou mais atraente.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;code&gt;crypto/hpke&lt;/code&gt;: Criptografia Moderna no stdlib
&lt;/h2&gt;

&lt;p&gt;O Go 1.26 adicionou o pacote &lt;code&gt;crypto/hpke&lt;/code&gt;, que implementa &lt;strong&gt;Hybrid Public Key Encryption&lt;/strong&gt; (RFC 9180). Isso inclui suporte a KEMs pós-quânticos como o ML-KEM — ou seja, criptografia que sobrevive a computadores quânticos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"crypto/hpke"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;suite&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;hpke&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewSuite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hpke&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KEM_X25519_HKDF_SHA256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hpke&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KDF_HKDF_SHA256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hpke&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AEAD_AES128GCM&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;pub&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;priv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;suite&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GenerateKeyPair&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;suite&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewSender&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pub&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"info"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;encappedKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sealer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Setup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;ciphertext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;sealer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Seal&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mensagem secreta"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;suite&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewReceiver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;priv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"info"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;opener&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Setup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;encappedKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;plaintext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;opener&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ciphertext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plaintext&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Menos dependência de bibliotecas terceiras para criptografia moderna. Para quem trabalha com compliance e segurança, isso é relevante.&lt;/p&gt;




&lt;h2&gt;
  
  
  Experimentos que Vale Ativar Agora
&lt;/h2&gt;

&lt;p&gt;O Go 1.26 vem com alguns experimentos que provavelmente serão padrão no 1.27. Vale ativar no seu ambiente de desenvolvimento e CI:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Goroutine Leak Profile&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;GOEXPERIMENT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;goroutineleakprofile go run main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Detecta goroutines que nunca vão desbloquear — aquelas que ficam esperando em channels, mutexes ou variáveis de condição que nenhuma goroutine ativa vai alcançar. Quantas vezes você já debugou um serviço que lentamente acumulava goroutines sem saber por quê? Esse experimento adiciona um endpoint &lt;code&gt;/debug/pprof/goroutineleak&lt;/code&gt; e overhead zero quando não está em uso.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;runtime/secret: Memória Segura&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;GOEXPERIMENT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;runtimesecret go run main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"runtime/secret"&lt;/span&gt;

&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Do&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;generateEphemeralKey&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;// Ao sair dessa função, tudo que foi usado aqui é zerado da memória&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para quem lida com dados sensíveis (chaves criptográficas, tokens, senhas), essa é uma adição importante. O runtime garante que os dados sejam apagados da memória após o uso — algo que a comunidade pedia desde 2017.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;simd/archsimd: SIMD Experimental&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;GOEXPERIMENT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;simd go run main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Acesso direto a operações SIMD específicas de arquitetura. Por enquanto só em amd64, mas é o primeiro passo concreto do Go em direção a computação vetorial de alta performance. Se você processa muitos dados numéricos, fique de olho nisso.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tooling: go fix Ficou Esperto
&lt;/h2&gt;

&lt;p&gt;O &lt;code&gt;go fix&lt;/code&gt; foi reconstruído em cima do mesmo framework de análise do &lt;code&gt;go vet&lt;/code&gt;. Isso significa que agora ele é mais inteligente, composable, e capaz de fazer modernizações que antes exigiam &lt;code&gt;sed&lt;/code&gt; e reza.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Antes: go fix era limitado e bugado em codebases grandes&lt;/span&gt;
&lt;span class="c"&gt;# Agora: ele reescreve padrões antigos automaticamente&lt;/span&gt;

go fix ./...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para times que têm codebases grandes e vivem adiando a modernização, esse é o tipo de melhoria que desbloqueia aquele upgrade que todo mundo sabe que precisa fazer mas ninguém quer tocar.&lt;/p&gt;

&lt;p&gt;Outra remoção: &lt;code&gt;cmd/doc&lt;/code&gt; e &lt;code&gt;go tool doc&lt;/code&gt; foram deletados. Use &lt;code&gt;go doc&lt;/code&gt; no lugar — aceita os mesmos flags e tem o mesmo comportamento. Sem drama.&lt;/p&gt;

&lt;p&gt;O pprof agora também tem a &lt;strong&gt;flame graph view como padrão&lt;/strong&gt; ao usar &lt;code&gt;-http&lt;/code&gt;. Se você ainda estava no graph view por inércia, bem-vindo ao presente.&lt;/p&gt;




&lt;h2&gt;
  
  
  Vale Atualizar Agora?
&lt;/h2&gt;

&lt;p&gt;Go 1.26 requer Go 1.24.6 ou posterior para build. Verifique seu CI/CD antes de atualizar se você builda o toolchain por conta.&lt;/p&gt;

&lt;p&gt;O GreenteaGC agora é padrão e o opt-out (&lt;code&gt;GOEXPERIMENT=nogreenteagc&lt;/code&gt;) vai ser removido no 1.27. Então se você tem alguma razão para desativá-lo, o momento de investigar e abrir issue é agora.&lt;/p&gt;

&lt;p&gt;Para o resto? Atualiza. Você vai ganhar performance de graça, código mais limpo com o novo &lt;code&gt;new&lt;/code&gt;, e melhorias de tooling que fazem diferença no dia a dia.&lt;/p&gt;

&lt;p&gt;É o tipo de release que não tem headline dramática, mas quando você olha os números no monitoramento duas semanas depois de atualizar, fica claro que valeu.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Ficou curioso para testar alguma das novidades? Me conta nos comentários o que mais chamou sua atenção. E se quiser ver os benchmarks na prática, dá uma olhada no meu &lt;a href="https://github.com/rflpazini/articles" rel="noopener noreferrer"&gt;repositório de artigos&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>softwaredevelopment</category>
      <category>performance</category>
      <category>programming</category>
    </item>
    <item>
      <title>Docker cagent: Como orquestrar agentes IA com YAML (e por que isso muda tudo)</title>
      <dc:creator>Rafael Pazini</dc:creator>
      <pubDate>Wed, 03 Sep 2025 20:39:45 +0000</pubDate>
      <link>https://dev.to/rflpazini/docker-cagent-como-orquestrar-agentes-ia-com-yaml-e-por-que-isso-muda-tudo-2fjh</link>
      <guid>https://dev.to/rflpazini/docker-cagent-como-orquestrar-agentes-ia-com-yaml-e-por-que-isso-muda-tudo-2fjh</guid>
      <description>&lt;p&gt;A Docker acabou de lançar algo que pode revolucionar como desenvolvemos com IA: o &lt;a href="https://github.com/docker/cagent" rel="noopener noreferrer"&gt;cagent&lt;/a&gt;. Se você já teve aquela dor de cabeça tentando orquestrar múltiplos agentes IA, configurar integrações complexas ou simplesmente não sabia como começar com agentes inteligentes, essa ferramenta foi feita para você.&lt;/p&gt;

&lt;p&gt;O cagent é um framework &lt;strong&gt;open-source&lt;/strong&gt; que permite orquestrar agentes IA usando apenas YAML e compartilhá-los como imagens Docker. É como ter o poder do Docker, mas para inteligências artificiais.&lt;/p&gt;

&lt;h2&gt;
  
  
  O Problema Que o cagent Resolve
&lt;/h2&gt;

&lt;p&gt;Hoje em dia, criar um agente IA funcional que faça mais do que responder perguntas básicas é complicado. Você precisa:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configurar diferentes modelos de linguagem&lt;/li&gt;
&lt;li&gt;Orquestrar múltiplos agentes trabalhando juntos
&lt;/li&gt;
&lt;li&gt;Integrar com APIs e ferramentas externas&lt;/li&gt;
&lt;li&gt;Manter consistência entre ambientes&lt;/li&gt;
&lt;li&gt;Versionar e compartilhar suas criações&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;É muita complexidade para algo que deveria ser simples. O &lt;strong&gt;cagent&lt;/strong&gt; resolve isso abstraindo toda essa complexidade por trás de uma interface familiar: YAML + Docker.&lt;/p&gt;

&lt;h2&gt;
  
  
  Arquitetura e Funcionalidades Principais
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Configuração Declarativa com YAML
&lt;/h3&gt;

&lt;p&gt;O cagent usa YAML para definir agentes, seguindo a mesma filosofia dos docker-compose.yml que já conhecemos. Aqui está um exemplo básico de como configurar um agente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;code-reviewer-agent&lt;/span&gt;
&lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
  &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;openai&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gpt-4&lt;/span&gt;
&lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github&lt;/span&gt;
    &lt;span class="na"&gt;config&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${GITHUB_TOKEN}&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;think&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;memory&lt;/span&gt;
&lt;span class="na"&gt;instructions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
  &lt;span class="s"&gt;You are a senior developer focused on code review.&lt;/span&gt;
  &lt;span class="s"&gt;Use the github tool to analyze pull requests and provide constructive feedback.&lt;/span&gt;
  &lt;span class="s"&gt;Always think before responding and remember context from previous reviews.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Orquestração Multi-Agente Inteligente
&lt;/h3&gt;

&lt;p&gt;Uma das funcionalidades mais poderosas é a capacidade de coordenar múltiplos agentes especializados. Imagine ter uma equipe virtual onde cada agente tem sua especialidade:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;development-team&lt;/span&gt;
&lt;span class="na"&gt;agents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;backend-specialist&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;anthropic&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;claude-3-sonnet&lt;/span&gt;
    &lt;span class="na"&gt;instructions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
      &lt;span class="s"&gt;Expert in backend development, APIs, and database design.&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;frontend-specialist&lt;/span&gt;  
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;openai&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gpt-4&lt;/span&gt;
    &lt;span class="na"&gt;instructions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
      &lt;span class="s"&gt;Expert in React, TypeScript, and modern frontend practices.&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;coordinator&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;openai&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gpt-4&lt;/span&gt;
    &lt;span class="na"&gt;instructions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
      &lt;span class="s"&gt;Coordinate tasks between backend and frontend specialists.&lt;/span&gt;
      &lt;span class="s"&gt;Delegate specific questions to the appropriate expert.&lt;/span&gt;
    &lt;span class="na"&gt;delegates_to&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;backend-specialist&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;frontend-specialist&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Suporte a Múltiplos Provedores de IA
&lt;/h3&gt;

&lt;p&gt;O framework suporta nativamente:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OpenAI&lt;/strong&gt; (GPT-3.5, GPT-4, GPT-4-turbo)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anthropic&lt;/strong&gt; (Claude 3 family)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Google Gemini&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modelos locais&lt;/strong&gt; via Docker Model Runner&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para modelos locais, a configuração fica assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;local&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;llama-3-8b&lt;/span&gt;
  &lt;span class="na"&gt;endpoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://localhost:8080/v1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Exemplos Práticos de Uso
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Caso 1: Agente de Revisão de Código
&lt;/h3&gt;

&lt;p&gt;Vamos criar um agente especializado em revisar código Python:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python-code-reviewer&lt;/span&gt;
&lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;openai&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gpt-4&lt;/span&gt;
&lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;think&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;memory&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github&lt;/span&gt;
&lt;span class="na"&gt;instructions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
  &lt;span class="s"&gt;You are a Python expert focused on code quality.&lt;/span&gt;
  &lt;span class="s"&gt;When reviewing code:&lt;/span&gt;
  &lt;span class="s"&gt;1. Check for PEP 8 compliance&lt;/span&gt;
  &lt;span class="s"&gt;2. Identify potential bugs&lt;/span&gt;
  &lt;span class="s"&gt;3. Suggest performance improvements&lt;/span&gt;
  &lt;span class="s"&gt;4. Verify error handling&lt;/span&gt;

  &lt;span class="s"&gt;Always use the 'think' tool before providing feedback.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para executar este agente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Construir o agente&lt;/span&gt;
cagent build &lt;span class="nt"&gt;-f&lt;/span&gt; go-reviewer.yml

&lt;span class="c"&gt;# Executar uma revisão&lt;/span&gt;
cagent run go-code-reviewer &lt;span class="s2"&gt;"Review this HTTP handler code: [code here]"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Caso 2: Sistema de Documentação Automática
&lt;/h3&gt;

&lt;p&gt;Um exemplo mais complexo seria um sistema que gera documentação automaticamente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;documentation-generator&lt;/span&gt;
&lt;span class="na"&gt;agents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;analyzer&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;anthropic&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;claude-3-sonnet&lt;/span&gt;
    &lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;think&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;todo&lt;/span&gt;
    &lt;span class="na"&gt;instructions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
      &lt;span class="s"&gt;Analyze code structure and identify components that need documentation.&lt;/span&gt;
      &lt;span class="s"&gt;Create a todo list of documentation tasks.&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;writer&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;openai&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gpt-4&lt;/span&gt;
    &lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;memory&lt;/span&gt;
    &lt;span class="na"&gt;instructions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
      &lt;span class="s"&gt;Generate comprehensive documentation based on code analysis.&lt;/span&gt;
      &lt;span class="s"&gt;Maintain consistency with existing documentation style.&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;coordinator&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;openai&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gpt-3.5-turbo&lt;/span&gt;
    &lt;span class="na"&gt;instructions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
      &lt;span class="s"&gt;Coordinate between analyzer and writer.&lt;/span&gt;
      &lt;span class="s"&gt;Ensure complete documentation coverage.&lt;/span&gt;
    &lt;span class="na"&gt;delegates_to&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;analyzer&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;writer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Caso 3: Agente de Monitoramento e Alertas
&lt;/h3&gt;

&lt;p&gt;Para DevOps, um agente que monitora logs e envia alertas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;log-monitor-agent&lt;/span&gt;
&lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;local&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;llama-3-8b&lt;/span&gt;
  &lt;span class="na"&gt;endpoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://localhost:8080/v1&lt;/span&gt;
&lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;webhook&lt;/span&gt;
    &lt;span class="na"&gt;config&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;slack_url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${SLACK_WEBHOOK}&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;memory&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;think&lt;/span&gt;
&lt;span class="na"&gt;instructions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
  &lt;span class="s"&gt;Monitor application logs for errors, performance issues, and security threats.&lt;/span&gt;
  &lt;span class="s"&gt;When critical issues are detected:&lt;/span&gt;
  &lt;span class="s"&gt;1. Use 'think' to analyze the severity&lt;/span&gt;
  &lt;span class="s"&gt;2. Check 'memory' for similar past incidents&lt;/span&gt;
  &lt;span class="s"&gt;3. Send appropriate alerts via webhook&lt;/span&gt;

  &lt;span class="s"&gt;Severity levels:&lt;/span&gt;
  &lt;span class="s"&gt;- CRITICAL: Immediate Slack alert&lt;/span&gt;
  &lt;span class="s"&gt;- WARNING: Hourly digest&lt;/span&gt;
  &lt;span class="s"&gt;- INFO: Daily summary&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Integração com Docker Hub
&lt;/h2&gt;

&lt;p&gt;Uma das features mais interessantes é a capacidade de compartilhar agentes como imagens Docker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Construir e publicar um agente&lt;/span&gt;
cagent build &lt;span class="nt"&gt;-f&lt;/span&gt; my-agent.yml &lt;span class="nt"&gt;-t&lt;/span&gt; username/my-agent:latest
cagent push username/my-agent:latest

&lt;span class="c"&gt;# Em outro projeto, usar o agente&lt;/span&gt;
cagent pull username/my-agent:latest
cagent run username/my-agent &lt;span class="s2"&gt;"Execute task here"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso cria um ecossistema onde a comunidade pode compartilhar agentes especializados, similar ao que aconteceu com imagens Docker tradicionais.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance e Escalabilidade
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Execução Local vs Nuvem
&lt;/h3&gt;

&lt;p&gt;O cagent permite estratégias híbridas interessantes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hybrid-processing-agent&lt;/span&gt;
&lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;openai&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gpt-4&lt;/span&gt;
  &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;local&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;llama-3-8b&lt;/span&gt;
    &lt;span class="na"&gt;endpoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://localhost:8080/v1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Otimização de Custos
&lt;/h3&gt;

&lt;p&gt;Para projetos que fazem muitas chamadas de API, você pode usar modelos menores para tarefas simples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;smart-routing-agent&lt;/span&gt;
&lt;span class="na"&gt;agents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;classifier&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;openai&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gpt-3.5-turbo&lt;/span&gt;  &lt;span class="c1"&gt;# Mais barato para classificação&lt;/span&gt;
    &lt;span class="na"&gt;instructions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
      &lt;span class="s"&gt;Classify incoming requests as SIMPLE or COMPLEX&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;simple-handler&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;local&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;small-model&lt;/span&gt;
    &lt;span class="na"&gt;instructions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
      &lt;span class="s"&gt;Handle simple, straightforward requests&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;complex-handler&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;openai&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gpt-4&lt;/span&gt;  &lt;span class="c1"&gt;# Modelo mais caro só quando necessário&lt;/span&gt;
    &lt;span class="na"&gt;instructions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
      &lt;span class="s"&gt;Handle complex requests requiring deep reasoning&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Considerações Técnicas e Implementação
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Gerenciamento de Estado e Memória
&lt;/h3&gt;

&lt;p&gt;O cagent inclui ferramentas de memória que persistem contexto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;memory&lt;/span&gt;
    &lt;span class="na"&gt;config&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;persistent&lt;/span&gt;
      &lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;redis://localhost:6379&lt;/span&gt;
      &lt;span class="na"&gt;ttl&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;7d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Integração com CI/CD
&lt;/h3&gt;

&lt;p&gt;Exemplo de integração com GitHub Actions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .github/workflows/agent-deploy.yml&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy Agent&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install cagent&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;curl -fsSL https://get.cagent.dev | sh&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build and deploy agent&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;cagent build -f agents/production-agent.yml -t company/prod-agent:${{ github.sha }}&lt;/span&gt;
          &lt;span class="s"&gt;cagent push company/prod-agent:${{ github.sha }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Monitoramento e Observabilidade
&lt;/h3&gt;

&lt;p&gt;Para ambientes de produção, o cagent oferece métricas built-in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;monitoring&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;metrics&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;response_time&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;token_usage&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;error_rate&lt;/span&gt;
  &lt;span class="na"&gt;export&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;prometheus&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;endpoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://prometheus:9090&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Primeiros Passos e Implementação
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Instalação
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Via curl (recomendado)&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://get.cagent.dev | sh

&lt;span class="c"&gt;# Via Docker&lt;/span&gt;
docker pull docker/cagent:latest
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;cagent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"docker run --rm -v &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;:/workspace docker/cagent"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Seu Primeiro Agente
&lt;/h3&gt;

&lt;p&gt;Crie um arquivo &lt;code&gt;hello-agent.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hello-world-agent&lt;/span&gt;
&lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;openai&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gpt-3.5-turbo&lt;/span&gt;
&lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;think&lt;/span&gt;
&lt;span class="na"&gt;instructions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
  &lt;span class="s"&gt;You are a helpful assistant that always thinks before responding.&lt;/span&gt;
  &lt;span class="s"&gt;Be concise but thorough in your explanations.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cagent build &lt;span class="nt"&gt;-f&lt;/span&gt; hello-agent.yml
cagent run hello-world-agent &lt;span class="s2"&gt;"Explain quantum computing in simple terms"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Projeto Prático: Bot de Suporte Técnico
&lt;/h3&gt;

&lt;p&gt;Vamos criar um sistema mais elaborado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Estrutura do projeto&lt;/span&gt;
tech-support-bot/
├── agents/
│   ├── triager.yml
│   ├── specialist.yml
│   └── coordinator.yml
├── tools/
│   └── ticket-system.yml
└── docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;agents/coordinator.yml:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;support-coordinator&lt;/span&gt;
&lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;anthropic&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;claude-3-sonnet&lt;/span&gt;
&lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ticket-system&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;think&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;memory&lt;/span&gt;
&lt;span class="na"&gt;agents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;level1-support&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;openai&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gpt-3.5-turbo&lt;/span&gt;
    &lt;span class="na"&gt;instructions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Handle basic technical questions&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;level2-support&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;openai&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gpt-4&lt;/span&gt;
    &lt;span class="na"&gt;instructions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Handle complex technical issues&lt;/span&gt;

&lt;span class="na"&gt;instructions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
  &lt;span class="s"&gt;You coordinate technical support requests.&lt;/span&gt;
  &lt;span class="s"&gt;1. Analyze the incoming request&lt;/span&gt;
  &lt;span class="s"&gt;2. Route to appropriate support level&lt;/span&gt;
  &lt;span class="s"&gt;3. Track resolution progress&lt;/span&gt;
  &lt;span class="s"&gt;4. Ensure customer satisfaction&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Por Que Isso É Revolucionário
&lt;/h2&gt;

&lt;p&gt;O cagent não é apenas mais uma ferramenta de IA, representa uma mudança fundamental em como pensamos sobre desenvolvimento com inteligência artificial. Assim como o Docker democratizou containers, o cagent pode democratizar agentes IA.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Impacto no Desenvolvimento:&lt;/strong&gt; Desenvolvedores podem focar na lógica de negócios invés de configuração complexa de IA. É a mesma revolução que vimos quando passou de servidores físicos para containers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ecossistema Colaborativo:&lt;/strong&gt; A capacidade de compartilhar agentes via Docker Hub pode criar um marketplace de especialistas artificiais, acelerando adoção de boas práticas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Redução de Custos:&lt;/strong&gt; Orquestração inteligente permite usar modelos apropriados para cada tarefa, otimizando custos operacionais.&lt;/p&gt;

&lt;h2&gt;
  
  
  Próximos passos
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Experimente localmente:&lt;/strong&gt; Comece com um agente simples usando modelos gratuitos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explore exemplos:&lt;/strong&gt; O repositório oficial tem templates práticos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integre gradualmente:&lt;/strong&gt; Adicione agentes em processos não-críticos primeiro&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contribua com a comunidade:&lt;/strong&gt; Compartilhe seus agentes especializados&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A revolução dos agentes IA começou. Com cagent, você tem as ferramentas para liderar essa transformação na sua empresa ou projetos pessoais.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Teste o cagent hoje e compartilhe sua experiência nos comentários. Qual seria seu primeiro caso de uso?&lt;/em&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>programming</category>
      <category>ai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Go 1.25: JSON v2 e Novo GC</title>
      <dc:creator>Rafael Pazini</dc:creator>
      <pubDate>Wed, 20 Aug 2025 21:50:28 +0000</pubDate>
      <link>https://dev.to/rflpazini/go-125-json-v2-e-novo-gc-4k07</link>
      <guid>https://dev.to/rflpazini/go-125-json-v2-e-novo-gc-4k07</guid>
      <description>&lt;p&gt;Chegou o Go 1.25 e, sinceramente, é sobre tempo. Duas mudanças que vão fazer diferença real no seu dia a dia: o &lt;strong&gt;JSON v2 experimental&lt;/strong&gt; que não é uma piada de performance e o &lt;strong&gt;GreenteaGC&lt;/strong&gt; que promete parar de sugar sua CPU.&lt;/p&gt;

&lt;p&gt;Vamos ver o que realmente mudou e se vale a pena migrar (spoiler: provavelmente sim).&lt;/p&gt;

&lt;h2&gt;
  
  
  Por que o JSON v2 existe?
&lt;/h2&gt;

&lt;p&gt;O &lt;code&gt;encoding/json&lt;/code&gt; padrão é tipo aquele colega de trabalho: faz o trabalho, mas reclama o tempo todo. Lento, cheio de alocações desnecessárias, e você sempre acaba procurando alternativas como &lt;a href="https://github.com/mailru/easyjson" rel="noopener noreferrer"&gt;EasyJSON&lt;/a&gt; ou &lt;a href="https://github.com/json-iterator/go" rel="noopener noreferrer"&gt;JSONIterator&lt;/a&gt; quando a coisa aperta.&lt;/p&gt;

&lt;p&gt;A equipe do Go finalmente acordou e disse: "Ok, vamos fazer direito dessa vez. "&lt;/p&gt;

&lt;p&gt;Como testar?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;GOEXPERIMENT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;jsonv2 go run main.go

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exemplo básico que funciona de verdade:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;jsonv2&lt;/span&gt; &lt;span class="s"&gt;"encoding/json/v2"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ID&lt;/span&gt;    &lt;span class="kt"&gt;int&lt;/span&gt;    &lt;span class="s"&gt;`json:"id"`&lt;/span&gt;
    &lt;span class="n"&gt;Name&lt;/span&gt;  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"name"`&lt;/span&gt;
    &lt;span class="n"&gt;Email&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"email"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;`{"id": 1, "name": "Rafael", "email": "me@rflpazini.sh"}`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;jsonv2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Usuário: %+v&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;jsonv2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  O que mudou na implementação do JSON v2
&lt;/h2&gt;

&lt;p&gt;A nova implementação não é apenas uma otimização superficial do código existente. A equipe do Go &lt;strong&gt;reescreveu o parser do zero&lt;/strong&gt;, focando em três problemas principais que atormentavam o &lt;code&gt;encoding/json&lt;/code&gt; original: &lt;strong&gt;alocações excessivas&lt;/strong&gt;, &lt;strong&gt;parsing sequencial ineficiente&lt;/strong&gt;, e &lt;strong&gt;falta de suporte nativo para streaming&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Arquitetura otimizada para Menos Alocações
&lt;/h3&gt;

&lt;p&gt;O maior vilão do JSON v1 sempre foram as alocações desnecessárias. Cada vez que você fazia &lt;code&gt;json.Unmarshal&lt;/code&gt; em uma struct grande, o parser criava dezenas de objetos intermediários (buffers temporários, slices auxiliares, interfaces{} para cada valor).&lt;/p&gt;

&lt;p&gt;O v2 introduz um &lt;strong&gt;sistema de pooling interno&lt;/strong&gt; e &lt;strong&gt;reutilização de buffers&lt;/strong&gt; que reduz drasticamente essas alocações. Em vez de criar novos objetos a cada operação, ele mantém pools de estruturas reutilizáveis que são recicladas entre chamadas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"encoding/json/v2"&lt;/span&gt;
    &lt;span class="s"&gt;"runtime"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;LargeStruct&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Users&lt;/span&gt;    &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;            &lt;span class="s"&gt;`json:"users"`&lt;/span&gt;
    &lt;span class="n"&gt;Metadata&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"metadata"`&lt;/span&gt;
    &lt;span class="n"&gt;Settings&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;Setting&lt;/span&gt;         &lt;span class="s"&gt;`json:"settings"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ID&lt;/span&gt;       &lt;span class="kt"&gt;int&lt;/span&gt;      &lt;span class="s"&gt;`json:"id"`&lt;/span&gt;
    &lt;span class="n"&gt;Name&lt;/span&gt;     &lt;span class="kt"&gt;string&lt;/span&gt;   &lt;span class="s"&gt;`json:"name"`&lt;/span&gt;
    &lt;span class="n"&gt;Email&lt;/span&gt;    &lt;span class="kt"&gt;string&lt;/span&gt;   &lt;span class="s"&gt;`json:"email"`&lt;/span&gt;
    &lt;span class="n"&gt;Tags&lt;/span&gt;     &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"tags"`&lt;/span&gt;
    &lt;span class="n"&gt;Profile&lt;/span&gt;  &lt;span class="n"&gt;Profile&lt;/span&gt;  &lt;span class="s"&gt;`json:"profile"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Profile&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Bio&lt;/span&gt;       &lt;span class="kt"&gt;string&lt;/span&gt;            &lt;span class="s"&gt;`json:"bio"`&lt;/span&gt;
    &lt;span class="n"&gt;Avatar&lt;/span&gt;    &lt;span class="kt"&gt;string&lt;/span&gt;            &lt;span class="s"&gt;`json:"avatar"`&lt;/span&gt;
    &lt;span class="n"&gt;Socials&lt;/span&gt;   &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"socials"`&lt;/span&gt;
    &lt;span class="n"&gt;Metadata&lt;/span&gt;  &lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;       &lt;span class="s"&gt;`json:"metadata"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Setting&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Key&lt;/span&gt;   &lt;span class="kt"&gt;string&lt;/span&gt;      &lt;span class="s"&gt;`json:"key"`&lt;/span&gt;
    &lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="s"&gt;`json:"value"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;demonstrateAllocations&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;`{
        "users": [
            {
                "id": 1,
                "name": "João Silva",
                "email": "joao@example.com",
                "tags": ["admin", "premium"],
                "profile": {
                    "bio": "Desenvolvedor Go há 5 anos",
                    "avatar": "https://example.com/avatar1.jpg",
                    "socials": {"github": "joaosilva", "twitter": "@joao"},
                    "metadata": {"level": 5, "badges": ["expert", "mentor"]}
                }
            }
        ],
        "metadata": {
            "version": "2.1",
            "timestamp": "2024-12-01T10:00:00Z"
        },
        "settings": [
            {"key": "theme", "value": "dark"},
            {"key": "notifications", "value": true}
        ]
    }`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="n"&gt;LargeStruct&lt;/span&gt;

    &lt;span class="c"&gt;// Measure allocations&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;m1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m2&lt;/span&gt; &lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MemStats&lt;/span&gt;
    &lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GC&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadMemStats&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;m1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GC&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadMemStats&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;m2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Alocações: %d bytes&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TotalAlloc&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;m1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TotalAlloc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Objetos criados: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Mallocs&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;m1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Mallocs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Parser não-sequencial e streaming nativo
&lt;/h3&gt;

&lt;p&gt;Outra mudança fundamental: o v1 sempre processava JSON de forma &lt;strong&gt;estritamente sequencial&lt;/strong&gt;, lia byte por byte, construindo a estrutura na ordem exata do documento. Isso funcionava, mas era ineficiente para JSONs grandes.&lt;/p&gt;

&lt;p&gt;O v2 implementa &lt;strong&gt;parsing em chunks&lt;/strong&gt; e &lt;strong&gt;streaming nativo&lt;/strong&gt;. Para JSONs grandes, ele pode processar pedaços do documento simultaneamente e construir a estrutura final de forma mais eficiente. Isso é especialmente poderoso quando você está lidando com arrays grandes ou objetos com muitas propriedades.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;jsonv2&lt;/span&gt; &lt;span class="s"&gt;"encoding/json/v2"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"strings"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;timeSeriesData&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;`{
        "metric": "cpu_usage",
        "timestamps": [1609459200, 1609459260, 1609459320, 1609459380, 1609459440],
        "values": [45.2, 67.8, 23.1, 89.5, 12.7, 56.3, 78.9, 34.6, 91.2, 18.4],
        "labels": ["server1", "server2", "server3", "server4", "server5"]
    }`&lt;/span&gt;

    &lt;span class="c"&gt;// Repete o JSON para simular um dataset maior&lt;/span&gt;
    &lt;span class="c"&gt;// Cada item separado por vírgula&lt;/span&gt;
    &lt;span class="n"&gt;repeticoes&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;1000&lt;/span&gt;
    &lt;span class="n"&gt;bigData&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;strings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timeSeriesData&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s"&gt;","&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;repeticoes&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;timeSeriesData&lt;/span&gt;
    &lt;span class="n"&gt;bigJSON&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"["&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;bigData&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"]"&lt;/span&gt;

    &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;TimeSeriesPoint&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Metric&lt;/span&gt;     &lt;span class="kt"&gt;string&lt;/span&gt;    &lt;span class="s"&gt;`json:"metric"`&lt;/span&gt;
        &lt;span class="n"&gt;Timestamps&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int64&lt;/span&gt;   &lt;span class="s"&gt;`json:"timestamps"`&lt;/span&gt;
        &lt;span class="n"&gt;Values&lt;/span&gt;     &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;float64&lt;/span&gt; &lt;span class="s"&gt;`json:"values"`&lt;/span&gt;
        &lt;span class="n"&gt;Labels&lt;/span&gt;     &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;  &lt;span class="s"&gt;`json:"labels"`&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;TimeSeriesPoint&lt;/span&gt;
    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;jsonv2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bigJSON&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;parseTime&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Since&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Erro: %v&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;totalValues&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;totalValues&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Values&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Parsed %d time series points com %d valores em %v&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;totalValues&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;parseTime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Throughput: %.0f valores/segundo&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="kt"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;totalValues&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;parseTime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Seconds&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Otimizações específicas para tipos comuns
&lt;/h3&gt;

&lt;p&gt;O v2 também inclui &lt;strong&gt;fast paths&lt;/strong&gt; otimizados para tipos que aparecem frequentemente em APIs modernas:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Strings e números&lt;/strong&gt; têm parsing especializado que evita conversões desnecessárias. &lt;strong&gt;Maps com chaves string&lt;/strong&gt; (o caso mais comum) têm tratamento otimizado. &lt;strong&gt;Slices de tipos primitivos&lt;/strong&gt; são processados em lotes quando possível.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;APIResponseOptimized&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Success&lt;/span&gt;    &lt;span class="kt"&gt;bool&lt;/span&gt;              &lt;span class="s"&gt;`json:"success"`&lt;/span&gt;
    &lt;span class="n"&gt;Data&lt;/span&gt;       &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;          &lt;span class="s"&gt;`json:"data"`&lt;/span&gt;        &lt;span class="c"&gt;// fast path para slice de strings&lt;/span&gt;
    &lt;span class="n"&gt;Count&lt;/span&gt;      &lt;span class="kt"&gt;int&lt;/span&gt;               &lt;span class="s"&gt;`json:"count"`&lt;/span&gt;       &lt;span class="c"&gt;// fast path para números&lt;/span&gt;
    &lt;span class="n"&gt;Metadata&lt;/span&gt;   &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"metadata"`&lt;/span&gt;    &lt;span class="c"&gt;// fast path para map[string]string&lt;/span&gt;
    &lt;span class="n"&gt;Timestamp&lt;/span&gt;  &lt;span class="kt"&gt;float64&lt;/span&gt;           &lt;span class="s"&gt;`json:"timestamp"`&lt;/span&gt;   &lt;span class="c"&gt;// fast path para float64&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Mensagens de erro mais úteis&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Um bônus que todo mundo vai amar: as mensagens de erro ficaram muito melhores. Em vez de "invalid character 'x' looking for beginning of value", agora você recebe contexto real:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Exemplo de JSON inválido&lt;/span&gt;
&lt;span class="n"&gt;badJSON&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;`{
    "users": [
        {"name": "João", "age": 30},
        {"name": "Maria", "age": "invalid"}, // erro aqui
        {"name": "Pedro", "age": 25}
    ]
}`&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Users&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"name"`&lt;/span&gt;
        &lt;span class="n"&gt;Age&lt;/span&gt;  &lt;span class="kt"&gt;int&lt;/span&gt;    &lt;span class="s"&gt;`json:"age"`&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="s"&gt;`json:"users"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;badJSON&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c"&gt;// v2 retorna algo como: "cannot unmarshal string into Go struct field .Users[1].Age of type int at line 4, column 32"&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quando vale usar? Se você processa muito JSON por segundo, trabalha com streaming de dados grandes, ou simplesmente está cansado de debuggar mensagens de erro confusas. A nova implementação resolve esses três problemas de uma vez.&lt;/p&gt;

&lt;h2&gt;
  
  
  GreenteaGC: Entendendo o Novo Coletor de Lixo
&lt;/h2&gt;

&lt;p&gt;Antes de falar do novo GC, preciso explicar por que o atual às vezes é um problema. O Go usa um coletor &lt;strong&gt;concurrent mark-and-sweep tricolor&lt;/strong&gt; desde a versão 1.5. Parece complexo, mas a ideia é simples: ele funciona junto com seu programa (concurrent), marca objetos que ainda estão sendo usados (mark), e depois varre os não marcados para liberar memória (sweep). O "tricolor" é só o algoritmo usado para marcar sem quebrar referências.&lt;/p&gt;

&lt;p&gt;O problema? Esse processo, mesmo sendo concurrent, ainda compete por recursos de CPU e pode causar &lt;strong&gt;pausas perceptíveis&lt;/strong&gt; em momentos críticos. Pior ainda: em programas que criam muitos objetos de vida curta (tipo APIs que processam requests), o GC pode ficar numa corrida constante tentando limpar a bagunça.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;O Que GreenteaGC Muda na Prática&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Como ativar o experimental:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;GOEXPERIMENT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;greenteagc go run main.go

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O &lt;code&gt;greenteagc&lt;/code&gt; reimplementa partes fundamentais do coletor com foco em &lt;strong&gt;reduzir o overhead por objeto&lt;/strong&gt; e &lt;strong&gt;diminuir o trabalho paralelo desnecessário&lt;/strong&gt;. Na prática, isso significa que ele é mais esperto sobre quando coletar lixo e quanto CPU gastar nisso.&lt;/p&gt;

&lt;p&gt;A grande diferença está na forma como ele lida com &lt;strong&gt;objetos pequenos e temporários&lt;/strong&gt;. O GC atual trata todos os objetos meio que igual - um &lt;code&gt;string&lt;/code&gt; de 10 bytes recebe o mesmo tipo de atenção que um slice gigante. O novo coletor tem estratégias diferentes baseadas no tamanho e padrão de uso dos objetos.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Onde Você Sente a Diferença&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;APIs de alta frequência&lt;/strong&gt; são o caso clássico. Imagine um endpoint que recebe 10.000 requests por segundo. Cada request cria várias structs temporárias, slices para processar dados, maps para organizar responses. Com o GC atual, toda essa criação/destruição gera trabalho constante para o coletor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"net/http"&lt;/span&gt;
    &lt;span class="s"&gt;"encoding/json/v2"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
    &lt;span class="s"&gt;"strconv"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;APIResponse&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Message&lt;/span&gt;    &lt;span class="kt"&gt;string&lt;/span&gt;            &lt;span class="s"&gt;`json:"message"`&lt;/span&gt;
    &lt;span class="n"&gt;Timestamp&lt;/span&gt;  &lt;span class="kt"&gt;int64&lt;/span&gt;             &lt;span class="s"&gt;`json:"timestamp"`&lt;/span&gt;
    &lt;span class="n"&gt;RequestID&lt;/span&gt;  &lt;span class="kt"&gt;string&lt;/span&gt;            &lt;span class="s"&gt;`json:"request_id"`&lt;/span&gt;
    &lt;span class="n"&gt;Metadata&lt;/span&gt;   &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"metadata"`&lt;/span&gt;
    &lt;span class="n"&gt;Processing&lt;/span&gt; &lt;span class="n"&gt;ProcessingInfo&lt;/span&gt;    &lt;span class="s"&gt;`json:"processing"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;ProcessingInfo&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;StartTime&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Time&lt;/span&gt; &lt;span class="s"&gt;`json:"start_time"`&lt;/span&gt;
    &lt;span class="n"&gt;Duration&lt;/span&gt;  &lt;span class="kt"&gt;string&lt;/span&gt;    &lt;span class="s"&gt;`json:"duration"`&lt;/span&gt;
    &lt;span class="n"&gt;Steps&lt;/span&gt;     &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;  &lt;span class="s"&gt;`json:"steps"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;processRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c"&gt;// Cada request cria várias structs e slices temporários&lt;/span&gt;
    &lt;span class="n"&gt;steps&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;steps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"validation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"processing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"formatting"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;metadata&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"user_agent"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserAgent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Method&lt;/span&gt;
    &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;

    &lt;span class="n"&gt;processing&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ProcessingInfo&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;StartTime&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Since&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;Steps&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;APIResponse&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="s"&gt;"Request processed successfully"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Timestamp&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unix&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;RequestID&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"req_"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;strconv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FormatInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UnixNano&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;Metadata&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Processing&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;processing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewEncoder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HandleFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/process"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;processRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ListenAndServe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;":8080"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pipelines de dados&lt;/strong&gt; também se beneficiam muito. Quando você processa milhares de registros por minuto, cada um passando por várias transformações que criam objetos intermediários, o GC tradicional pode virar gargalo real.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;DataPipeline&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;Record&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Record&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ID&lt;/span&gt;        &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Data&lt;/span&gt;      &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="n"&gt;Metadata&lt;/span&gt;  &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Processed&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Time&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;DataPipeline&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;ProcessBatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rawData&lt;/span&gt; &lt;span class="p"&gt;[][]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;Record&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="n"&gt;Record&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rawData&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;rawData&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;// Cada iteração cria vários objetos temporários&lt;/span&gt;
        &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;intermediate&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
        &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;intermediate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;metadata&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;extractMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;intermediate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;processed&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;transformData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;intermediate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Record&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;        &lt;span class="n"&gt;generateID&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;      &lt;span class="n"&gt;processed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Metadata&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Processed&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Os números que importam
&lt;/h3&gt;

&lt;p&gt;Em benchmarks divulgados pela equipe do Go, o &lt;code&gt;greenteagc&lt;/code&gt; mostra &lt;strong&gt;reduções de overhead entre 10% e 40%&lt;/strong&gt;, dependendo do padrão de alocação. Isso se traduz em:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Menos pausas perceptíveis&lt;/strong&gt;: aqueles microfreezees de 5-15ms que aparecem no percentil 99 de latência diminuem significativamente.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Melhor throughput sustentado&lt;/strong&gt;: menos CPU gasta em GC = mais CPU disponível para seu código.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comportamento mais previsível&lt;/strong&gt;: menos variação na latência, especialmente importante para sistemas que precisam de SLA consistente.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cenários que mais se beneficiam
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Serviços em containers&lt;/strong&gt; são um caso especial. Quando você roda no Kubernetes com limites de CPU bem definidos, cada ciclo desperdiçado pelo GC é um ciclo que não está processando requests reais. O novo coletor entende melhor esses limites e se adapta.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sistemas de alta concorrência&lt;/strong&gt; onde você tem centenas ou milhares de goroutines criando objetos simultaneamente. O GC atual pode ter dificuldade para coordenar a limpeza entre todas essas threads. O &lt;code&gt;greenteagc&lt;/code&gt; tem estratégias melhores para lidar com essa complexidade.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Aplicações que fazem marshaling/unmarshaling intensivo&lt;/strong&gt; - que é exatamente onde o JSON v2 também ajuda. A combinação dos dois pode ser especialmente poderosa: menos alocações na serialização JSON + GC mais eficiente para limpar o que sobra.&lt;/p&gt;

&lt;p&gt;Com o &lt;code&gt;greenteagc&lt;/code&gt;, você não vai ver milagres, mas vai notar estabilidade maior na latência e uso mais eficiente de recursos. É especialmente visível em load testing sustentado, onde o comportamento do GC ao longo do tempo faz mais diferença que picos isolados.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparação Honesta: JSON v2 vs EasyJSON
&lt;/h2&gt;

&lt;p&gt;Durante anos, se você queria performance real com JSON em Go, tinha que partir pro EasyJSON. Gerava código otimizado, era rápido, mas que trabalhão configurar e manter.&lt;/p&gt;

&lt;p&gt;Os números que importam:&lt;/p&gt;

&lt;p&gt;Para &lt;strong&gt;unmarshaling de structs&lt;/strong&gt;: JSON v2 chegou bem perto, às vezes até superando quando você tem muitos &lt;code&gt;interface{}&lt;/code&gt; e &lt;code&gt;map[string]any&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Para &lt;strong&gt;marshaling de dados conhecidos&lt;/strong&gt;: EasyJSON ainda leva vantagem, mas a diferença não é mais abismal.&lt;/p&gt;

&lt;p&gt;Para &lt;strong&gt;casos genéricos&lt;/strong&gt;: JSON v2 destroi tanto o v1 quanto o EasyJSON, porque foi otimizado exatamente para isso.&lt;/p&gt;

&lt;p&gt;A interpretação honesta? Se você quer simplicidade e performance decente, teste JSON v2. Se você quer exprimir cada ciclo de CPU e já tem estruturas definidas, EasyJSON ainda é rei. Mas agora pelo menos temos escolha real.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benchmark com dados do mundo real
&lt;/h2&gt;

&lt;p&gt;Vamos usar dados do &lt;strong&gt;GitHub Archive&lt;/strong&gt;, ou seja, JSONs reais, grandes, variados. É o teste mais honesto possível, sem truque de benchmark sintético.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Você consegue encontrar todos esses exemplos, no meu &lt;a href="https://github.com/rflpazini/articles/tree/main/json_v2" rel="noopener noreferrer"&gt;repositório do github&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Primeiro, baixando os dados:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; data &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;data
curl &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; 2025-07-01-12.json.gz &lt;span class="se"&gt;\&lt;/span&gt;
  https://data.gharchive.org/2025-07-01-12.json.gz
&lt;span class="nb"&gt;gzip&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; 2025-07-01-12.json.gz   &lt;span class="c"&gt;# valida o arquivo&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; ..

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Setup do teste (estrutura organizada):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bench-json/
├── go.mod
├── benchmark
│   ├── bench_v1_test.go
│   └── bench_v2_test.go
└── internal/
    └── ndjson.go         # helpers de leitura

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Helpers para lidar com NDJSON (internal/ndjson.go):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;internal&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"bufio"&lt;/span&gt;
    &lt;span class="s"&gt;"io"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;ScanLinesNoAlloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;atEOF&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;advance&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;atEOF&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;indexByte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'\n'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;atEOF&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;indexByte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;NewNDJSONScanner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Reader&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;bufio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Scanner&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;bufio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewScanner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1024&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="m"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;64&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="m"&gt;1024&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="m"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// até 64 MB/linha&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ScanLinesNoAlloc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Benchmark para v1 (bench_v1_test.go):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"bufio"&lt;/span&gt;
    &lt;span class="s"&gt;"compress/gzip"&lt;/span&gt;
    &lt;span class="s"&gt;"os"&lt;/span&gt;
    &lt;span class="s"&gt;"testing"&lt;/span&gt;
    &lt;span class="s"&gt;"encoding/json"&lt;/span&gt; &lt;span class="c"&gt;// v1&lt;/span&gt;

    &lt;span class="s"&gt;"github.com/rflpazini/jsonv2/internal"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="n"&gt;any&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;benchmarkNDJSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReportAllocs&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;gz&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;gzip&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;internal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewNDJSONScanner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bufio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gz&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

        &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
        &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;bytesProcessed&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Scan&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bytes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;bytesProcessed&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="kt"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;ev&lt;/span&gt; &lt;span class="n"&gt;Event&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ev&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ev&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;gz&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytesProcessed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Benchmark_V1_GHArchive_UnmarshalMap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;benchmarkNDJSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"data/2025-07-01-12.json.gz"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Benchmark para a v2 (bench_v2_test.go):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"bufio"&lt;/span&gt;
    &lt;span class="s"&gt;"compress/gzip"&lt;/span&gt;
    &lt;span class="n"&gt;jsonv2&lt;/span&gt; &lt;span class="s"&gt;"encoding/json/v2"&lt;/span&gt;
    &lt;span class="s"&gt;"os"&lt;/span&gt;
    &lt;span class="s"&gt;"testing"&lt;/span&gt;

    &lt;span class="s"&gt;"github.com/rflpazini/jsonv2/internal"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;benchmarkNDJSONv2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReportAllocs&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;gz&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;gzip&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;internal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewNDJSONScanner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bufio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gz&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

        &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Scan&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bytes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;ev&lt;/span&gt; &lt;span class="n"&gt;Event&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;jsonv2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ev&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ev&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;gz&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Benchmark_V2_GHArchive_UnmarshalMap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;benchmarkNDJSONv2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"../data/2025-07-01-12.json.gz"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como rodar os testes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# v1 padrão&lt;/span&gt;
go &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;-bench&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;UnmarshalMap &lt;span class="nt"&gt;-run&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;^&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nt"&gt;-benchmem&lt;/span&gt; ./...

&lt;span class="c"&gt;# v2 experimental&lt;/span&gt;
&lt;span class="nv"&gt;GOEXPERIMENT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;jsonv2 go &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;-bench&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;UnmarshalMap &lt;span class="nt"&gt;-run&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;^&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nt"&gt;-benchmem&lt;/span&gt; ./...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Resultados que você sente na prática
&lt;/h2&gt;

&lt;p&gt;Rodei o benchmark com dados reais do GitHub Archive no meu MacBook M3 Pro. Vou traduzir os números técnicos para o que isso significa no seu dia a dia:&lt;/p&gt;

&lt;h3&gt;
  
  
  ⏱️ Latência da API
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Antes (JSON v1):&lt;/strong&gt; Sua API que processa 150MB de dados JSON demora &lt;strong&gt;5.38 segundos&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Depois (JSON v2):&lt;/strong&gt; A mesma API agora demora &lt;strong&gt;3.63 segundos&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Na prática:&lt;/strong&gt; Se sua API respondia em 200ms, agora responde em &lt;strong&gt;135ms&lt;/strong&gt;. É a diferença entre uma API que parece rápida e uma que parece instantânea.&lt;/p&gt;

&lt;h3&gt;
  
  
  💾 Uso de Memória
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Antes:&lt;/strong&gt; Para processar esses dados, Go aloca &lt;strong&gt;2.47GB de memória&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Depois:&lt;/strong&gt; Agora aloca apenas &lt;strong&gt;2.29GB&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Na prática:&lt;/strong&gt; &lt;strong&gt;180MB a menos de pressão no GC&lt;/strong&gt;. Isso significa menos pausas, menos CPU gasta limpando lixo, containers mais estáveis no Kubernetes.&lt;/p&gt;

&lt;h3&gt;
  
  
  🚀 Throughput
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Antes:&lt;/strong&gt; Processava dados a &lt;strong&gt;0.03 MB/s&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Depois:&lt;/strong&gt; Agora processa a &lt;strong&gt;0.05 MB/s&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Na prática:&lt;/strong&gt; Uma API que conseguia processar &lt;strong&gt;1000 requests/segundo&lt;/strong&gt; agora processa &lt;strong&gt;1480 requests/segundo&lt;/strong&gt; com a mesma máquina.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔧 Objetos Criados
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Antes:&lt;/strong&gt; Criou &lt;strong&gt;47 milhões&lt;/strong&gt; de objetos temporários&lt;br&gt;
&lt;strong&gt;Depois:&lt;/strong&gt; Criou apenas &lt;strong&gt;36 milhões&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Na prática:&lt;/strong&gt; &lt;strong&gt;11 milhões&lt;/strong&gt; a menos de trabalho para o Garbage Collector. Menos interrupções, menos spikes de CPU, comportamento mais previsível.&lt;/p&gt;

&lt;h3&gt;
  
  
  💰 Custo Real
&lt;/h3&gt;

&lt;p&gt;Se você roda no AWS/GCP e processa &lt;strong&gt;1TB de JSON por mês&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Antes:&lt;/strong&gt; Precisava de uma instância de &lt;strong&gt;4 vCPUs&lt;/strong&gt; para manter latência aceitável&lt;br&gt;
&lt;strong&gt;Depois:&lt;/strong&gt; Consegue rodar na mesma carga com &lt;strong&gt;3 vCPUs&lt;/strong&gt; ou processar 48% mais dados na mesma máquina&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Economia:&lt;/strong&gt; ~$50-100/mês por instância, dependendo da região e tipo de máquina.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;📊 Resumo Visual&lt;/strong&gt;
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;MÉTRICA&lt;/th&gt;
&lt;th&gt;JSON v1&lt;/th&gt;
&lt;th&gt;JSON v2&lt;/th&gt;
&lt;th&gt;MELHORIA&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Tempo de resposta&lt;/td&gt;
&lt;td&gt;200ms&lt;/td&gt;
&lt;td&gt;135ms&lt;/td&gt;
&lt;td&gt;32% mais rápido&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Requests/segundo&lt;/td&gt;
&lt;td&gt;1000&lt;/td&gt;
&lt;td&gt;1480&lt;/td&gt;
&lt;td&gt;48% mais throughput&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uso de memória&lt;/td&gt;
&lt;td&gt;2.47GB&lt;/td&gt;
&lt;td&gt;2.29GB&lt;/td&gt;
&lt;td&gt;180MB menos pressão&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pausas do GC&lt;/td&gt;
&lt;td&gt;Visíveis&lt;/td&gt;
&lt;td&gt;Imperceptíveis&lt;/td&gt;
&lt;td&gt;Muito mais estável&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custo mensal (AWS)&lt;/td&gt;
&lt;td&gt;$120&lt;/td&gt;
&lt;td&gt;$80&lt;/td&gt;
&lt;td&gt;$40 economizados&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Isso não é benchmark sintético, são dados reais de eventos do GitHub, com a complexidade e variação que você encontra em produção. A melhoria é real e você vai sentir no monitoramento.&lt;/p&gt;

&lt;h2&gt;
  
  
  Impacto no dia a dia
&lt;/h2&gt;

&lt;p&gt;Onde você vai sentir a diferença? APIs de alta carga vão processar JSON mais rápido, microservices vão se comunicar com menos overhead, pipelines de ETL vão ter menos pausas do GC, e containers no Kubernetes vão usar melhor os limites de CPU.&lt;/p&gt;

&lt;p&gt;Quando migrar? Se você tem APIs que processam muito JSON, sistemas sensíveis à latência, workloads que criam muitos objetos temporários, ou simplesmente curiosidade científica, vale testar agora. É experimental, mas já está estável o suficiente para brincar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vale testar?
&lt;/h2&gt;

&lt;p&gt;Go 1.25 não trouxe apenas melhorias incrementais, trouxe um salto real nas partes que mais usamos: JSON e gerenciamento de memória.&lt;/p&gt;

&lt;p&gt;Para quem quer estabilidade, continue no GC padrão e &lt;code&gt;encoding/json&lt;/code&gt;. Funciona bem, sempre funcionou. Para quem gosta de viver no futuro, ative &lt;code&gt;json/v2&lt;/code&gt; e &lt;code&gt;greenteagc&lt;/code&gt; e meça os resultados. Os números que mostrei são reais e reproduzíveis.&lt;/p&gt;

&lt;p&gt;O melhor do Go sempre foi esse equilíbrio: estabilidade no core, inovação nos experimentos. Agora é nossa vez de testar essas novidades e dar feedback para a comunidade. Teste, meça, e me conta os resultados. Aposto que você vai gostar do que vai encontrar.&lt;/p&gt;

</description>
      <category>go</category>
      <category>softwaredevelopment</category>
      <category>programming</category>
      <category>performance</category>
    </item>
    <item>
      <title>Docker Offload: potência de nuvem com a simplicidade de sempre</title>
      <dc:creator>Rafael Pazini</dc:creator>
      <pubDate>Thu, 10 Jul 2025 20:33:33 +0000</pubDate>
      <link>https://dev.to/rflpazini/docker-offload-potencia-de-nuvem-com-a-simplicidade-de-sempre-3olk</link>
      <guid>https://dev.to/rflpazini/docker-offload-potencia-de-nuvem-com-a-simplicidade-de-sempre-3olk</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Se eu já rodo &lt;code&gt;docker compose up&lt;/code&gt; pra tudo, por que teria de aprender outro comando, ou pior, abrir um console na AWS, só pra treinar um modelo pesado?”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Foi exatamente aí que a galera da Docker acertou em cheio com o &lt;strong&gt;Docker Offload&lt;/strong&gt;: um clique, e o que estava consumindo sua CPU (ou derretendo sua GPU) passa a rodar num runner de nuvem, mas sem mudar seu fluxo local. Vamos aos detalhes.&lt;/p&gt;




&lt;h3&gt;
  
  
  O que é o Docker Offload?
&lt;/h3&gt;

&lt;p&gt;Em poucas palavras, é um serviço que “teleporta” builds e containers para máquinas na nuvem, com GPU NVIDIA L4, mantendo a experiência local. Ele nasceu para o novo mundo dos &lt;strong&gt;agentes de IA&lt;/strong&gt; (Compose 2.0) e tarefas que exigem muito hardware, como LLMs e pipelines de vídeo.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Recurso&lt;/th&gt;
&lt;th&gt;Por que isso importa?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GPU on-demand&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Treine ou execute LLMs sem ter placa dedicada&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Integração nativa com Docker Desktop/Engine&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Mesmos comandos (&lt;code&gt;docker run&lt;/code&gt;, &lt;code&gt;docker compose up&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Sessões efêmeras&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Nada de “limpar servidor” depois&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;300 min grátis + \$0,015/GPU min&lt;/strong&gt; (beta)&lt;/td&gt;
&lt;td&gt;Dá pra testar sem abrir a carteira&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  Debaixo do capô
&lt;/h3&gt;

&lt;p&gt;O Offload reutiliza a infraestrutura que move o &lt;strong&gt;Docker Build Cloud&lt;/strong&gt;, mas vai além: ele não serve só para &lt;em&gt;build&lt;/em&gt;, e sim para execução contínua de containers com GPU. A experiência híbrida (local ↔ nuvem) usa port‑forwarding e bind‑mounts para você nem perceber que algo saiu da sua máquina.&lt;/p&gt;




&lt;h3&gt;
  
  
  Como habilitar em 3 passos
&lt;/h3&gt;

&lt;p&gt;Bora mostrar esse carinha rodando a todo vapor. &lt;/p&gt;

&lt;p&gt;Primeira coisa é garantir que vc tem a versão do Docker Desktop &lt;code&gt;4.43+&lt;/code&gt; e a conta Pro&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker offload start &lt;span class="c"&gt;# para ativar sua sessão&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi44exe81r94vupjiwc0j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi44exe81r94vupjiwc0j.png" alt="docker offload start" width="800" height="278"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker offload status &lt;span class="c"&gt;# para consultar se sua sessão está ativa&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fldv9rln60cl634l9o9u1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fldv9rln60cl634l9o9u1.png" alt="docker offload status" width="800" height="266"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E agora podemos rodar um container para ver mais informações da GPU que estamos utilizando&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;--gpus&lt;/span&gt; all nvidia/cuda:12.4.0-base-ubuntu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5zu5wdq164sbcj5cbbnx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5zu5wdq164sbcj5cbbnx.png" alt="GPU info" width="800" height="487"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Boa Rafa, e se eu quiser rodar um MySQL neste mesmo contexto? Tenho que fazer algo?&lt;/p&gt;

&lt;p&gt;Isso é o legal dessa feature, você só precisa rodar como já estamos acostumados.&lt;/p&gt;

&lt;p&gt;Eu fiz um exemplo de teste, onde criei um Docker Compose com 3 containers:um banco de dados, uma api em Node e um NGINX como servidor http, para exibir uma pagina html simples.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres:16-alpine&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;my-app-net&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_USER=user&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_PASSWORD=password&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_DB=testdb&lt;/span&gt;
    &lt;span class="na"&gt;healthcheck&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CMD-SHELL"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pg_isready&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-U&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-d&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;testdb"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5s&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5s&lt;/span&gt;
      &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;

  &lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;node:22-alpine&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;my-app-net&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="s"&gt;sh -c "npm install -g json-server &amp;amp;&amp;amp; json-server --host 0.0.0.0 --watch db.json"&lt;/span&gt;
    &lt;span class="na"&gt;working_dir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/app&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./api-data:/app&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;condition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;service_healthy&lt;/span&gt;

  &lt;span class="na"&gt;frontend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx:alpine&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;my-app-net&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8080:80"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8081:80"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./nginx-content:/usr/share/nginx/html&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;api&lt;/span&gt;

&lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;my-app-net&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bridge&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para rodar, eu só tenho que garantir que estou no Docker Offload context e rodar o meu Docker compose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up &lt;span class="nt"&gt;--build&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;+] Running 3/3
 ✔ Container offload-db-1        Healthy                                                                                      5.8s
 ✔ Container offload-api-1       Started                                                                                      0.6s
 ✔ Container offload-frontend-1  Started
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E agora eu só acesso a linha &lt;code&gt;localhost:8080&lt;/code&gt;, como se eu estivesse rodando localmente minha aplicação. Simples assim! 😎&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvydam2pfrpky6ckjt300.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvydam2pfrpky6ckjt300.png" alt="Docker offload hello world" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Contextos: Local vs Offload
&lt;/h3&gt;

&lt;p&gt;Quando você ativa o Offload, o Docker cria automaticamente um &lt;strong&gt;contexto&lt;/strong&gt; remoto chamado &lt;code&gt;offload&lt;/code&gt;. Contextos são perfis que apontam o CLI para diferentes &lt;em&gt;daemons&lt;/em&gt;; assim, você muda de “máquina” sem trocar de terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker context &lt;span class="nb"&gt;ls
&lt;/span&gt;NAME             DESCRIPTION                                      DOCKER ENDPOINT                                           ERROR
default          Current DOCKER_HOST based configuration          unix:///var/run/docker.sock
desktop-linux    Docker Desktop                                   unix:///Users/rflpazini/.docker/run/docker.sock
docker-cloud &lt;span class="k"&gt;*&lt;/span&gt;   docker cloud context created by version v0.4.2   unix:///Users/rflpazini/.docker/cloud/docker-cloud.sock
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;O &lt;code&gt;*&lt;/code&gt; indica o contexto &lt;strong&gt;ativo&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;docker context use offload&lt;/code&gt; para mandar todos os comandos para o runner na nuvem.&lt;/li&gt;
&lt;li&gt;Volte para o notebook com &lt;code&gt;docker context use default&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No &lt;strong&gt;Docker Desktop&lt;/strong&gt;, o botão de &lt;strong&gt;toggle Local ↔ Offload&lt;/strong&gt; (☁️) troca automaticamente o contexto; o ícone do notebook muda para uma nuvem, e o header do app fica roxo quando você está em Offload.&lt;br&gt;
&lt;em&gt;Docker Local:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqkkhrsz4bszxfxuj8lah.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqkkhrsz4bszxfxuj8lah.png" alt="Docker local" width="800" height="194"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Docker offload:&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo2dtv1ntt22hamajxqbk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo2dtv1ntt22hamajxqbk.png" alt="Docker Offload" width="800" height="176"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  “Está em BETA, mesmo assim funciona?” - meus testes de estresse
&lt;/h3&gt;

&lt;p&gt;Pensando nisso e durante a ajuda nos testes da ferramenta, estou usando ela fazem 2 dias desde que disponibilizaram para os Docker Captains, eu fiz os seguintes testes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Falha de rede simulada&lt;/strong&gt;. Interrompi o download durante um &lt;code&gt;docker build&lt;/code&gt; gigante via &lt;code&gt;wget&lt;/code&gt;; a sessão se recuperou sem corromper camadas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource exhaustion&lt;/strong&gt;. Disparei OOM matando um container propositalmente e ainda lancei um &lt;em&gt;fork‑bomb&lt;/em&gt;; o runner isolou o caos e o Compose continuou intacto.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compose complexo&lt;/strong&gt;. Subi front‑end, API, DB e Redis, com health‑checks e volumes bind; tudo funcionou.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Workloads de IA&lt;/strong&gt;. Rodei o &lt;strong&gt;gemma‑3‑7B&lt;/strong&gt; via Model Runner com GPU e desempenho semelhante a instâncias GKE equivalentes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Todos os testes funcionaram 100%, sem problemas. Então eu diria que vale a pena usar.&lt;br&gt;
Um ponto te atenção que devemos ter é que neste momento ele está disponível apenas na &lt;code&gt;US East region&lt;/code&gt;, então isso pode afetar um pouco a latencia de seu uso.&lt;/p&gt;




&lt;h3&gt;
  
  
  Custos
&lt;/h3&gt;

&lt;p&gt;Como tudo na vida, existe os custos. E atualmente são estes:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Faixa&lt;/th&gt;
&lt;th&gt;Valor&lt;/th&gt;
&lt;th&gt;Observações&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Primeiros 300 min por mês&lt;/td&gt;
&lt;td&gt;Gratuito&lt;/td&gt;
&lt;td&gt;Renovação automática&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Minuto com GPU&lt;/td&gt;
&lt;td&gt;US$ 0,015&lt;/td&gt;
&lt;td&gt;Cobrados apenas se sessão ativa&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Minuto só CPU&lt;/td&gt;
&lt;td&gt;US$ 0,01&lt;/td&gt;
&lt;td&gt;Útil para pipelines CI pesados&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tráfego de saída&lt;/td&gt;
&lt;td&gt;Sem custo (primeiros 100 GB) / US$ 0,02 por GB (após)&lt;/td&gt;
&lt;td&gt;Cobrança feita por minuto arredondado para cima; desligue a sessão para parar o relógio.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Quando (não) usar
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Use se…&lt;/th&gt;
&lt;th&gt;Talvez não seja a melhor se…&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Precisa de GPU esporádica para IA ou vídeo&lt;/td&gt;
&lt;td&gt;O time já tem cluster Kubernetes com GPUs livres&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Seu laptop é um Mac M3 sem CUDA 😅&lt;/td&gt;
&lt;td&gt;Latência é crítica; os runners estão só em &lt;strong&gt;us‑east‑1&lt;/strong&gt; hoje&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Builds grandes travam seu CI&lt;/td&gt;
&lt;td&gt;Você não tem conta Pro ou quer custo fixo mensal&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  Dicas de produtividade
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Cache inteligente&lt;/strong&gt;. Combine &lt;code&gt;docker buildx build --cache-to=type=registry&lt;/code&gt; com Offload para acelerar builds subsequentes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alias rápido&lt;/strong&gt;. &lt;code&gt;alias dco='docker compose --offload'&lt;/code&gt; e pronto.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logs locais&lt;/strong&gt;. Use &lt;code&gt;docker logs -f&lt;/code&gt; normalmente, o Desktop faz &lt;em&gt;stream&lt;/em&gt; para você.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reutilize no CI&lt;/strong&gt;. O token em &lt;code&gt;~/.docker/offload/config.json&lt;/code&gt; pode ser exportado na pipeline, manuseie com cuidado.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;O Docker Offload acerta em cheio quem quer &lt;strong&gt;ficar no mesmo CLI&lt;/strong&gt;, mas precisa &lt;strong&gt;explodir limites de hardware&lt;/strong&gt; de vez em quando. Não substitui clusters 24/7, mas entrega a elasticidade que faltava no &lt;em&gt;loop&lt;/em&gt; de desenvolvimento e, como bônus, sem aquele barulho de turbina do notebook.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Próximos passos&lt;/strong&gt;. Cadastre‑se na beta, ganhe seus 300 minutos e me conta no LinkedIn como foi sua experiência. Se o seu fan‑cooler agradecer, já valeu o teste. 😉&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>docker</category>
      <category>ai</category>
      <category>cloud</category>
      <category>programming</category>
    </item>
    <item>
      <title>MCP: A Docker guide</title>
      <dc:creator>Rafael Pazini</dc:creator>
      <pubDate>Tue, 27 May 2025 19:29:23 +0000</pubDate>
      <link>https://dev.to/rflpazini/mcp-a-docker-guide-3mp4</link>
      <guid>https://dev.to/rflpazini/mcp-a-docker-guide-3mp4</guid>
      <description>&lt;p&gt;Hey dev, how's it going?&lt;/p&gt;

&lt;p&gt;A few months ago, everyone was talking about &lt;em&gt;AI&lt;/em&gt; and &lt;em&gt;Agents&lt;/em&gt;. Now, there’s a fresh buzzword lighting up the tech world: &lt;strong&gt;MCP&lt;/strong&gt;. Don’t worry—it’s not the next Marvel villain or a secret NASA chip.&lt;/p&gt;

&lt;p&gt;Honestly? Until recently, the only “agent” I knew was 007… 😂&lt;/p&gt;

&lt;p&gt;But today, I’m going to walk you through how to build your own &lt;strong&gt;MCP (Model Context Protocol) server&lt;/strong&gt; using &lt;strong&gt;Node.js&lt;/strong&gt; (yes, Node, not Go!), integrate it with &lt;strong&gt;Claude Desktop&lt;/strong&gt;, and give your AI assistant the superpower to interact directly with APIs—without you ever needing to copy and paste JSON manually.&lt;/p&gt;

&lt;p&gt;Let’s break this down carefully so that both junior and senior developers can follow along.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is MCP (Model Context Protocol)?
&lt;/h2&gt;

&lt;p&gt;The MCP is an open, standardized protocol (released in early 2025) that allows applications and services to provide structured, live context to Large Language Models (LLMs) like Claude. In short, it’s a two-way communication bridge: your tools and data can now &lt;em&gt;talk&lt;/em&gt; directly to your LLM.&lt;/p&gt;

&lt;p&gt;Before MCP, if you wanted your assistant to know something, you had to copy-paste outputs, logs, or reports—or worse, manually describe data or system states. With MCP, your assistant can securely, reliably, and consistently access real-time external data.&lt;/p&gt;

&lt;p&gt;The protocol defines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Metadata format&lt;/strong&gt;: Describes what a server can do.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Action format&lt;/strong&gt;: Defines the operations (or tools) available.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Request/response format&lt;/strong&gt;: Structures how data is exchanged.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authentication &amp;amp; authorization&lt;/strong&gt;: Ensures secure, controlled access.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How does MCP work?
&lt;/h2&gt;

&lt;p&gt;Here’s the flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;MCP Servers&lt;/strong&gt;: Any app or service that exposes MCP-compliant endpoints, declaring its tools and capabilities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP Clients&lt;/strong&gt;: Systems like Claude Desktop that discover, connect to, and interact with available MCP servers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Communication flow&lt;/strong&gt;:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Claude Desktop discovers available MCP servers.&lt;/li&gt;
&lt;li&gt;The user makes a request needing live system context.&lt;/li&gt;
&lt;li&gt;Claude Desktop identifies the right MCP server.&lt;/li&gt;
&lt;li&gt;It sends a structured request.&lt;/li&gt;
&lt;li&gt;The server processes and returns structured data.&lt;/li&gt;
&lt;li&gt;Claude integrates the result into the user’s conversation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything is explicitly authorized: the user decides which servers can talk to their assistant.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why should you care?
&lt;/h2&gt;

&lt;p&gt;This setup unlocks massive advantages:&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;No more copy-pasting data&lt;/strong&gt;: Claude can directly pull API results.&lt;br&gt;
✅ &lt;strong&gt;Always live data&lt;/strong&gt;: You get current, fresh responses.&lt;br&gt;
✅ &lt;strong&gt;Accessible to non-technical users&lt;/strong&gt;: Anyone can query complex systems using plain language.&lt;br&gt;
✅ &lt;strong&gt;Huge productivity gains&lt;/strong&gt;: You can stack or automate workflows that used to need multiple tools.&lt;br&gt;
✅ &lt;strong&gt;Lower learning curve&lt;/strong&gt;: Juniors don’t need to master every API; they just ask questions.&lt;br&gt;
✅ &lt;strong&gt;Safe &amp;amp; private&lt;/strong&gt;: Only explicitly permitted data flows through.&lt;/p&gt;

&lt;p&gt;Imagine saying, “How many active users did we have last week?” and getting the precise answer &lt;em&gt;without&lt;/em&gt; opening Postman, Kibana, or your database console.&lt;/p&gt;
&lt;h2&gt;
  
  
  Docker MCP: your launchpad
&lt;/h2&gt;

&lt;p&gt;Docker MCP makes this even easier by packaging MCP servers as Docker containers. Here’s why that matters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Standardized&lt;/strong&gt;: Everyone follows the same integration spec.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easy to deploy&lt;/strong&gt;: &lt;code&gt;docker run&lt;/code&gt; and you’re off.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Portable&lt;/strong&gt;: Runs anywhere Docker runs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pre-built servers&lt;/strong&gt;: Browse ready-to-use integrations in the Docker Hub MCP catalog.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Quickstart Docker setup
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 11434:11434 &lt;span class="nt"&gt;-v&lt;/span&gt; /var/run/docker.sock:/var/run/docker.sock docker/mcp-server
docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--label&lt;/span&gt; mcp.enabled&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true &lt;/span&gt;mcp/github
docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--label&lt;/span&gt; mcp.enabled&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true &lt;/span&gt;mcp/petstore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Once running, Claude Desktop connects to &lt;code&gt;http://localhost:11434&lt;/code&gt; and discovers all enabled MCP servers.&lt;/p&gt;
&lt;h2&gt;
  
  
  Diving into the PetStore API example
&lt;/h2&gt;

&lt;p&gt;Let’s focus on the &lt;strong&gt;PetStore API&lt;/strong&gt;—a demo API often used for testing. It’s great for practicing because it simulates a live system for managing pets, orders, and users.&lt;/p&gt;
&lt;h3&gt;
  
  
  Setting it up in Claude Desktop
&lt;/h3&gt;

&lt;p&gt;In your Claude configuration, you’d link the PetStore MCP server like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"petstoreGateway"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"docker"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"run"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"--rm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"-i"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"-e"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"API_1_NAME=petstore"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"-e"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"API_1_SWAGGER_URL=https://petstore.swagger.io/v2/swagger.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"-e"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"API_1_BASE_URL=https://petstore.swagger.io/v2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"rflpazini/mcp-api-gateway"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Sample use cases: talking to PetStore
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Example 1: Querying Available Pets
&lt;/h3&gt;

&lt;p&gt;User: &lt;em&gt;"Claude, list all available pets for adoption."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Claude: &lt;em&gt;[Fetching from PetStore API…]&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;"Here are the currently available pets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dog (ID 101)&lt;/li&gt;
&lt;li&gt;Cat (ID 102)&lt;/li&gt;
&lt;li&gt;Parrot (ID 103)"&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example 2: Placing an order
&lt;/h3&gt;

&lt;p&gt;User: &lt;em&gt;"Claude, place an order for pet ID 101 for customer John Doe."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Claude: &lt;em&gt;[Processing via MCP…]&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;"Order placed successfully:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Order ID: 5001&lt;/li&gt;
&lt;li&gt;Pet ID: 101&lt;/li&gt;
&lt;li&gt;Customer: John Doe"&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example 3: Checking order status
&lt;/h3&gt;

&lt;p&gt;User: &lt;em&gt;"Claude, check the status of order 5001."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Claude: &lt;em&gt;[Querying MCP…]&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;"Order 5001 is currently marked as 'Processing'."&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 4: Adding a new pet
&lt;/h3&gt;

&lt;p&gt;User: &lt;em&gt;"Claude, add a new pet: name 'Buddy', type 'Dog', status 'Available'."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Claude: &lt;em&gt;[Calling PetStore API…]&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;"New pet 'Buddy' has been successfully added to the inventory!"&lt;/p&gt;

&lt;h2&gt;
  
  
  Deep Dive: why this matters for all developers
&lt;/h2&gt;

&lt;p&gt;For &lt;strong&gt;junior devs&lt;/strong&gt;, MCP abstracts the complexity: they don’t need to memorize API endpoints, craft curl requests, or handle auth headers. They just interact through conversation.&lt;/p&gt;

&lt;p&gt;For &lt;strong&gt;senior devs&lt;/strong&gt;, MCP opens up automation, scalability, and integration potential: you can design multi-step workflows, run cross-service queries, and even set up self-updating dashboards powered by conversational requests.&lt;/p&gt;

&lt;p&gt;Plus, you can extend the system: add more APIs, build custom MCP servers, and define fine-grained controls over what’s exposed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;The MCP + Docker combo is a game changer for how we interact with APIs and systems. It flattens the learning curve, boosts team efficiency, and turns conversational interfaces into real power tools for both tech-savvy and non-technical users.&lt;/p&gt;

&lt;p&gt;So... what API will &lt;em&gt;you&lt;/em&gt; connect to Claude first?&lt;/p&gt;

&lt;p&gt;Check out the complete project on &lt;a href="https://github.com/rflpazini/mcp-api-gateway" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; and start transforming your workflow today!&lt;/p&gt;

</description>
      <category>docker</category>
      <category>mcp</category>
      <category>programming</category>
      <category>ai</category>
    </item>
    <item>
      <title>Go Tool: Uma análise da nova ferramenta para gerenciar dependências</title>
      <dc:creator>Rafael Pazini</dc:creator>
      <pubDate>Fri, 16 May 2025 18:52:56 +0000</pubDate>
      <link>https://dev.to/rflpazini/go-tool-uma-analise-da-nova-ferramenta-para-gerenciar-dependencias-20ii</link>
      <guid>https://dev.to/rflpazini/go-tool-uma-analise-da-nova-ferramenta-para-gerenciar-dependencias-20ii</guid>
      <description>&lt;p&gt;Por um tempo, os desenvolvedores Go precisaram usar soluções improvisadas para gerenciar dependências de ferramentas. Com o lançamento do &lt;strong&gt;Go 1.24&lt;/strong&gt;, isso mudou completamente. Vamos ver como!&lt;/p&gt;

&lt;p&gt;Quem trabalha com Go sabe bem o quanto o ecossistema de ferramentas é fundamental para o desenvolvimento produtivo. Desde geradores de código como &lt;code&gt;stringer&lt;/code&gt; até analisadores estáticos como &lt;code&gt;staticcheck&lt;/code&gt;, essas ferramentas se tornaram parte essencial do fluxo de trabalho diário. No entanto, gerenciar essas dependências sempre foi um desafio - especialmente ao trabalhar em equipe.&lt;/p&gt;

&lt;p&gt;Até agora, a solução padrão era o famoso padrão "tools.go" - um arquivo com imports em branco que não eram realmente usados no código, mas garantiam que as ferramentas fossem baixadas quando necessário. Era funcional, mas nunca pareceu uma solução elegante.&lt;/p&gt;

&lt;p&gt;O &lt;a href="https://tip.golang.org/doc/go1.24#tools" rel="noopener noreferrer"&gt;Go 1.24&lt;/a&gt;, lançado em fevereiro de 2025, finalmente resolve esse problema introduzindo uma maneira oficial e elegante de gerenciar ferramentas: a nova funcionalidade go tool e a diretiva tool no arquivo go.mod. Esta mudança, representa uma melhoria significativa na experiência do desenvolvedor Go, permitindo um gerenciamento mais claro e eficiente das dependências de ferramentas.&lt;/p&gt;

&lt;h2&gt;
  
  
  O Problema Anterior
&lt;/h2&gt;

&lt;p&gt;Antes do Go 1.24, para garantir que ferramentas como &lt;code&gt;stringer&lt;/code&gt;, &lt;code&gt;mockgen&lt;/code&gt; ou &lt;code&gt;staticcheck&lt;/code&gt; estivessem disponíveis para todos da equipe, os desenvolvedores tipicamente usavam uma abordagem que ficou conhecida como o "padrão tools.go". Esse padrão envolvia:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Criar um arquivo chamado "tools.go" com restrições de build para que não fosse incluído na compilação normal&lt;/li&gt;
&lt;li&gt;Adicionar imports em branco de todas as ferramentas necessárias&lt;/li&gt;
&lt;li&gt;Usar &lt;code&gt;go run&lt;/code&gt; para executar essas ferramentas quando necessário
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;//go:build tools&lt;/span&gt;
&lt;span class="c"&gt;// +build tools&lt;/span&gt;

&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="s"&gt;"golang.org/x/tools/cmd/stringer"&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="s"&gt;"golang.org/x/vuln/cmd/govulncheck"&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="s"&gt;"honnef.co/go/tools/cmd/staticcheck"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Embora funcional, esta abordagem tinha várias desvantagens:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Misturava ferramentas de desenvolvimento com dependências reais do código&lt;/li&gt;
&lt;li&gt;Exigia comandos como &lt;code&gt;go run golang.org/x/tools/cmd/stringer&lt;/code&gt;, que eram verbosos&lt;/li&gt;
&lt;li&gt;Cada execução requeria uma recompilação da ferramenta, tornando o processo lento&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A nova solução: go tool e a Diretiva tool
&lt;/h2&gt;

&lt;p&gt;O Go 1.24 introduz uma solução elegante para esse problema com dois novos recursos principais:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A diretiva &lt;code&gt;tool&lt;/code&gt; no arquivo go.mod&lt;/li&gt;
&lt;li&gt;O comando &lt;code&gt;go tool&lt;/code&gt; para executar ferramentas&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Adicionando Ferramentas ao Projeto
&lt;/h3&gt;

&lt;p&gt;Para adicionar uma ferramenta ao seu projeto, agora você pode simplesmente usar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go get &lt;span class="nt"&gt;-tool&lt;/span&gt; golang.org/x/tools/cmd/stringer

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este comando baixa a ferramenta e adiciona uma diretiva &lt;code&gt;tool&lt;/code&gt; ao seu arquivo go.mod:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;module example.com/myproject
go 1.24

tool &lt;span class="o"&gt;(&lt;/span&gt;
    golang.org/x/tools/cmd/stringer
&lt;span class="o"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para versões específicas, basta adicionar o número da versão:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go get &lt;span class="nt"&gt;-tool&lt;/span&gt; honnef.co/go/tools/cmd/staticcheck@v0.5.1

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Executando ferramentas
&lt;/h3&gt;

&lt;p&gt;Após adicionar uma ferramenta, você pode executá-la facilmente com o comando &lt;code&gt;go tool&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go tool stringer &lt;span class="nt"&gt;-type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Day enum.go

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ou para ferramentas com nomes ambíguos, use o caminho completo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go tool golang.org/x/tools/cmd/stringer &lt;span class="nt"&gt;-type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Day enum.go

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O comando &lt;code&gt;go tool&lt;/code&gt; sem argumentos lista todas as ferramentas disponíveis, incluindo as nativas do Go e as definidas no seu módulo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Caching de executáveis
&lt;/h3&gt;

&lt;p&gt;Uma grande vantagem da nova abordagem é que os executáveis criados pelo &lt;code&gt;go tool&lt;/code&gt; agora são armazenados em cache no Go build cache. Isso significa que as execuções repetidas são muito mais rápidas, pois a ferramenta não precisa ser recompilada a cada vez.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefícios da nova abordagem
&lt;/h2&gt;

&lt;p&gt;A nova diretiva &lt;code&gt;tool&lt;/code&gt; e o comando &lt;code&gt;go tool&lt;/code&gt; oferecem diversos benefícios:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Separação clara&lt;/strong&gt;: Ferramentas são claramente distinguidas das dependências de código&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sintaxe simplificada&lt;/strong&gt;: Comandos mais curtos e intuitivos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Versionamento&lt;/strong&gt;: Versões específicas das ferramentas podem ser bloqueadas facilmente&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Melhor desempenho&lt;/strong&gt;: Graças ao caching de executáveis&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistência&lt;/strong&gt;: Todas as pessoas da equipe usam exatamente as mesmas versões das ferramentas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Meta-padrão&lt;/strong&gt;: O padrão &lt;code&gt;tool&lt;/code&gt; permite operações em todas as ferramentas simultaneamente, como &lt;code&gt;go get tool&lt;/code&gt; para atualizar todas elas&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Exemplo do mundo real: Geração de Mocks para testes
&lt;/h2&gt;

&lt;p&gt;Vamos ver um exemplo prático de como usar a nova funcionalidade &lt;code&gt;go tool&lt;/code&gt; para gerar mocks para testes usando a ferramenta mockgen.&lt;/p&gt;

&lt;h3&gt;
  
  
  Passo 1: Adicionar mockgen ao projeto
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Adicionar mockgen como ferramenta&lt;/span&gt;
go get &lt;span class="nt"&gt;-tool&lt;/span&gt; github.com/golang/mock/mockgen

&lt;span class="c"&gt;# Verificar se foi adicionada corretamente&lt;/span&gt;
&lt;span class="nb"&gt;cat &lt;/span&gt;go.mod

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nosso go.mod agora terá uma seção como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tool (
    github.com/golang/mock/mockgen
)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Passo 2: Criar uma interface para mock
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// service.go&lt;/span&gt;
&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;UserService&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;GetUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;CreateUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ID&lt;/span&gt;   &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Age&lt;/span&gt;  &lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Passo 3: Gerar o mock usando go tool
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go tool mockgen &lt;span class="nt"&gt;-source&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;service.go &lt;span class="nt"&gt;-destination&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mocks/mock_service.go &lt;span class="nt"&gt;-package&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mocks

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Passo 4: Usar o mock em testes
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// service_test.go&lt;/span&gt;
&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;service_test&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"testing"&lt;/span&gt;

    &lt;span class="s"&gt;"github.com/golang/mock/gomock"&lt;/span&gt;
    &lt;span class="s"&gt;"example.com/myproject/mocks"&lt;/span&gt;
    &lt;span class="s"&gt;"example.com/myproject/service"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestUserService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ctrl&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;gomock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewController&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;ctrl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Finish&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;mockUserService&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;mocks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewMockUserService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctrl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Configurar expectativas&lt;/span&gt;
    &lt;span class="n"&gt;mockUser&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"John"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Age&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;mockUserService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EXPECT&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mockUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Testar funcionalidade que usa o serviço&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;mockUserService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Erro não esperado: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;"John"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Nome esperado: John, obtido: %s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este exemplo demonstra como a nova funcionalidade &lt;code&gt;go tool&lt;/code&gt; simplifica o processo de desenvolvimento, especialmente para tarefas como geração de código. A sintaxe é mais limpa e todo o processo fica mais transparente para todos os membros da equipe.&lt;/p&gt;

&lt;h2&gt;
  
  
  Considerações e Limitações
&lt;/h2&gt;

&lt;p&gt;Apesar dos muitos benefícios, existem algumas considerações importantes ao usar a nova funcionalidade:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Versões compartilhadas de dependências&lt;/strong&gt;: Ferramentas e código-fonte compartilham a mesma resolução de versão de dependências. Isso significa que, se uma ferramenta e seu código usam a mesma biblioteca mas com versões diferentes, pode haver conflitos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aumento do tamanho do cache&lt;/strong&gt;: Como os executáveis são armazenados em cache, isso pode aumentar o tamanho total do cache de build.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apenas ferramentas Go&lt;/strong&gt;: Este mecanismo só funciona para ferramentas escritas em Go. Para ferramentas em outras linguagens, você ainda precisará de métodos alternativos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compatibilidade&lt;/strong&gt;: A funcionalidade está disponível apenas no Go 1.24 ou posterior.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;A nova funcionalidade &lt;code&gt;go tool&lt;/code&gt; e a diretiva &lt;code&gt;tool&lt;/code&gt; no Go 1.24 representam uma evolução significativa na forma como os desenvolvedores Go gerenciam ferramentas. Em vez de usar soluções improvisadas, agora temos uma abordagem oficial, elegante e eficiente.&lt;/p&gt;

&lt;p&gt;Para desenvolvedores que trabalham em equipes ou em projetos complexos, essa mudança traz benefícios imediatos em termos de consistência, simplicidade e desempenho. É mais um exemplo de como a linguagem Go continua evoluindo de forma pragmática, mantendo a simplicidade e atendendo às necessidades reais dos desenvolvedores.&lt;/p&gt;

&lt;p&gt;Se você ainda não experimentou o Go 1.24, esta é mais uma excelente razão para fazer a atualização e começar a aproveitar todo o potencial do novo gerenciamento de ferramentas.&lt;/p&gt;

</description>
      <category>go</category>
      <category>coding</category>
      <category>tooling</category>
      <category>programming</category>
    </item>
    <item>
      <title>Docker Model Runner: IA Local sem dor de cabeça</title>
      <dc:creator>Rafael Pazini</dc:creator>
      <pubDate>Wed, 07 May 2025 13:55:14 +0000</pubDate>
      <link>https://dev.to/rflpazini/docker-model-runner-ia-local-sem-dor-de-cabeca-4ank</link>
      <guid>https://dev.to/rflpazini/docker-model-runner-ia-local-sem-dor-de-cabeca-4ank</guid>
      <description>&lt;p&gt;Já imaginou poder rodar aqueles modelos de IA gigantes no seu computador tão facilmente quanto pedir um delivery de comida? Pois é isso que o Docker Model Runner faz! É como se fosse um Uber para modelos de IA: você "chama" o modelo, ele vem rapidinho, faz o trabalho e depois vai embora sem ocupar espaço quando você não precisa mais.&lt;/p&gt;

&lt;p&gt;Lançado como beta no Docker Desktop 4.40, o Docker Model Runner é aquela novidade que faz você pensar: &lt;strong&gt;"Como vivíamos sem isso antes?"&lt;/strong&gt;. Se você já passou horas configurando ambientes para rodar IA localmente (aquele inferno de dependências que nunca termina), vai entender o porquê.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conhecendo a ferramenta
&lt;/h2&gt;

&lt;p&gt;Se você está começando agora e mal sabe a diferença entre um &lt;strong&gt;container&lt;/strong&gt; e uma &lt;strong&gt;tupperware&lt;/strong&gt;, relaxa! Vou explicar como se estivéssemos em um churrasco 🍗:&lt;/p&gt;

&lt;p&gt;O Docker Model Runner é como um churrasqueiro profissional que você contrata para sua festa. Ele:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Traz sua própria churrasqueira (servidor de inferência)&lt;/li&gt;
&lt;li&gt;Sabe exatamente como preparar cada tipo de carne (modelos de IA)&lt;/li&gt;
&lt;li&gt;Limpa tudo quando termina (gerencia recursos)&lt;/li&gt;
&lt;li&gt;E o melhor: você não precisa aprender a fazer churrasco para desfrutar dele!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Para quem já manja dos paranauês, o Docker Model Runner é um servidor de inferência baseado em llama.cpp que roda diretamente no host (não em containers) e expõe uma API compatível com OpenAI. Os modelos são distribuídos como artefatos OCI via Docker Hub e são carregados dinamicamente na memória apenas quando solicitados.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pense no Docker Model Runner como um "docker-compose up" para sua IA local. Sem ficar se batendo com drivers, ambientes Python e bibliotecas incompatíveis.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A arquitetura é elegante: em vez de virtualizar o ambiente inteiro, o Model Runner aproveita os recursos nativos do host, incluindo aceleração de GPU, eliminando o overhead de containerização para tarefas de inferência intensivas.&lt;/p&gt;

&lt;h3&gt;
  
  
  A mágica por trás das cortinas
&lt;/h3&gt;

&lt;p&gt;Quando você digita &lt;code&gt;docker model run ai/llama3.2:1B-Q8_0 "Explique contêineres"&lt;/code&gt;, o que acontece? É bem simples:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;O Docker não inicia um container tradicional (surpresa!)&lt;/li&gt;
&lt;li&gt;Em vez disso, faz uma chamada à API do servidor de inferência embutido no Docker Desktop&lt;/li&gt;
&lt;li&gt;O servidor carrega o modelo em memória (se já não estiver carregado)&lt;/li&gt;
&lt;li&gt;Executa a inferência usando recursos nativos do host&lt;/li&gt;
&lt;li&gt;O modelo fica "de plantão" por 5 minutos e, se não receber novas solicitações, é descarregado.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Comandos básicos
&lt;/h3&gt;

&lt;p&gt;Tá querendo experimentar? Aqui vai um guia rápido do tipo "Receitinha simples pro almoço":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Verificando se está tudo funcionando&lt;/span&gt;
docker model status
&lt;span class="c"&gt;# Deve responder algo tipo: "Docker Model Runner is running" (tudo certo!)&lt;/span&gt;

&lt;span class="c"&gt;# Vendo quais modelos você já tem baixados&lt;/span&gt;
docker model list
&lt;span class="c"&gt;# No início provavelmente vai estar vazio, tipo geladeira de estudante&lt;/span&gt;

&lt;span class="c"&gt;# Baixando um modelo pequeno para teste&lt;/span&gt;
docker model pull ai/smollm2
&lt;span class="c"&gt;# Esse modelo é pequeno, tipo um pãozinho de queijo - rápido e satisfatório!&lt;/span&gt;

&lt;span class="c"&gt;# Executando o modelo com uma pergunta&lt;/span&gt;
docker model run ai/smollm2 &lt;span class="s2"&gt;"Explique o que é Docker como se eu tivesse 5 anos"&lt;/span&gt;
&lt;span class="c"&gt;# Agora o modelo vai responder, provavelmente com algo sobre caixinhas mágicas...&lt;/span&gt;

&lt;span class="c"&gt;# Quando não precisar mais, remova para liberar espaço&lt;/span&gt;
docker model &lt;span class="nb"&gt;rm &lt;/span&gt;ai/smollm2
&lt;span class="c"&gt;# Tchau, modelo! Foi bom enquanto durou!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E agora você deve estar se perguntando: "Rafa, como eu consigo saber quais modelos estão disponíveis?" &lt;br&gt;
Todos os modelos disponíveis estão no Docker Hub com o namespace &lt;code&gt;ai&lt;/code&gt;: &lt;a href="https://hub.docker.com/u/ai" rel="noopener noreferrer"&gt;https://hub.docker.com/u/ai&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Exemplos do mundo Real (nada de "Hello World" aqui!)
&lt;/h2&gt;

&lt;p&gt;Agora vamos para a parte mais legal: chega de falação e vamos ver como isso é utilizado na vida real. Vou utilizar Go para criar os exemplos, mas você pode adaptar para qualquer linguagem.&lt;/p&gt;
&lt;h3&gt;
  
  
  Antes de começar (TL;DR)
&lt;/h3&gt;

&lt;p&gt;Se você é do tipo que pula a introdução dos livros e vai direto para a ação, aqui está o guia estilo "miojo de 3 minutos":&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Atualize o Docker Desktop para 4.40+&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Abra as Configurações&lt;/strong&gt; (aquele ícone de engrenagem)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Navegue até "Features in development" &amp;gt; aba "Beta"&lt;/strong&gt; (onde as coisas legais ficam)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ative "Enable Docker Model Runner"&lt;/strong&gt; (clique no checkbox)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bônus: Ative "Enable host-side TCP support"&lt;/strong&gt; (para acessar via localhost, a porta padrão é 12434)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clique em "Apply &amp;amp; Restart"&lt;/strong&gt; (e vá pegar um café enquanto reinicia)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Teste com:&lt;/strong&gt; &lt;code&gt;docker model status&lt;/code&gt; (deve dizer que está rodando)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Como Escolher o Modelo Certo?
&lt;/h3&gt;

&lt;p&gt;Escolher um modelo é como escolher um carro: depende do seu destino e do tamanho da sua garagem (ou, neste caso, da sua RAM).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Para iniciantes ou hardware limitado&lt;/strong&gt;: Comece com modelos pequenos como &lt;code&gt;ai/smollm2:360M-Q4_K_M&lt;/code&gt; ou &lt;code&gt;ai/llama3.2:1B-Q8_0&lt;/code&gt;. São como carros compactos - cabem em qualquer garagem e consomem pouca gasolina.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Para equilíbrio entre qualidade e velocidade&lt;/strong&gt;: Experimente modelos de tamanho médio como &lt;code&gt;ai/llama3.2:8B-Q4_K_M&lt;/code&gt;. São como sedans de médio porte - bons para a maioria das situações do dia a dia.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Para tarefas complexas&lt;/strong&gt;: Se você tem uma GPU poderosa, experimente modelos grandes como &lt;code&gt;ai/llama3.2:70B-Q4_0&lt;/code&gt;. São como SUVs de luxo - mais lentos para estacionar, mas confortáveis para longas viagens.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;O truque está no nome: o número antes do hífen é o tamanho (em bilhões de parâmetros) e o código após o Q indica o nível de quantização (Q8 é melhor qualidade que Q4, mas ocupa mais espaço).&lt;/p&gt;

&lt;blockquote&gt;
&lt;h4&gt;
  
  
  Dica: Experimente antes de comprar
&lt;/h4&gt;

&lt;p&gt;Não sabe qual modelo escolher? Faça como nas cafeterias chiques: peça uma amostra!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Caso 1: O atendente virtual
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cenário:&lt;/strong&gt; Você trabalha em uma empresa que fabrica eletrodomésticos e precisa criar um atendente virtual que entenda os manuais dos produtos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problema da Vida Real:&lt;/strong&gt; APIs externas são caras, serviços de nuvem expõem dados sensíveis e sua chefe está de olho no orçamento como um falcão.&lt;/p&gt;

&lt;p&gt;Lembre-se: dependendo do volume de tráfego e de onde estiver rodando este modelo, as repostas podem ser lentas. Para ver o código completo do projeto, é só acessar o &lt;a href="https://github.com/rflpazini/articles/tree/main/docker_model_runner" rel="noopener noreferrer"&gt;link do meu github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solução com Docker Model Runner:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"bytes"&lt;/span&gt;
    &lt;span class="s"&gt;"encoding/json"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"io/ioutil"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;
    &lt;span class="s"&gt;"net/http"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// Request structures&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Message&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Role&lt;/span&gt;    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"role"`&lt;/span&gt;
    &lt;span class="n"&gt;Content&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"content"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;ModelRequest&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Model&lt;/span&gt;    &lt;span class="kt"&gt;string&lt;/span&gt;    &lt;span class="s"&gt;`json:"model"`&lt;/span&gt;
    &lt;span class="n"&gt;Messages&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt; &lt;span class="s"&gt;`json:"messages"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// Model response structures&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Choice&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Message&lt;/span&gt; &lt;span class="n"&gt;Message&lt;/span&gt; &lt;span class="s"&gt;`json:"message"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;ModelResponse&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Choices&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;Choice&lt;/span&gt; &lt;span class="s"&gt;`json:"choices"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// API structures&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;HelpRequest&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Question&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"question"`&lt;/span&gt;
    &lt;span class="n"&gt;Model&lt;/span&gt;    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"model"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;HelpResponse&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Answer&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"answer"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HandleFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/help"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;handleHelp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Virtual assistant running on port 3000!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ListenAndServe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;":3000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;handleHelp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ResponseWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Check HTTP method&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Method&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MethodPost&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Method not allowed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusMethodNotAllowed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Decode request body&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;reqBody&lt;/span&gt; &lt;span class="n"&gt;HelpRequest&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewDecoder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;reqBody&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Error processing request"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusBadRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Use default model if not specified&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;reqBody&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"ai/llama3.2:1B-Q8_0"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Prepare request for Docker Model Runner&lt;/span&gt;
    &lt;span class="n"&gt;modelReq&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ModelRequest&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Messages&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;Role&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="s"&gt;"system"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"You are an assistant specialized in LG brand appliances."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;Role&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="s"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;reqBody&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Question&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Convert to JSON&lt;/span&gt;
    &lt;span class="n"&gt;reqJSON&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;modelReq&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Error preparing request"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusInternalServerError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// Send request to Docker Model Runner&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"http://localhost:12434/engines/llama.cpp/v1/chat/completions"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"application/json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewBuffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reqJSON&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Error querying the model"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusInternalServerError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;ioutil&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Error reading model response"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusInternalServerError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;modelResp&lt;/span&gt; &lt;span class="n"&gt;ModelResponse&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unmarshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;modelResp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Error processing model response"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusInternalServerError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;modelResp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Choices&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Model returned no response"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StatusInternalServerError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;HelpResponse&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Answer&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;modelResp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Content-Type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"application/json"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewEncoder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui criamos nosso servidor do assistente. Basicamente ele vai:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Receber uma requisição no endpoint &lt;code&gt;/help&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Usar o modelo que foi passado na requisição&lt;/li&gt;
&lt;li&gt;Responder a pergunta que foi enviada pelo usuário&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Este é um exemplo de requisição:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
  http://localhost:3000/help &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "question": "Como eu reseto o Wi-Fi da minha televisão?",
    "model": "ai/llama3.2:1B-Q8_0"
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E após nosso servidor processar a resposta, ele deve retornar algo assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"answer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"**Resetação do Wi-Fi na Televisão LG**&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"Olá! Eu sou aqui para ajudá-lo a resolver qualquer problema que você "&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"possa estar enfrentando com sua televisão LG.&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"Aqui estão os passos para resetar o Wi-Fi na sua televisão LG:&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="s2"&gt;"**Requisitos:**&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"- A televisão LG deve estar conectada à internet.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"- Você deve ter acesso ao painel de controle da televisão ou à tela do aplicativo LG.&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="s2"&gt;"**Passos para resetar o Wi-Fi:**&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"1. **Localize o botão de reset**: Procure por um botão de reset na parte de trás da televisão. "&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="s2"&gt;"Ele geralmente é um pequeno botão que se assemelha a um botão de &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;reset&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"2. **Pressione o botão de reset**: Pressione o botão de reset várias vezes até que ele fique selado.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"3. **Aguarde alguns segundos**: Aguarde alguns segundos até que a tela fique normal novamente.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"4. **Conecte-se à internet**: Conecte-se à internet novamente.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"5. **Ative o Wi-Fi**: Ative o Wi-Fi na televisão LG e faça login com seu nome de usuário e senha.&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="s2"&gt;"**Dicas adicionais:**&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"- Se você não conseguir encontrar o botão de reset, verifique se ele está localizado na "&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"parte superior ou inferior da televisão.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"- Se a televisão LG tiver um painel de controle, você pode verificar se a opção de reset está disponível.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"- Se você estiver usando um aplicativo LG, verifique se a opção de reset está disponível no aplicativo.&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="s2"&gt;"**Dúvidas?**&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"Se você tiver alguma dúvida ou precisar de mais ajuda, não hesite em perguntar. "&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"Estou aqui para ajudá-lo!&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"Espero que essas instruções tenham sido úteis. Se tiver mais alguma dúvida, "&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"por favor, não hesite em perguntar."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Resultado&lt;/strong&gt;: Um atendente virtual que roda 100% local, não expõe dados sensíveis, não depende da internet, e sua chefe adora porque não tem fatura mensal de API!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Limitações (Ninguém é Perfeito)
&lt;/h3&gt;

&lt;p&gt;Como tudo na vida, o Docker Model Runner tem seus "poréns":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Não tem salvaguardas contra modelos gigantes&lt;/strong&gt; - seu computador pode virar uma panela de pressão se você tentar rodar um modelo que não cabe na RAM.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;É beta&lt;/strong&gt; - então espere alguns bugs do tipo "funcionava ontem, hoje não".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Não roda em containers&lt;/strong&gt; - ao contrário do Docker tradicional, roda diretamente no host.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  O Futuro é Logo Ali
&lt;/h3&gt;

&lt;p&gt;O Docker não está parado no tempo. Logo mais, o Model Runner vai ganhar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Capacidade de personalizar e publicar seus próprios modelos&lt;/strong&gt; (para os chefs de IA)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integração com Docker Compose&lt;/strong&gt; (para quem gosta de orquestrar seus serviços)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parcerias com gigantes como Google e HuggingFace&lt;/strong&gt; (mais modelos para brincar)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;É como esperar a próxima temporada da sua série favorita - você sabe que vem coisa boa por aí!&lt;/p&gt;

&lt;h3&gt;
  
  
  Mais tempo codando, menos tempo configurando
&lt;/h3&gt;

&lt;p&gt;O Docker Model Runner é como aquele amigo que aparece para ajudar na mudança com uma van, ferramentas e ainda traz pizza: resolve seu problema e ainda torna o processo agradável!&lt;/p&gt;

&lt;p&gt;Para desenvolvedores brasileiros que sempre tiveram que se virar com criatividade (o famoso "jeitinho" no bom sentido), o Docker Model Runner é uma ferramenta que finalmente nos coloca no mesmo patamar dos grandes centros de tecnologia - podemos desenvolver aplicações de IA de ponta sem depender de APIs caras ou infraestrutura complexa.&lt;/p&gt;

&lt;p&gt;Seja você um desenvolvedor querendo experimentar IA sem gastar uma fortuna em GPUs, ou um CTO procurando soluções para manter dados sensíveis dentro da empresa, o Docker Model Runner é aquele "pulo do gato" que faltava no seu arsenal técnico.&lt;/p&gt;

&lt;p&gt;É isso meu povo e minha pova, deixem nos comentários se tiverem duvidas ou qualquer questão que eu possa ajudar 🥰&lt;/p&gt;

</description>
      <category>docker</category>
      <category>ai</category>
      <category>programming</category>
      <category>go</category>
    </item>
    <item>
      <title>Go Concurrency: Como rodar múltiplas coisas ao mesmo tempo sem pirar</title>
      <dc:creator>Rafael Pazini</dc:creator>
      <pubDate>Wed, 12 Feb 2025 14:54:55 +0000</pubDate>
      <link>https://dev.to/rflpazini/go-concurrency-como-rodar-multiplas-coisas-ao-mesmo-tempo-sem-pirar-5ej</link>
      <guid>https://dev.to/rflpazini/go-concurrency-como-rodar-multiplas-coisas-ao-mesmo-tempo-sem-pirar-5ej</guid>
      <description>&lt;p&gt;Go foi projetado desde o início para facilitar a concorrência, tornando possível escrever código que executa várias tarefas ao mesmo tempo sem perder a cabeça. Neste artigo, vou te mostrar o que é concorrência, como funciona em Go e como você pode usar goroutines e channels para deixar seu código mais eficiente e responsivo.&lt;/p&gt;




&lt;h2&gt;
  
  
  Concorrência vs. Paralelismo: Qual é a Diferença?
&lt;/h2&gt;

&lt;p&gt;Antes de tudo, vamos esclarecer um ponto: concorrência não é a mesma coisa que paralelismo.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Concorrência&lt;/strong&gt;: quando seu código lida com múltiplas tarefas ao mesmo tempo, alternando entre elas conforme necessário.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Paralelismo&lt;/strong&gt;: quando seu código executa várias tarefas ao mesmo tempo, literalmente ao mesmo tempo, geralmente em múltiplos núcleos de CPU.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pensa assim: você está cozinhando um jantar. Enquanto a água ferve (uma tarefa), você pica os legumes (outra tarefa). Isso é concorrência. Agora, se você tivesse um clone seu picando os legumes enquanto você ferve a água, isso seria paralelismo.&lt;/p&gt;




&lt;h2&gt;
  
  
  Goroutines: Executando Funções Concorrentemente
&lt;/h2&gt;

&lt;p&gt;Em Go, criar uma função concorrente é incrivelmente fácil. Basta colocar &lt;code&gt;go&lt;/code&gt; antes da chamada da função e pronto, ela roda em segundo plano sem te incomodar.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exemplo simples de goroutine:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;digaOla&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Olá, mundo!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;digaOla&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c"&gt;// Rodando a função como goroutine&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// Esperando um pouco para ver a saída&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui, &lt;code&gt;digaOla()&lt;/code&gt; é executada de forma concorrente, mas como o programa principal pode terminar antes que ela rode, colocamos um &lt;code&gt;time.Sleep(time.Second)&lt;/code&gt; só pra garantir que dê tempo de ver a saída. Claro que, em código real, a gente usaria algo mais robusto, como channels, para sincronização.&lt;/p&gt;




&lt;h2&gt;
  
  
  Channels: Conversando Entre Goroutines
&lt;/h2&gt;

&lt;p&gt;Goroutines são legais, mas como elas conversam entre si? Em Go, usamos &lt;strong&gt;channels&lt;/strong&gt;, que funcionam como uma esteira de produção: uma goroutine coloca um dado de um lado e outra goroutine pega do outro.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unbuffered Channels: Mensagens "Na Hora"
&lt;/h3&gt;

&lt;p&gt;Os unbuffered channels são como passar um recado para um amigo pessoalmente: você fala e ele escuta na mesma hora.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;mensagens&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// Criando um channel de strings&lt;/span&gt;

    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;mensagens&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="s"&gt;"Olá, Go!"&lt;/span&gt;
    &lt;span class="p"&gt;}()&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;mensagens&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// Recebendo a mensagem do channel&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui, a goroutine anônima envia uma mensagem pelo channel, e a &lt;code&gt;main&lt;/code&gt; recebe e imprime. O channel &lt;strong&gt;bloqueia&lt;/strong&gt; até que haja um receptor do outro lado, garantindo sincronização.&lt;/p&gt;

&lt;h3&gt;
  
  
  Buffered Channels: Guardando Mensagens
&lt;/h3&gt;

&lt;p&gt;Buffered channels são como um correio: você pode colocar mensagens na caixa antes que o carteiro as retire.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;numeros&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// Criando um buffered channel com capacidade 3&lt;/span&gt;

    &lt;span class="n"&gt;numeros&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;numeros&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
    &lt;span class="n"&gt;numeros&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;numeros&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// 1&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;numeros&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// 2&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;numeros&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// 3&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui, o channel pode armazenar até 3 valores sem bloquear. Se tentarmos enviar um 4º valor antes de consumir algum, o programa trava até que haja espaço.&lt;/p&gt;




&lt;h2&gt;
  
  
  Select: Lidando com Múltiplos Channels
&lt;/h2&gt;

&lt;p&gt;O comando &lt;code&gt;select&lt;/code&gt; em Go permite ouvir vários channels ao mesmo tempo, tipo um garçom atendendo várias mesas ao mesmo tempo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;canal1&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;canal2&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;canal1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="s"&gt;"Mensagem do canal 1"&lt;/span&gt;
    &lt;span class="p"&gt;}()&lt;/span&gt;

    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;canal2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="s"&gt;"Mensagem do canal 2"&lt;/span&gt;
    &lt;span class="p"&gt;}()&lt;/span&gt;

    &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;msg1&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;canal1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;msg2&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;canal2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui, &lt;code&gt;select&lt;/code&gt; escolhe o primeiro channel que estiver pronto, garantindo que a resposta mais rápida seja processada primeiro.&lt;/p&gt;




&lt;h2&gt;
  
  
  Concorrência na Vida Real
&lt;/h2&gt;

&lt;p&gt;Agora que você já viu como usar goroutines e channels, aqui estão alguns exemplos do mundo real onde a concorrência brilha:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Servidores Web&lt;/strong&gt;: Cada requisição é tratada em uma goroutine separada, evitando travamentos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scrapers de Dados&lt;/strong&gt;: Se você precisar buscar informações de vários sites, pode fazer isso concorrentemente e acelerar o processo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Jogos Multiplayer&lt;/strong&gt;: Goroutines podem gerenciar o estado de cada jogador e enviar atualizações rapidamente.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Go torna a concorrência fácil e eficiente, permitindo criar aplicações escaláveis e responsivas sem dores de cabeça. Ao dominar goroutines, channels e &lt;code&gt;select&lt;/code&gt;, você consegue construir sistemas que aproveitam melhor o hardware e evitam travamentos.&lt;/p&gt;

&lt;p&gt;Então, da próxima vez que precisar rodar várias coisas ao mesmo tempo, lembre-se: goroutines são seus amigos, e channels são a melhor forma de manter a conversa em ordem! 🚀&lt;/p&gt;

</description>
      <category>go</category>
      <category>softwaredevelopment</category>
      <category>programming</category>
    </item>
    <item>
      <title>Dominando o Docker Bake: Simplificando Builds Complexos</title>
      <dc:creator>Rafael Pazini</dc:creator>
      <pubDate>Wed, 05 Feb 2025 04:24:27 +0000</pubDate>
      <link>https://dev.to/rflpazini/dominando-o-docker-bake-simplificando-builds-complexos-3iao</link>
      <guid>https://dev.to/rflpazini/dominando-o-docker-bake-simplificando-builds-complexos-3iao</guid>
      <description>&lt;p&gt;Com o aumento da complexidade nas aplicações modernas, especialmente em ambientes que utilizam &lt;em&gt;monorepos&lt;/em&gt; ou múltiplos contêineres, o gerenciamento de builds no Docker pode rapidamente se tornar uma tarefa desafiadora. Felizmente, o &lt;strong&gt;Docker Bake&lt;/strong&gt; surgiu como uma solução poderosa para simplificar, otimizar e acelerar esses processos. Neste post, vamos explorar o que é o Docker Bake, como utilizá-lo de forma eficaz, e alguns exemplos práticos que vão desde configurações básicas até recursos avançados.&lt;/p&gt;




&lt;h2&gt;
  
  
  O que é o Docker Bake?
&lt;/h2&gt;

&lt;p&gt;O &lt;strong&gt;Docker Bake&lt;/strong&gt; é uma ferramenta que permite definir e executar builds de imagens Docker de forma declarativa e eficiente. Ele é especialmente útil para cenários onde você precisa construir múltiplas imagens simultaneamente, compartilhar configurações entre diferentes ambientes ou simplificar comandos de build complexos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vantagens do Docker Bake:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Simplicidade:&lt;/strong&gt; Abstrai configurações complexas em um comando simples.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibilidade:&lt;/strong&gt; Suporte para funções customizadas, &lt;em&gt;matrices&lt;/em&gt;, e muito mais.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistência:&lt;/strong&gt; Compartilhamento fácil de configurações com o time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance:&lt;/strong&gt; Builds paralelos para acelerar workflows.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Como Funciona o Docker Bake?
&lt;/h2&gt;

&lt;p&gt;O Docker Bake usa arquivos de configuração em formato HCL (&lt;code&gt;docker-bake.hcl&lt;/code&gt;) ou JSON (&lt;code&gt;docker-bake.json&lt;/code&gt;) para definir &lt;em&gt;targets&lt;/em&gt;, variáveis, e estratégias de &lt;em&gt;caching&lt;/em&gt;. É como se fosse um "Makefile" para imagens Docker, mas com muito mais poder e simplicidade.&lt;/p&gt;

&lt;h3&gt;
  
  
  Estrutura Básica de um Arquivo &lt;code&gt;docker-bake.hcl&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"TAG"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"latest"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="s2"&gt;"app"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"."&lt;/span&gt;
  &lt;span class="nx"&gt;dockerfile&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Dockerfile"&lt;/span&gt;
  &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"meuapp:${TAG}"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="s2"&gt;"app-prod"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;inherits&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"app"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;args&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;ENV&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"production"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"meuapp:prod"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com esse arquivo, você pode rodar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker buildx bake app-prod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso constrói a imagem com o &lt;em&gt;tag&lt;/em&gt; &lt;code&gt;meuapp:prod&lt;/code&gt; e a variável de ambiente &lt;code&gt;ENV=production&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Recursos Avançados do Docker Bake
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Matrix de Targets&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Se você precisa construir a mesma imagem para diferentes arquiteturas ou ambientes, o Docker Bake permite definir &lt;em&gt;matrices&lt;/em&gt; para automatizar esse processo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"PLATFORMS"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"linux/amd64"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"linux/arm64"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="s2"&gt;"multiarch-app"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"."&lt;/span&gt;
  &lt;span class="nx"&gt;dockerfile&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Dockerfile"&lt;/span&gt;
  &lt;span class="nx"&gt;platforms&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;PLATFORMS&lt;/span&gt;
  &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"meuapp:multiarch"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, com um único comando, você cria imagens para múltiplas arquiteturas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker buildx bake multiarch-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. &lt;strong&gt;Entitlements (Permissões Especiais)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Com o Bake, você pode controlar permissões especiais usando o flag &lt;code&gt;--allow&lt;/code&gt;. Isso é útil para builds que precisam de acesso a recursos como o sistema de arquivos host ou rede.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker buildx bake app-prod &lt;span class="nt"&gt;--allow&lt;/span&gt; network.host &lt;span class="nt"&gt;--allow&lt;/span&gt; fs.read&lt;span class="o"&gt;=&lt;/span&gt;/dados/externos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa abordagem melhora a segurança, garantindo que apenas as permissões necessárias sejam concedidas.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Deduplicacão de Contextos&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Se você está construindo várias imagens que compartilham o mesmo contexto, o Bake agora deduplica automaticamente essas transferências, acelerando significativamente o tempo de build.&lt;/p&gt;

&lt;p&gt;Antes, era necessário definir contextos nomeados manualmente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;group&lt;/span&gt; &lt;span class="s2"&gt;"apps"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;targets&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"app1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"app2"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="s2"&gt;"app1"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"."&lt;/span&gt;
  &lt;span class="nx"&gt;dockerfile&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Dockerfile.app1"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="s2"&gt;"app2"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"."&lt;/span&gt;
  &lt;span class="nx"&gt;dockerfile&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Dockerfile.app2"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, o Bake otimiza isso automaticamente sem necessidade de ajustes adicionais.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Validação de Variáveis&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Assim como no Terraform, o Docker Bake agora permite validar variáveis para garantir que os valores fornecidos sejam adequados.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"VERSION"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;validation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;condition&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;VERSION&lt;/span&gt; &lt;span class="err"&gt;!&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
    &lt;span class="nx"&gt;error_message&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"A variável VERSION é obrigatória."&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;validation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;condition&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;VERSION&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
    &lt;span class="nx"&gt;error_message&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"A VERSION deve ter mais de 3 caracteres."&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se a variável &lt;code&gt;VERSION&lt;/code&gt; não for definida ou for muito curta, o Bake retornará um erro descritivo.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. &lt;strong&gt;Atributos Componíveis&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A partir da versão GA do Bake, atributos como &lt;code&gt;cache-from&lt;/code&gt;, &lt;code&gt;output&lt;/code&gt;, e &lt;code&gt;secret&lt;/code&gt; podem ser definidos como objetos estruturados, facilitando a reutilização e composição.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="s2"&gt;"app"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cache-from&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"registry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"usuario/app:cache"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"local"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"./cache"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"local"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dest&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"./build"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"oci"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dest&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"./app.oci"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Casos de Uso Reais
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Monorepos&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Se você trabalha com um &lt;em&gt;monorepo&lt;/em&gt; contendo diversos serviços, o Docker Bake facilita a construção de todos os serviços de forma paralela e otimizada.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;group&lt;/span&gt; &lt;span class="s2"&gt;"servicos"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;targets&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"api"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"frontend"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"worker"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="s2"&gt;"api"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"./api"&lt;/span&gt;
  &lt;span class="nx"&gt;dockerfile&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Dockerfile"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="s2"&gt;"frontend"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"./frontend"&lt;/span&gt;
  &lt;span class="nx"&gt;dockerfile&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Dockerfile"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="s2"&gt;"worker"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"./worker"&lt;/span&gt;
  &lt;span class="nx"&gt;dockerfile&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Dockerfile"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rodando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker buildx bake servicos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. &lt;strong&gt;Microservices Distribuídos&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Mesmo que você não utilize um &lt;em&gt;monorepo&lt;/em&gt;, é possível gerenciar builds de múltiplos microserviços que residem em diferentes repositórios ou diretórios.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="s2"&gt;"auth-service"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"../auth-service"&lt;/span&gt;
  &lt;span class="nx"&gt;dockerfile&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Dockerfile"&lt;/span&gt;
  &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"empresa/auth:latest"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="s2"&gt;"payment-service"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"../payment-service"&lt;/span&gt;
  &lt;span class="nx"&gt;dockerfile&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Dockerfile"&lt;/span&gt;
  &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"empresa/payment:latest"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;group&lt;/span&gt; &lt;span class="s2"&gt;"microservices"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;targets&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"auth-service"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"payment-service"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com isso, você pode construir todos os microserviços com um único comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker buildx bake microservices
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. &lt;strong&gt;Execução de Testes Automatizados&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O Docker Bake também é útil para pipelines de CI/CD, facilitando a execução de testes automatizados.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="s2"&gt;"test"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"."&lt;/span&gt;
  &lt;span class="nx"&gt;dockerfile&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Dockerfile.test"&lt;/span&gt;
  &lt;span class="nx"&gt;args&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;TEST_ENV&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ci"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"type=local,dest=./test-results"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rodando o comando abaixo, você dispara o ambiente de testes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker buildx bake &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso permite a integração fácil com ferramentas de CI como GitHub Actions ou GitLab CI.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Integração com Docker Compose&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Você também pode usar o Bake junto com o Docker Compose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker buildx bake &lt;span class="nt"&gt;--file&lt;/span&gt; docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso permite reaproveitar suas configurações de &lt;em&gt;services&lt;/em&gt; do Compose para gerenciar builds.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;O Docker Bake é uma ferramenta essencial para quem busca simplificar e otimizar workflows de build no Docker. Com recursos como &lt;em&gt;matrices&lt;/em&gt; de targets, deduplicacção de contextos, permissões configuráveis e validação de variáveis, ele oferece um ambiente robusto para desenvolvedores e times de DevOps.&lt;/p&gt;

&lt;p&gt;Se você ainda está lutando com comandos complexos e builds lentos, é hora de dar uma chance ao Docker Bake e transformar sua experiência de desenvolvimento.&lt;/p&gt;




&lt;h3&gt;
  
  
  Recursos Adicionais
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/build/bake/" rel="noopener noreferrer"&gt;Documentação Oficial do Docker Bake&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/guides/compose-bake/" rel="noopener noreferrer"&gt;Guia de Uso com Compose&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/build/bake/contexts/#deduplicate-context-transfer" rel="noopener noreferrer"&gt;Novidades do Docker Bake GA&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Experimente e compartilhe suas experiências nos comentários!&lt;/p&gt;

</description>
      <category>docker</category>
      <category>backend</category>
      <category>devops</category>
      <category>softwaredevelopment</category>
    </item>
  </channel>
</rss>
