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 seu 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.
Instale 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á-lhe 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. Mitigue 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 stopMapeie 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.
Como configurar o wp-config.php por ambiente
Este ficheiro é o cérebro da instalação. Depois do assistente de instalação, não o deixe 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 seu 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
Impeça 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 );Use 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. Precisa 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. Guarde a rotação no runbook de deploy, não num post-it. Gere valores novos a partir da API oficial de salts do WordPress.org e nunca os faça commit em repositórios públicos.
Como ativar o debug log no WordPress sem mostrar erros
Nunca mostre erros PHP aos visitantes. Registe-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: aponte 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, deixe WP_DEBUG a false excepto no meio de um incidente. SAVEQUERIES consome memória; nunca o deixe ligado de um dia para o outro.
Complemente 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ça um conflito - Logs do contentor (
wp-env logs) ou do PHP-FPM do host, conforme o stack
Quando o ecrã branco aparece em staging, leia 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.
Comandos WP-CLI úteis com wp-env e Valet
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. Confirme com wp cli info e wp eval 'echo PHP_VERSION;'. Se o CLI usa 8.3 e o web usa 8.1, vai 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 use 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.
Como configurar o Xdebug no WordPress
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, ligue o módulo PHP do serviço de aplicação, defina XDEBUG_MODE=debug (ou o modo que a sua versão documenta) e aponte o IDE para o host e porta correctos. Em stacks estilo Valet, active a extensão no PHP do host e use um snippet de configuração que só carrega quando uma cookie ou query string de trigger está presente.
Cuidados que evitam horas perdidas:
- Desligue Xdebug quando não está a depurar; o custo de latência em cada pedido é real
- Alinhe paths do contentor com path mappings do IDE; um breakpoint “fantasma” quase sempre é path mismatch
- Não faça commit de ficheiros
xdebug.inicom IPs de portátil de colegas; use 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, anote isso no ticket. O Docker local não inventa Redis ou um edge network a menos que os declare no env.
Como alinhar o ambiente local com o 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
Copie um dump anonimizado de staging para local quando o bug depende de dados reais. Remova utilizadores, emails e tokens antes do dump sair do servidor. Depois do import, wp search-replace com dry-run e confirme 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.
O que versionar na pasta wp-content
wp-content é onde o projeto vive e onde o lixo se acumula. Trate-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- Remova temas e plugins default que não usa depois de ter o seu tema ativo e testado
- Não versione
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.
Como configurar o Composer 2 para gerir plugins e dependências WordPress
O Composer 2 gere pacotes PHP, plugins, temas e ferramentas de desenvolvimento de forma determinística em toda a equipa de engenharia. No desenvolvimento profissional de WordPress, as dependências nunca devem ser guardadas diretamente no controlo de versões como arquivos zip descarregados manualmente do diretório de plugins. Utilizar o Composer permite declarar versões exatas, automatizar atualizações de segurança em pipelines de CI e manter o repositório git limpo.
Plugins e temas disponíveis em WordPress.org podem ser instalados diretamente via Composer através do repositório público WPackagist (wpackagist.org). O pacote composer/installers assegura que os pacotes do tipo wordpress-plugin sejam colocados em wp-content/plugins/ e os do tipo wordpress-muplugin em wp-content/mu-plugins/, em vez de terminarem na pasta padrão vendor/.
Um ficheiro composer.json testado em produção para um projeto WordPress moderno define restrições rigorosas de plataforma PHP, configura os instaladores necessários e inclui dependências essenciais de desenvolvimento:
{
"name": "wppoland/projeto-wordpress",
"description": "Configuração para programadores WordPress com Composer 2",
"type": "project",
"license": "GPL-2.0-or-later",
"repositories": [
{
"type": "composer",
"url": "https://wpackagist.org"
}
],
"require": {
"php": ">=8.2",
"composer/installers": "^2.3"
},
"require-dev": {
"squizlabs/php_codesniffer": "^3.11",
"wp-coding-standards/wpcs": "^3.1",
"phpstan/phpstan": "^1.12",
"szepeviktor/phpstan-wordpress": "^1.3",
"roave/security-advisories": "dev-latest"
},
"config": {
"allow-plugins": {
"composer/installers": true,
"dealerdirect/phpcodesniffer-composer-installer": true
},
"optimize-autoloader": true,
"sort-packages": true
},
"scripts": {
"phpcs": "phpcs --standard=WordPress src/",
"phpcbf": "phpcbf --standard=WordPress src/",
"phpstan": "phpstan analyse --level=6 src/"
}
}Faça commit do ficheiro composer.lock no git. O ficheiro lock garante que todos os programadores da equipa e todos os executores de CI correm exatamente as mesmas versões de pacotes até ao hash de commit. Nos servidores de produção, execute composer install --no-dev --optimize-autoloader durante o deploy. Isto ignora ferramentas exclusivas de desenvolvimento, gera um classmap autoloader otimizado e evita a presença de pacotes de análise no servidor web público.
Análise estática de código e normas PHP com PHPCS e PHPStan
Enquanto ferramentas de frontend asseguram a qualidade de JavaScript e CSS, a base de código PHP do lado do servidor exige o mesmo rigor. Executar análise estática e verificações de estilo localmente evita que erros de sintaxe, consultas SQL inseguras, saídas de dados sem escape ou nonces em falta cheguem à revisão de código.
Aplicação de normas WordPress Coding Standards com PHPCS
O ecossistema WordPress mantém normas oficiais de código (WPCS) através do PHP_CodeSniffer. Estas regras verificam convenções de nomenclatura do core, formatação de arrays e vulnerabilidades críticas de segurança, tais como dados em bruto da superglobal $_POST ou ausência de funções de sanitização como sanitize_text_field() e esc_html().
Crie um ficheiro phpcs.xml.dist na raiz do seu repositório:
<?xml version="1.0"?>
<ruleset name="WordPress Project Standards">
<description>Normas PHPCS para projetos WordPress.</description>
<file>./src</file>
<arg name="basepath" value="."/>
<arg name="colors"/>
<arg name="extensions" value="php"/>
<arg name="parallel" value="8"/>
<rule ref="WordPress-Core"/>
<rule ref="WordPress-Docs"/>
<rule ref="WordPress.Security.EscapeOutput"/>
<rule ref="WordPress.Security.ValidatedSanitizedInput"/>
<exclude-pattern>*/vendor/*</exclude-pattern>
<exclude-pattern>*/node_modules/*</exclude-pattern>
<exclude-pattern>*/build/*</exclude-pattern>
</ruleset>Execute composer run phpcs localmente antes de abrir um pull request. Havendo violações de formatação, execute composer run phpcbf para corrigir automaticamente espaços, indentação e docblocks sem alterar a lógica da aplicação.
Análise estática aprofundada com PHPStan e phpstan-wordpress
O PHPCS avalia estrutura e estilo, mas não analisa a consistência de tipos nem a validade do fluxo de chamadas. O PHPStan examina o código PHP sem o executar, detetando métodos inexistentes, tipos incompatíveis em parâmetros e ramos de execução inalcançáveis. Como o WordPress depende fortemente de hooks dinâmicos e variáveis globais, a extensão szepeviktor/phpstan-wordpress fornece ao PHPStan as assinaturas de funções do core, propriedades de WP_Post e argumentos de filtros.
Configure o ficheiro phpstan.neon.dist no nível de regras 6:
includes:
- vendor/szepeviktor/phpstan-wordpress/extension.neon
parameters:
level: 6
paths:
- src/
excludePaths:
- vendor/
- node_modules/
- build/A inclusão do PHPStan no seu pipeline de integração contínua garante que refatorar a assinatura de uma função ou renomear um callback de hook não cause falhas inesperadas no ambiente de produção.
Checklist WordPress antes de ir para produção
Antes de ir a produção:
- Defina
WP_ENVIRONMENT_TYPEparaproduction - Defina
DISALLOW_FILE_EDITatrueeFORCE_SSL_ADMINatrue - Limite
WP_POST_REVISIONS - Mova
WP_DEBUG_LOGpara pasta privada;WP_DEBUG_DISPLAYficafalse - Confirme que Xdebug não está activo no PHP de produção
- Corra
wp plugin liste compare com o inventário do repositório - Limpe
debug.log, dumps e ficheiros temporários emwp-content - Valide 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.







