Opções para rodar localmente
| Opção | Complexidade | Quando usar |
|---|---|---|
airflow standalone | Mínima | Exploração rápida, SQLite + SequentialExecutor |
| Docker Compose oficial | Média | Desenvolvimento fiel ao ambiente de produção |
| Docker Compose customizado | Alta | Controle total sobre versões e configurações |
Quickstart com airflow standalone
Sem Docker, para exploração rápida:
pip install "apache-airflow==2.9.3" \
--constraint "https://raw.githubusercontent.com/apache/airflow/constraints-2.9.3/constraints-3.11.txt"
export AIRFLOW_HOME=~/airflow
airflow standalone
# UI disponível em http://localhost:8080
# Usuário: admin | Senha: impressa no terminalUsa SQLite como backend e SequentialExecutor: não adequado para produção ou testes de paralelismo.
Docker Compose (setup recomendado)
Baixar o arquivo oficial
mkdir airflow-local && cd airflow-local
curl -LfO 'https://airflow.apache.org/docs/apache-airflow/2.9.3/docker-compose.yaml'Estrutura de pastas
mkdir -p ./dags ./logs ./plugins ./config
echo -e "AIRFLOW_UID=$(id -u)" > .envairflow-local/
├── docker-compose.yaml
├── .env # AIRFLOW_UID, segredos
├── dags/ # seus DAGs (montado no container)
├── logs/ # logs de task (montado)
├── plugins/ # plugins customizados
└── config/
└── airflow.cfg # overrides de configuração (opcional)
Inicializar o banco e subir
# Inicializa o banco de metadados e cria o usuário admin
docker compose up airflow-init
# Sobe toda a stack
docker compose up -dA UI fica disponível em http://localhost:8080 (usuário: airflow / senha: airflow).
Serviços do Docker Compose padrão
graph TB subgraph Airflow Stack WS[airflow-webserver\n:8080] SCH[airflow-scheduler] WK[airflow-worker] TRG[airflow-triggerer] INIT[airflow-init] end PG[(postgres\n:5432)] RD[(redis\n:6379)] SCH --> RD WK --> RD WS --> PG SCH --> PG WK --> PG TRG --> PG
O compose padrão usa CeleryExecutor com Redis como broker e PostgreSQL como metadata DB.
Variáveis de ambiente essenciais
# .env
AIRFLOW_UID=50000
# Chave de criptografia para conexões (gerar uma vez com: python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())")
AIRFLOW__CORE__FERNET_KEY=sua_chave_aqui
# Backend de metadados
AIRFLOW__DATABASE__SQL_ALCHEMY_CONN=postgresql+psycopg2://airflow:airflow@postgres/airflow
# Executor
AIRFLOW__CORE__EXECUTOR=CeleryExecutor
# Broker Celery
AIRFLOW__CELERY__BROKER_URL=redis://:@redis:6379/0
AIRFLOW__CELERY__RESULT_BACKEND=db+postgresql://airflow:airflow@postgres/airflow
# Desabilitar exemplos incluídos no Airflow
AIRFLOW__CORE__LOAD_EXAMPLES=False
# Fuso horário padrão
AIRFLOW__CORE__DEFAULT_TIMEZONE=America/Sao_Paulo
# Número de DAGs parseados em paralelo pelo scheduler
AIRFLOW__SCHEDULER__PARSING_PROCESSES=2Docker Compose customizado (produção-like)
Para ter mais controle, crie um docker-compose.yml próprio:
x-airflow-common: &airflow-common
image: apache/airflow:2.9.3-python3.11
environment:
AIRFLOW__CORE__EXECUTOR: CeleryExecutor
AIRFLOW__DATABASE__SQL_ALCHEMY_CONN: postgresql+psycopg2://airflow:airflow@postgres/airflow
AIRFLOW__CELERY__BROKER_URL: redis://:@redis:6379/0
AIRFLOW__CELERY__RESULT_BACKEND: db+postgresql://airflow:airflow@postgres/airflow
AIRFLOW__CORE__FERNET_KEY: ${AIRFLOW__CORE__FERNET_KEY}
AIRFLOW__CORE__LOAD_EXAMPLES: "false"
AIRFLOW__WEBSERVER__SECRET_KEY: ${AIRFLOW__WEBSERVER__SECRET_KEY}
volumes:
- ./dags:/opt/airflow/dags
- ./logs:/opt/airflow/logs
- ./plugins:/opt/airflow/plugins
- ./config/airflow.cfg:/opt/airflow/airflow.cfg
user: "${AIRFLOW_UID:-50000}:0"
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
services:
postgres:
image: postgres:15-alpine
environment:
POSTGRES_USER: airflow
POSTGRES_PASSWORD: airflow
POSTGRES_DB: airflow
healthcheck:
test: ["CMD", "pg_isready", "-U", "airflow"]
interval: 10s
retries: 5
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
retries: 5
airflow-webserver:
<<: *airflow-common
command: webserver
ports:
- "8080:8080"
healthcheck:
test: ["CMD", "curl", "--fail", "http://localhost:8080/health"]
interval: 30s
retries: 5
airflow-scheduler:
<<: *airflow-common
command: scheduler
airflow-worker:
<<: *airflow-common
command: celery worker
deploy:
replicas: 2 # dois workers em paralelo
airflow-triggerer:
<<: *airflow-common
command: triggerer
airflow-init:
<<: *airflow-common
command: >
bash -c "
airflow db migrate &&
airflow users create
--username admin
--password admin
--firstname Admin
--lastname User
--role Admin
--email [email protected]
"
volumes:
postgres_data:Instalar dependências Python customizadas
Para adicionar pacotes (providers, bibliotecas de negócio), crie uma imagem derivada:
# Dockerfile
FROM apache/airflow:2.9.3-python3.11
USER airflow
COPY requirements.txt /requirements.txt
RUN pip install --no-cache-dir -r /requirements.txt# requirements.txt
apache-airflow-providers-google==10.15.0
apache-airflow-providers-amazon==8.20.0
apache-airflow-providers-databricks==6.6.0
pandas==2.0.3
pyarrow==14.0.1# No docker-compose.yml, substituir a imagem base:
# image: apache/airflow:2.9.3-python3.11
# por:
# build: .Comandos úteis no dia a dia
# Ver status dos containers
docker compose ps
# Logs do scheduler
docker compose logs -f airflow-scheduler
# Abrir shell em um container
docker compose exec airflow-scheduler bash
# Listar DAGs
docker compose exec airflow-scheduler airflow dags list
# Testar uma task específica
docker compose exec airflow-scheduler \
airflow tasks test meu_dag nome_da_task 2026-01-01
# Disparar DAG manualmente
docker compose exec airflow-scheduler \
airflow dags trigger meu_dag
# Escalar workers
docker compose up -d --scale airflow-worker=4
# Parar tudo (mantém volumes)
docker compose down
# Parar e apagar volumes (reset completo)
docker compose down -vairflow.cfg: principais configurações
[core]
dags_folder = /opt/airflow/dags
load_examples = False
default_timezone = America/Sao_Paulo
parallelism = 32 # máximo de tasks simultâneas em toda a instância
max_active_tasks_per_dag = 16
max_active_runs_per_dag = 4
[scheduler]
dag_dir_list_interval = 30 # com que frequência escanear a pasta de DAGs (segundos)
parsing_processes = 2 # processos paralelos de parsing
[webserver]
workers = 4 # gunicorn workers para o webserver
expose_config = True # permite ver airflow.cfg na UI (cuidado em prod)Ver também: airflow | airflow-dag-desenvolvimento | airflow-deploy-kubernetes | docker-compose | Docker | docker-conceitos-fundamentais