Referencia .deploy.yml

O .deploy.yml e o arquivo de configuracao central que define como sua aplicacao sera deployada.

Modos de Deploy (v1.2.3+)

O Runner opera em dois modos exclusivos, determinados pela presenca de image: ou build::

Tem image: ?           -> MODO IMAGE (sem build, monta source via volume)
Tem build: ?           -> MODO BUILD (docker build com Dockerfile do repo)
Ambos?                 -> Erro
Nenhum?                -> Erro

Modo IMAGE

Usa uma imagem pre-construida do registry. O Runner monta o codigo fonte via volume.

project: meu-site
image: caddy:2-alpine
port: 80
  • NAO faz build
  • Monta source: src/{instance}/current:/app:ro
  • Auto-mount de data/, logs/, keys/
  • Health check: curl/wget

Modo BUILD

Faz docker build usando o Dockerfile que esta no repositorio.

project: meu-app
build:
  dockerfile: Dockerfile
  context: .
port: 80
  • Faz docker build com o Dockerfile do repo
  • Codigo embedded na imagem (COPY no Dockerfile)
  • Auto-mount de data/, logs/, keys/ (NAO monta source)
  • Health check: bash /dev/tcp

Tabela Comparativa

Modo IMAGE Modo BUILD
Config image: xxx build:
Build? NAO SIM (docker build)
Codigo Volume mount (:ro) Embedded na imagem
Dockerfile no repo Nao precisa OBRIGATORIO
Source mount src/inst/current:/app:ro Nenhum
Persistent volumes data/, logs/, keys/ data/, logs/, keys/
Health check curl/wget bash /dev/tcp

Retrocompatibilidade

Antes Agora (equivalente)
image_mode: bind-mount + image: xxx image: xxx
image_mode: self-contained build: (Dockerfile default)
image_mode: dockerfile (alias) type: docker-build + build: { ... }
app_type: docker-build build: (Dockerfile default)

O alias image_mode: dockerfile continua sendo aceito pelo runner (interpretado como self-contained), mas emite warning de depreciacao. Migre para a forma canonica type: docker-build + build: para silenciar.

Estrutura Completa

# ============================================
# IDENTIFICACAO
# ============================================
project: meu-projeto          # Nome do projeto (obrigatorio)
system: front                 # Tipo de sistema (front, sys, api, worker)

# ============================================
# MODO DE DEPLOY (escolher um)
# ============================================
# Opcao A: Modo IMAGE (imagem pronta)
image: registry.local/base-sys:1.0

# Opcao B: Modo BUILD (Dockerfile do repo)
build:
  dockerfile: Dockerfile      # Default: "Dockerfile"
  context: .                  # Default: "."

port: 8000                             # Porta interna

# ============================================
# PORTAS (v2.0.1 — deploy sem Traefik)
# ============================================
ports:
  - "80:80"                    # host:container
  - "10.108.0.4:80:80"        # ip:host:container (bind na VPC)

# ============================================
# CONFIG TEMPLATES (v2.0.0 — Helm-style)
# ============================================
config_templates:
  values_dir: config           # Default: "config"
  templates_dir: templates     # Default: "templates"

# ============================================
# REDES E VOLUMES
# ============================================
networks:
  - public                    # Network do Traefik (obrigatoria)
  - mysql                     # Se usar MySQL
  - redis                     # Se usar Redis

volumes:
  - logs:/app/logs:rw         # Formato: nome:mount:mode
  - certs:/app/certs:ro

# ============================================
# VARIAVEIS DE AMBIENTE
# ============================================
environment:
  PYTHONPATH: /app/src
  FLASK_ENV: production
  DEBUG: "false"
  LOG_LEVEL: info

# ============================================
# HEALTH CHECK (tres modos mutuamente exclusivos)
# ============================================
# Prioridade: cmd > tcp > path
#
# Modo HTTP (default) — GET no path indicado
healthcheck:
  path: /health               # Endpoint HTTP
  interval: 10s
  timeout: 5s
  retries: 3
