Communitygithub.com

Bohdan-Meshcheriakov/deploy-data-clerk

Habilita a implantação, configuração e manutenção contínua do aplicativo no cluster Kubernetes gerenciado da Data Clerk. Use-o sempre que precisar implantar, publicar, alterar variáveis de ambiente, gerenciar segredos, adicionar migrações de banco de dados, configurar domínios/HTTPS ou resolver problemas de indisponibilidade.

O que é deploy-data-clerk?

Esta skill automatiza e descreve o processo completo de implantação e operação de um aplicativo no ambiente Data Clerk, um cluster Kubernetes gerenciado. Ela define um contrato claro entre o desenvolvedor e o operador do cluster, garantindo que alterações no código (push para `main`) e em segredos criptografados com sops sejam refletidas no site ao vivo com segurança e sem interrupções. A skill cobre todas as etapas críticas: leitura de configurações do projeto, construção de imagens Docker, uso de variáveis de ambiente, gerenciamento de banco de dados PostgreSQL (incluindo migrações e backups automáticos), configuração de rede (Cloudflare, Traefik, WebSockets) e solicitações para o operador (como novos domínios ou aumento de recursos). Ela é especialmente útil para desenvolvedores que não têm acesso direto ao cluster, fornecendo um fluxo de trabalho reprodutível e seguro que evita erros comuns como perda de dados ou tempo de inatividade. Suporta qualquer stack (Node, Python, Go, etc.) através de templates e referências detalhadas.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Bohdan-Meshcheriakov/data-clerk-skills/tree/HEAD/skills/deploy-data-clerk

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Implantação no Data Clerk

Este aplicativo é executado no Data Clerk, um pequeno cluster Kubernetes gerenciado por um operador (um humano, contato em PROJECT.md). O proprietário deste repositório geralmente não é uma pessoa de infraestrutura. Ele nunca deve precisar tocar em servidores, Kubernetes ou console de nuvem: ele faz push para main, e o cluster faz o resto. Seu trabalho é manter as coisas assim: trabalhe dentro do repositório, siga o contrato abaixo e, quando algo realmente precisar do lado do cluster, escreva uma solicitação clara para o operador, em vez de improvisar.

Explique as coisas ao usuário em palavras simples ("seu site será atualizado em cerca de cinco minutos"), não em termos de Kubernetes.

Comece aqui

  1. Leia deploy-data-clerk/PROJECT.md. Ele contém os valores deste projeto: URL pública, pasta de implantação, nome da imagem, porta, comando de migração, limites, quem é o operador. Tudo abaixo que diz "de PROJECT.md" significa esse arquivo. Se o nome da pasta em PROJECT.md for diferente de deploy-data-clerk/ (projetos mais antigos usam deploy/), use o que PROJECT.md disser.
  2. Sem PROJECT.md, ou ele ainda tem valores __PLACEHOLDER__? O projeto ainda não foi integrado: siga references/new-project.md.
  3. Escrevendo ou alterando um Dockerfile, decidindo como estruturar o aplicativo, ou a stack não é Node? Leia references/stacks.md (qualquer linguagem, full-stack vs frontend separado + API, FastAPI, Go).
  4. Antes da primeira tarefa de segredos em uma máquina, verifique se as ferramentas funcionam: sops --version e um teste de descriptografia (sops decrypt <pasta de implantação>/secrets.env > /dev/null). Se algum falhar, siga references/setup-tools.md.

Como uma alteração chega ao site ao vivo

O que mudouO que aconteceAo vivo depois de
Código (push para main)GitHub Actions constrói uma imagem Docker e a envia; o cluster percebe a nova tag de imagem e a distribui~3–7 min (tempo de construção + ~1 min)
secrets.env (push para main)O cluster relê a pasta de implantação a cada 5 min, descriptografa, atualiza o env do aplicativo e reinicia o aplicativo~5 min
Um novo arquivo em migrations/Executa automaticamente antes da nova versão iniciarcom a implantação de código
Qualquer coisa fora de mainNada. Branches e PRs não são implantados—

A distribuição é cuidadosa: a nova versão inicia ao lado da antiga, as migrações são executadas primeiro, e o tráfego só é movido quando a nova versão responde à verificação de saúde. Se a construção, uma migração ou a verificação de saúde falhar, a versão antiga continua servindo e o site permanece no ar. Uma implantação falha significa "a alteração não está ao vivo", não "o site está fora do ar".

