runner app

v2.157.0+. Comandos que alteram o que o servidor guarda sobre uma app registrada:

  • rename: o nome de exibição (v2.157.0);
  • origem: o repositório e a branch rastreada (v2.193.0);
  • instancia: a instância em que a app roda (v2.193.0);
  • manifest-path: o manifesto da app no repositório, em monorepo (v2.194.0);
  • identidade: o nome técnico da app, usado nos containers, rotas e imagens (v2.195.0).

Todos respondem em envelope v2 com -o json.

O nome de exibição serve para distinguir apps com o mesmo project: em listagens e painéis. Ele vale para todas as instâncias da app. Não muda o diretório, os containers, os routers nem o .deploy.yml.

Uso

runner app rename <app> --display-name "<texto>"
runner app rename <app> --clear
Flag Descrição
--display-name <texto> Grava o nome de exibição
--clear Apaga o nome de exibição
-o json Saída em envelope v2

<app> é o nome do diretório da app ou uma consulta que case com exatamente uma app registrada.

Regras do texto

  • De 1 a 80 caracteres.
  • Sem quebra de linha nem caractere de controle.
  • Os espaços nas pontas são removidos.

Exemplos

runner app rename minha-api --display-name "Minha API"
runner app rename minha-api --clear -o json

Saída JSON

Sucesso:

{
  "success": true,
  "schema_version": "2.0",
  "command": "app.rename",
  "data": { "app": "minha-api", "display_name": "Minha API" }
}

Com --clear, display_name vem null.

Erro (exit 1):

{
  "success": false,
  "schema_version": "2.0",
  "command": "app.rename",
  "error": {
    "code": "E7001",
    "message": "o nome de exibição não pode ter quebra de linha nem caractere de controle",
    "details": { "reason": "display_name_invalido", "app": "minha-api" }
  }
}
details.reason Código Causa
app_inexistente E4003 Nenhuma app registrada com esse nome. O comando não cria state
app_ambigua E7001 A consulta casa com mais de uma app. Passe o nome do diretório
display_name_invalido E7001 Texto vazio, com mais de 80 caracteres ou com caractere de controle

Onde o nome aparece

  • runner snapshot -o json: campo display_name em cada item de projects[] e de instances[]. Fica null quando a app não tem nome.
  • runner --capabilities anuncia a feature app.display_name.v1.

runner app origem (v2.193.0)

Troca de onde vem o código: repositório, provedor e branch rastreada, num comando só.

runner app origem <app> [--repo <repo>] [--provider <tipo>] [--branch <branch>] [--dry-run]
Flag Descrição
--repo <repo> Repositório novo: owner/name (GitHub) ou URL https/ssh
--provider <tipo> Provedor de servidor próprio. Só vale com --repo
--branch <branch> Branch rastreada nova
--dry-run Confere e mostra o que mudaria, sem gravar

Antes de gravar, o runner confere:

  1. a forma do repositório. URL com credencial é recusada; registre o token com runner tokens set;
  2. que o repositório de destino pode ser lido;
  3. que a branch existe nesse repositório. Sem --branch, vale a branch atual.

O comando grava só o registro. O próximo runner fetch --deploy (ou um runner deploy) implanta a partir da origem nova.

runner app origem loja --branch release/2.0 --dry-run -o json
runner app origem loja --repo https://gitlab.com/time/loja.git --branch dist -o json

runner app instancia (v2.193.0)

Leva a app para outra instância.

runner app instancia <app> --to <instância> [--dry-run]

A ordem é sempre a mesma:

  1. deploy na instância nova;
  2. conferência de que o container novo existe;
  3. remoção da instância antiga.

Se o deploy falhar, nada é removido e a app continua na instância antiga. --dry-run mostra o plano: containers e rotas que seriam removidos.

runner app instancia loja --to staging --dry-run -o json
runner app instancia loja --to staging -o json

Exit 3 indica que a instância nova está no ar mas algo ficou pendente: remoção incompleta da antiga, ou um passo depois do deploy (como publicar os secrets). O campo pendente diz o quê.

runner app manifest-path (v2.194.0)

Troca o manifesto que a app usa dentro do repositório. Serve para monorepo, com um .deploy.yml por serviço.

runner app manifest-path <app> <caminho> [--dry-run]

<caminho> é relativo à raiz do repositório (ex: apps/api/.deploy.yml). .deploy.yml volta ao manifesto da raiz.

