---
title: "Deploy WordPress sem downtime com Trellis: atomic releases, rollback instantâneo e hooks"
url: "https://helloblog.io/pt/deploy-wordpress-sem-downtime-com-trellis/"
date: "2025-10-02"
modified: "2026-01-20"
author: "João Santos"
language: "pt_PT"
categories: ["Ecossistema WordPress"]
tags: ["Bedrock", "Deploy", "DevOps", "Trellis", "WordPress"]
featured_image: "https://helloblog.io/app/uploads/sites/9/2026/01/featured-3-1024x572.png"
excerpt: "Se já fizeste deploy via FTP/rsync e apanhaste o site a meio, com ficheiros “misturados”, isto é para ti. O Trellis aplica uma estratégia moderna de *atomic deployments* para mudar de versão por symlink — rápido, previsível e com rollback imediato."
---

# Deploy WordPress sem downtime com Trellis: atomic releases, rollback instantâneo e hooks

No ecossistema WordPress ainda é comum ver deploys “à antiga”: subir ficheiros por FTP, correr um `rsync` para produção, ou carregar num botão de um plugin do host. Funciona… até ao dia em que não funciona: o site fica a servir uma mistura de ficheiros antigos e novos, aparece um erro aleatório no front-office, ou uma página do admin começa a falhar durante aqueles minutos de atualização.

O Trellis (da Roots) traz para WordPress um padrão que já é banal em aplicações modernas: **deploy sem downtime** com *atomic deployments* (deploy atómico). A ideia é simples e poderosa: preparar a nova versão isoladamente e só no fim fazer a troca de forma instantânea.

## O que “zero downtime” significa na prática (e o que não significa)

Um deploy *zero downtime* garante que o site continua acessível e funcional durante todo o processo. Em vez de ires substituindo ficheiros “em cima” do que está em produção, fazes um build completo noutro sítio e só depois apontas o servidor para a nova release.

Importante: isto resolve o lado **do código e ficheiros**. A base de dados é outra conversa — já lá vamos.

## O problema clássico dos deploys WordPress (FTP, rsync e afins)

A maioria dos deploys WordPress cai numa destas categorias:

- **FTP manual**: lento e propenso a inconsistências; durante o upload o site pode servir ficheiros parcialmente atualizados.
- **Sincronização de ficheiros (ex.: `rsync`)**: mais rápido do que FTP, mas continua a sobrescrever ficheiros enquanto o site está online.
- **Deploy “por plugin” do host**: prático, mas muitas vezes também atualiza in-place e sem uma estratégia robusta de rollback.

O denominador comum é o mesmo: há uma janela em que o utilizador pode apanhar o site num estado intermédio, e se algo corre mal, reverter tende a ser manual e stressante.

## Como o Trellis resolve: deploy atómico e imutável com releases

O Trellis usa uma abordagem **atómica** (a mudança de versão acontece num único passo) e **imutável** (uma release, depois de criada, não é “mexida” em produção). Cada deploy cria uma pasta nova com o projeto completo e no final troca um symlink para a nova pasta.

### Estrutura de diretórios que o Trellis cria

Ao fazer deploy para um servidor com Trellis, ficas tipicamente com uma estrutura deste género:

```
/srv/www/example.com/
├── current/             # Symlink para a release ativa
├── releases/            # Histórico de releases
│   ├── 20250930124530/
│   ├── 20250930083045/
│   └── 20250930141622/  # Mais recente
├── shared/              # Ficheiros partilhados entre releases
│   └── uploads/
└── logs/
```

O ponto-chave é o `current/`: o web server serve sempre a partir daí, mas `current` é apenas um symlink. Quando o deploy termina, o Trellis troca esse symlink para a pasta da nova release — e a “troca” é imediata.

### O que acontece quando executas `trellis deploy production`

O fluxo de deploy do Trellis é dividido em etapas bem definidas. Em alto nível, funciona assim:

1. **Initialize**: garante a estrutura (`current`, `releases`, `shared`, etc.) e cria uma pasta nova de release (timestamp).
2. **Update**: faz clone do repositório Git para uma área temporária, separada do site live.
3. **Prepare**: copia os ficheiros necessários para a nova release.
4. **Build**: corre `composer install` para instalar dependências.
5. **Share**: faz symlink de diretórios/ficheiros partilhados (por exemplo `uploads`) a partir de `shared/` para a nova release.
6. **Finalize**: atualiza o symlink `current` para apontar para a nova release.

