Saudações.
Hoje vou ensinar como enlatei o Agente Pi (Pi Coding Agent) em um container Docker.
Pré-requisitos:
- Servidor, VPS ou VM com Linux;
- Docker;
1 – Sobre o Pi Agent
O Pi é um agente de IA para programação executado no terminal, especializado e refinado para planejar (plan) e construir (build) softwares.
Ele é uma “versão gratuita e aberta do Claude Code” e faz parte do monorepo earendil-works/pi, que inclui:
- CLI @earendil-works/pi-coding-agent;
- runtime @earendil-works/pi-agent-core;
- API unificada de modelos @earendil-works/pi-ai.
Você conversa com o modelo no terminal, e por padrão ele recebe ferramentas para ler arquivos, criar arquivos, editar arquivos e executar comandos bash.
A documentação alerta que o Pi roda no diretório atual e pode modificar arquivos ali, o ideal é usar Git, snapshots ou algum fluxo de rollback caso você não goste do que aconteceu e queira voltar a como era antes.
Para funcionar ele precisa:
- Acesso a Internet durante a execução;
- Chave de API para algum modelo de IA.
Links:
- Projeto no GitHub: https://github.com/earendil-works/pi;
- Projeto NPM: https://www.npmjs.com/package/@earendil-works/pi-coding-agent
- Documentação: https://pi.dev/docs/latest
2 – Pi Agent no Docker
Usar o PI no Docker é muito simples, vou mostrar como montei a imagem para fins didáticos e no capítulo posterior você poderá usar minha imagem pronta montada com os mesmos scripts apresentados aqui.
2.1 – Caminhos e volumes
Esses caminhos precisam ser mapeados e direcionado para volumes, assim o container separa:
- Programas: Os binários e bibliotecas de códigos;
- Dados: Configurações e informações acumuladas pelo OC;
- Cache: Arquivos gerados para acelerar a execução;
- Workspace: Projeto de código onde serão produzidos os artefatos do agente, como códigos, documentações, etc;
2.2 – Arquivos para construir a imagem
Dockerfile da imagem:
# syntax=docker/dockerfile:1.7
# Base Alpine com node 26, minimalista
FROM node:26-alpine3.22
ARG APP_UID=1001
ARG APP_GID=1001
# Versao do Pi, usar latest ou versao especifica
# docker buikd ... --build-arg AGENTPI_VERSION=1.x.y
ARG PI_VERSION=latest
ENV \
LANG=C.UTF-8 \
LC_ALL=C.UTF-8
# Pacotes base:
RUN set -eux; \
apk update; \
apk upgrade; \
apk add \
bash \
ca-certificates \
curl \
wget \
git \
openssh-client \
tar \
xz\
zstd \
unzip \
tzdata \
openssl \
less \
procps \
jq \
sqlite; \
true
# Instala Pi via npm
RUN set -eux; \
npm install -g "@earendil-works/pi-coding-agent@${PI_VERSION}"; \
pi --version
# Usuario não-root para rodar o agente.
# A HOME real sera em /data, para persistir tudo que for config/
RUN \
set -eux; \
mkdir -p /data/home/pi; \
addgroup -g "${APP_GID}" pi; \
adduser -u "${APP_UID}" -G pi -D \
-h /data/home/pi -s /bin/bash pi; \
\
chown pi:pi /data -R; \
mkdir -p /data /cache /workspace /cache/tmp /root/.local; \
chmod 0755 /data /cache /workspace; \
chmod 1777 /cache/tmp
# (PAREI AQUI)
# Redireciona /tmp para /cache/tmp, inclusive para arquivos .so temporarios.
RUN \
rm -rf /tmp; \
ln -s /cache/tmp /tmp
# Criar links de /root para os volumes caso rode processos como root dentro do container
RUN \
rm -rf /root/.config /root/.cache /root/.npm /root/.local/share; \
ln -s /data/config /root/.config; \
ln -s /data/share /root/.local/share; \
ln -s /cache/xdg /root/.cache; \
ln -s /cache/npm /root/.npm
# Variaveis centrais:
# - XDG_CONFIG_HOME e XDG_DATA_HOME em /data
# - XDG_CACHE_HOME, npm cache e TMPDIR em /cache
# - NO_PROXY para evitar que o servidor local do TUI passe por proxy
ENV HOME=/data/home/pi \
XDG_CONFIG_HOME=/data/config \
XDG_DATA_HOME=/data/share \
XDG_CACHE_HOME=/cache/xdg \
PI_CONFIG_DIR=/data/config/pi \
NPM_CONFIG_CACHE=/cache/npm \
NPM_CONFIG_PREFIX=/data/npm-global \
TMPDIR=/cache/tmp \
NO_PROXY=localhost,127.0.0.1 \
PATH=/data/npm-global/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# Diretorio padrao inicial
WORKDIR /workspace
# Volumes anonimos (default, requer mapeamento no run)
VOLUME ["/data", "/cache", "/workspace"]
2.3 – Construção da imagem
Para construir a imagem, crie uma pasta para esse projeto “pi-builder” crie os dois arquivos (conteúdo acima) nos seguintes caminhos:
- Dockerfile: ./docker/Dockerfile
- Entrypoint: ./rootfs/opt/entrypoint.sh
Execute o build para construir a imagem:
# Constuir imagem pi:latest
docker build . -f docker/Dockerfile --no-cache -t pi:latest;
Caso queira construir uma imagem versionada usando uma versão específica do Pi:
# Construir imagem de versao especifica do pi:
PI_VERSION="1.x.y";
docker build . \
-f docker/Dockerfile\
-t pi:$PI_VERSION \
--build-arg PI_VERSION=$PI_VERSION;
3 – Rodando Pi no Docker
Vamos rodar o OC no Docker, criando o container pi-dev.
2.1 – Rede Docker
Criando a rede para containers (network_public):
# Rede de containers
docker network create network_public \
-d bridge \
-o com.docker.network.bridge.name=br-net-public \
-o com.docker.network.driver.mtu=1500 \
-o com.docker.network.bridge.gateway_mode_ipv4=nat-unprotected \
--subnet 10.249.0.0/16 \
--gateway 10.249.255.254;
2.2 – Volume
A pasta /workspace dentro do container deve ser mapeada na pasta onde estará seu projeto de software no HOST.
Ela é a pasta onde os programas são executados por padrão (workdir do container).
Nesse exemplo vou armazenar tudo em /storage/pi-dev para você testar e aprender, e depois você personaliza.
# Nome do container
NAME="pi-dev";
# Diretorio do volume no HOST
DATADIR=/storage/$NAME;
# Pastas de volumes montados na pasta principal do volume no host
mkdir -p $DATADIR;
# - Configs e DB de contexto
mkdir -p $DATADIR/data;
# - Cache do bibliotecas
mkdir -p $DATADIR/cache;
# - Pasta com projeto de software (caminho padrao inicial /workspace)
mkdir -p $DATADIR/workspace;
2.3 – Container do OC
Comando para rodar no “docker run”:
# Variaveis
NAME="pi-dev";
# Para usar sua imagem local construida no cap. 2
#IMAGE="pi:latest";
# Para usar minha imagem pronta:
IMAGE="tmsoftbrasil/pi:latest";
# Diretorio de dados persistentes:
DATADIR=/storage/$NAME;
# Pastas de volumes montados
# na pasta principal do volume no host
mkdir -p $DATADIR;
mkdir -p $DATADIR/data;
mkdir -p $DATADIR/cache;
mkdir -p $DATADIR/workspace;
# Rodar container
# Renovar/rodar
docker rm -f $NAME 2>/dev/null
# --read-only
docker run \
-d --restart=always \
--name $NAME --hostname $LOCAL.intranet.br \
\
--tmpfs /run:rw,noexec,nosuid,size=16m \
--tmpfs /tmp:rw,noexec,nosuid,size=16m \
\
--cpus=2 \
--memory 2g --memory-swap 2g --memory-reservation 256m \
\
--network network_public \
\
-v $DATADIR/data:/data \
-v $DATADIR/cache:/cache \
-v $DATADIR/workspace:/workspace \
\
\
$IMAGE \
tail -f /dev/null;
2.4 – Stack para Compose
Caso prefira no modelo de Stack para docker compose:
name: pi-dev
services:
pi-dev:
image: tmsoftbrasil/pi:latest
container_name: pi-dev
hostname: pi-dev
restart: always
read_only: true
command: tail -f /dev/null
tmpfs:
- /run:rw,noexec,nosuid,size=16m
- /tmp:rw,noexec,nosuid,size=16m
deploy:
resources:
limits:
cpus: "2"
memory: 2g
reservations:
memory: 256m
mem_swappiness: 0
memswap_limit: 2g
networks:
- network_public
volumes:
- /storage/pi-dev/data:/data
- /storage/pi-dev/cache:/cache
- /storage/pi-dev/workspace:/workspace
networks:
network_public:
external: true3 – Primeiro acesso
Obtenha shell no container “pi-dev“:
# Obter shell no container:
docker exec -it pi-dev bash;
# Rodar Pi:
pi;
# Ou, rodar direto o pi dentro do container:
docker exec -it pi-dev pi;
3.1 – Tela inicial
Execute:
| Comando | Descrição |
|---|---|
| /login | Fazer login em plataforma oAuth ou informar chave de API |
| /model | Escolher o modelo LLM |
Eu prefiro usar via API, usar o OpenRouter com o modelo DeepSeek-V4-PRO.
.
Agora é contigo. Use sua criatividade.
Terminamos por hoje!
Patrick Brandão, patrickbrandao@gmail.com
“O segredo de avançar é começar.
O segredo de começar é dividir seus projetos
complexos e esmagadores em tarefas
pequenas e gerenciáveis,
e depois começar pela primeira.“
Mark Twain
