O desenvolvimento WordPress ultrapassou os uploads por FTP é os paineis dé alojamento partilhado. Em 2026, as equipas profissionais tratam o WordPress como qualquer outro projeto de software, com dependencias versionadas, ambientes containerizados e pipelines de implementação automatizadas. Sé ainda está a editar ficheiros diretamente num servidor em produção, este guia vai mudar a forma como trabalha.
Este tutorial aborda duas abordagens complementares ao desenvolvimento moderno de WordPress: Docker Compose para ambientes de servidor reprodutiveis e Composer com Bedrock para gestão de dependencias. Vai obter ficheiros de configuração completos e prontos a copiar, configuração do Xdebug para depuração PHP adequada é um fluxo de implementação que leva o seu código da maquina local para produção de forma segura.
Porque e qué a configuração tradicional do WordPress o está a limitar
A abordagem classica de descarregar um ficheiro ZIP de wordpress.org e carrega-lo via FTP cria varios problemas que sé acumulam ao longo do tempo:
- Desvio dé ambiente - a sua configuração local MAMP ou XAMPP nunca corresponde exatamenté ao servidor de produção, levando a erros do tipo “funciona na minha maquina”.
- Sem rastreamento de dependencias - plugins e temas são descarregados é atualizados manualmente, tornando impossível reproduzir exatamenté o mesmo site noutra maquina.
- Sem controlo de versão para o nucleo - os ficheiros do nucleo do WordPress ficam no seu repositorio (ou pior, não são rastreados de todo), misturando código da aplicação com código do framework.
- Implementacoes manuais - copiar ficheiros por FTP e propenso a erros e não fornece mecanismo de reversão.
O Docker é o Composer resolvem cada um destes problemas de forma sistematica.
Configurar WordPress com Docker Compose
O Docker Compose permite-lhe definir toda a sua pilha de servidor num único ficheiro YAML. Cada programador na equipa obtem exatamenté a mesma versão de PHP, versão de MySQL e configuração de servidor ao executar um único comando.
Pré-requisitos
Instale o Docker Desktop para o seu sistema operativo. O Docker Desktop inclui tanto o motor Docker como o plugin CLI docker compose. Verifique a instalacao:
docker --version
docker compose version
Estrutura do projeto
Crié um diretorio de projeto limpo:
mkdir wordpress-docker && cd wordpress-docker
mkdir -p wp-content/themes wp-content/plugins wp-content/uploads
O docker-compose.yml completo
Crié um ficheiro docker-compose.yml na raiz do seu projeto:
version: "3.9"
services:
db:
image: mysql:8.0
container_name: wp_mysql
restart: unless-stopped
environment:
MYSQL_DATABASE: ${DB_NAME:-wordpress}
MYSQL_USER: ${DB_USER:-wpuser}
MYSQL_PASSWORD: ${DB_PASSWORD:-wppassword}
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-rootpassword}
volumes:
- db_data:/var/lib/mysql
ports:
- "3306:3306"
networks:
- wp_network
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
wordpress:
image: wordpress:6.7-php8.3-apache
container_name: wp_app
restart: unless-stopped
depends_on:
db:
condition: service_healthy
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_NAME: ${DB_NAME:-wordpress}
WORDPRESS_DB_USER: ${DB_USER:-wpuser}
WORDPRESS_DB_PASSWORD: ${DB_PASSWORD:-wppassword}
WORDPRESS_DEBUG: ${WP_DEBUG:-1}
WORDPRESS_CONFIG_EXTRA: |
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
define('SCRIPT_DEBUG', true);
define('DISALLOW_FILE_EDIT', true);
volumes:
- ./wp-content/themes:/var/www/html/wp-content/themes
- ./wp-content/plugins:/var/www/html/wp-content/plugins
- ./wp-content/uploads:/var/www/html/wp-content/uploads
- ./php-custom.ini:/usr/local/etc/php/conf.d/custom.ini
ports:
- "8080:80"
networks:
- wp_network
phpmyadmin:
image: phpmyadmin:5
container_name: wp_phpmyadmin
restart: unless-stopped
depends_on:
- db
environment:
PMA_HOST: db
PMA_PORT: 3306
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-rootpassword}
ports:
- "8081:80"
networks:
- wp_network
mailhog:
image: mailhog/mailhog:latest
container_name: wp_mailhog
ports:
- "1025:1025"
- "8025:8025"
networks:
- wp_network
volumes:
db_data:
networks:
wp_network:
driver: bridge
Está configuração fornece-lhe quatro serviços:
- MySQL 8.0 com verificação de saude para qué o WordPress aguarde qué a base de dados esteja pronta antes de iniciar.
- WordPress 6.7 em PHP 8.3 com Apache, montando apenas os seus temas, plugins e uploads personalizados.
- phpMyAdmin para gestão visual da base de dados em
http://localhost:8081. - MailHog para capturar e-mails enviados durante o desenvolvimento em
http://localhost:8025.
Variáveis dé ambiente com .env
Crié um ficheiro .env na raiz do projeto:
# Base de dados
DB_NAME=wordpress
DB_USER=wpuser
DB_PASSWORD=secure_local_password_2026
DB_ROOT_PASSWORD=secure_root_password_2026
# WordPress
WP_DEBUG=1
# Site
SITE_URL=http://localhost:8080
O Docker Compose lé automáticamente ficheiros .env do diretorio do projeto. Adicione .env ao seu .gitignore imediatamente e faca commit dé um modelo .env.example em vez disso.
Configuração PHP personalizada
Crie php-custom.ini para definições PHP adequadas ao desenvolvimento:
upload_max_filesize = 128M
post_max_size = 128M
memory_limit = 512M
max_execution_time = 300
max_input_vars = 3000
display_errors = On
error_reporting = E_ALL
Iniciar o ambiente
docker compose up -d
Abra http://localhost:8080 e complete a instalacao do WordPress. Os diretorios de temas e plugins estao montados a partir da maquina anfitria, pelo que quaisquer alterações que faca no seu editor aparecem instantaneamente na instancia WordPress em execucao.
Comandos Docker uteis para o trabalho diario
# Ver registos de todos os contentores
docker compose logs -f
# Ver registos apenas do WordPress
docker compose logs -f wordpress
# Abrir uma shell dentro do contentor WordPress
docker compose exec wordpress bash
# Executar comandos WP-CLI dentro do contentor
docker compose exec wordpress wp plugin list --allow-root
# Parar todos os contentores (preserva dados)
docker compose stop
# Parar e remover contentores (preserva dados de volumes)
docker compose down
# Reinicializacao completa incluindo base de dados
docker compose down -v
WordPress baseado em Composer com Bedrock
Enquanto o Docker trata do ambiente de servidor, o Bedrock da Roots reestrutura o proprio WordPress numa aplicação devidamente gerida pelo Composer. O Bedrock trata o nucleo do WordPress como uma dependencia, não como a raiz do projeto, o que muda tudo sobre como gere e implementa WordPress.
Porque e qué o Bedrock importa
O WordPress padrão mistura código dé aplicação (o seu tema, plugins) com código de framework (wp-admin, wp-includes) no mesmo diretorio. O Bedrock separa estas preocupacoes:
project-root/
config/ # Configuração específica do ambiente
application.php
environments/
development.php
staging.php
production.php
web/ # Raiz do documento (publica)
app/ # Equivalenté ao wp-content
themes/
plugins/
uploads/
wp/ # Nucleo do WordPress (gerido pelo Composer)
wp-config.php # Carregador mínimo
vendor/ # Dependencias do Composer
.env # Variáveis dé ambiente
composer.json # Manifesto de dependencias
O nucleo do WordPress reside em web/wp/ e nunca e modificado. O seu código personalizado reside em web/app/. O diretorio vendor/ e web/wp/ estão ambos no gitignore porqué o Composer recria-os a partir do composer.json.
Instalar Bedrock
composer create-project roots/bedrock my-wordpress-project
cd my-wordpress-project
A estrutura do composer.json
O composer.json do Bedrock geré o nucleo do WordPress, plugins e temas como pacotes:
{
"name": "your-agency/client-project",
"type": "project",
"license": "MIT",
"description": "WordPress project managed with Bedrock and Composer",
"require": {
"php": ">=8.1",
"composer/installers": "^2.3",
"vlucas/phpdotenv": "^5.6",
"oscarotero/env": "^2.1",
"roots/bedrock-autoloader": "^1.0",
"roots/bedrock-disallow-indexing": "^2.0",
"roots/wordpress": "6.7.*",
"roots/wp-config": "1.0.0",
"roots/wp-password-bcrypt": "1.1.0",
"wpackagist-plugin/wordpress-seo": "^23.0",
"wpackagist-plugin/wp-super-cache": "^1.12",
"wpackagist-plugin/wordfence": "^7.11"
},
"require-dev": {
"squizlabs/php_codesniffer": "^3.10",
"roave/security-advisories": "dev-latest"
},
"config": {
"optimize-autoloader": true,
"preferred-install": "dist",
"allow-plugins": {
"composer/installers": true,
"roots/wordpress-core-installer": true
}
},
"repositories": [
{
"type": "composer",
"url": "https://wpackagist.org",
"only": [
"wpackagist-plugin/*",
"wpackagist-theme/*"
]
}
],
"extra": {
"installer-paths": {
"web/app/mu-plugins/{$name}/": [
"type:wordpress-muplugin"
],
"web/app/plugins/{$name}/": [
"type:wordpress-plugin"
],
"web/app/themes/{$name}/": [
"type:wordpress-theme"
]
},
"wordpress-install-dir": "web/wp"
}
}
O ponto crucial: o WordPress Packagist espelha todo o repositorio de plugins e temas do WordPress.org como pacotes Composer. Adicionar um plugin e tao simples como:
composer require wpackagist-plugin/advanced-custom-fields
Remove-lo e igualmente limpo:
composer remove wpackagist-plugin/advanced-custom-fields
Configuração dé ambiente Bedrock
O Bedrock usa ficheiros .env em vez de codificar valores diretamente no wp-config.php:
# Ficheiro .env para Bedrock
DB_NAME=wordpress
DB_USER=wpuser
DB_PASSWORD=secure_local_password_2026
DB_HOST=db:3306
DB_PREFIX=wp_
WP_ENV=development
WP_HOME=http://localhost:8080
WP_SITEURL=${WP_HOME}/wp
# Gere estes em https://roots.io/salts.html
AUTH_KEY='generate-unique-key-here'
SECURE_AUTH_KEY='generate-unique-key-here'
LOGGED_IN_KEY='generate-unique-key-here'
NONCE_KEY='generate-unique-key-here'
AUTH_SALT='generate-unique-salt-here'
SECURE_AUTH_SALT='generate-unique-salt-here'
LOGGED_IN_SALT='generate-unique-salt-here'
NONCE_SALT='generate-unique-salt-here'
Cada ambiente (desenvolvimento, staging, produção) tem o seu proprio ficheiro .env no respetivo servidor. A mesma base de código funciona em todo o lado, com o comportamento controlado inteiramente por variáveis dé ambiente.
Combinar Docker e Bedrock
O verdadeiro poder surgé ao executar o Bedrock dentro do Docker. Modifiqué o docker-compose.yml para montar o seu projeto Bedrock em vez da imagem WordPress padrão:
services:
wordpress:
build:
context: .
dockerfile: Dockerfile
volumes:
- .:/var/www/html
environment:
- WP_ENV=development
Com um Dockerfile personalizado:
FROM php:8.3-apache
RUN apt-get update && apt-get install -y \
libzip-dev \
libpng-dev \
libjpeg-dev \
libfreetype6-dev \
libicu-dev \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install \
mysqli \
pdo_mysql \
zip \
gd \
intl \
opcache
RUN a2enmod rewrite
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
ENV APACHE_DOCUMENT_ROOT /var/www/html/web
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' \
/etc/apache2/sites-available/*.conf \
/etc/apache2/apache2.conf
WORKDIR /var/www/html
Isto da-lhé um ambiente Bedrock totalmente containerizado ondé o composer install e executado dentro do contentor é a raiz do documento aponta para o diretorio web/ do Bedrock.
Configuração do Xdebug para depuração PHP
A depuração passo a passo substitui var_dump e error_log por um depurador adequado que lhe permite pausar a execucao, inspecionar variáveis e percorrer o código linha a linha.
Adicionar Xdebug ao contentor Docker
Crié um ficheiro xdebug.ini:
[xdebug]
zend_extension=xdebug
xdebug.mode=debug,develop
xdebug.start_with_request=yes
xdebug.client_host=host.docker.internal
xdebug.client_port=9003
xdebug.discover_client_host=0
xdebug.log=/tmp/xdebug.log
xdebug.idekey=VSCODE
Adicioné a instalação do Xdebug ao seu Dockerfile:
RUN pecl install xdebug-3.3.2 \
&& docker-php-ext-enable xdebug
COPY xdebug.ini /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
Configuração do VS Code
Crie .vscode/launch.json na raiz do seu projeto:
{
"version": "0.2.0",
"configurations": [
{
"name": "Listen for Xdebug (Docker)",
"type": "php",
"request": "launch",
"port": 9003,
"pathMappings": {
"/var/www/html": "${workspaceFolder}"
},
"log": true
}
]
}
Instalé a extensão PHP Debug do Xdebug no VS Code, defina um breakpoint em qualquer ficheiro PHP, pressione F5 para comecar a escutar e recarregué a sua página WordPress. O depurador vai pausar no seu breakpoint.
Configuração do PhpStorm
O PhpStorm trata ligacoes Xdebug do Docker nativamente:
- Va a Settings > PHP > Debug e verifique qué a porta 9003 está definida.
- Va a Settings > PHP > Servers, adicioné um novo servidor com
localhostna porta8080e configuré o mapeamento de caminhos de/var/www/htmlpara a raiz do seu projeto. - Clique no botao Start Listening for PHP Debug Connections na barra de ferramentas.
Fluxo de implementação: do local ao staging a produção
Uma pipeline de implementação profissional garante qué as alterações de código fluem previsivelmente do desenvolvimento para produção sem copia manual de ficheiros.
O modelo de três ambientes
- Local (Docker) - onde escreve e testá código.
- Staging - um servidor que espelha a produção para testes finais.
- Produção - o sité ativo.
Implementação baseada em Git com GitHub Actions
O seu repositorio deve conter o código do tema, plugin e configuração Bedrock. Não deve conter o nucleo do WordPress, vendor/ ou uploads/.
Exemplo .github/workflows/deploy.yml:
name: Deploy to staging
on:
push:
branches: [staging]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.3"
- name: Install dependencies
run: composer install --no-dev --optimize-autoloader
- name: Run code quality checks
run: vendor/bin/phpcs --standard=WordPress web/app/themes/
- name: Deploy via rsync
uses: burnett01/rsync-deployments@7.0
with:
switches: -avz --delete --exclude='.env' --exclude='web/app/uploads/'
path: ./
remote_path: /var/www/staging.example.com/
remote_host: ${{ secrets.STAGING_HOST }}
remote_user: ${{ secrets.STAGING_USER }}
remote_key: ${{ secrets.STAGING_SSH_KEY }}
Sincronização de base de dados e uploads
O código e implementado através do Git, mas bases de dados e uploads de media requerem tratamento separado:
# Exportar base de dados de produção
wp db export production-backup.sql --ssh=user@production
# Importar para staging
wp db import production-backup.sql --ssh=user@staging
# Procurar e substituir URLs
wp search-replace 'https://example.com' 'https://staging.example.com' --ssh=user@staging
# Sincronizar uploads da produção para staging
rsync -avz user@production:/var/www/html/web/app/uploads/ \
user@staging:/var/www/html/web/app/uploads/
Para desenvolvimento local, usé os comandos WP-CLI wp db export e wp db import através do Docker:
docker compose exec wordpress wp db export /tmp/backup.sql --allow-root
docker cp wp_app:/tmp/backup.sql ./backups/
Comparação: Docker vs Composer vs LocalWP vs MAMP
| Funcionalidade | Docker Compose | Composer (Bedrock) | LocalWP | MAMP/XAMPP |
|---|---|---|---|---|
| Reprodutibilidade do ambiente | Excelente - definida em código | N/A (apenas gestão de código) | Limitada - por maquina | Limitada - por maquina |
| Consistencia de equipa | Paridade total entre maquinas | Paridade total para dependencias | Configuração manual por programador | Configuração manual por programador |
| Controlo de versão PHP | Versão exata no Dockerfile | Requer servidor separado | Alternavel por site | Definicao global |
| Gestão de dependencias | N/A (apenas servidor) | Excelente - composer.lock | Nenhuma | Nenhuma |
| Paridade com produção | Corresponde exatamenté a produção | Correspondé as dependencias de produção | Aproximada | Aproximada |
| Curva dé aprendizagem | Moderada - requer conforto com CLI | Moderada - conhecimento do ecossistema PHP | Baixa - baseada em GUI | Baixa - baseada em GUI |
| Integração CI/CD | Nativa | Nativa | Nenhuma | Nenhuma |
| Isolamento multiprojetos | Isolamento completo de contentores | Separado por projeto | Separado por site | Servidor partilhado |
| Configurações de servidor | Controlo total | N/A | Limitadas | Limitadas |
| Velocidade dé arranque | Moderada (primeiro pull e lento) | Rápida (composer install) | Rápida | Rápida |
A conclusao principal: Docker e Composer são complementares, não concorrentes. O Docker substitui o MAMP/XAMPP como ambiente de servidor, enquanto o Composer substitui a gestão manual de plugins/temas. O LocalWP continua a ser uma escolha válida para prototipagem rápida, mas falta-lhé a reprodutibilidade e integração CI/CD qué as equipas profissionais necessitam.
Dicas de desempenho para Docker no macOS
O Docker no macOS sofreu historicamente de desempenho lento do sistema de ficheiros devido a camada de virtualizacao. Em 2026, o Docker Desktop usa VirtioFS por defeito, o que melhora dramaticamenté as velocidades de I/O. Sé ainda está a sentir lentidao:
- Verifique sé o VirtioFS está ativado em Docker Desktop > Settings > General.
- Limité os volumes montados apenas ao que precisa (temas, plugins, uploads), não a instalação completa do WordPress.
- Usé as diretivas de cache integradas do Docker se necessário:
volumes: - ./wp-content:/var/www/html/wp-content:cached. - Atribua recursos suficientes em Docker Desktop > Settings > Resources (pelo menos 4 GB de RAM e 2 CPUs).
Considerações de segurança para desenvolvimento local
Mesmo em ambientes locais, os habitos de segurança importam porqué as configurações frequentemente escapam para produção:
- Nunca faca commit de ficheiros
.envpara o Git. Use.env.examplecomo modelo. - Use palavras-passe fortes e únicas no seu
.envmesmo localmente, para nunca implementar acidentalmente credenciais fracas. - Mantenha
DISALLOW_FILE_EDITdefinido comotrueem todos os ambientes. - Execute
composer auditregularmente para verificar vulnerabilidades conhecidas nas suas dependencias. - Fixe versões específicas no
composer.jsonpara implementacoes em produção em vez de usar restricoes de versão flexiveis.
Resolução de problemas comuns
O contentor MySQL encerra imediatamente
Verifiqué os registos com docker compose logs db. A causa mais comum é um volume existente com dados incompativeis. Execute docker compose down -v para remover volumes e comecar de novo.
O WordPress não consegue ligar-sé a base de dados
Verifique sé o valor WORDPRESS_DB_HOST correspondé ao nome do serviço no docker-compose.yml (tipicamente db:3306). Assegure-se de qué o contentor da base de dados está saudavel antes do WordPress iniciar, usando a condicao depends_on mostrada na configuração acima.
O Xdebug não liga
Confirme que host.docker.internal resolve corretamente dentro do contentor. No Linux, podera precisar dé adicionar extra_hosts: - "host.docker.internal:host-gateway" a definicao do serviço WordPress.
Erros de permissao de ficheiros
Sé o WordPress não consegue escrever em wp-content/uploads, ajusté as permissoes dentro do contentor:
docker compose exec wordpress chown -R www-data:www-data /var/www/html/wp-content/uploads
Próximos passos para o seu fluxo de trabalho
Assim que tiver o Docker é o Composer a funcionar, considere estas adicoes para profissionalizar ainda mais a sua configuração:
- WP-CLI como dependencia do Composer para gestão WordPress por scripts.
- PHPStan ou Psalm para análise estatica do código PHP dos seus temas e plugins.
- GitHub Actions ou GitLab CI para testes automatizados em cada pull request.
- Redis ou Memcached como serviço Docker adicional para cache dé objetos duranté o desenvolvimento.
- Traefik ou Nginx Proxy para gerir multiplos projetos WordPress locais com dominios personalizados em vez de números de porta.
A engenharia WordPress moderna significa tratar o seu site como um produto de software, com builds reprodutiveis, testes automatizados e implementacoes seguras. As ferramentas abordadas neste guia, Docker Compose para ambientes e Composer com Bedrock para gestão de dependencias, formam a base que toda equipa WordPress seria necessita em 2026.
Na wppoland.com, construimos e mantemos projetos WordPress usando exatamente estes fluxos de trabalho. Se a sua equipa precisa de ajuda para modernizar o seu processo de desenvolvimento WordPress, configurar pipelines CI/CD ou migrar de configurações legadas para ambientes containerizados, a nossa equipa de engenharia esta disponivel para consultoria e implementação. Os preços são sempre individuais e dependem do ambito do seu projeto.


