Otimizar volumes Docker Compose: restaurar em produção sem downtime

14 min de leitura · · Docker, Docker-Compose, volumes, restore, produção, AviraHost, Linux · 0

Otimizar volumes Docker Compose é o processo de restaurar dados de named volumes ou bind mounts em produção com staging, sincronização e cutover controlado, sem derrubar o tráfego e sem apagar o volume ativo. Para restaurar em produção sem downtime, siga estes passos:

  1. Inventarie volumes e mounts com docker volume ls e docker compose config.
  2. Crie um volume ou diretório de staging e restaure o backup nele.
  3. Sincronize com rsync ou container auxiliar enquanto o serviço antigo atende.
  4. Valide checksums, contagem de arquivos e healthcheck no staging.
  5. Faça o cutover com docker compose up -d apontando para o volume já consistente.
  6. Monitore logs e métricas e só então remova o staging antigo.

Pré-requisitos

  • Acesso root ou sudo em host Linux de produção (ex.: Rocky Linux 10 ou AlmaLinux 10).
  • Docker Engine e Docker Compose plugin instalados e estáveis no host.
  • Backup recente e íntegro do volume (tar, snapshot ou cópia versionada).
  • Espaço em disco suficiente para volume de staging paralelo ao volume ativo.
  • Janela de manutenção opcional apenas para o cutover final (segundos a poucos minutos).
  • Conhecimento do docker-compose.yml (ou compose.yaml) e dos nomes reais dos volumes.
  • SSH funcional no servidor; se precisar relembrar o acesso, veja Acessando servidores VPS Linux da AviraHost.

Otimizar volumes Docker Compose com inventário e plano de cutover

Antes de tocar em dados, o inventário evita restaurar no volume errado ou sobrescrever o path que a aplicação usa agora. Em produção, named volumes e bind mounts se comportam de forma diferente: o named volume fica sob o driver local (em geral em /var/lib/docker/volumes), enquanto o bind mount aponta para um diretório do host que você controla. Listar e inspecionar é o primeiro passo para otimizar volumes Docker Compose sem surpresa no cutover.

Liste os volumes e confira o que o Compose realmente declara:

docker volume ls
docker compose config
docker compose ps
docker volume inspect NOME_DO_VOLUME
Output esperado (trecho):
DRIVER    VOLUME NAME
local     projeto_app_data
local     projeto_db_data
...
"Mountpoint": "/var/lib/docker/volumes/projeto_db_data/_data",
"Labels": {
  "com.docker.compose.project": "projeto",
  "com.docker.compose.volume": "db_data"
}

Anote o nome canônico do volume, o Mountpoint e se o serviço usa volumes: nomeado ou bind (caminho absoluto). Confirme qual serviço depende daquele volume e se há réplica, proxy reverso ou healthcheck que permita trocar o backend sem cortar o cliente. Em stacks com banco e app, planeje restaurar o volume de dados primeiro no staging e só depois alinhar o serviço de aplicação. Documente o comando de cutover e o comando de rollback (voltar o compose ao volume anterior) antes de qualquer escrita. Esse plano é o que diferencia restore “no escuro” de restore seguro em produção.

Se o host estiver sob carga, evite operações pesadas de I/O no mesmo disco do volume ativo sem throttling; prefira staging em outro filesystem quando possível. Para boas práticas gerais de host, consulte também Dicas de Otimização de Servidores Linux.

Preparar staging e restaurar o backup sem tocar no volume vivo

O volume de staging é a peça central para restore sem downtime: você materializa o backup em um volume ou diretório paralelo enquanto o container de produção continua montando o volume antigo. Assim a aplicação não vê arquivos pela metade e o tráfego só muda quando o staging estiver validado.

Crie um volume de staging com nome explícito e restaure o backup nele. Exemplo com named volume e arquivo tar do backup:

docker volume create projeto_db_data_staging
docker run --rm \
  -v projeto_db_data_staging:/restore \
  -v /backup/docker:/backup:ro \
  alpine:3.24 \
  sh -c "cd /restore && tar -xzf /backup/db_data_YYYYMMDD.tar.gz"
Output esperado:
projeto_db_data_staging
(sem erros de tar; ao final o shell encerra com código 0)

Para bind mount, crie um diretório paralelo no host (ex.: /srv/app/data_staging), restaure o conteúdo lá e mantenha permissões de UID/GID iguais às do container. Verifique ownership antes de subir qualquer serviço de teste:

sudo mkdir -p /srv/app/data_staging
sudo tar -xzf /backup/app_data_YYYYMMDD.tar.gz -C /srv/app/data_staging
sudo chown -R 1000:1000 /srv/app/data_staging
du -sh /srv/app/data_staging
find /srv/app/data_staging -type f | wc -l
Output esperado:
1.2G    /srv/app/data_staging
18432

Atenção: nunca use docker compose down -v nesta fase. A flag -v remove volumes nomeados declarados no compose e apaga dados de produção. Pare apenas o que for estritamente necessário no cutover, e nunca remova o volume ativo até o staging estar validado e o tráfego migrado.

Opcionalmente suba um compose paralelo (outro project name ou arquivo override) montando só o staging, com portas internas ou rede isolada, para smoke test sem expor o público. Isso reduz risco quando o volume contém schema de banco ou uploads críticos.

Sincronizar dados e validar integridade antes do cutover

Sincronização incremental fecha a janela entre o backup e o momento do cutover. Se o serviço ainda grava no volume antigo, faça uma primeira cópia completa para o staging e, perto do cutover, uma segunda passagem com rsync para copiar apenas o delta. Em muitos cenários de leitura intensa (sites estáticos, media, caches frios) a segunda passagem é curta; em bancos com escrita alta, combine freeze de escrita da aplicação, snapshot ou modo somente leitura quando a stack permitir.

Exemplo de sincronização entre mountpoints de volumes (ajuste os paths do docker volume inspect):

