Deploy do GitHub

Clona, faz o build e publica um repo do GitHub no VPS; deploy a cada push, histórico por fases e rollback.

  • Categoria: Servidores e infraestrutura
  • Estado: Disponível
  • Requisitos: Um VPS ativo da empresa com a função deploy_github disponível; A conta do GitHub de quem vincula, conectada à ArduMaker com acesso ao repo; Ser membro da empresa com acesso a esse VPS (no Git um membro faz o mesmo que um admin)
  • Ferramentas MCP (Só leem): listar_repos_github_vps, ver_repo_github_vps, listar_commits_repo_github_vps, ver_commit_repo_github_vps, listar_logs_repo_github_vps, ver_log_repo_github_vps, ver_asistente_git_app, ver_config_deploy_app, ver_propietarios_github, ver_operacion_app
  • Ferramentas MCP (Escrevem ou modificam): instalar_app, vincular_repo_github_vps, crear_repo_github_vps, editar_repo_github_vps, redeploy_repo_github, guardar_config_deploy_app, controlar_app
  • Ferramentas MCP (Destrutivas): eliminar_repo_github_vps, desinstalar_app, publicar_repo_en_dominio

Markdown

O que permite fazer?

O deploy de Git leva um repositório do GitHub para um VPS e o mantém atualizado: clona, faz o build, deixa rodando como serviço systemd (ou contêiner), publica com HTTPS e faz o deploy de novo a cada push na branch escolhida.

  • Detectar o que é o repo (Node, Django, Python, site estático, Docker, Procfile) e propor comandos de build e início.
  • Declarar em um documento de deploy as fases (pre_pull, install, build, release), os processos (serviços, temporizadores, tarefas pontuais, estáticos, Docker, TCP), as variáveis de ambiente e a publicação.
  • Fazer deploy automático a cada push, manual, ou de um commit específico da branch.
  • Voltar ao commit de um deploy anterior que terminou bem.
  • Ver o histórico de deploys com cada fase, seus tempos e os comandos com a saída (com os segredos ocultos).
  • Criar um repositório novo no GitHub pela ArduMaker e fazer o deploy.

Quando convém usar?

  • Um site, uma API ou um worker que vive no GitHub e precisa ficar sempre igual à branch principal.
  • Tarefas agendadas do projeto (um timer) que precisam viajar com o código.
  • Uma equipe que quer ver qual commit está em produção e poder voltar atrás sem entrar no servidor.

Como funciona na ArduMaker?

1. Vincular e clonar

Há duas portas. A recomendada é instalar como app (instalar_app com app_type: git, repo_id, branch e, se quiser, port e o documento deploy): fica no inventário de Apps e a operação é durável. A outra é a aba GitHub do VPS (vincular_repo_github_vps), que só clona e roda em segundo plano.

Ao vincular, a ArduMaker cria no GitHub um webhook com um segredo próprio do repo: cada entrega chega assinada com HMAC-SHA256 e sem nada secreto na URL. O repo é clonado em <pasta-do-deploy>. A URL com o token do GitHub fica na pasta .git, que pertence a root e não pode ser lida pela app.

2. Detectar e configurar

ver_asistente_git_app lista os repos que a conta do GitHub pode ler, suas branches e, com repo e branch, o que detecta lendo os arquivos sem executar nada: framework, comandos de build e início e uma porta livre do VPS. Os formatos conhecidos são Docker (também Compose), Procfile, Node web, Django, site estático Vite, Python web e manual. Uma migração proposta sempre chega sem confirmar: o documento não valida até que uma pessoa a confirme.

O que cada deploy roda é sempre um documento: o salvo com guardar_config_deploy_app ou, se o repo nunca salvou um, o derivado dos scripts de sempre (pre-pull, post-pull e serviços). Salvar um documento migra o repo: a partir daí manda o documento.

3. Deploy por fases

Cada deploy roda estas fases em ordem e as registra no histórico. Se uma falhar, as seguintes não rodam e o repo fica em error com um texto curto (Deploy failed at the <fase> phase), nunca a saída bruta de um comando.

FaseO que faz
prepararUsuário Linux da app, pasta da plataforma, arquivos de variáveis, Docker se necessário
pre_pullphases.pre_pull na pasta do clone
pullTraz a branch (ou deixa a pasta no commit pedido)
installphases.install, passo longo
buildphases.build, passo longo; depois os contêineres dos processos docker
releaseA migração, só se confirmada
procesosEscreve ou reinicia unidades, temporizadores e tarefas pontuais
publicarServer block do domínio no nginx do VPS, se o perfil publica
saludVerifica se a app responde ou se as unidades continuam vivas