O resultado é que não existe aquela fase perigosa em que o utilizador apanha metade do tema novo com metade do plugin antigo. Ou estás na release anterior, ou na release nova.

## Base de dados: o ponto onde “zero downtime” exige cuidado extra

O Trellis trata do deploy do **codebase**, mas **não inclui migrações de base de dados para um novo schema como parte do deploy** (segundo a documentação do Trellis). Ou seja: se a tua atualização implica alterações estruturais na BD, tens de planear isso separadamente.

Se usas Acorn (o framework da Roots que traz componentes do Laravel para WordPress), podes criar e executar **Laravel migrations** no contexto do teu projeto WordPress e integrá-las no processo de deploy.

#### Regra prática para migrações

Mesmo com deploy atómico de ficheiros, uma migração “breaking” na BD pode introduzir downtime funcional (erros, dados inconsistentes) se não for backward-compatible. Planeia migrações com cuidado e, quando possível, em etapas compatíveis com versões antigas e novas.

## Rollback instantâneo: a vantagem que muda o jogo

Deploy imutável dá-te um benefício imediato: **rollback rápido**. Como cada release é uma pasta completa e não é alterada após o deploy, reverter é só voltar a apontar o symlink `current` para a release anterior.

```
trellis rollback production
```

Por defeito, o Trellis mantém **as cinco releases mais recentes** no servidor, o que costuma ser suficiente para reverter rapidamente se apanhares um bug em produção.

## Hooks de deploy: onde personalizas o processo sem “gambiarras”

Na prática, quase ninguém quer um deploy completamente “puro”. Queres limpar cache, correr verificações, tirar backups, notificar a equipa. O Trellis prevê isso com **hooks** (pontos de extensão do processo) em várias fases.

- `deploy_build_before` e `deploy_build_after` para passos extra de build.
- `deploy_finalize_before` e `deploy_finalize_after` para tarefas imediatamente antes/depois da troca do symlink.
- Hooks para cada grande etapa: initialize, update, prepare, build, share e finalize.

Isto permite padrões úteis como: backup antes do deploy, limpeza de caches depois da troca, notificações, ou até *smoke tests* contra a release recém-preparada.

## Como começar (sem teres de mudar o teu setup local)

Um detalhe que muita gente não percebe à primeira: não precisas de adotar Trellis como “workflow completo” para tirares proveito do deploy atómico. Dá para usares o teu ambiente local preferido (Valet, Lando, DDEV, etc.) e ficares com o Trellis apenas para a parte do deploy.

1. Estrutura o projeto com **Bedrock** (organização mais moderna do WordPress e dependências via Composer).
2. Instala e configura o **Trellis** para os teus ambientes e credenciais de deploy.
3. No `wordpress_sites.yml`, aponta para o teu repositório Git (fonte do código).
4. Executa `trellis deploy production` para o primeiro deploy.

O primeiro deploy tende a demorar mais porque cria a estrutura no servidor e instala tudo. A partir daí, os deploys ficam mais previsíveis — e, mais importante, sem aquela janela de risco em que o site pode ficar “a meio”.

## Resumo do que ganhas com Trellis neste cenário

- Deploys **sem downtime** ao evitar sobrescrever ficheiros em produção.
- Mudança **atómica** via symlink (`current`) — ou estás numa release, ou noutra.
- Releases **imutáveis**, facilitando debugging e previsibilidade.
- **Rollback** em segundos com `trellis rollback`.
- **Hooks** para encaixar cache, backups, testes e automatismos no pipeline.

## Referências / Fontes

- [Zero Downtime WordPress Deployments with Trellis](https://roots.io/zero-downtime-wordpress-deployments-with-trellis/)
- [Deployments | Trellis Documentation](https://roots.io/trellis/docs/deployments/)
- [Bedrock](https://roots.io/bedrock/)
- [Trellis](https://roots.io/trellis/)
- [Creating and running Laravel migrations | Acorn Documentation](https://roots.io/acorn/docs/creating-and-running-laravel-migrations/)