#
# Modo TCP — sondagem de porta (servicos nao-HTTP)
# healthcheck:
#   tcp: 25                   # Considera healthy se a porta aceita conexao
#
# Modo CMD — exec dentro do container (use o binario que voce ja tem)
# healthcheck:
#   cmd: ["/app/bin/healthcheck", "--strict"]
#
# Modo EXIT — CLI tools/scanners (sem container permanente)
# healthcheck:
#   mode: exit
#
# Importante: se o seu Dockerfile ja declara HEALTHCHECK, o runner respeita
# essa declaracao e nao injeta nada por cima.

# ============================================
# GITHUB (DEPRECATED na v2.16.0+)
# ============================================
# A partir da v2.16.0, repo/branch vivem no state file (manifesto do runner)
# em /opt/runner/state/{app}.yml. O `runner add --repo X --branch Y` salva
# direto no state — nao precisa do `github:` no .deploy.yml.
#
# Migration silenciosa: apps existentes com `github:` no .deploy.yml tem o
# valor copiado pro state na primeira execucao, com warning de deprecated.
# A leitura compat continua funcionando, mas o campo sera removido em uma
# major futura.
#
# github:
#   repo: usuario/meu-repo      # DEPRECATED — agora vem de runner add --repo
#   user: usuario               # DEPRECATED

# ============================================
# VERSAO
# ============================================
version:
  source: file                # file | git-tag | git-commit | branch-name
  file: package.json          # Arquivo que contem a versao
  field: version              # Campo dentro do arquivo

# ============================================
# DEPENDENCIAS ENTRE APPS (opcional)
# ============================================
# Lista de outros projetos registrados que devem estar deployados (e
# saudaveis) antes deste. Consumido pelo `runner deploy --all` para
# topologicamente ordenar a sequencia. Cycles sao detectados e abortam
# o deploy. Deps que apontam para projetos nao registrados localmente
# emitem warning mas nao bloqueiam.
depends_on:
  - inboxer-mta               # MTA precisa estar healthy antes do SYS subir
  - inboxer-redis

# ============================================
# INSTANCIAS
# ============================================
instances:
  production:
    domain: app.projeto.com.br
    source:
      type: dist              # Usa branch dist
    keep_versions: 3          # Manter ultimas 3 versoes
    canary:                   # Configuracao de canary (v1.2.0)
      enabled: true
      auto_promote:
        enabled: true
        initial_weight: 10
        increment: 10
        interval: 5m
        final_weight: 100

  staging:
    domain: staging.projeto.com.br
    source:
      type: branch
      branch: develop         # Usa branch develop
    keep_versions: 2

  release:
    domain: release.projeto.com.br
    source:
      type: tag               # Usa tags Git (v1.2.0)
      tag_pattern: "v*"       # Padrao glob para filtrar tags

  hotfix:
    source:
      type: local             # Usa diretorio local (v1.2.0)
      path: /builds/hotfix/

  canary:
    source:
      type: image             # Usa imagem Docker pronta (v1.2.0)
      image: ghcr.io/org/app:canary

  pr:
    domain_pattern: "pr-${PR_NUMBER}.staging.projeto.com.br"
    source:
      type: pr                # Usa refs/pull/N/head
    ephemeral: true           # Instancia temporaria
    ttl_hours: 48             # Auto-destruicao apos 48h

# ============================================
# STAGING (configuracao global)
# ============================================
staging:
  enabled: true
  domain_template: "pr-${PR_NUMBER}.staging.${DOMAIN}"
  container_template: "staging_${PROJECT}_pr${PR_NUMBER}"
  max_instances: 3
  ttl_hours: 48

# ============================================
# NOTIFICACOES
# ============================================
notify:
  channels:
    - integration: telegram   # Referencia config.yml
      chat_id: "-123456789"
      events:
        - deploy_started
        - deploy_success
        - deploy_failure

    - integration: flare
      events:
        - deploy_success

