Um container não é um ambiente
O curso anterior terminou com uma imagem que roda esta aplicação. Isso é um processo. Um ambiente funcional para este app são pelo menos dois, porque o app precisa do PostgreSQL, e um ambiente realista acrescenta um worker de jobs e às vezes mais.
Rode isso à mão e a sessão fica assim:
docker network create nor_net
docker volume create nor_pgdata
docker run -d --name nor_db --network nor_net \
-v nor_pgdata:/var/lib/postgresql/data \
-e POSTGRES_PASSWORD=secret postgres:17
docker run -d --name nor_web --network nor_net -p 3000:80 \
-e DATABASE_URL=postgres://postgres:secret@nor_db/newbie_on_rails_development \
-e RAILS_MASTER_KEY=... newbie_on_rails
Funciona, mas ninguém consegue trabalhar assim. Ninguém decora isso, ninguém revisa, e quem entra no projeto precisa receber os comandos numa mensagem em vez de lê-los no repositório.
O que o Compose é
O Compose é aquela sessão, escrita como um arquivo e executada por um comando:
docker compose up
Um arquivo descreve os serviços, a rede entre eles, os volumes que sobrevivem a eles e a configuração que cada um recebe. Ele fica versionado no repositório, então o ambiente é revisável num pull request como qualquer outra coisa.
Repare no comando: docker compose, duas palavras. O antigo docker-compose com hífen é a ferramenta original em Python. O Compose atual é um plugin da CLI do Docker. Os dois podem funcionar na sua máquina, e o com hífen é o que um dia vai deixar de funcionar.
O que ele não é
Vale marcar duas fronteiras logo de saída, porque as duas geram confusão com frequência.
Primeiro, o Compose roda containers numa máquina só. Ele não distribui containers entre hosts, não faz deploy gradual nem failover automático, então não serve como orquestrador de produção. Para esta aplicação, a produção fica com o Kamal (o próximo curso), e o Compose é o ambiente de desenvolvimento.
Segundo, o Compose trabalha junto com o seu Dockerfile. Ele constrói ou baixa imagens, e quem define a imagem continua sendo o Dockerfile do curso anterior. Tudo o que você aprendeu lá continua valendo. O Compose é a camada que diz como as instâncias dessas imagens se relacionam.
flowchart TB
D["Dockerfile: como uma imagem é construída"] --> I["Imagem"]
I --> C["compose.yaml: como os serviços se relacionam"]
C --> S1["web"]
C --> S2["db"]
C --> S3["worker"]
O menor arquivo útil
Para esta aplicação:
name: newbie_on_rails
services:
db:
image: postgres:17
environment:
POSTGRES_PASSWORD: secret
volumes:
- pgdata:/var/lib/postgresql/data
web:
build: .
command: ./bin/rails server -b 0.0.0.0
ports:
- "3000:3000"
environment:
DATABASE_URL: postgres://postgres:secret@db/newbie_on_rails_development
depends_on:
- db
volumes:
pgdata:
Toda linha da sessão digitada à mão está ali, e três coisas agora saem de graça. Os serviços se encontram pelo nome: o web alcança o PostgreSQL no hostname db, sem nenhum endereço em lugar nenhum. A rede é criada automaticamente. E o ambiente inteiro inicia, para e é destruído como uma unidade. O arquivo ainda é um esboço: ele roda a imagem com as configurações de produção, e este app tem mais três bancos (cache, queue e cable) que o DATABASE_URL não cobre. A aula 7 monta a versão que sobe de verdade.
O nome do arquivo importa
O Compose procura por estes nomes, nesta ordem:
compose.yaml ← o nome canônico, prefira este
compose.yml
docker-compose.yaml ← mantido por compatibilidade
docker-compose.yml ← mantido por compatibilidade
A maioria dos tutoriais usa docker-compose.yml, porque esse foi o nome por anos. O atual é compose.yaml. Se os dois existirem, o Compose prefere o canônico, e essa situação é confusa de depurar, então mantenha um só.
O que este curso cobre
- Um container não é um ambiente (você está aqui).
- O arquivo: serviços, imagens e o que mudou.
- Rede e ordem de inicialização.
- Dados que sobrevivem a um restart.
- Configuração e secrets.
- Trabalhando nele no dia a dia.
- Juntando tudo: um arquivo Compose para este app.
No fim você vai ter um compose.yaml que sobe esta aplicação e o banco dela com um comando, e vai saber quais linhas dele são essenciais.
Pontos-chave
- Um ambiente funcional são vários containers. Dá para rodá-los à mão, mas não dá para trabalhar assim.
- O Compose escreve aquela sessão como um arquivo no repositório, iniciado com
docker compose up. - Use
docker compose(duas palavras); odocker-composecom hífen é a ferramenta antiga separada. - O Compose é ferramenta de desenvolvimento para uma máquina. Ele não é orquestrador de produção nem substitui o seu Dockerfile.
- Prefira o canônico
compose.yaml; o nomedocker-compose.ymlda maioria dos tutoriais é mantido só por compatibilidade.
Continue com a aula 2
Serviços, imagens e o que mudou
A chave version obsoleta, os elementos de topo, build ou image, o command, escutar em 0.0.0.0 e âncoras YAML.
Com uma conta grátis você também tem os quizzes, seu progresso e suas anotações, e a discussão.