- Castro/
- blog/
- Como adicionar apenas um novo serviço a um Compose em produção com docker compose up -d --no-deps/
Como adicionar apenas um novo serviço a um Compose em produção com docker compose up -d --no-deps
Por que, em host compartilhado, validar o Compose e subir somente o serviço novo com --no-deps reduz o blast radius da mudança.
Um docker compose up -d parece inofensivo quando a mudança no YAML é pequena.
O problema é que o Compose não lê intenção. Ele lê o projeto inteiro.
Em uma migração real de APIs para hosts Docker já usados por outros serviços, a regra operacional ficou explícita:
se a mudança é um serviço novo, subir só aquele serviço.
O fluxo usado era próximo de:
| |
O objetivo não era fazer uma “mágica sem downtime”.
Era algo mais básico e importante: não envolver aplicações que não faziam parte da mudança.
Antes do up, validar o arquivo #
A primeira etapa não era subir nada.
Era pedir para o Compose interpretar o YAML:
| |
Depois conferir as imagens:
| |
Isso pega uma classe inteira de problemas antes de qualquer alteração no runtime:
- YAML inválido;
- variável não resolvida;
- nome de serviço errado;
- imagem inesperada;
- referência de configuração incorreta.
Em ambiente versionado, o próximo passo é quase obrigatório:
| |
Se eu não consigo explicar o diff antes do deploy, ainda não estou pronto para aplicar o diff.
Por que não usar docker compose up -d geral #
Imagine um host com vários serviços existentes:
| |
O trabalho atual é adicionar serviço-novo.
Rodar:
| |
entrega ao Compose o projeto inteiro para reconciliação.
Mesmo quando ele não recria tudo, você aumentou desnecessariamente o escopo da operação e ficou dependente do estado de todos os componentes definidos naquele arquivo.
Na migração que originou este artigo, isso era um risco sem benefício.
Então a execução foi limitada:
| |
O que --no-deps significa aqui #
O parâmetro instrui o Compose a não iniciar serviços declarados como dependências daquele serviço por causa dessa operação.
Isso faz sentido quando:
- as dependências necessárias já estão ativas;
- a mudança não pretende reconciliá-las;
- o operador validou essa condição antes;
- o objetivo é limitar a alteração ao serviço especificado.
Não é uma regra universal para todo deploy.
Se o novo serviço depende de uma dependência que ainda precisa ser criada, --no-deps pode justamente impedir o comportamento esperado.
O valor está no uso consciente, não no parâmetro em si.
Pull também deve ser específico #
O mesmo raciocínio vale para imagem:
| |
Antes de subir, eu quero saber se o host realmente consegue baixar aquela imagem.
Se o pull falha por registry, IAM ou autenticação, melhor descobrir nesse comando do que misturado com a criação do container.
Esse isolamento melhora o diagnóstico:
| |
Depois do up, não parar no docker ps #
Container Up não é aplicação validada.
A sequência usada na migração validava várias camadas.
Primeiro:
| |
Depois, quando havia health endpoint, testar diretamente o container:
| |
Só depois seguir para reverse proxy, origin externo e CDN/HMG.
Essa ordem evita começar a investigação no componente mais distante do problema.
O benefício real é blast radius #
A pergunta que guia esse tipo de deploy é:
quantos componentes eu preciso colocar em risco para fazer esta mudança?
Se a resposta é “um”, executar um comando que engloba cinco serviços é um desenho operacional pior.
Na prática, a mudança ficou parecida com:
| |
Cada etapa responde uma pergunta antes de avançar para a seguinte.
Quando eu não usaria esse padrão #
Eu não usaria --no-deps automaticamente quando:
- a dependência também faz parte da mudança;
- uma nova rede/serviço dependente precisa ser criada;
- houve alteração conjunta de versões entre componentes acoplados;
- o estado atual das dependências é desconhecido;
- a própria mudança exige recriação coordenada.
Nesse caso, o problema não é o comando mais amplo. É fingir que a mudança é menor do que realmente é.
Checklist curto #
Para adicionar um único serviço em um Compose que já atende outras aplicações:
| |
O que ficou desse caso #
O comando mais perigoso nem sempre é o que parece destrutivo.
Às vezes é só um comando amplo demais para uma mudança pequena.
docker compose up -d --no-deps <serviço> funcionou como guard-rail porque o contexto já estava validado e o objetivo era adicionar uma API em paralelo sem pedir ao Compose que tocasse no restante do host.
A ideia que vale reaproveitar é mais geral:
se a mudança tem blast radius de um serviço, tente manter a execução com blast radius de um serviço também.
Me chama.
Manda o contexto, os sintomas e o que já foi testado. Bora organizar as evidências antes de sair mexendo.