Com a app instalada em Apps, o deploy é executado pelo runner de operações e é retomado se o worker cair. Um repo sem app roda o mesmo deploy em segundo plano. Vários pushes seguidos são agrupados: no máximo um deploy rodando e um na fila por app.

O que muda realmente?

<pk> é o número do repo na ArduMaker. Com policies.run_as: "root" o usuário não é criado e tudo pertence a root.

O quêOndeDono e modo
Usuário da appardu-app<pk>, de sistema, sem login—
Clone<pasta-do-deploy>do usuário; .git de root
Pasta da plataforma/etc/ardumaker/deploy/ardu-repo<pk>/root:ardu-app<pk> 0750
Variáveis de execução e de build…/run.env, …/build.envardu-app<pk> 0600
Scripts de cada passo e sua saída…/install.sh, build.sh, release.sh, <paso>.log0750 / root
Serviço principal/etc/systemd/system/ardu-repo<pk>.serviceroot 0644
Outros processos e temporizadoresardu-repo<pk>-<proceso>.service / .timerroot 0644
Contêineresardu-repo<pk>, ardu-repo<pk>-<proceso>—
Server block/etc/nginx/sites-available/<dominio>.conf—

Uma unidade que não mudou só é reiniciada; uma que mudou é reescrita. Uma unidade adotada (de um repo antigo) é reiniciada e nunca é escrita nem apagada. O que um deploy criou e o documento já não tem é apagado no deploy seguinte.

O documento de deploy

É um JSON versionado (schema_version: 2). É lido com ver_config_deploy_app e substituído inteiro com guardar_config_deploy_app (apply=true o aplica na hora com um reconfigure).

ParteValores
profilestatic, web, worker, scheduled, job, docker, network e code (só código: em cada push traz o repositório e mais nada; sem instalar, compilar, migrar, processos nem publicação)
phasespre_pull, install, build e release (command, confirmed, on_update)
processesAté 20, do tipo service, timer (com schedule), oneoff, static, docker ou tcp; portas de 1024 a 65535, sem repetir
network.publish.modenone, auto_subdomain, domain, port
network.health.typehttp, unit, timer, static
envLista de {name, value} com scope build, run ou ambos
policiesbuild_timeout_s 60–7200 (600 por padrão, por passo), memory_max_mb e cpu_quota_pct sem limite por padrão, run_as (app_user ou root), rollback_on_failed_health
autodeployenabled: se um push faz deploy

Variáveis e segredos

Uma variável com nome de segredo (*_TOKEN, *_PASSWORD, *_KEY…), com secret: true ou com uma URL que traz usuário e senha é guardada criptografada e no documento fica só a referência. Na leitura, env mostra só {name, scope, has_value}, nunca um valor. Enviar uma variável sem value mantém a guardada.

  • Os valores são escritos em run.env e build.env (0600) só na fase preparar. Um valor com quebra de linha é recusado.
  • Mudar uma variável de build (NEXT_PUBLIC_*, VITE_*) obriga a compilar de novo: o reconfigure faz isso com o mesmo código e sem release.
  • No log de cada comando a carga secreta é substituída pelo tamanho e a saída leva cada segredo oculto ([redacted]).

Passos longos, limites e saúde

install, build e release rodam cada um em uma unidade transitória própria, com o usuário da app, /tmp privado e set -e (para no primeiro comando que falhar):

sudo systemd-run --unit=ardu-deploy<pk>-<paso> --wait --collect --pipe \
  -p User=ardu-app<pk> -p RuntimeMaxSec=<build_timeout_s> -p NoNewPrivileges=yes -p PrivateTmp=yes \
  -p EnvironmentFile=/etc/ardumaker/deploy/ardu-repo<pk>/build.env \
  /bin/bash /etc/ardumaker/deploy/ardu-repo<pk>/<paso>.sh
SaúdeO que se verifica
httpcurl em 127.0.0.1:<porta><caminho> até 25 vezes; sem expect vale qualquer resposta que não seja 5xx
unitCada unidade ativa duas vezes com 8 s de intervalo e sem novos reinícios
timerO .timer habilitado e ativo, e seu horário válido
staticA pasta existe e o nginx do VPS responde sem 5xx para o domínio

Portas e publicação

A app escuta em uma porta interna do VPS. Se for instalada por Apps sem port (ou com "auto"), é usada a primeira porta livre. As portas dos motores e do agente nunca são publicadas. O endereço automático é git-<id> dentro da zona da plataforma; também é possível usar um domínio próprio que aponte para o VPS.

A fase publicar escreve o server block no nginx do VPS; o DNS, o proxy até o VPS, o certificado e a verificação do link por HTTPS são feitos pela publicação de Apps. Se essa parte falhar (por exemplo, o DNS ainda não propagou), a nova tentativa publica sem refazer o build. Um nginx editado à mão não é sobrescrito.