# ============================================
# ROUTING MODE (obrigatorio para canary)
# ============================================
routing_mode: traefik_dynamic  # traefik_dynamic | traefik_labels | none

Campos Detalhados

Identificacao

Campo Tipo Obrigatorio Descricao
project string Sim Nome do projeto. Usado no container name, Traefik config, labels e diretorio
system string Nao Identificador do subtipo (front, sys, api, worker). Usado como label de display e no atalho CLI runner deploy project/system
type string Nao Tipo da aplicacao (front-static, sys, api, docker-build)

O campo system e cosmético — nao afeta build, routing ou container name. Serve para:

  • Atalho CLI: runner deploy sweepapex/front (resolve project=sweepapex + system=front)
  • Display nos logs: sweepapex/front deployed
  • Organizacao quando um projeto tem multiplos repos (front, sys, worker)

Modo de Deploy

Campo Tipo Default Descricao
image string - Imagem Docker (define modo IMAGE)
build object - Config de build (define modo BUILD)
build.dockerfile string Dockerfile Caminho do Dockerfile
build.context string . Contexto de build
build.args map {} Build args injetados como --build-arg KEY=VAL. v2.20.0+; v2.21.0+ suporta interpolação {{::Var}} resolvida de .env/.secrets
port integer - Porta interna do container
image_mode string bind-mount Deprecated — prefira image: ou build:. Aceita bind-mount, self-contained, e o alias dockerfile (que vira self-contained com warning de depreciacao).

Regra: image e build sao mutuamente exclusivos. Usar apenas um.

Build Args (v2.20.0+)

build.args permite injetar variáveis em build time via --build-arg. Em v2.21.0+, valores suportam interpolação {{::Var}} resolvida de .env e .secrets da app.

build:
  context: .
  dockerfile: Dockerfile
  args:
    BUILD_ENV: production                          # literal
    VITE_API_URL: "{{::API_URL}}"                  # interpola de .env/.secrets (v2.21.0+)
    VITE_DEFAULT_DOMAIN: "{{::DOMAIN?app.example.com}}"   # com default

Order de resolução: .secrets primeiro (mais específico), .env fallback. Suporta {{::Key?default}}. Se a var não resolve, erro instrutivo aponta pra runner env set.

Ports (v2.0.1)

Mapeamento de portas do host para o container. Usado em deploys sem Traefik (servidores backend acessiveis via proxy externo pela VPC).

ports:
  - "80:80"                    # Todas as interfaces
  - "10.108.0.4:80:80"        # Bind no IP da VPC (recomendado)
  - "127.0.0.1:8080:80"       # Bind no localhost
Formato Exemplo Resultado
host:container "80:80" Todas as interfaces
ip:host:container "10.108.0.4:80:80" Bind no IP especifico

Quando ports esta configurado e a instancia nao tem domain, o runner:

  • Pula a geracao de Traefik config
  • Para o container antigo antes de iniciar o novo (stop-then-start, ~5s downtime)
  • Mapeia -p no docker run

Config Templates (v2.0.0)

Configuracao opcional para renderizacao de config files Helm-style via Tera.

config_templates:
  values_dir: config           # Default: "config"
  templates_dir: templates     # Default: "templates"