SRC=$(docker volume inspect -f '{{ .Mountpoint }}' projeto_db_data)
DST=$(docker volume inspect -f '{{ .Mountpoint }}' projeto_db_data_staging)
sudo rsync -aHAX --info=progress2 "$SRC"/ "$DST"/
Output esperado:
... 1,234,567,890 100%  85.00MB/s    0:00:14 (xfr#18432, to-chk=0/18450)

Alternativa com container e volumes-from (útil quando não quer montar o path do host diretamente):

docker run --rm \
  --volumes-from container_producao_db \
  -v projeto_db_data_staging:/staging \
  alpine:3.24 \
  sh -c "rsync -a /var/lib/mysql/ /staging/"

Valide integridade com tamanho, contagem e amostragem de hashes — não confie só no “tar terminou sem erro”:

find "$DST" -type f | wc -l
du -sb "$SRC" "$DST"
# amostragem de hashes (ajuste o find conforme o dataset)
find "$DST" -type f | head -n 50 | xargs -r sha256sum > /tmp/staging_sample.sha
# compare com amostra equivalente do backup ou do volume origem

Rode healthcheck da aplicação contra o stack de staging (compose paralelo). Confirme logs limpos, queries de sanidade no banco e que a contagem de registros críticos bate com o esperado. Só depois disso o cutover é seguro. Se algo divergir, corrija no staging e repita a sincronização; o volume de produção permanece intacto.

Cutover em produção e rollback controlado

O cutover é a troca do serviço para o volume já restaurado e validado. O objetivo é manter a janela de indisponibilidade mínima: idealmente só o tempo de recriar o container com o mount correto, enquanto o proxy ou o balanceador ainda pode servir cache ou outro backend se a arquitetura permitir. Em um único host com um único container, o downtime costuma ser o restart do serviço — ainda assim sem reprocessar o restore inteiro online.

Fluxo típico com named volume renomeado logicamente via compose (declare o volume externo ou altere o mapeamento no override):

# Exemplo: compose.override.staging.yml aponta db_data -> projeto_db_data_staging
# ou renomeie volumes com cuidado após parar o serviço

docker compose stop db
# opcional: renomear volumes no host Docker (pare o serviço antes)
docker volume create projeto_db_data_old
# estratégia segura: altere o compose para usar o volume staging já validado
docker compose up -d db
docker compose ps
docker compose logs --tail=100 db
Output esperado:
NAME           IMAGE          STATUS
projeto-db-1   postgres:...   Up (healthy)
... linhas de log sem erro de open file / corrupt / permission denied

Para bind mounts, altere o path no compose (de /srv/app/data para /srv/app/data_staging já validado) ou faça troca atômica de diretório com o serviço parado por segundos:

docker compose stop app
sudo mv /srv/app/data /srv/app/data_old
sudo mv /srv/app/data_staging /srv/app/data
docker compose up -d app

Atenção: a troca de diretório exige que nenhum processo esteja com arquivos abertos no path antigo. Confirme com docker compose stop (e, se necessário, verifique processos no host) antes do mv.

Mantenha o volume ou diretório antigo (_old) até validar produção por um período razoável. Rollback = apontar o compose de volta para o volume antigo e docker compose up -d. Não apague staging nem old até checksums, healthchecks e métricas de negócio estarem ok. Em ambientes com proxy, alinhe o cutover com a camada de roteamento; se usar Nginx no mesmo host, evite recarregar regras de forma que derrube conexões desnecessariamente durante o restart do backend.

Para entender o papel do VPS como base desse tipo de operação, o material Compreendendo o Servidor VPS: O que é e Como Funciona! ajuda a dimensionar disco e I/O para staging paralelo.

Problemas comuns e como resolver

Sintoma: container sobe healthy mas dados parecem de backup antigo

Causa: o compose ainda monta o volume ou path anterior, ou há dois volumes com nomes parecidos e o serviço não usa o staging validado.
Solução: rode docker volume inspect e docker inspect no container e confira o Mountpoint real. Ajuste o compose, recrie o serviço com docker compose up -d --force-recreate e valide contagem de arquivos e hashes no mountpoint ativo antes de liberar tráfego.

Sintoma: permission denied após restore no volume

Causa: UID/GID do processo no container não batem com os arquivos restaurados (comum em Alpine vs imagem Debian, ou backup feito como root).
Solução: ajuste chown/chmod no Mountpoint conforme o usuário da imagem, ou use entrypoint oficial de correção de permissões se existir. Teste com um container one-shot montando o mesmo volume antes do cutover.

Sintoma: disco enche durante o staging

Causa: restore paralelo exige espaço próximo ao tamanho do volume ativo mais overhead do tar/rsync.
Solução: libere logs e imagens antigas com cuidado (docker system df), mova staging para outro disco/mount e repita. Nunca apague o volume de produção para “abrir espaço” durante o restore.

Sintoma: rsync demora e a janela de cutover cresce

Causa: primeira cópia completa em dataset grande ou disco lento; escrita contínua no volume origem aumenta o delta.
Solução: faça pré-sync com o serviço no ar, reduza escrita (manutenção de app), rode rsync final com serviço parado ou em modo somente leitura e só então faça o up -d. Evite comprimir na hora do cutover.

Perguntas frequentes sobre otimizar volumes Docker Compose

Como restaurar um volume Docker Compose sem derrubar o serviço?

Use um volume ou diretório de staging, sincronize os dados com rsync ou docker run --volumes-from enquanto o serviço antigo ainda atende, e só então faça o cutover com docker compose up -d no stack atualizado. Assim o tráfego só muda quando o volume já está consistente.

Named volume e bind mount: qual é mais seguro para restore em produção?

Named volumes facilitam backup com docker volume e containers auxiliares; bind mounts dão controle direto no filesystem do host. Em produção, o mais seguro é ter backup versionado de ambos e testar o restore em um compose paralelo antes do cutover.

O que fazer se o container sobe mas os dados do volume parecem antigos?

Confirme o nome e o driver do volume com docker volume inspect, verifique se o compose aponta para o volume correto e se não há outro serviço montando um path diferente. Depois valide checksums ou contagem de arquivos no mountpoint antes de liberar o tráfego.

Posso usar docker compose down -v ao restaurar volumes?

Não em produção se quiser preservar dados: a flag -v remove volumes nomeados declarados no compose. Para restore sem perda, pare apenas o serviço necessário, restaure o conteúdo do volume e suba de novo com up -d, sem -v.

Como validar que o restore do volume Docker Compose não corrompeu arquivos?

Compare tamanho, quantidade de arquivos e hashes (sha256sum) entre backup e volume restaurado, rode healthchecks da aplicação e leia logs do serviço logo após o up. Só considere o cutover concluído quando a aplicação responder com os dados esperados.

Conclusão

  • Trate restore de volume como deploy: staging, validação e cutover, nunca tar direto em cima do volume quente de produção.
  • Proíba down -v no runbook de produção e mantenha volume/diretório _old até a validação pós-cutover.
  • Automatize inventário, rsync e checagens de hash em scripts versionados para repetir o processo com o mesmo rigor.

Leia também

Precisa de ajuda com volumes Docker Compose em produção?

Um VPS com disco e I/O adequados facilita staging paralelo e cutover sem pressão de espaço. Se quiser infraestrutura estável para Docker Compose em produção, avalie um ambiente dimensionado para o seu workload.

Conhecer Servidor VPS AviraHost


Esta resposta foi útil?