`runner restart`

Recycle do container que está atualmente servindo uma app, sem ir pelo pipeline de deploy completo. Útil para:

  • Destravar um processo preso (loop, deadlock, file descriptor leak)
  • Reciclar conexões persistentes (DB pool, websockets, etc.)

Disponível desde v2.22.9.

O restart não aplica env novo. Ele faz stop/start do mesmo container, e o env de um container é fixado quando ele é criado. Depois de runner env set ou env unset, aplique com runner deploy <app> --force, que recria o container pelo pipeline, com healthcheck. Até a v2.157.0 a ajuda do comando dizia o contrário.

Sintaxe

runner restart <app> [-i instance] [--timeout N] [--json]
Flag Default Descrição
-i, --instance a do registro¹ Instance a reiniciar
--timeout 10 Stop timeout em segundos antes do SIGKILL
--json false Output em JSON
-x, --exact false Desliga a resolucao por query: um alvo so
-y, --yes false Confirma quando a query casa varios alvos do mesmo projeto. Nao autoriza atravessar projetos

¹ Sem -i, vale a instância com que a app foi registrada (runner add --instance <N>), depois a default do manifesto, depois production (v2.151.2+). Antes da v2.151.2, o default era sempre production, e uma app registrada em staging respondia sobre uma instância que nem tem.

Com vários alvos, cada um reinicia na instância do seu registro.

Como resolve o container

Desde a v2.151.3, o runner acha o container pelos labels dele: o registro da app (ccs.systems/uid) e a instância (ccs.systems/instance). Se houver mais de um, como depois de um rollback, vale o que está rodando.

Só em container antigo, sem esses labels, o nome é montado a partir do state ({project}_{instance}_{versão}, com - trocado por _). Mesmo assim, ele só é usado se o container existir. Se não existir, o comando falha e diz o que procurou.

Antes da v2.151.3, o nome era sempre montado a partir do state. Com instância com hífen (staging-b), o comando respondia ✓ Restarted sem reiniciar nada. Depois de um rollback, mirava o container parado da versão abandonada.

Faz docker stop (com timeout) + docker start. Não toca em volumes, networks, nem na imagem — apenas recicla o processo.

Exemplos

# Restart padrão (instância do registro, timeout=10s)
runner restart meu-app

# Restart de instance específica
runner restart meu-app -i staging

# Timeout maior pra apps com graceful shutdown lento
runner restart meu-app --timeout 30

# JSON pra orquestrador/CCS
runner restart meu-app --json

Output JSON

{
  "action": "restart",
  "app": "meu-app",
  "instance": "production",
  "version": "v1.2.3",
  "container": "meu_app_production_v1-2-3",
  "success": true,
  "stop_error": null,
  "start_error": null,
  "timestamp": "2026-05-15T..."
}

Erros comuns

Erro Causa
app '<X>' not registered (no state file) App não passou por runner add
app '<X>' has no current_version (not deployed yet?) App registrada mas nunca deployada
stop failed: 404 No such container Container já parado ou removido — rode runner deploy

Veja também

Multiplos alvos e a fronteira do projeto (v2.80.0+)

<app> nao e um nome exato: e uma query, casada por segmento. runner restart ccs alcanca ccs/sys, ccs/front e ccs/worker — replicar o comando nos sistemas de um projeto e o desenho do runner, nao um acidente.

Situacao Comportamento
1 alvo Executa direto, sem cerimonia
N alvos, mesmo projeto Lista os alvos e pede confirmacao. -y, --yes dispensa
N alvos, projetos distintos Terminal: pergunta. Cron/CI (sem TTY): aborta com exit != 0. Nenhuma flag autoriza

O "projeto" aqui e a raiz antes do primeiro hifen: ccs-front e ccs-sys sao o mesmo projeto (ccs); ccs-front e nfse-front nao sao.

Por que `--yes` nao autoriza atravessar

--yes e passado por habito, em script e cron. Se valesse para o cruzamento, o gate morreria exatamente onde ninguem esta olhando. Uma query casa por segmento e deveria cair dentro de uma familia — atravessar e anomalia, nao intencao.

ERROR restart atravessa 2 projetos (ccs, nfse) em 4 alvos:
  - ccs/sys
  - ccs/front
  - nfse/sys
  - nfse/front

Uma query casa por segmento e deveria cair dentro de UMA família — atravessar aqui é anomalia, não intenção, e por isso nenhuma flag autoriza.
Este comando não opera em massa entre projetos: rode um projeto por vez.
Para um alvo só: -x

Em terminal interativo o cruzamento pergunta em vez de abortar. Em cron/CI (sem TTY) aborta com exit != 0.

Saidas:

  • -x, --exact — desliga a query e mira um alvo so
  • rodar um projeto por vez
By Borlot.com.br on 15/05/2026