Para verificar uma implantação: gh run list --workflow "Deploy to cluster" --limit 3 (ou a aba Actions no GitHub), depois abra a URL pública. Para reimplantar sem alteração de código: gh workflow run "Deploy to cluster", que constrói uma nova tag, então o aplicativo reinicia com um ambiente fresco.

O contrato (o que mantém as implantações funcionando)

Cada regra existe porque quebrá-la falha silenciosamente ou perde dados. Siga-as e avise o usuário se uma solicitação quebrar alguma.

  • Escute em $PORT (a porta em PROJECT.md, definida pelo cluster), em 0.0.0.0, não localhost.
  • A imagem é construída a partir de <pasta de implantação>/Dockerfile para linux/amd64 e é executada como um usuário não root. Sem root, sem portas abaixo de 1024, sem capacidades extras do Linux.
  • As tags de imagem são YYYYMMDDHHMMSS-<shortsha>. O cluster implanta o número mais alto e ignora silenciosamente qualquer tag que não esteja neste formato. Nunca altere a etapa de tag em .github/workflows/deploy-cluster.yml.
  • O disco do contêiner é limpo em toda implantação e reinicialização. Nunca mantenha uploads de usuários, arquivos SQLite ou qualquer coisa preciosa no disco local. Coloque os dados no banco de dados; para arquivos (fotos, vídeo), peça ao operador armazenamento de objetos.
  • Verificação de saúde: o cluster testa o caminho de saúde em PROJECT.md (/healthz recomendado). Faça-o retornar 200 rapidamente, sem chamada de banco de dados ou renderização de página, ou um banco de dados lento faz o cluster pensar que o aplicativo está morto.
  • DATABASE_URL vem do cluster. Nunca coloque em secrets.env (isso substituiria o real) e nunca defina no momento da construção da imagem.
  • Tempo de execução versus tempo de construção. secrets.env atinge o aplicativo apenas em tempo de execução. A imagem é construída no GitHub Actions sem ele. Qualquer coisa embutida no frontend em tempo de construção (VITE_*, NEXT_PUBLIC_*, REACT_APP_*) não pode vir de secrets.env: leia esses valores no servidor em tempo de execução e passe-os para a página, ou (se não forem secretos) comprometa-os no código.
  • Segredos que o aplicativo gera para si mesmo quando ausentes (segredo de autenticação/sessão, sais de criptografia, chaves de push): defina-os em secrets.env. Caso contrário, toda reinicialização cria novos, usuários são desconectados, assinaturas de push quebram, e assim por diante.
  • As migrações devem ser seguras para a versão antiga. Por cerca de um minuto, ambas as versões são executadas contra o novo esquema. Adicione colunas e tabelas livremente. Renomeie ou remova em duas implantações: primeiro pare de usar, depois remova. Detalhes em references/database.md.

Variáveis de ambiente e segredos

Toda configuração de tempo de execução está em <pasta de implantação>/secrets.env, comprometida criptografada com sops. Apenas os valores são criptografados; os nomes das chaves permanecem legíveis. Altere-o com o próprio sops. Nunca descriptografe para um arquivo que você possa comprometer, e nunca imprima valores secretos no chat ou logs.

sops set deploy-data-clerk/secrets.env '["STRIPE_SECRET_KEY"]' '"sk_live_..."'
sops unset deploy-data-clerk/secrets.env '["OLD_KEY"]'
sops decrypt deploy-data-clerk/secrets.env | cut -d= -f1

Em seguida, commit e push para main; fica ao vivo em ~5 min. Quando o usuário tiver que fornecer o valor (uma chave de API de algum painel), peça para ele executar a linha sops set ele mesmo, ou cole o valor apenas em seu próprio terminal. O guia completo (chaves, onde elas vivem, rotação, pegadinhas) está em references/secrets.md.

Banco de dados

Postgres 18, gerenciado pelo operador. O aplicativo recebe seu próprio banco de dados e usuário via DATABASE_URL. Mudanças de esquema são arquivos de migração que se aplicam automaticamente na implantação (references/database.md).

Backups: um backup completo todas as noites às 03:00 UTC mais um log contínuo de cada alteração, armazenado fora do servidor no Google Cloud Storage. O operador pode restaurar o banco de dados para qualquer momento nos últimos 7 dias. Portanto, se dados forem excluídos ou uma migração der errado, não entre em pânico e não tente corrigir manualmente: anote a hora em que aconteceu e peça ao operador uma restauração (modelo em references/troubleshooting.md). Uma restauração retrocede todo o banco de dados, então as alterações feitas após esse momento são perdidas.

