Playbooks
Playbooks são arquivos YAML que definem como serviços devem ser deployados. Funcionam como templates executáveis que carregam a lógica de deployment.
Nota: Playbooks usam a sintaxe DPL (DeployAlly Playbook Language). Consulte a referência DPL para detalhes de sintaxe, tipos de input, interpolação e condicionais.
Visão Geral
Um playbook contém:
- Metadata: Identificação e descrição
- Taxonomia: Posição na hierarquia
- Dependencies: Relações com outros serviços
- Rules: Lógica condicional de deployment
- Profiles: Configurações por ambiente
- Inputs: Parâmetros fornecidos pelo usuário
- Key Files: Arquivos de configuração gerenciados
- Volumes, Ports, Networks: Configuração Docker
Estrutura Completa
version: "1.0"
kind: Asset | Application | Infrastructure | Composite
metadata:
name: MySQL Database Server
slug: mysql
type: database
category: assets
description: Banco de dados relacional MySQL
version: "8.4"
priority: 5
taxonomy:
kingdom: assets
family: database
species: mysql
variant: standard
specimen: "8.4"
dependencies:
assets: []
applications: []
rules:
- name: singleton_check
when: ...
then: ...
profiles:
minimal: ...
development: ...
production: ...
image:
repository: mysql
tag: "8.4"
inputs:
required: ...
optional: ...
advanced: ...
key_files:
- name: mysql_config
container_path: /etc/mysql/conf.d/custom.cnf
template: ...
volumes:
- name: data
mount_path: /var/lib/mysql
ports:
- name: mysql
container_port: 3306
network:
name: mysql
driver: bridge
healthcheck:
type: tcp
port: 3306
pre_deploy: []
post_deploy: []
upgrade: {}Seções Detalhadas
Metadata
Identificação do playbook:
metadata:
name: MySQL Database Server # Nome amigável
slug: mysql # Identificador único
type: database # Tipo do serviço
category: assets # Categoria
description: Banco de dados... # Descrição
version: "8.4" # Versão do template
priority: 5 # Ordem de deploy (menor = primeiro)Priority:
1-4: Infrastructure (Traefik, networks)5-10: Assets (MySQL, Redis, PostgreSQL)20+: Applications (WordPress, n8n)
Dependencies
Define relações com outros serviços. Dois tipos:
Assets (Infraestrutura Compartilhada)
Serviços que podem ser compartilhados entre aplicações:
dependencies:
assets:
- slug: mysql
optional: false
check:
type: container
label: "da_type=mysql"
provision:
action: prompt # prompt | auto | fail
template: mysql
message: "MySQL não encontrado. Criar agora?"
exports:
- from: container.name
to: WORDPRESS_DB_HOST
- from: MYSQL_DATABASE
to: WORDPRESS_DB_NAME
- from: MYSQL_PASSWORD
to: WORDPRESS_DB_PASSWORD
secret: trueApplications (Dependências Específicas)
Outras aplicações necessárias:
dependencies:
applications:
- slug: api-gateway
optional: trueAlternativas
Quando há múltiplas opções (ex: PostgreSQL ou MySQL):
dependencies:
assets:
- slug: database
alternatives:
- slug: postgresql
exports:
- from: container.name
to: DB_POSTGRESDB_HOST
- slug: mysql
exports:
- from: container.name
to: DB_MYSQLDB_HOST
provision:
action: prompt
message: "Qual database usar?"
options:
- label: "PostgreSQL (recomendado)"
template: postgresql
- label: "MySQL"
template: mysqlDependência Opcional com Fallback
- slug: redis
optional: true
check:
type: container
label: "da_type=redis"
provision:
action: prompt
message: "Redis melhora performance. Adicionar?"
fallback:
env:
CACHE_TYPE: "file"
when_present:
env:
CACHE_TYPE: "redis"
REDIS_HOST: "{{REDIS_HOST}}"Rules (Motor de Lógica)
Rules executam em ordem e podem tomar decisões automaticamente:
rules:
- name: detect_production
when:
any:
- env.ENVIRONMENT == "production"
- context.domain not contains "dev."
then:
set_profile: production
set:
restart_policy: always
resources.memory.limit: "{{profiles.production.memory}}"
- name: singleton_check
when:
all:
- context.containers_with_label("da_type=mysql").count > 0
then:
action: prompt
message: "MySQL já existe. O que fazer?"
options:
- label: "Criar nova instância"
action: update
set:
inputs.MYSQL_DATABASE: "{{inputs.MYSQL_DATABASE}}_{{context.generate_id(4)}}"
- label: "Usar existente"
action: abort
- name: port_conflict
when:
all:
- context.port_in_use(3306)
then:
action: prompt
message: "Porta 3306 em uso. Como resolver?"
options:
- label: "Usar porta aleatória"
set:
ports.external: 0
- label: "Parar container existente"
action: stop_containerAções disponíveis:
prompt: Perguntar ao usuárioauto: Executar automaticamentewarn: Mostrar avisorequire_input: Exigir valorfail: Abortar deployment
Context Variables:
context.containers_with_label(...): Listar containerscontext.port_in_use(port): Verificar portocontext.network_exists(name): Verificar networkcontext.server.memory_available: RAM disponívelcontext.traefik_available: Traefik rodando?
Profiles
Configurações pré-definidas para diferentes ambientes:
profiles:
minimal:
description: Configuração mínima para testes
resources:
memory: "128M"
ports:
expose: none
volumes:
persistent: false
development:
description: Configuração para desenvolvimento
resources:
memory: "256M"
ports:
expose: localhost
external: 3306
bind: "127.0.0.1"
volumes:
persistent: true
environment:
override:
LOG_LEVEL: "DEBUG"
production:
description: Configuração para produção
resources:
memory: "512M"
cpu: 1.0
ports:
expose: internal
volumes:
persistent: true
backup: true
restart_policy: always
environment:
override:
LOG_LEVEL: "WARNING"Inputs
Valores fornecidos pelo usuário durante deploy:
inputs:
required:
MYSQL_ROOT_PASSWORD:
type: password
label: Senha do root
description: Senha do usuário root do MySQL
secret: true
validation: "^.{8,}$"
generate:
type: password
length: 24
MYSQL_DATABASE:
type: string
label: Nome do banco
validation: "^[a-z][a-z0-9_]*$"
validation_message: "Use apenas letras minúsculas, números e underscore"
optional:
MYSQL_USER:
type: string
label: Usuário do banco
default: "app"
profiles:
development: "dev_user"
production: "app_user"
advanced:
MAX_CONNECTIONS:
type: number
label: Conexões máximas
default: 100
profiles:
minimal: 10
production: 500Tipos suportados:
password: Senha (oculta, secret)string: Textonumber: Número inteiroboolean: Checkboxselect: Dropdown com opções
Geração automática:
generate:
type: password | uuid | slug
length: 24
charset: alphanumeric | hex | base64Key Files
Arquivos de configuração gerenciados pelo DeployAlly:
key_files:
- name: mysql_config
description: Arquivo my.cnf customizado
container_path: /etc/mysql/conf.d/custom.cnf
mode: ro
template: |
[mysqld]
innodb_buffer_pool_size = {{system.memory_mb | percent: 60}}M
max_connections = {{inputs.MAX_CONNECTIONS | default: 100}}
examples:
- name: "Alta Performance"
description: Configuração otimizada para produção
content: |
[mysqld]
innodb_buffer_pool_size = 1G
innodb_log_file_size = 256M
max_connections = 500
- name: "Baixo Consumo"
description: Configuração para ambientes limitados
content: |
[mysqld]
innodb_buffer_pool_size = 128M
max_connections = 50Template Filters:
{{system.memory_mb | percent: 60}} # 60% da RAM
{{system.memory_mb | percent: 60 | min: 256}} # Mínimo 256
{{system.cpus | multiply: 2}} # CPUs * 2
{{inputs.VALUE | default: "fallback"}} # Valor padrãoFluxo de Key Files:
- Deploy: Usuário escolhe template, exemplo ou arquivo próprio
- Storage: Salvo em
/opt/deployally/{uid}/files/{name} - Mount: Montado read-only no container
- Update:
deployally updatepermite editar (backup automático)
Volumes
volumes:
- name: data
mount_path: /var/lib/mysql
size: 10Gi
persistent: true
backup: true
- name: config
mount_path: /etc/mysql/conf.d
type: config
mode: ro
- name: logs
mount_path: /var/log/mysql
type: bind
host_path: /var/log/mysql-{{instance_id}}Tipos:
named: Volume Docker nomeado (padrão)bind: Bind mount do hostconfig: Arquivo de configuraçãotmpfs: Em memória
Ports
ports:
- name: mysql
container_port: 3306
expose: true
protocol: TCP
external: 3306 # Porta do host (0 = aleatória)
bind: "0.0.0.0" # IP para bind
- name: admin
container_port: 33060
expose: false # Não expor externamenteNetwork
network:
name: mysql
driver: bridge
aliases:
- mysql
- db
- database
join:
- publicPadrão de Networks:
- Cada Asset cria sua própria network
- Applications juntam a múltiplas networks
- Exemplo: WordPress junta
public,mysql,redis
Healthcheck
healthcheck:
type: tcp | http | exec
port: 3306 # Para tcp
path: /health # Para http
command: ["mysqladmin", "ping"] # Para exec
initial_delay: 30
interval: 10
timeout: 5
retries: 3Lifecycle Hooks
Pre-Deploy
pre_deploy:
- name: create_network
action: docker_network
network_name: "{{network.name}}"
condition: "not context.network_exists(network.name)"
- name: backup_existing
action: shell
command: "docker exec {{container}} mysqldump --all-databases > /backup/pre-upgrade.sql"
condition: "context.upgrading"Post-Deploy
post_deploy:
- name: wait_healthy
action: wait_healthy
timeout: 60s
- name: run_migrations
action: exec
command: "mysql < /docker-entrypoint-initdb.d/migrations.sql"
condition: "context.has_migrations"
- name: show_credentials
action: display
message: |
MySQL disponível em: {{container.name}}:3306
Database: {{inputs.MYSQL_DATABASE}}
User: {{inputs.MYSQL_USER}}Ações de Hook:
docker_network: Criar networkshell: Executar no hostexec: Executar no containerwait_healthy: Aguardar healthchecktest_connection: Testar conexãodisplay: Mostrar mensagem
Upgrade Strategy
upgrade:
strategy: rolling | replace | blue-green
backup_before: true
rollback_on_fail: true
preserve_data: true
post_upgrade:
- action: exec
command: "mysql_upgrade"
condition: "context.major_version_change"Playbooks Disponíveis
| Playbook | Kind | Dependencies | Descrição |
|---|---|---|---|
mysql.yaml |
Asset | Nenhuma | MySQL 8.4, 5.7 |
postgresql.yaml |
Asset | Nenhuma | PostgreSQL 16 |
redis.yaml |
Asset | Nenhuma | Redis 7 Alpine |
traefik.yaml |
Infrastructure | Nenhuma (singleton) | Reverse proxy + SSL |
wordpress.yaml |
Application | MySQL, Redis (opt) | WordPress CMS |
n8n.yaml |
Application | PostgreSQL/MySQL, Redis (opt) | Workflow automation |
mautic.yaml |
Application | MySQL | Marketing automation |
chatwoot.yaml |
Application | PostgreSQL, Redis | Helpdesk |
Exemplo Completo: WordPress
version: "1.0"
kind: Application
metadata:
name: WordPress
slug: wordpress
type: cms
category: applications
description: WordPress CMS com suporte a Redis
version: "6"
priority: 20
taxonomy:
kingdom: applications
family: cms
species: wordpress
variant: standard
specimen: "6"
dependencies:
assets:
- slug: mysql
optional: false
check:
type: container
label: "da_type=mysql"
provision:
action: prompt
template: mysql
exports:
- from: container.name
to: WORDPRESS_DB_HOST
- from: MYSQL_DATABASE
to: WORDPRESS_DB_NAME
- from: MYSQL_USER
to: WORDPRESS_DB_USER
- from: MYSQL_PASSWORD
to: WORDPRESS_DB_PASSWORD
secret: true
- slug: redis
optional: true
check:
type: container
label: "da_type=redis"
provision:
action: prompt
message: "Redis melhora performance. Adicionar?"
fallback:
env:
WP_CACHE_TYPE: "file"
when_present:
env:
WP_CACHE_TYPE: "redis"
WP_REDIS_HOST: "{{REDIS_HOST}}"
rules:
- name: detect_production
when:
all:
- inputs.WORDPRESS_DOMAIN not contains "dev."
then:
set_profile: production
- name: configure_traefik
when:
all:
- inputs.WORDPRESS_DOMAIN is not empty
- context.traefik_available
then:
action: auto
set:
labels:
"traefik.enable": "true"
"traefik.http.routers.wp-{{instance_id}}.rule": "Host(`{{inputs.WORDPRESS_DOMAIN}}`)"
"traefik.http.routers.wp-{{instance_id}}.tls.certresolver": "myresolver"
profiles:
development:
resources:
memory: "256M"
environment:
WP_DEBUG: "true"
production:
resources:
memory: "512M"
environment:
WP_DEBUG: "false"
image:
repository: wordpress
tag: "6-php8.2-apache"
inputs:
required:
WORDPRESS_DOMAIN:
type: string
label: Domínio do site
validation: "^[a-z0-9][a-z0-9.-]+\\.[a-z]{2,}$"
optional:
WORDPRESS_TABLE_PREFIX:
type: string
label: Prefixo das tabelas
default: "wp_"
volumes:
- name: wp-content
mount_path: /var/www/html/wp-content
persistent: true
ports:
- name: http
container_port: 80
expose: false
network:
name: public
join:
- mysql
- redis
healthcheck:
type: http
path: /wp-admin/install.php
port: 80
initial_delay: 30
post_deploy:
- name: show_info
action: display
message: |
WordPress disponível em: https://{{inputs.WORDPRESS_DOMAIN}}
Complete a instalação no navegador.Próximos Passos
- DPL Language - Referência completa da sintaxe
- Manifestos - Como o DeployAlly armazena configurações
- Ecologia - Relações entre serviços
- Referência CLI - Comandos para trabalhar com playbooks