Este blog, feito em WordPress, foi originalmente instalado em uma VPS que compartilho com meu irmão, com a stack inteira do NGINX/MySQL/PHP instalada diretamente no host, até o Redis para cacheamento. Na época eu estava “procrastinando” meu primeiro contato mais sério com containerização, e pouco tempo depois, já familiarizado com containers, planejei dockerizar o blog. Assim que sobrou um tempo me dediquei a essa tarefa, e compartilho aqui os pontos de atenção para quem planejar fazer uma migração do WordPress para containers.
Alguns detalhes da minha arquitetura: como o NGINX no host está servindo várias aplicações, e não só o meu site, ele não seria containerizado. A terminação do TLS é realizada no NGINX, também, e não no WP.

Neste cenário, os pontos de atenção durante a migração são:
- Backup e credenciais do servidor de banco de dados.
- Se você tiver um wp-config.php com muitas customizações, terá que incluí-las em um novo wp-config que os contêineres WP criam.
- Quanto às permissões nos arquivos do WP, os IDs de usuário e grupo do dono precisam ser os mesmos, tanto no host quando nos containers (costuma ser 82 em imagens alpine e 33 em imagens debian).
- Configurar headers no NGINX, para lidar com problemas relacionados a terminação TLS.
A idéia central da migração é subir contêineres WP + BD genéricos e depois injetar nosso site neles, mapeando os volumes do container de banco de dados e do WP para dados que já temos.
Assim, os dados continuam no nosso host, e só precisamos montar os volumes pertinentes nos containers que subirmos.
Manifesto do docker compose
Localizado em uma pasta para abrigarmos os dados do blog, o manifesto yaml do docker compose é simples:
services:
mariadb:
container_name: <container do bd>
image: mariadb:lts
environment:
MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD}
volumes:
- ./mariadb:/var/lib/mysql
- ./backup:/tmp/dump
wordpress:
container_name: <container do wp>
image: wordpress:fpm-alpine
volumes:
- ./data:/var/www/html
depends_on:
- mariadb
ports:
- 127.0.0.1:39000:9000
environment:
WORDPRESS_DB_HOST: ${WORDPRESS_DB_HOST}
WORDPRESS_DB_NAME: ${WORDPRESS_DB_NAME}
WORDPRESS_DB_USER: ${WORDPRESS_DB_USER}
WORDPRESS_DB_PASSWORD: ${WORDPRESS_DB_PASSWORD}
Uma colinha para a definição das variáveis de ambiente no .env:
MARIADB_ROOT_PASSWORD=
WORDPRESS_DB_HOST=
WORDPRESS_DB_NAME=
WORDPRESS_DB_USER=
WORDPRESS_DB_PASSWORD=Para outras variáveis, cheque na página da imagem WP.
Antes da execução, certifique-se da existência das pastas data, mariadb e backup no diretório do docker-compose.
Passo 1: Dump do banco de dados
Uma boa referência para esta primeira parte está aqui: migrando um blog wordpress para um container docker. A diferença é que o autor não utiliza NGINX.
Na pasta onde está o docker compose, o diretório mariadb conterá todos os arquivos relacionados ao banco de dados, pois é mapeada para /var/lib/mysql dentro do contêiner do mariadb.
A partir da pasta que contém o docker-compose.yaml, e ainda no host onde está o servidor do seu banco de dados, dê um dump na sua base do wordpress:
mysqldump -u [usuario] -p[senha] [nome do banco de dados wp] > ./backup/dump.sqlA pasta local backup será mapeada para /tmp/backup dentro do contêiner.
Suba os containers com
docker compose up -dEntre no container do banco de dados:
docker exec -it [container bd] /bin/bashEntre no servidor mariadb:
mariadb -u root -pCrie a database do seu blog:
create database <novo nome da base>;Crie o usuário do wordpress conforme suas variáveis de ambiente:
grant all privileges on <nome da base>.* to '<usuario wordpress>'@'%' identified by '<senha do usuario wp>';Saia do servidor com um exit, e ainda no container recrie o banco de dados:
mariadb -u root -p<senha root do mariadbx> <novo nome da base> < /tmp/dump/dump.sqlPronto! Já temos todo o banco de dados no host. Qualquer coisa, só precisamos subir o container com o mesmo volume ./mariadb:/var/lib/mysql . Nessa altura podemos parar os containers com um docker compose down.
Passo 2: Dados do wordpress
Aqui temos um problema: quem já subiu um wordpress na unha com certeza já teve que mexer pelo menos uma vez no arquivo wp-config.php para configurar as constantes de endereço/usuario/senha do banco de dados, além de outras configurações. No contexto de containers, a maioria destas constantes vira uma variável de ambiente.
Enfim, é bom você montar o seu .env com base no que já existia no seu wp-config.php.
Para trocar o wp-config.php padrão pelo que utiliza variáveis de ambiente:
- Na pasta data/, no mesmo local do docker-compose.yml, você deve conseguir achar o wp-config.php padrão criado por containers WP. Copie-o para um local seguro, e se você tiver configurações fora do padrão para o seu WP, coloque neste arquivo ou na variável
WORDPRESS_CONFIG_EXTRAcomo expressões php. - Coloque todo os arquivos core do seu WordPress na pasta
data, sobrescrevendo os arquivos recém criados pela nova instalação do WordPress pelo os do seu site. - Sobrescreva o wp-config.php antigo pelo novo, agora dentro da pasta
data.
Permissões nos arquivos core do WP
Eu tive vários problemas com permissões: na imagem wordpress:fpm-alpine, o userid e groupid do www-data é 82, ao contrário de 33 (padrão no Debian).
Estes IDs precisam ser idênticos no host e no container.
No seu host, mude-os se necessário, com:
sudo usermod -u [ID] www-data
sudo groupmod -g [ID] www-data
Ou coloque o ID desejado, de acordo com a distro do seu container, como owner dos arquivos de seu blog.
sudo chown -R [ID]:[ID] /path/to/blog/data
Passo 3: NGINX
Extremamente comum em ambientes containerizados, reverses proxies permitem você redirecionar requisicoes HTTP em um único host para diversos outros endpoints com base nos endereços das requisicões.
O WordPress avisa em uma doc que terminações de TLS em um proxy podem causar loops de redirecionamento, e aconselha setar um header específico para contornar o problema.
O principal bloco de configuração do meu site no NGINX ficou mais ou menos assim:
server {
root /path/to/blog/data;
index index.php;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:39000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param HTTP_X_FORWARDED_PROTO $http_x_forwarded_proto if_not_empty;
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
listen 443 ssl; # managed by Certbot
listen [::]:443 ssl; # managed by Certbot
# coisas do Certbot
}Atenção para o paramêtro fastcgi_param SCRIPT_FILENAME, que coloca /var/www/html como o ponto de partida do caminho para os scripts php relativo ao container, ao invés do caminho definido na diretiva root, relativo ao host. Se não acertasse esse caminho, você estaria tentando acessar, dentro do container, um endereço absoluto do host.
algumas referências:
https://www.digitalocean.com/community/tutorials/php-fpm-nginx