Fatos de rede que seu código pode precisar

  • Caminho do tráfego: visitante → Cloudflare → Traefik (ingresso do cluster) → aplicativo. Certificados HTTPS são automáticos. O aplicativo em si fala HTTP simples em $PORT; X-Forwarded-Proto: https indica que o original era HTTPS. Confie nos cabeçalhos de proxy e não redirecione para HTTPS no aplicativo (isso causaria um loop).
  • IP real do visitante: leia o cabeçalho CF-Connecting-IP. X-Forwarded-For contém um endereço do Cloudflare, portanto, limitar a taxa com base nele coloca todos os visitantes em um único balde.
  • Traefik adiciona estes cabeçalhos: HSTS (2 anos, preload), X-Content-Type-Options: nosniff, X-Frame-Options: SAMEORIGIN (o site não pode ser incorporado em um iframe em outros domínios). Cabeçalhos extras (CSP, COOP/COEP para SharedArrayBuffer, permitindo iframes) são definidos pelo operador mediante solicitação.
  • O ingresso não compacta respostas. Cloudflare compacta tipos de texto comuns; para controle total, compacte no aplicativo ou forneça ativos pré-compactados.
  • Conexões longas (SSE, websockets) são aceitáveis, mas o Cloudflare encerra uma conexão ociosa após ~100 s. Envie um heartbeat a cada ~30 s e reconecte no cliente.
  • Saída: o aplicativo pode chamar qualquer endpoint público da internet em qualquer porta. Isso inclui APIs de LLM, Stripe, e-mail, S3 e bancos de dados gerenciados ou Redis (Neon, Supabase, Atlas, Upstash) em seus endpoints públicos. Ele não pode alcançar redes privadas (VPC peering, PrivateLink, IPs privados) ou outros projetos no cluster. O tráfego de entrada só vem através da URL pública.
  • Serviços de terceiros: coloque suas chaves e URLs em secrets.env. Se um serviço precisar de uma lista de permissões de IP, o cluster tem um IP de saída estático: peça ao operador por ele (não é publicado) e informe ao usuário que ele é compartilhado com outros projetos no cluster. O servidor está no centro dos EUA, portanto, prefira regiões US-central/us-east para bancos de dados externos (um banco de dados na UE adiciona ~100 ms por consulta). Um banco de dados externo é de propriedade do usuário: os backups do Data Clerk não o cobrem. Para chamadas lentas de LLM, transmita a resposta ou execute-as como jobs em segundo plano; uma solicitação de navegador esperando mais de ~100 s é interrompida.
  • Os recursos são limitados (memória/CPU em PROJECT.md). Exceder o limite de memória mata e reinicia o aplicativo. Se isso acontecer, peça ao operador mais espaço em vez de tentar resolver no código.
  • Uma cópia do aplicativo é executada (uma réplica). Não confie no estado em memória para sobreviver a uma implantação e mantenha as sessões no banco de dados ou em cookies assinados.

O que apenas o operador pode fazer

O usuário não tem acesso ao cluster, e isso é por design. Escreva ao operador uma solicitação curta (veja references/troubleshooting.md para o modelo) para:

novo domínio ou subdomínio · mais memória/CPU · armazenamento de arquivos/objetos · restauração de banco de dados · logs do aplicativo ou causas de falha · cabeçalhos de segurança alterados · alteração do comando de migração ou inicialização, porta ou caminho de saúde · jobs agendados (cron) · serviços extras (Redis, filas) · um segundo aplicativo no mesmo projeto · integração de um novo repositório.

Mais detalhes

  • references/stacks.md: o contrato universal para qualquer linguagem; full-stack vs SPA + API vs estático; Node, Python FastAPI, Go e outras stacks.
  • references/new-project.md: integração de um repositório (arquivos a adicionar, o que pedir ao operador, Dockerfile por stack).
  • references/secrets.md: sops em profundidade, o arquivo de chave, rotação, variáveis de tempo de construção.
  • references/database.md: migrações, string de conexão, backups, correções de dados.
  • references/setup-tools.md: instalação segura de sops/git/gh no macOS, Linux e Windows. Execute scripts/install-tools.sh ou scripts/install-tools.ps1.
  • references/troubleshooting.md: "minha alteração não está ao vivo", "site está fora", erros comuns, o modelo de solicitação do operador.
  • assets/: modelos de Dockerfile (Node, Python, Go) e modelos para o workflow de implantação, kustomization.yaml, .sops.yaml, .gitattributes e PROJECT.md.

Habilidades Relacionadas