Antes de gravar, o runner confere, na branch rastreada:

  1. que o arquivo existe;
  2. que o deploy o aceita (sintaxe e regras do manifesto);
  3. que ele declara a instância em que a app roda hoje.

Com manifesto fixado no servidor (runner manifest pin), a troca é recusada: publique ou descarte o pin antes.

O container em execução muda no próximo deploy: versão nova pelo cron, ou runner deploy <app> --force. O nome dos containers não muda, mesmo que o manifesto novo declare outro project:.

runner app manifest-path loja apps/api/.deploy.yml --dry-run -o json
runner app manifest-path loja apps/api/.deploy.yml -o json

runner app identidade (v2.195.0)

Troca o nome técnico da app (nome_base). É o nome que aparece nos containers, nas rotas do Traefik, nas tags de imagem, no canary e nos signals. O diretório da app, o label ccs.systems/uid, os volumes e o project: não mudam.

runner app identidade <app> --nome-base <novo> [--dry-run]

O nome segue a regra de nome de imagem Docker: letras minúsculas, números, - e _, de 1 a 63 caracteres.

A troca não tira a app do ar:

  1. sobe a mesma versão com o nome novo, ao lado da antiga;
  2. espera o container novo ficar saudável e grava a rota nova;
  3. tira a rota antiga e confirma pela API do Traefik que ela saiu. Sem API, o runner espera o tempo de recarga do Traefik e avisa confirmacao_sem_api;
  4. só então para o container antigo.

Se a app estiver num balanceador (runner lb), a inscrição passa para o nome novo com o mesmo peso.

Se algo falhar antes da rota nova, o nome antigo continua no ar e nada muda. Se falhar depois, o nome novo já está servindo: o comando sai com exit 3 e pendente, e o cron termina a limpeza.

A troca é recusada com canary em curso, deploy em andamento, adoção pendente, app de PR, ou um nome já usado por outra app.

runner app identidade loja-antiga --nome-base loja --dry-run -o json
runner app identidade loja-antiga --nome-base loja -o json

Saída JSON das trocas

origem e instancia usam o mesmo formato:

{
  "success": true,
  "schema_version": "2.0",
  "command": "app.origem",
  "data": {
    "app": "loja",
    "nome_base": "loja",
    "antes": { "repo": "devborlot/loja", "provider": "github", "branch": "dist" },
    "depois": { "repo": "devborlot/loja", "provider": "github", "branch": "release/2.0" },
    "changed": true,
    "dry_run": false,
    "provoca_deploy": true,
    "avisos": [],
    "pendente": []
  }
}
Campo Significado
app Diretório da app (o mesmo do label ccs.systems/uid)
antes, depois O valor antes e depois da troca. Nunca levam credencial
changed false quando o valor pedido já era o atual (exit 0)
provoca_deploy A troca leva a um deploy (pelo próximo fetch, no origem)
avisos Lista de {codigo, message}
pendente O que ficou por fazer (exit 3)

No manifest-path, antes/depois são {manifest_path} (null = raiz).

No identidade, antes/depois são {nome_base}, e o data traz também container (o novo), removidos (containers, rotas, tags), balanceador (ou null) e deploy.

No instancia, antes/depois são {instance}, e o data traz também:

  • plano: containers e rotas a remover;
  • deploy: o container novo;
  • removidos: os containers removidos.

Recusas (exit 1, error.details.reason):

Comando reason
origem nada_a_trocar, provider_sem_repo, branch_invalida, repo_com_credencial, repo_invalido, repo_inacessivel, sem_repo, branch_inexistente, token_ilegivel, deploy_em_curso
instancia instancia_inexistente, deploy_falhou, deploy_sem_container, invalid_manifest_path, migracao_falhou, deploy_em_curso
manifest-path invalid_manifest_path, manifesto_inexistente, manifesto_invalido, instancia_inexistente, branch_inexistente, manifest_pin_ativo, manifest_pin_ilegivel, origem_de_arquivo, sem_repo, repo_inacessivel, deploy_em_curso
identidade nome_base_invalido, nome_base_equivalente, nome_base_de_outra_app, prioridade_em_conflito, canary_em_curso, troca_pendente, adocao_pendente, app_de_pr, docker_indisponivel, deploy_em_curso, deploy_falhou, deploy_sem_container
todos app_inexistente, app_ambigua

runner --capabilities anuncia app.origem.v1, app.instancia.v1, app.manifest_path.v1 e app.identidade.v1.

Ver também

By Borlot.com.br on 19/10/2026