Quando presente e o repo tem templates/*.tpl, o runner renderiza templates automaticamente durante o deploy (Phase 1.3). Ver `runner config` para gerenciar valores.

Networks

Lista de redes Docker para conectar o container.

networks:
  - public    # Obrigatoria para Traefik
  - mysql     # Se usar MySQL
  - redis     # Se usar Redis
  - mongo     # Se usar MongoDB

Hosts (v2.20.0+)

DNS aliases injetados como --add-host KEY:VAL no docker run. Map (não array) — last-wins em duplicatas.

hosts:
  host.docker.internal: host-gateway   # resolve em Linux Docker
  internal-api: 10.0.0.5
  cache-server: 10.0.0.10

Útil pra:

  • host.docker.internal em Linux Docker (não funciona por default sem --add-host=host.docker.internal:host-gateway)
  • Aliases pra serviços internos sem depender de DNS externo
  • Override temporário de hosts pra debug

Volumes

Lista de volumes no formato nome:mount:mode.

volumes:
  - logs:/app/logs:rw
  - certs:/app/certs:ro
  - data:/app/data:rw

Environment

HashMap de variaveis de ambiente. Suporta valores fixos, gerados e prompts interativos (Env Wizard).

environment:
  FLASK_ENV: production                          # valor fixo
  BASE_DOMAIN: "{{::Domain?projeto.com.br}}"     # prompt com default
  DB_NAME: "{{::Database name}}"                 # prompt sem default

Secrets

HashMap de variaveis sensiveis. Escritas em .secrets (permissao 600) em vez de .env.

secrets:
  DB_PASSWORD: "{RANDOM}"                        # gera automaticamente
  JWT_SECRET: "${GENERATE:hex:64}"               # hex 64 chars
  SMTP_PASSWORD: "{{::SMTP Password}}"           # prompt ao operador

Consulte o guia completo do Env Wizard para sintaxe detalhada e exemplos.

Health Check

Tres modos mutuamente exclusivos, com a seguinte prioridade: cmd > tcp > path.

Campo Tipo Default Descricao
path string /health Modo HTTP: endpoint testado via curl/wget (image mode) ou bash /dev/tcp (build mode). Deve comecar com /.
tcp integer - Modo TCP: porta interna para sondagem. Use para servicos nao-HTTP (SMTP, Redis, ...).
cmd array of strings - Modo CMD: comando exec rodado dentro do container. Use quando a imagem ja tem um binario de healthcheck. Ex: cmd: ["/app/bin/check", "--strict"].
mode string - Modo EXIT: mode: exit para CLI tools/scanners que nao ficam rodando. fetch --deploy skipa, runner deploy valida com docker run --rm.
start_period string 30s Grace period antes do Docker comecar a rodar checks. Aumente para containers lentos (multi-stage builds, JVMs).
interval string 10s Intervalo entre checks
timeout string 5s Timeout do check
retries integer 3 Tentativas antes de unhealthy

Heranca de HEALTHCHECK do Dockerfile: se a imagem base (ou a imagem buildada pelo seu Dockerfile) ja declara um HEALTHCHECK, o runner respeita essa declaracao e nao injeta nenhum --health-cmd por cima. Isso permite que projetos com Dockerfile customizado tenham controle total da estrategia de health. Use runner deploy -V para ver qual comando sera efetivamente usado.

Depends On

Lista de projetos que devem ser deployados antes deste quando voce roda runner deploy --all. Os nomes referem-se ao campo project: de outros apps registrados localmente.

depends_on:
  - inboxer-mta
  - inboxer-redis

Comportamento:

  • O runner faz topological sort e deploya na ordem correta.
  • Cycles (a -> b -> a) sao detectados e abortam o --all com mensagem listando os projetos envolvidos.
  • Deps que apontam para projetos nao registrados localmente emitem warning e sao silenciosamente ignoradas — util quando o dep roda em outro servidor.
  • Se uma dep falhar durante o --all, seus dependentes sao automaticamente pulados (com log) ao inves de tentar deployar sem a base.

Version

Campo Tipo Descricao
source string Fonte da versao
file string Arquivo com a versao
field string Campo no arquivo

Valores de source:

  • file - Extrai de arquivo (package.json, version.json)
  • git-tag - Usa tag Git mais recente
  • git-commit - Usa hash do commit
  • branch-name - Usa nome da branch

Instances

Cada instancia define um ambiente de deploy.

Campo Tipo Descricao
domain string Dominio da instancia
domain_pattern string Padrao de dominio (para PRs)
source.type string Tipo de fonte
source.branch string Nome da branch (se type=branch)
source.tag_pattern string Padrao de tags (se type=tag)
source.path string Caminho local (se type=local)
source.image string Imagem Docker (se type=image)
keep_versions integer Quantas versoes manter
ephemeral boolean Se e instancia temporaria
ttl_hours integer TTL em horas (para ephemeral)
environment_overrides map Variaveis de ambiente especificas desta instancia (sobrescreve environment)
canary object Configuracao de canary

Tipos de source (v1.2.0):

Tipo Descricao Campos
dist Branch dist (artifacts compilados) -
branch Branch especifica branch
pr Pull Request (refs/pull/N/head) -
tag Tag Git especifica tag_pattern
local Diretorio local path
image Imagem Docker pronta image

Canary Config (v1.2.0)

Configuracao de canary deployment por instancia:

instances:
  production:
    canary:
      enabled: true
      auto_promote:
        enabled: true
        initial_weight: 10       # Peso inicial do canary
        increment: 10            # Incremento por step
        interval: 5m             # Intervalo entre steps
        final_weight: 100        # Peso final (promocao completa)
        health_check_before: true
      abort_on:
        - health_check_failed
        - error_rate_above:5%
        - latency_p99_above:500ms

Campos de auto_promote:

Campo Tipo Default Descricao
enabled boolean false Habilitar promocao automatica
initial_weight integer 10 Peso inicial
increment integer 10 Incremento por step
interval string 5m Intervalo entre steps
final_weight integer 100 Peso final
health_check_before boolean true Verificar health antes de cada step

Condicoes de abort:

  • health_check_failed - Health check falhou
  • error_rate_above:X% - Taxa de erro acima de X%
  • latency_p99_above:Xms - Latencia p99 acima de X ms

Instance Depends_on (v2.21.0+)

Cross-app health checks por instance: app A só inicia depois que app B está pronto. Diferente do top-level depends_on: (que ordena runner deploy --all), o instances.<inst>.depends_on: é checado em cada start_container e bloqueia o spin-up até o dep estar healthy.

instances:
  production:
    domain: app.example.com
    source: { type: branch, branch: main }
    keep_versions: 3
    depends_on:
      - app: meu-livekit
        condition: healthy           # healthy | started
        timeout: 300s                # opcional, default 300s
      - app: meu-redis
        instance: production         # opcional, default = mesma instance
        condition: started
Campo Tipo Default Descricao
app string - Slug do app dependência (obrigatório)
instance string mesma instance Instance específica do dep
condition enum healthy healthy (Health.Status=healthy) ou started (running)
timeout string "300s" Max wait — 300s / 5m / 1h

Comportamento: runner polla docker inspect por cada dep até condition met OR timeout. Bypass via --insecure.

Erro de timeout:

Error: dependency_timeout: meu-livekit/production not ready after 300s (condition=Healthy)

Routing Mode

Valor Canary Descricao
traefik_dynamic Sim Arquivos YAML dinamicos (obrigatorio para canary)
traefik_labels Nao Labels nos containers
none Nao Sem routing (workers)

Importante: Se canary.enabled: true, routing_mode DEVE ser traefik_dynamic.

Staging

Configuracao global de staging.

Campo Tipo Default Descricao
enabled boolean false Habilitar staging
domain_template string - Template de dominio
container_template string - Template de container
max_instances integer 3 Max stagings por projeto
ttl_hours integer 48 TTL padrao

Variaveis de template:

  • ${PR_NUMBER} - Numero da PR
  • ${PROJECT} - Nome do projeto
  • ${BRANCH} - Nome da branch
  • ${DOMAIN} - Dominio base
  • ${INSTANCE} - Nome da instancia (v2.0.0)
  • ${DATETIME} - Timestamp (YYYYmmdd-HHMMSS)
  • ${HASH} - 6 caracteres de UUID
  • ${RANDOM} - 6 caracteres alfanumericos

Notify (v1.2.0)

Configuracao de notificacoes por aplicacao:

notify:
  channels:
    - integration: telegram      # Referencia integrations do config.yml
      chat_id: "-123456789"      # Override per-app
      events:
        - deploy_started
        - deploy_success
        - deploy_failure

    - integration: flare
      events:
        - deploy_success

    - integration: slack
      channel: "#deploys"
      events: all                # Todos os eventos

Eventos disponiveis:

  • deploy_started
  • deploy_success
  • deploy_failure
  • rollback_started
  • rollback_success
  • canary_weight_changed
  • canary_promoted
  • instance_destroyed
  • health_check_failed
  • all (todos os eventos)

Exemplos por Tipo

Frontend estatico — Modo IMAGE (Caddy)

project: meu-app
image: caddy:2-alpine
port: 80

networks:
  - public

healthcheck:
  path: /
  interval: 30s

github:
  repo: usuario/meu-app-front

version:
  source: file
  file: package.json
  field: version

instances:
  production:
    domain: app.meusite.com.br
    source:
      type: dist
    keep_versions: 3

Backend Flask — Modo BUILD com Canary

project: meu-api
build:
  dockerfile: Dockerfile
port: 8000
routing_mode: traefik_dynamic    # Obrigatorio para canary

networks:
  - public
  - mysql
  - redis

environment:
  PYTHONPATH: /app/src
  FLASK_ENV: production

healthcheck:
  path: /health
  interval: 10s
  timeout: 5s
  retries: 3

github:
  repo: usuario/meu-api-sys

version:
  source: file
  file: version.json
  field: version

instances:
  production:
    domain: sys.meusite.com.br
    source:
      type: dist
    keep_versions: 3
    canary:
      enabled: true
      auto_promote:
        enabled: true
        initial_weight: 10
        increment: 10
        interval: 5m
      abort_on:
        - health_check_failed
        - error_rate_above:5%

Documentacao — Modo IMAGE (PimDocs)

project: runner-docs
image: leonardoborlot/pimdocs:latest
port: 4321

networks:
  - public

healthcheck:
  path: /
  interval: 30s

instances:
  production:
    domain: docs.runner.ccs.systems
    source:
      type: dist

App PHP — Modo BUILD com multi-stage

project: meu-laravel
build:
  dockerfile: docker/Dockerfile.prod
  context: .
port: 80

networks:
  - public
  - mysql

volumes:
  - storage:/app/storage:rw

healthcheck:
  path: /health

instances:
  production:
    domain: app.meusite.com.br
    source:
      type: dist
    keep_versions: 3

Deploy de Tags (Releases)

project: meu-app
port: 8000
networks:
  - public

instances:
  release:
    domain: app.meusite.com.br
    source:
      type: tag
      tag_pattern: "v*"          # v1.0.0, v1.1.0, etc
    keep_versions: 5

Deploy de Imagem Docker

project: meu-app
port: 8000
networks:
  - public

instances:
  canary:
    domain: canary.meusite.com.br
    source:
      type: image
      image: ghcr.io/usuario/meu-app:canary

Deploy Local (Hotfix)

project: meu-app
port: 8000
networks:
  - public

instances:
  hotfix:
    domain: hotfix.meusite.com.br
    source:
      type: local
      path: /builds/emergency/

CLI Tool / Scanner — Modo Exit

project: meu-scanner
build:
  dockerfile: Dockerfile

healthcheck:
  mode: exit        # Sem container permanente

github:
  repo: usuario/meu-scanner

version:
  source: git-commit

instances:
  production:
    source:
      type: dist

Com Staging de PRs

project: meu-app
port: 8000
networks:
  - public

instances:
  production:
    domain: app.meusite.com.br
    source:
      type: dist
    keep_versions: 3

  staging:
    domain: staging.meusite.com.br
    source:
      type: branch
      branch: develop

  pr:
    domain_pattern: "pr-${PR_NUMBER}.staging.meusite.com.br"
    source:
      type: pr
    ephemeral: true
    ttl_hours: 48

staging:
  enabled: true
  max_instances: 5
  ttl_hours: 48

Deploy sem Traefik — Port-only (v2.0.1)

Para servidores backend sem Traefik local, acessiveis via proxy externo pela VPC:

project: meu-backend
build:
  dockerfile: Dockerfile
port: 80

ports:
  - "10.108.0.5:80:80"        # Bind na interface VPC

networks:
  - mysql

environment:
  DB_HOST: 10.108.0.3
  REDIS_HOST: 10.108.0.3

healthcheck:
  path: /health
  interval: 30s

instances:
  production:
    # SEM domain → runner pula Traefik, usa apenas ports
    source:
      type: branch
      branch: dev
    keep_versions: 3

Frontend Vite com `build.args` interpolados (v2.21.0+)

Frontends que precisam injetar variáveis em build time (Vite, Next.js, Angular). Os valores em build.args interpolam de .env/.secrets da app:

project: meu-frontend
build:
  context: .
  dockerfile: Dockerfile
  args:
    VITE_API_URL: "{{::API_URL}}"
    VITE_PUBLIC_DOMAIN: "{{::DOMAIN?app.example.com}}"
    BUILD_ENV: production

port: 80
networks:
  - public

healthcheck:
  mode: http
  path: /
  interval: 30s

instances:
  production:
    domain: app.example.com
    source:
      type: branch
      branch: main
    keep_versions: 3

Valores das vars (API_URL, DOMAIN) são gerenciados via runner env set <app> --key API_URL --value ... (ou wizard inicial). Resolução: .secrets primeiro, .env fallback, default opcional via ?default.

Multi-app com `depends_on:` cross-app (v2.21.0+)

App agent que precisa esperar LiveKit + Redis ficarem prontos antes de subir. Cada dep é polled via docker inspect até condition (healthy/started) ou timeout:

# meu-agent/.deploy.yml (depende de meu-livekit + meu-redis)

project: meu-agent
build:
  context: .
  dockerfile: Dockerfile

port: 8000
networks:
  - public

environment:
  LIVEKIT_URL: "ws://meu-livekit-prod:7880"
  REDIS_HOST: "meu-redis-prod"

instances:
  production:
    domain: agent.example.com
    source: { type: branch, branch: main }
    keep_versions: 3
    depends_on:
      - app: meu-livekit
        condition: healthy
        timeout: 300s
      - app: meu-redis
        condition: started
        timeout: 60s

Se meu-livekit ou meu-redis não atingir condition no timeout, o deploy falha com dependency_timeout: <app>/<instance> not ready after Ns. Bypass: --insecure.

Multi-Ambiente com Environment Overrides (v1.5.0)

project: meu-app
build:
  dockerfile: Dockerfile
port: 8000

environment:
  DB_HOST: mysql
  LOG_LEVEL: info

instances:
  production:
    domain: app.meusite.com.br
    source:
      type: dist
    environment_overrides:
      DB_HOST: mysql-prod
      DB_NAME: app_prod

  staging:
    domain: staging.meusite.com.br
    source:
      type: branch
      branch: dev
    environment_overrides:
      DB_HOST: mysql-staging
      DB_NAME: app_staging

Exemplo Minimo

O menor .deploy.yml funcional:

# Modo IMAGE (imagem pronta)
project: meu-app
image: caddy:2-alpine
port: 80

instances:
  production:
    domain: app.meusite.com.br
    source:
      type: dist
# Modo BUILD (com Dockerfile no repo)
project: meu-app
build:
  dockerfile: Dockerfile
port: 80

instances:
  production:
    domain: app.meusite.com.br
    source:
      type: dist

Validacao

Valide seu arquivo com:

runner validate --file /caminho/.deploy.yml

Gerando Template

Gere um template completo com:

runner generate-config > .deploy.yml
By Borlot.com.br on 28/02/2026