WordPress gerido por Composer num parágrafo
O WP Packages é o segundo repositório Composer open source para o diretório do WordPress.org. O WPackagist faz o mesmo trabalho desde 2013. A história interessante não é “qual o espelho que vence”, mas o facto de em 2026 qualquer agência WordPress portuguesa que corra CI/CD, deploys multi-ambiente ou sequer um único projeto Bedrock ganhar com o tratamento de plugins como dependências Composer. O botão “Instalar” do dashboard não sobrevive ao contacto com um artefacto de deploy.
O resto deste guia atravessa o stack Roots (Bedrock, Sage, Trellis), as compensações entre WP Packages e WPackagist, o problema dos plugins premium de que ninguém gosta de falar, e os modos de falha que tropeçam equipas a saírem do fluxo de instalação por dashboard.
O que a Roots realmente entregou
Em março de 2026 a equipa Roots (Scott Walkinshaw, Ben Word e contribuidores) lançou o WP Packages em wp-packages.org. Espelha cada plugin e tema gratuito do diretório WordPress.org e serve-os como repositório Composer JSON.
O lançamento não foi suave. O projeto saiu numa terça-feira como “WP Composer”. Até sexta-feira, Nils Adermann (cocriador do Composer, também contribuidor para a especificação SemVer) tinha contactado para alertar que Composer é uma marca registada detida pelo projeto Composer. A Roots renomeou ao longo do fim de semana, manteve os URLs wp-composer.org existentes a responder com 410 mais aviso de descontinuação, e fez push de uma atualização do template Bedrock para que novos projetos apontassem para o host renomeado. Este é o tipo de incidente que num fornecedor empresarial teria levado seis semanas de revisão jurídica. Projetos open-source resolvem isto antes do post mortem aparecer no blog.
O composer.json que substitui o seu dashboard
{
"repositories": [
{
"type": "composer",
"url": "https://wp-packages.org"
}
],
"require": {
"php": ">=8.2",
"wp-packages/advanced-custom-fields": "^6.3",
"wp-packages/woocommerce": "^9.4",
"wp-packages/wordpress-seo": "^23.0"
}
}
O composer install resolve então uma árvore, escreve composer.lock e descarrega ZIPs para web/app/plugins/ (layout Bedrock) ou wp-content/plugins/ (WordPress vanilla com composer/installers). Num projeto Bedrock com 25 plugins, a instalação com cache quente corre em 30 a 90 segundos. Cache fria, sem diretório de cache do Composer, runner CI fresco: 2 a 4 minutos, principalmente tempo de download. Esse número começa a importar quando se encadeia composer install em todos os builds de PR.
O que o self-hosting realmente lhe dá
O self-hosting do WP Packages é a única funcionalidade que o WPackagist não iguala. Três cenários reais do mercado português onde compensa:
- Conformidade CNPD e auditoria de cadeia de fornecimento. Bancos, autarquias e clientes do setor público têm requisitos de proteção de dados e auditoria que exigem que cada dependência seja servida a partir de infraestrutura controlada. Com WP Packages forka o projeto, espelha-o num endpoint interno em Claranet, OVHcloud Datacenter Lisboa ou um VPS PTisp dedicado, e o seu composer.json deixa de falar com um host de terceiros durante o deploy.
- Runners CI em rede fechada. Jenkins ou GitLab Runner dentro de uma VPN bancária ou ministerial não atinge wpackagist.org nem wp-packages.org. Com WP Packages self-hosted mais uma cache local Composer, o pipeline de deploy é offline-clean.
- Filtragem personalizada. Um caso real de uma agência do Porto: plugins não atualizados há mais de 18 meses foram bloqueados de instalação na infraestrutura interna. Forkaram WP Packages, adicionaram o filtro à indexação, e
composer requirenum plugin desatualizado falha agora com erro claro em vez de instalar silenciosamente código abandonado.
Para a maioria das equipas o WPackagist chega. Os casos acima são aqueles em que deixa de chegar.
WPackagist: ainda o padrão por boa razão
O WPackagist é gerido pela Outlandish, uma cooperativa britânica. Espelha o diretório WordPress.org desde 2013 com muito poucas interrupções. A convenção de nomenclatura de pacotes (wpackagist-plugin/woocommerce, wpackagist-theme/twentytwentyfour) tornou-se a convenção de facto; quase todo o tutorial Bedrock escrito antes de março de 2026 assume WPackagist.
Lado a lado
| Propriedade | WPackagist | WP Packages |
|---|---|---|
| Ativo desde | 2013 | Março 2026 |
| Mantido por | Outlandish | Roots |
| Código do repositório open source | Fechado | Sim (MIT) |
| Self-hostável | Não | Sim |
| Prefixo de vendor | wpackagist-plugin/, wpackagist-theme/ | wp-packages/ |
| Método de sincronização | Cron consulta SVN do WordPress.org | Cron consulta API do WordPress.org |
| Default no esqueleto Bedrock | Sim (hoje) | Não (troca manual) |
| Track record operacional | 12+ anos | Algumas semanas |
Quando mudar, quando não
Mude para WP Packages se precisa de self-hosting, se já padronizou todo o stack Roots e prefere suporte de fornecedor único, ou se atingiu um atraso de sincronização do WPackagist que partiu um build e quer um segundo espelho como backup. Fique no WPackagist se o seu CI está verde, o composer.lock é reproduzível e “vamos migrar o prefixo de vendor em 200 sites de cliente” não está no roadmap de ninguém.
Os dois não se excluem mutuamente. Nada o impede de declarar ambos os repositórios e fixar plugins específicos a espelhos específicos. É isso que a maioria das agências vai acabar por fazer na prática.
Bedrock, Sage, Trellis: onde o Composer realmente compensa
O stack Roots é a razão pela qual Composer-no-WordPress se sente nativo em vez de aparafusado.
Bedrock: o layout do projeto
O Bedrock é um esqueleto de projeto, não um framework. O que efetivamente faz:
- Separa o core do WordPress em
web/wp/(gerido pelo Composer), pelo que owp-config.phpé um loader fino em vez do ficheiro de configuração canónico. - Move toda a configuração de ambiente para
.env(lido porvlucas/phpdotenv) econfig/environments/{development,staging,production}.php. A constanteWP_ENVcontrola qual ficheiro de ambiente é carregado. - Trata
web/app/plugins/,web/app/themes/eweb/app/mu-plugins/como destinos de instalação Composer viacomposer/installers. - Vem com um autoloader
mu-plugins/register-theme-directory.phppara quecomposer requirenum tema o registe efetivamente no WordPress.
.env está em gitignore. Segredos de produção vivem no gestor de segredos (HashiCorp Vault, AWS Secrets Manager), não em wp-config.php. Este é o contrato que torna WP_DEBUG, chaves de licença ACF Pro e credenciais de base de dados seguros por ambiente. Para conformidade com o RGPD e supervisão da CNPD, a separação entre código versionado e armazenamento de segredos é praticamente exigida.
composer create-project roots/bedrock meu-projeto
cd meu-projeto
cp .env.example .env
# editar .env com credenciais locais de DB e WP_ENV=development
composer install
Hosting português para Bedrock: Amen.pt tem SSH e Composer no plano Pro Webhosting e superiores, com documentação para Bedrock. PTisp tem Composer nos planos Premium e VPS. Webhost.pt suporta Composer nos planos Profissional. Claranet tem servidores dedicados com root para qualquer toolchain. Hostinger Portugal (apesar de não ser português, popular cá) tem SSH nos planos Business. Em geral evite hosting partilhado sem SSH; em 2026 Composer-build-no-servidor é um antipadrão.
Sage 10 para Sage 11: o imposto de migração
O Sage é o tema da Roots. O Sage 11 (lançado em 2024) trouxe o Acorn, um container ao estilo Laravel a correr dentro do WordPress, mais templates Blade em vez de PHP simples. Migrações do Sage 10 para o Sage 11 têm modos de falha específicos que vale a pena conhecer antes de se inscrever:
- Acorn breaking changes. Hooks registados pelo mecanismo de service provider do Acorn disparam mais tarde do que os mesmos hooks registados em
functions.php. Código que assumia prioridade 10 eminitpode precisar de mover para prioridade 20 ou para outro hook. - Blade vs templates PHP.
single.blade.phpem vez desingle.php. Chamadas antigas aget_template_partainda funcionam mas contornam a pipeline Blade e perdem a mecânica de section/yield. - Pipeline de assets. O Sage 10 usava Bud (wrapper do Webpack 5); o Sage 11 mudou para Vite. Ficheiros de configuração Bud não são portáveis. O seu
tailwind.config.jsé, mas atenção a diferenças na ordem dos plugins PostCSS.
A migração não é um botão único. Reserve dois dias para um tema pequeno, uma semana para algo com blocos Gutenberg personalizados.
Trellis: a opção que provavelmente não precisa
O Trellis é Ansible mais Vagrant para desenvolvimento local e provisionamento remoto. Constrói servidores Ubuntu LTS com Nginx, MariaDB, PHP-FPM, Redis e uma pipeline de deploy. Em linguagem clara: o Trellis é excelente para agências com infraestrutura própria (50 a 200 sites em servidores dedicados na Claranet ou OVHcloud) e excessivo para todos os outros. Se está a fazer deploy para hosting WordPress gerido (Kinsta, WP Engine, Pressable), o Trellis não é a ferramenta certa. Se está a gerir a sua própria frota DigitalOcean ou Hetzner, é.
Modos de falha que ninguém menciona na introdução
Estes são os quatro modos pelos quais composer install arruína a tarde de alguém.
Drift de versão de PHP entre local e CI
composer require resolve contra a versão de PHP que vê hoje. Um plugin marcado "php": ">=8.2" instala bem no seu portátil com PHP 8.3. Um ambiente de staging congelado em PHP 8.1 falhará composer install com um erro pouco útil de platform-requirement. Pin config.platform.php no composer.json para a versão mais baixa que qualquer ambiente corra:
{
"config": {
"platform": {
"php": "8.2.20"
}
}
}
Esta única linha salva mais deploys do que qualquer otimização de CI. Especialmente relevante para hosting partilhado português onde PHP 8.1 e 8.2 ainda são default em planos Amen.pt e Webhost.pt antigos em 2026.
mu-plugins/register.php carregado contra a versão WordPress errada
O autoloader do Bedrock em mu-plugins/ corre na altura do boot PHP, antes do core WordPress ser inicializado. Se fizer composer update do core WordPress para uma versão que mudou a semântica de WP_PLUGIN_DIR (aconteceu em WP 6.5), o autoloader pode registar diretórios de tema que já não existem. Sintoma: ecrã branco em produção, OK em staging. Correção: bloqueie roots/wordpress numa minor conhecida boa e suba deliberadamente.
Ativação de licença ACF Pro em ambientes de deploy
O ACF Pro autentica a sua licença contra advancedcustomfields.com. Builds de artefactos de deploy (Bitbucket Pipelines, GitHub Actions) correm como container fresco sem DOM, sem sessão de admin, e com IP que o servidor de licenças do ACF nunca viu. O fluxo de ativação que funciona em wp-admin não funciona num runner CI. Correções que efetivamente funcionam em 2026:
- Use o proxy Roots Premium se está num plano de organização Roots (intermedeia ACF Pro e outras licenças premium através do Composer).
- Defina
ACF_PRO_LICENSEcomo variável de ambiente lida pela API PHP do ACF e ignore o fluxo de ativação do dashboard completamente. - Use HTTP basic auth do Composer (
auth.json) para autenticar contra o endpoint Composer oficial do ACF emconnect.advancedcustomfields.com.
As duas primeiras são as únicas que sobrevivem a uma migração de servidor sem intervenção manual.
Incompatibilidade de lockfile entre Composer 2.7 e Composer 2.6
O Composer 2.7 mudou a forma como composer.lock regista platform overrides. Um composer.lock escrito por 2.7 falha a instalação em 2.6 com um erro enganador “the lock file is not up to date”. Padronize a versão do Composer no CI (composer self-update 2.7.7) e documente no README. Sim, isto é irritante. Sim, mordeu equipas suficientes para o Composer 2.8 vir a avisar explicitamente.
Plugins premium: a parte que a documentação esconde
Metade dos plugins num site de cliente real não estão no diretório WordPress.org. ACF Pro, Gravity Forms, WP Migrate, GP Premium, FacetWP, WP All Import Pro. No contexto português, adicione frequentemente Cookiebot ou complianz para conformidade RGPD/CNPD, e por vezes Yoast Premium ou RankMath Pro. O suporte a Composer varia muito:
- ACF Pro: endpoint Composer oficial em
connect.advancedcustomfields.com. Funciona bem, requerauth.jsoncom chave de licença como password. - Gravity Forms: suporte oficial a Composer desde 2023. Chave de licença em
auth.json, nome do pacotegravityforms/gravityforms. - Cookiebot/Complianz: sem endpoint oficial Composer. SatisPress ou inclusão manual.
- WP Migrate Pro (Delicious Brains, agora WP Engine): descarga de ZIP com URL com chave de licença. Repositório Composer personalizado a declarar o pacote como tipo
packagecom URL inline, ou proxy via SatisPress. - WP All Import Pro: sem endpoint Composer. ZIPs alojados num URL com chave de licença. SatisPress ou commit do ZIP num repositório privado.
Três padrões cobrem todos os anteriores:
- Roots Premium (roots.io/premium). Um proxy Composer gerido que trata licenças para ACF Pro, Gravity Forms e outros. Preço individual; para agências com 50+ sites a matemática normalmente fecha.
- SatisPress. Um plugin WordPress que transforma a sua própria instalação WordPress num repositório Composer. Instala plugins premium normalmente, expõe-os via
https://o-seu-host-privado/satispress/, bloqueia-os com HTTP basic auth. - Private Packagist da packagist.com. Repositório Composer alojado com suporte a pacotes privados. Custa mais que SatisPress, requer zero infraestrutura.
Qualquer que seja a escolha, a regra é: chaves de licença nunca vão para composer.json ou auth.json versionado em git. Vivem em variáveis de ambiente lidas em tempo de instalação, ou em segredos CI injetados em auth.json durante o passo de build. A conformidade RGPD exige separação clara entre código versionado e armazenamento de credenciais.
Integração CI que sobrevive à realidade
Uma pipeline de deploy funcional:
# .github/workflows/deploy.yml (excerto)
- name: Set up PHP 8.2
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
tools: composer:2.7
- name: Cache Composer
uses: actions/cache@v4
with:
path: ~/.composer/cache
key: composer-${{ hashFiles('composer.lock') }}
- name: Install
run: composer install --no-dev --optimize-autoloader --prefer-dist --no-interaction
env:
COMPOSER_AUTH: ${{ secrets.COMPOSER_AUTH_JSON }}
- name: Deploy artifact
run: rsync -avz --delete --exclude='.git' --exclude='node_modules' ./ deploy@host:/var/www/html/
Três regras que poupam tempo de debug:
- Nunca corra
composer updateem CI. Atualize localmente, faça commit do novocomposer.lock, faça push. CI correcomposer installcontra exatamente esse lockfile. - Coloque em cache
~/.composer/cachecom hash decomposer.lockcomo chave. Instalações frias passam de 4 minutos para 30 segundos. - Injete
auth.jsona partir de um segredo. A variável de ambienteCOMPOSER_AUTHé lida nativamente pelo Composer. Nunca faça commit de credenciais licenciadas.
O que mudou na cultura WordPress em 2026
Composer-no-WordPress era antes uma coisa de loja Roots. Em 2026 é o default para qualquer agência portuguesa ou equipa interna que faça deploy para mais do que um ambiente. Três sinais do ecossistema mais amplo:
- As submissões de plugins WordPress.org passaram as 500 por semana no início de 2026, um aumento de 100 a 150 semanais entre 2022 e 2024 (fonte: relatórios semanais da equipa Plugin Review). A maioria do novo volume é código assistido por IA. A equipa de Plugins recruta revisores voluntários; o limiar de qualidade do diretório está sob pressão.
- Tanto Kinsta como WP Engine adicionaram suporte nativo a builds Composer ao seu deploy Git push no final de 2025. A categoria “managed WordPress hosting que ignora composer.json” está a encolher.
- WP-CLI 2.10 adicionou subcomandos
wp composerque envolvemcomposer install,composer updatee validação de lockfile. O Composer está a tornar-se parte da superfície oficial do WP-CLI.
A lição para gestão de plugins-como-dependência: as ferramentas amadurecem mais rápido do que a capacidade de revisão do diretório WordPress.org. Um espelho self-hostável como o WP Packages é mais útil neste contexto do que teria sido há cinco anos, quando o diretório era um jardim fechado em que todos confiavam por defeito.
Última atualização: 2026-04-01
Precisa de ajuda para migrar um site para Bedrock ou configurar uma pipeline de deploy conduzida por Composer? Veja os nossos serviços de desenvolvimento WordPress.
