A “famosa instalação de 5 minutos” é um slogan de marketing, não um padrão profissional. Uma instalação padrão do WordPress é faladora, não otimizada e frequentemente insegura.
Como programadores, não apenas instalamos o WordPress; nós provisionâmo-lo. Este guia cobre o ambiente local, as constantes de wp-config.php, WP-CLI, notas de Xdebug, paridade com staging e higiene de wp-content que devem estar no teu boilerplate para cada projeto de cliente em 2026.
Ambiente local: Docker, wp-env e opções estilo Valet
Instalações manuais de Apache e PHP no host divergem. Uma máquina corre PHP 8.2, outra ainda tem 8.1, e o build de blocos falha só no CI. Para trabalho em equipa, o caminho oficial documentado no handbook de desenvolvimento do editor de blocos é um stack contentorizado (Docker) com wp-env: WordPress, base de dados e ferramentas opcionais, definidos a partir de um .wp-env.json na raiz do projeto.
Instala uma vez como dependência de desenvolvimento:
npm install --save-dev @wordpress/env
npx wp-env startConfiguração mínima para um plugin em desenvolvimento:
{
"core": "WordPress/WordPress#6.7",
"plugins": [ "." ],
"config": {
"WP_DEBUG": true,
"WP_DEBUG_LOG": true,
"WP_DEBUG_DISPLAY": false,
"SCRIPT_DEBUG": true
}
}Porque isto ajuda em projetos de plugins e temas modernos:
- A versão do core fica pinada no Git, por isso “funciona na minha máquina” deixa de ser debate.
wp-env run clidá-te WP-CLI dentro dos mesmos contentores que o browser usa.- Testes e scripts e2e do ecossistema
@wordpress/scriptsesperam este layout.
Para trabalho clássico em temas PHP (sem foco em blocos), um stack estilo Laravel Valet continua válido: Nginx (ou Caddy) no host, PHP-FPM local, MySQL ou MariaDB, e um domínio *.test via DNS local. A ideia é a mesma do Valet: pouco atrito no dia a dia, HTTPS local simples, sem reinventar um produto. O risco é a deriva de versões entre colegas. Mitiga com um ficheiro de versões no repositório (por exemplo .php-version ou a versão no README) e com a regra de que o site de referência da equipa corre em Docker quando o CI também corre em Docker.
O que evitar: misturar três stacks no mesmo projeto sem documentar qual é a fonte da verdade. Se o CI sobe com wp-env, o onboarding do colega novo são três linhas: instalar Docker, npm install, npx wp-env start. Qualquer checklist mais longa costuma significar que o ambiente escapou para pacotes não documentados no host.
Comandos úteis quando o stack Docker está de pé:
npx wp-env run cli wp plugin list
npx wp-env run cli wp cache flush
npx wp-env logs
npx wp-env stopMapeia um domínio customizado no ficheiro hosts só quando cookies ou SSO quebram em localhost. Caso contrário o URL por omissão chega e mantém certificados simples.
Controlo de ambiente e disciplina no wp-config.php
Este ficheiro é o cérebro da instalação. Depois do assistente de instalação, não o deixes em valores acidentais. Tudo o que importa fica explícito, os secrets ficam fora do Git, e a próxima pessoa no projeto encontra uma nota curta junto às constantes.
Desde o WordPress 5.5, WP_ENVIRONMENT_TYPE é o interruptor que plugins e temas devem ler:
// No wp-config.php
define( 'WP_ENVIRONMENT_TYPE', 'local' ); // local | development | staging | productionNo teu código:
if ( wp_get_environment_type() === 'production' ) {
// Cache ligado, logging verboso desligado
} else {
define( 'SCRIPT_DEBUG', true );
}Staging pode permitir instalação de plugins e Query Monitor. Produção não. Uma constante substitui dezenas de flags WP_LOCAL_DEV caseiras que as equipas esquecem de sincronizar.
| Ambiente | Debug típico | Alterações de ficheiros no admin | Cache |
|---|---|---|---|
local | Log; display opcional | Permitido | Desligado |
development | Log ligado | Permitido | Desligado ou suave |
staging | Log ligado, display off | Muitas vezes permitido | Parcial |
production | Display off; log só em incidente | Preferencialmente fechado | Ligado |
Hardening de segurança
Impede que clientes (ou atacantes) partam o site através do painel:
define( 'DISALLOW_FILE_EDIT', true );
define( 'FORCE_SSL_ADMIN', true );
define( 'WP_POST_REVISIONS', 10 );Usa DISALLOW_FILE_MODS só quando a árvore é imutável e as actualizações entram por CI. Em alojamentos geridos onde o painel ainda aplica patches a plugins, essa constante luta contra o host.
Revisões de posts
Assassino silencioso do tamanho da tabela posts. Precisas realmente de 100 versões da página “Sobre nós”?
define( 'WP_POST_REVISIONS', 10 ); // manter as últimas 10Desactivar por completo (false) raramente compensa: um erro de edição sem histórico custa mais do que alguns megabytes na base de dados.
Chaves de autenticação e salts
As constantes AUTH_KEY, SECURE_AUTH_KEY e restantes não são decoração. Alterá-las termina imediatamente a sessão de todos os utilizadores. É a opção nuclear depois de um compromisso. Guarda a rotação no runbook de deploy, não num post-it. Gera valores novos a partir da API oficial de salts do WordPress.org e nunca os commits em repositórios públicos.
Depuração profissional no wp-config.php
Nunca mostres erros PHP aos visitantes. Regista-os. A documentação oficial de debugging no WordPress deixa isto explícito: WP_DEBUG_DISPLAY deve ficar desligado em qualquer ambiente que clientes vejam.
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', '/var/log/wordpress/debug.log' ); // fora da raiz web
define( 'WP_DEBUG_DISPLAY', false );
@ini_set( 'display_errors', 0 );
// Só em sessões curtas de perfilagem
define( 'SAVEQUERIES', false );Melhor prática: aponta WP_DEBUG_LOG para um caminho fora do document root e nega acesso HTTP a qualquer debug.log residual em wp-content. Em produção, deixa WP_DEBUG a false excepto no meio de um incidente. SAVEQUERIES consome memória; nunca o deixes ligado de um dia para o outro.
Complementa as constantes com ferramentas que explicam o que aconteceu:
- Query Monitor para hooks, pedidos HTTP e queries lentas na barra de admin
- Browser DevTools com
SCRIPT_DEBUGpara carregar scripts do core não minificados enquanto caças um conflito - Logs do contentor (
wp-env logs) ou do PHP-FPM do host, conforme o stack
Quando o ecrã branco aparece em staging, lê debug.log, o log de erros do host e os logs do contentor antes de instalar mais um plugin de “debug”. A maioria das falhas de configuração aparece como um fatal único no log, não como uma funcionalidade em falta.
WP-CLI no dia a dia
O handbook de WP-CLI é a referência para automatizar o que o painel faz à mão. No Docker:
npx wp-env run cli wp core version
npx wp-env run cli wp plugin list --status=active
npx wp-env run cli wp option get siteurl
npx wp-env run cli wp search-replace 'https://staging.exemplo.pt' 'https://exemplo.pt' --dry-runNum stack estilo Valet, o binário wp aponta para o mesmo PHP-FPM que serve o site. Confirma com wp cli info e wp eval 'echo PHP_VERSION;'. Se o CLI usa 8.3 e o web usa 8.1, vais caçar “bugs” que só existem nessa assimetria.
Casos de uso que poupam horas:
- Activar ou desactivar plugins em massa depois de um import
- Limpar rewrite rules (
wp rewrite flush) após mudanças de permalink - Importar dump SQL e correr
wp search-replacecom--dry-runprimeiro - Gerar utilizadores de teste sem abrir o painel
- Exportar e importar conteúdo com
wp export/wp importem pipelines
Não uses WP-CLI para “atalhos” que escondem o estado real do repositório. Se um plugin só existe no servidor e não no Git, o CLI pode activá-lo, mas o próximo deploy apaga-o. A regra é a mesma do painel: o repositório é a fonte da verdade; o CLI é o operador.
Notas práticas de Xdebug
Xdebug é útil quando o log e o Query Monitor não chegam. Não é um serviço que fica ligado 24 horas. Em contentores Docker, liga o módulo PHP do serviço de aplicação, define XDEBUG_MODE=debug (ou o modo que a tua versão documenta) e aponta o IDE para o host e porta correctos. Em stacks estilo Valet, activa a extensão no PHP do host e usa um snippet de configuração que só carrega quando uma cookie ou query string de trigger está presente.
Cuidados que evitam horas perdidas:
- Desliga Xdebug quando não estás a depurar; o custo de latência em cada pedido é real
- Alinha paths do contentor com path mappings do IDE; um breakpoint “fantasma” quase sempre é path mismatch
- Não commits ficheiros
xdebug.inicom IPs de portátil de colegas; usa variáveis de ambiente - Em produção, Xdebug não entra. Ponto. Diagnóstico em produção passa por logs e staging reproduzível
Se o bug só aparece com object cache ou CDN, anota isso no ticket. O Docker local não inventa Redis ou um edge network a menos que os declares no env.
Paridade com staging
Ambiente local que “quase” parece staging produz deploys surpresa. Paridade não significa clonar produção completa; significa alinhar as variáveis que mudam o comportamento do código.
Checklist mínima de paridade:
- Mesma major de PHP e mesma major de MySQL/MariaDB que staging
- Mesmo
WP_ENVIRONMENT_TYPEsemântico (staging usastaging, local usalocal) - Mesmo conjunto de plugins activos e mesmas versões pinadas no lockfile ou no composer
- Mesmas constantes críticas: SSL, revisões,
DISALLOW_FILE_EDIT - Object cache e cron: se staging usa Redis e cron do sistema, o local deve documentar o desvio ou aproximar-se
Copia um dump anonimizado de staging para local quando o bug depende de dados reais. Remove utilizadores, emails e tokens antes do dump sair do servidor. Depois do import, wp search-replace com dry-run e confirma home e siteurl.
URLs hardcoded em conteúdo e em opções serializadas são a causa clássica de “funciona em staging, parte no local”. WP-CLI trata serialização; um find-replace ingénuo no SQL não.
Se a equipa usa deploys imutáveis, staging deve espelhar o mesmo pipeline: build de assets, composer install --no-dev, sync de artefactos. Local pode usar npm start em watch mode; staging não deve depender do laptop de ninguém.
Higiene de wp-content
wp-content é onde o projeto vive e onde o lixo se acumula. Trata-o como código versionado mais uploads, não como uma pasta mágica.
Regras práticas:
- Temas e plugins customizados vivem no Git. Plugins de terceiros: ou Composer, ou versões pinadas e documentadas
uploads/fica fora do Git (ou só com fixtures pequenas). Backups de media não pertencem ao repositóriomu-plugins/para regras de equipa (lean core, guards de ambiente). Um must-use pequeno vale mais do que um plugin “disable everything” do diretóriodebug.log,*.sql, dumps e exports CSV não ficam sob a raiz web acessível- Remove temas e plugins default que não usas depois de teres o teu tema ativo e testado
- Não versionas
upgrade/, caches de object cache em disco, nem pastas de backup de plugins de segurança
Exemplo de must-use enxuto:
<?php
/**
* Plugin Name: Lean core
*/
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
remove_action( 'wp_print_styles', 'print_emoji_styles' );
add_filter( 'xmlrpc_enabled', '__return_false' );
remove_action( 'wp_head', 'wp_generator' );Desactivar emojis, XML-RPC e o generator-tag por código evita mais um plugin pesado. Remover a versão do WordPress do HTML é ofuscação, não protecção: patches, salts fortes, SSL e permissões restritivas pesam mais.
Permissões de ficheiros: o utilizador do servidor web precisa de escrever em uploads/ e, em alguns hosts, em upgrade/. O resto do core e dos plugins customizados deve ser só de leitura em produção. Se o painel consegue editar functions.php, DISALLOW_FILE_EDIT falhou ou nunca foi aplicado.
Checklist antes do lançamento
Antes de ires a produção:
- Define
WP_ENVIRONMENT_TYPEparaproduction - Define
DISALLOW_FILE_EDITatrueeFORCE_SSL_ADMINatrue - Limita
WP_POST_REVISIONS - Move
WP_DEBUG_LOGpara pasta privada;WP_DEBUG_DISPLAYficafalse - Confirma que Xdebug não está activo no PHP de produção
- Corre
wp plugin liste compara com o inventário do repositório - Limpa
debug.log, dumps e ficheiros temporários emwp-content - Valida permissões e que o document root não serve paths acima de
wp-content/uploadssem necessidade
Uma instância WordPress bem provisionada é silenciosa, previsível e alinhada entre local, staging e produção. O setup não acaba no installer; acaba quando a próxima pessoa da equipa consegue reproduzir o mesmo comportamento sem adivinhar.
Veja os nossos serviços de segurança WordPress.






