Migrando/Dockerizando instalação WordPress


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:

YAML
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:

INI
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 datamariadb 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:

Bash
mysqldump -u [usuario] -p[senha] [nome do banco de dados wp] > ./backup/dump.sql

A pasta local backup será mapeada para /tmp/backup dentro do contêiner.

Suba os containers com

Bash
docker compose up -d

Entre no container do banco de dados:

Bash
docker exec -it [container bd] /bin/bash

Entre no servidor mariadb:

Bash
mariadb -u root -p

Crie a database do seu blog:

SQL
create database <novo nome da base>;

Crie o usuário do wordpress conforme suas variáveis de ambiente:

SQL
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:

SQL
mariadb -u root -p<senha root do mariadbx> <novo nome da base> < /tmp/dump/dump.sql

Pronto! 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_EXTRA como 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:

Bash
	 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.

Bash
	 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:

Nginx
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://medium.com/swlh/wordpress-deployment-with-nginx-php-fpm-and-mariadb-using-docker-compose-55f59e5c1a

https://www.digitalocean.com/community/tutorials/php-fpm-nginx


Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

To respond on your own website, enter the URL of your response which should contain a link to this post’s permalink URL. Your response will then appear (possibly after moderation) on this page. Want to update or remove your response? Update or delete your post and re-enter your post’s URL again. (Find out more about Webmentions.)