Push, commits específicos e rollback

  • Um push de outra branch é ignorado. Com autodeploy desligado, uma entrega repetida do GitHub ou um deploy já rodando, o push registra os commits mas não faz deploy, e a resposta diz por quê.
  • redeploy com commit_sha deixa a pasta nesse commit da branch e roda um update normal, com release se confirmada.
  • rollback com run_id volta ao commit de um deploy que terminou bem (git reset --hard <sha>) com a configuração atual. Um deploy de outro repo, um que falhou ou o que já está publicado é recusado.
  • Com rollback_on_failed_health: true, um deploy disparado por push que falha em salud volta uma vez ao último commit saudável e desliga o autodeploy, deixando o motivo registrado.

Desvincular um repo

Excluir o repo remove o que o documento criou: unidades e temporizadores, contêineres, a pasta da plataforma, o usuário da app com sua pasta e a entrada de safe.directory; depois a unidade e o contêiner principais, o clone e o webhook do GitHub. O que foi adotado não é tocado.

Esquema

  1. GitHub: push na branch seguida; webhook assinado
  2. Backend da ArduMaker: registra commits e enfileira o deploy
  3. Agente do VPS: executa cada fase
  4. Clone + build: systemd-run como ardu-app<pk>
  5. `ardu-repo<pk>.service`: a app em 127.0.0.1:<porta>
  6. nginx do VPS: server block do domínio
  7. Internet: HTTPS no domínio publicado
De um push à app publicada — O certificado é colocado pela plataforma na frente do VPS; o nginx do VPS encaminha o domínio para a porta interna da app.

Resultado esperado

O repo fica pulled (ou online após a instalação) com last_commit_sha igual ao commit que está na pasta. ver_repo_github_vps traz last_runs: origem (webhook, manual ou mcp), commits, resultado e como foi cada fase. Se foi publicado, ver_app mostra a URL HTTPS só quando o link foi verificado.

systemctl status ardu-repo<pk>.service
curl -I http://127.0.0.1:<puerto>/

Erros e resolução

ErroCausaTentar de novo?
github_no_vinculadoQuem pede não tem GitHub conectado ou o token venceuSim, após reconectar o GitHub
repo_inaccesible / rama_inexistenteA conta não lê o repo ou a branch não existeNão
clon_fallido / github_no_respondeO clone falhou (não deixa nada) ou o GitHub não respondeuSim
puerto_ocupadoOutro app do VPS já usa essa portaCom outra porta
deploy_en_cursoJá havia outro deploy rodando nesse repoSim, quando terminar
preparacion_fallida, pull_fallido, build_fallido, release_fallida, app_no_arranco, salud_fallida, nginx_del_vps_invalidoA fase que falhouManualmente, nunca sozinho
config_invalidaO documento não valida; errors por caminho (processes.web.port)Corrigindo o documento
  • preparar failed - missing value for <VARIABLE>: falta o valor de uma variável; o deploy para antes de tocar o VPS.
  • Aviso limits_not_applied: o VPS recusou os limites de memória ou CPU e o passo rodou sem eles.
  • Aviso health_check_failed: em um repo de configuração herdada a saúde que não passa é um aviso, não um erro.
  • A app responde só em [::1]: o nginx do VPS chega por 127.0.0.1; é preciso escutar em 127.0.0.1 ou 0.0.0.0.

Onde olhar: ver_repo_github_vps (últimos deploys e fases), listar_logs_repo_github_vps e ver_log_repo_github_vps (comando e saída, com o token e os segredos ocultos), e ver_operacion_app para a operação de Apps.

Relação com MCP

O deploy de Git tem acesso MCP completo; referência em /mcp/docs e /mcp/deploy. As escritas podem ser feitas por qualquer membro com acesso ao VPS, exceto um agente autorizado como somente leitura.

TipoFerramentas
Leituralistar_repos_github_vps, ver_repo_github_vps, listar_commits_repo_github_vps, ver_commit_repo_github_vps, listar_logs_repo_github_vps, ver_log_repo_github_vps, ver_asistente_git_app, ver_config_deploy_app, ver_propietarios_github
Modificaminstalar_app, vincular_repo_github_vps, crear_repo_github_vps, editar_repo_github_vps, guardar_config_deploy_app, redeploy_repo_github, controlar_app, publicar_repo_en_dominio
Destrutivaseliminar_repo_github_vps, desinstalar_app

controlar_app sobre um app git aceita redeploy (com commit_sha opcional), rollback (com run_id) e reconfigure (aplica o documento sem trazer código). publicar_repo_en_dominio faz em uma chamada domínio, verificação, ativação com SSL, server block e instalação; com simular=true mostra o plano e com desde retoma onde falhou.

Funcionalidades relacionadas