runner env
Comandos para gerenciar variaveis de ambiente e secrets.
Visao Geral
O Runner separa configuracao em dois arquivos:
.env- Variaveis de configuracao (permissao 644).secrets- Credenciais sensiveis (permissao 600)
Estes arquivos podem ser gerados automaticamente no primeiro deploy via Env Wizard, a partir das secoes environment: e secrets: do .deploy.yml.
Camadas por instancia (v2.85.0)
O env efetivo de um deploy e o merge de duas camadas, a da instancia vencendo:
valor final = .env + .env.<instancia>A base (.env) guarda o que e comum a todas as instancias (TZ, LOG_LEVEL). A
camada da instancia (.env.production, .env.staging) guarda o que nao pode
ser comum: endpoint de banco, bucket, chave de API do ambiente. App que so tem
.env funciona igual — o merge devolve a base, nada a migrar.
A barreira de procedencia
Uma chave listada em required: tem que resolver de fonte escopada por
instancia (.env.<instancia>). Resolver so da base compartilhada dispara:
| Origem do deploy | Comportamento |
|---|---|
fetch --deploy (cron) |
Avisa e segue — o cron nao derruba a frota por config herdada |
Interativo / switch-instance |
Bloqueia — e onde o incidente acontece, e ha um humano para reagir |
O caso que a barreira previne: um DATABASE_URL de staging na base satisfazia o
required: de production, o deploy passava e o healthcheck ficava verde (banco
de staging e um banco valido), mas producao escrevia no lugar errado.
Escape pontual (nao recomendado — o certo e escopar a chave):
RUNNER_ALLOW_SHARED_REQUIRED=1 runner deploy <app>Escrever na camada certa
runner env set <app> KEY VALOR # instancia ATIVA (default)
runner env set <app> KEY VALOR --instance staging # outra instancia
runner env set <app> KEY VALOR --shared # base compartilhada (deliberado)O default deixou de ser a base: escopado por instancia e o seguro, compartilhar e ato deliberado.
Limitacao conhecida: o bundle cifrado (
.runner/secrets.enc) e app-level e nao tem dimensao de instancia. Valores em.env.<instancia>nao entram no bundle e nao sao restaurados porrunner deploy --allnum servidor novo. Trate a camada da instancia como config a reprovisionar no disaster recovery.
Deteccao Automatica de Secrets (v2.4.2)
O runner detecta automaticamente se uma variavel e sensivel pelo nome, usando Aho-Corasick multi-pattern matching com 3 niveis de confianca:
| Confianca | Comportamento | Exemplos |
|---|---|---|
| Alta (95%+) | Auto-encripta se tem ckey, warning se nao | DB_PASSWORD, API_KEY, GITHUB_TOKEN, STRIPE_SECRET |
| Media (75%) | Aviso "pode ser sensivel, use --secret" | MY_TOKEN, APP_SECRET, AUTH_BEARER |
| Nao detectado | Salva no .env sem questionamento |
LOG_LEVEL, DB_HOST, APP_ENV, CACHE_KEY |
Falsos positivos conhecidos sao filtrados automaticamente: keyboard, primary_key, max_tokens, public_key, tokenizer, hash_map, cache_key, etc.
Flags
| Flag | Efeito |
|---|---|
| (sem flag) | Auto-detecta pelo nome. Alta confianca + ckey = encripta. Sem ckey = .env + warning |
--secret |
Forca como secret. Requer ckey — sem ckey retorna erro |
--force |
Forca como secret sem questionamento. Requer ckey |
# Auto-detecta: DB_PASSWORD → secret (alta confianca)
runner env set myapp --key DB_PASSWORD --value xxx
# → Com ckey: "Detectado como secret. Salvando em .secrets (encriptado)"
# → Sem ckey: "Salvando em .env (plaintext). Acessivel a qualquer usuario..."
# Forcar como secret (requer ckey)
runner env set myapp --key CUSTOM_FIELD --value xxx --secret
runner env set myapp --key CUSTOM_FIELD --value xxx --force
# Sem ckey + --secret = erro
runner env set myapp --key X --value Y --secret
# → "Secrets requerem encriptacao. Registre a app com --ckey"Comandos
Status
runner env status --app <path>Exemplo:
runner env status --app /data/apps/usuario_meu-appOutput:
Environment de meu-app:
.env:
FLASK_ENV=production
DEBUG=false
LOG_LEVEL=info
.secrets:
DB_PASSWORD=***
REDIS_PASSWORD=***
SECRET_KEY=***A partir da v2.85.0, env status mostra as camadas resolvidas e a
origem de cada chave — se veio da base (.env) ou da camada da instancia
(.env.<instancia>). Ver Camadas por instancia.
Definir Variavel
runner env set --app <path> --key <key> --value <value>Exemplo:
runner env set --app /data/apps/meu-app --key LOG_LEVEL --value debugDefinir Secret
runner env set --app <path> --key <key> --value <value> --secretExemplo:
runner env set --app /data/apps/meu-app --key API_KEY --value sk_live_xxx --secretSem o valor na linha de comando (recomendado para segredo):
runner env set meu-app API_KEY --secret # pede o valor num prompt oculto (eco *)
printf %s "$SECRET" | runner env set meu-app API_KEY --secret --stdin # automaçãoValor digitado na linha de comando fica no ~/.bash_history e no ps. O
runner mascara as linhas antigas nos arquivos de history e avisa; para a
sessão atual do shell, instale o gancho: runner shell-hook --install
(v2.135.0, shell-hook).
Regenerar Secret
runner env regenerate --app <path> --key <key>Gera novo valor aleatorio para o secret.
Exemplo:
runner env regenerate --app /data/apps/meu-app --key SECRET_KEYValidar Variaveis
runner env validate <app> [--required "VAR1,VAR2,VAR3"] [-i <instância>]Verifica se todas as variaveis obrigatorias estao definidas e nao-vazias.
Por instância (v2.151.0+). A validação faz a mesma conta do deploy: lê as camadas .env / .env.<instância> e, no esquema v2, o arquivo de secrets da instância. Sem -i, vale a instância do registro (state → default do manifesto → production). Instância fora do manifesto é recusada com Instance '<nome>' not found (v2.151.1+).
Antes da v2.151.0, o
env validatelia só.env/.secretse não aceitava-i. Num registro de instância não-default, ele acusava como ausentes chaves que estavam no cofre da instância, enquanto o deploy acertava.
A partir de v2.32.0, sem --required cai no campo required: do .deploy.yml automaticamente. Empty plaintext (KEY=) conta como missing — fecha o cenario do healthcheck loop de 173s descrito em runner deploy.
Exemplo:
# Override explicito
runner env validate meu-app --required "DB_HOST,DB_USER,DB_PASSWORD"
# Usa required: do manifest (v2.32.0+)
runner env validate meu-appOutput (sucesso):
INFO All required variables are presentOutput (falha):
ERROR missing_required: variables required by the manifest are unset or
empty: NEXT_PUBLIC_SUPABASE_ANON_KEY, DB_PASSWORD.
Set them with `runner env set <app> <KEY> <VALUE>` (or `--secret -f` for
secrets), then retry the deploy.Bulk Load (v2.32.0+)
runner env load <app> carrega N keys de uma vez a partir de um arquivo .env-format. Resolve o atrito de loops bash de runner env set quando voce tem 10+ secrets pra setar.
runner env load <app> [--file <path>] [flags]Flags:
| Flag | Descricao |
|---|---|
--file <path> |
Caminho explicito do arquivo .env. Sem isso, walks cwd → <app>/pull/ por candidates .env*/.secrets* |
--all-secret |
Forca todas as keys pra .secrets (requer --ckey) |
--all-plain |
Forca todas as keys pra .env (plaintext) |
--no-propagate |
Nao toca apps que compartilham o ckey desta |
--yes, -y |
Pula prompts interativos (file picker + propagation confirm) |
--json |
Output estruturado |
Comportamento:
- Source resolution:
--fileexplicit ganha; senao varrecwdprimeiro, depois<app>/pull/. Templates (.env.example,.env.template,.env.sample) sao excluidos pra nao silenciosamente sobrescrever secrets reais. - Classify: usa o mesmo
secret_detectquerunner env setusa por default. Override com--all-secret/--all-plain. - Propagate (DEFAULT ON): walks state dir, fingerprint do ckey desta app, aplica o mesmo write set em cada peer com fingerprint igual. Pula com
--no-propagate. Confirm prompt antes de aplicar (ou--yespra CI).
Exemplo: monorepo com 2 apps que compartilham ckey
runner env load web-api --file ./prod.env --yes
# INFO Set NODE_ENV: production (file: /data/apps/web-api/.env)
# INFO Set DB_PASSWORD: *** (encrypted in .secrets)
# INFO Set NODE_ENV: production (file: /data/apps/web-front/.env)
# INFO Set DB_PASSWORD: *** (encrypted in .secrets)
# Loaded 6 plain + 2 secret keys into web-api from ./prod.env.
# Propagated to: web-frontApenas a app alvo:
runner env load web-api --file ./api-only.env --no-propagate --yesRe-run e idempotente — no_changes: true quando o arquivo ja foi totalmente carregado.
Match — conferir um valor sem revelar nenhum
runner env match <app> <KEY> [-i <instance>]
runner env match <app> <KEY> --stdinResolve o caso de quem precisa alterar um secret e nao sabe qual e o valor atual: voce cola o que tem em maos e o runner responde apenas se e o mesmo. Nem o valor registrado nem o que voce colou aparecem na saida.
| Flag | Descricao |
|---|---|
--stdin |
Le o valor a comparar do stdin, em vez de argumento (nao fica no historico do shell) |
-i, --instance |
Instance alvo |
Issue #81.
List — as KEYS, sem decifrar
runner env list <app> [-i <instance>]Lista as chaves de secrets sem decifrar nada (esquema v2). Nao precisa da chave privada, e os valores nunca sao exibidos — util para conferir o inventario de secrets de uma app a partir de um contexto que nao pode le-los.
Issue #65.
Unset — remover uma key
runner env unset <app> <KEY> # remove do .env (plaintext)
runner env unset <app> <KEY> --secret # remove do .secrets| Flag | Descricao |
|---|---|
-s, --secret |
Remove do .secrets em vez do .env |
O alvo padrao e o .env, porque o caso comum e derrubar uma variavel plaintext ou
uma duplicata que tambem existe encriptada no .secrets. Como o .secrets vence em
runtime, remover a copia plaintext nao quebra a app.
Desde a v2.158.0:
- chave que não está no arquivo-alvo é erro: exit 1,
chave_nao_encontrada: '<KEY>' não está em <onde> — nada removido.A mensagem sugere a outra flag (--secretou sem); - se a chave saiu localmente mas o push do cofre falhou: exit 1,
cofre_nao_propagado: …. A chave pode voltar no próximo deploy. Confira o token comrunner tokens test <app>.
env set e env unset não mudam o container em execução. Aplique com
runner deploy <app> --force.
Arquivos
.env
Variaveis de configuracao (nao sensiveis):
FLASK_ENV=production
DEBUG=false
LOG_LEVEL=info
BASE_URL=https://app.meusite.com.br.secrets
Credenciais sensiveis (encriptadas em repouso com --ckey):
DB_PASSWORD=senha_secreta
REDIS_PASSWORD=outra_senha
SECRET_KEY=chave_muito_secreta_gerada
API_KEY=sk_live_xxxxxxxxxxxxPermissoes: chmod 600 .secrets
Comportamento por versao:
| Versao | Sem --ckey |
Com --ckey |
|---|---|---|
| < v2.0.4 | .secrets criado em plaintext |
.secrets encriptado |
| v2.0.4+ | .secrets nao criado — secrets vao pro .env |
.secrets encriptado (sem mudanca) |
runner env set --secret e runner env regenerate continuam gravando no .secrets se ele existir. Se a app nao tem .secrets (registrada sem ckey), estes comandos gravam no .env.
Templates
O Runner processa templates em .env.template:
Sintaxe
# Valor fixo
FLASK_ENV=production
# Gerar automaticamente
SECRET_KEY=${GENERATE:secret:64}
DB_PASSWORD=${GENERATE:password:32}
# Valor manual (prompt no primeiro deploy)
EXTERNAL_API_KEY=${MANUAL:API key do servico externo}
# Referencia a contexto
PROJECT_NAME=${CONTEXT:PROJECT}
DOMAIN=${CONTEXT:DOMAIN}Tipos de GENERATE
| Tipo | Descricao | Exemplo |
|---|---|---|
secret:N |
String alfanumerica de N caracteres | abc123xyz... |
password:N |
Senha com caracteres especiais | aB3$xY9@... |
uuid |
UUID v4 | 550e8400-e29b-... |
hex:N |
String hexadecimal de N bytes | a1b2c3d4... |
Variaveis de CONTEXT
| Variavel | Descricao |
|---|---|
PROJECT |
Nome do projeto |
DOMAIN |
Dominio principal |
VERSION |
Versao atual |
INSTANCE |
Nome da instancia |
Docker Compose
O Runner configura env_file automaticamente:
services:
app:
env_file:
- .env
- .secretsProvisionamento GENERATE (v1.3.2)
No primeiro deploy, o Runner le .env.template e gera valores para variaveis com ${GENERATE:...}. Os valores gerados sao gravados em .env e .secrets.
Em deploys seguintes, o Runner nao sobrescreve valores ja resolvidos. Variaveis com padrao GENERATE no template sao ignoradas nas flags -e do container, garantindo que o valor gerado no primeiro deploy seja preservado.
Antes da v1.3.2, valores contendo ${GENERATE:...} eram injetados como -e flags no docker run, sobrescrevendo os valores ja resolvidos em .env/.secrets.
Seguranca
.secretstem permissao 600- Dollar signs (
$) sao escapados para$$ - Secrets nao aparecem em logs
env statusmostra***para secrets- v2.50.0: o aviso de divergência do
env set(manifesto declara X mas o runtime usa Y) mascara valores de keys sensíveis — do.secrets, declaradas emsecrets:do manifesto, ou com nome secret-like — exibindo só um prefixo de 4 chars + tamanho. Antes o valor ia em claro pro stdout.
Encriptacao e Recovery
Se a app foi registrada com runner add --ckey, os arquivos .env e .secrets sao encriptados e persistidos no repositorio como .runner/secrets.enc apos cada deploy.
Em caso de perda do servidor, runner add --ckey restaura automaticamente os secrets a partir do repo.
Consulte o guia Secrets e Encriptacao para detalhes completos.