Migrando um blog do WordPress para um contêiner Docker – iMasters
we are developersBack-EndTem 38 artigos publicados com 144400 visualizações desde 2009Arquiteto e desenvolvedor, agilista, pai, filho, escalador, ciclista, quebrador
we are developers
Back-End
Tem 38 artigos publicados com 144400 visualizações desde 2009
Arquiteto e desenvolvedor, agilista, pai, filho, escalador, ciclista, quebrador de status quo, Microsoft MVP. Escreve artigos, fundou o .Net Architects, mantém o podcast Tecnoretórica e da Lambda3, um blog e muitos projetos no Github. É agilista, e trouxe os programas da Scrum.org pro Brasil. Criou a Lambda3, que insiste em fazer projetos e consultoria direito.
O blog Lambda3 foi migrado para uma máquina mais nova. É um WordPress, rodando numa máquina no Azure. Ele estava, inicialmente, em uma máquina pequena, e conforme a audiência foi crescendo, a máquina cresceu junto. Mas ainda estava no modelo antigo de gestão do Azure (ASM), e a máquina era menos eficiente que as mais novas, que têm SSD, entre outros pontos.
Resolvemos migrá-lo para o modelo ARM e máquinas melhores. No processo, oras, por que não colocá-lo pra rodar num contêiner com Docker? Foi exatamente o que fizemos! E este artigo é pra contar para vocês como fazer isso. Parecia meio complicado a princípio, mas foi bem tranquilo no final.
O WordPress possui um repositório oficial no Docker Hub, e as imagens estão sempre taggeadas de acordo com a versão do WordPress que elas representam. Na home do repo há até indicações de como rodar um contêiner já com o MySql, e até um exemplo com docker-compose. Só que contêineres WordPress são um pouco peculiares. É importante eu fazer essa introdução para que algumas decisões que tomamos fiquem mais claras.
O WordPress possui um banco de dados para os dados estruturados, e um diretório wp-content para armazenar todo conteúdo, como imagens e arquivos em geral. É nesse diretório também que ficam os temas e plugins. Isso é ótimo, porque assumimos que tudo que está fora desse diretório é do engine do WordPress, e esse diretório mantém o estado do blog em si. Entretanto, isso não é verdade. Não é incomum plugins e temas instalarem recursos em outros diretórios do WordPress. Se todo conteúdo ficasse somente no diretório wp-content seria fácil: o diretório seria montado a partir de um volume, e poderíamos trocar a imagem de base quando quiséssemos atualizar o WordPress. Mas, como há conteúdo fora desse diretório, isso não é possível.
Outro problema é o próprio sistema de atualizações do WordPress. Ele é capaz de atualizar não só plugins, mas o WordPress em si. E quando o WordPress é atualizado, não somente os arquivos diversos do WordPress são atualizados (todos os que não estão no diretório wp-content), mas também o banco de dados. Ou seja, trocar a imagem de base do WordPress gerará um problema de inconsistência com a base de dados.
Isso quer dizer que o volume do Docker para o WordPress não pode ser somente o diretório wp-content, mas todo o conteúdo do WordPress, inclusive os arquivos do WordPress em si, e não só o conteúdo do blog. O que fica estranho depois é que, ao inspecionar o contêiner, você pode ver a versão, por exemplo, 4.2.0, mas na verdade, a versão que está rodando já foi atualizada, e agora é a 4.4.0. Mas não há como resolver esse problema. O próprio repo do Docker Hub te direciona a isso. A imagem de base e a versão servem somente para fazer o bootstrap inicial do WordPress, depois disso, não significam nada.
O interessante é que, se você montar o diretório onde o WordPress vai rodar, que é o /var/www/html (ele é baseado na imagem de PHP, e no caso estamos falando de Apache2), o contêiner vai respeitar isso e não vai sobrescrever nenhum arquivo. Guarde essa informação.
O banco de dados é um conteiner simples de MySQL. Pode ser também um MariaDb, que é um fork feito pela comunidade quando o MySQL foi parar na mão da Oracle (tire suas próprias conclusões do porquê) plenamente compatível, e é o que estou usando. A escolha é sua. Tanto o MariaDb, quanto o MySQL possuem repositórios oficiais no Docker Hub.
O primeiro passo é fazer um dump do MySQL/MariaDb que contém o banco de dados atual do WordPress. Isso é bem simples, basta rodar, no server, o mysqldump:
Você também pode fazer com um server remoto, veja mais nos docs do mysqldump pra ver as opções. Isso vai gerar um dump, que você vai poder usar pra restaurar depois. É um arquivo de texto simples, você pode abri-lo pra ver o que ele gerou. No entanto, ele não contém o nome do banco, assim, abra o arquivo, e na primeira linha coloque:
Escolhi montar o contêiner do MariaDb com um volume montado a partir do file system do host. Poderia ser também com um volume do Docker direto, não montado no host, não faria diferença. Vamos criar um server MariaDb que inicialmente não conterá nenhum dado, depois que ele subir eu vou acessá-lo e restaurar o dump, o que vai gerar os dados no volume. Assim, rodei:
O diretório do contêiner /var/lib/mysql é onde o MariaDb coloca os dados, e montei esse diretório no host em /data/blog/mysql. E meu dump estava em /tmp/dump que montei no contêiner no diretório /backup. Depois disso, basta acessar o contêiner, que já estava rodando:
Com isso, estamos com um terminal dentro do contêiner que está rodando o banco de dados. Agora vamos acessar a console do MariaDb e criar o banco. Digite:
Em seguida, digite sua senha. Você deve estar na console.
Então, crie o banco de dados:
E crie um usuário para acessar o banco de dados do WordPress. É importante o uso do @’%’
que identifica o usuário porque o acesso vai vir pra um ip/host que você não controlará. Se colocar @’localhost’ não vai funcionar:
(Você provavelmente não quer dar todos os privilégios a esse usuário. Estude os docs para dar as permissões mais apropriadas ao seu cenário.)
Então, saia da console, e importe o arquivo de dump que foi montado no diretório /backup:
Com isso feito, você já pode matar esse contêiner. A essa altura, o banco já foi restaurado com sucesso e os arquivos já estão no volume. Não queremos manter esse mesmo contêiner porque que tem um diretório de backup montado.
E assim, a parte do banco está concluída.
O WordPress é bem simples de se preparar. Eu resolvi montar uma imagem própria porque eu tinha configurações a fazer no PHP e no Apache, assim, criei esse Dockerfile:
A notar:
Se você não quiser usar SSL e não quiser configurar o PHP, pode usar direto a imagem de base do wordpress:4.7.1-apache (ou até outra, há opções com Alpine e FPM, por exemplo).
Meu arquivo de Php.ini possui somente 3 configs para o tamanho do upload e tempo de execução:
Além disso, você vai precisar observar o arquivo wp-config.php e notar se precisa alterar algo. Minhas informações do banco de dados mudaram. Especificamente a variável DB_HOST vai mudar – utilize MySQL para o novo nome. Vamos linkar o contêiner do MariaDb com esse nome.
Eu também precisei alterar as variável WPCACHEHOME porque eu uso o plugin WP Super Cache (que é muito bom, por sinal), e essa variável aponta o local do cache. O novo local ficou como: /var/www/html/wp-content/plugins/wp-super-cache/. E esse plugin mantinha o local também no arquivo wp-content/wp-cache-config.php, que também precisei alterar.
Tive problemas com permissões nos arquivos. Como os arquivos já existem e vão ser montados a partir do file system do host, o Apache do contêiner não conseguia acessar. No host, tive que alterar o owner dos arquivos e diretórios para www-data. Isso é no host, não no contêiner – e é antes do contêiner subir. Vá ao diretório onde os arquivos do WordPress estão e rode:
Não vamos rodar tudo na mão, né? Pra isso, tempos o docker-compose. Aqui o meu compose file:
Pra criar os contêineres a partir da configuração do compose basta rodar:
A notar:
Tudo funcionou perfeitamente. Testei na minha máquina primeiro, alterando o arquivo hosts para ver se funcionava. Com o sucesso, alterei o DNS do blog pra apontar para o novo local. No Azure, configurei a política do Network Security Group para abrir somente as portas 80 e 443.
O resultado é que uma máquina menor está com um desempenho melhor. Aqui os testes do Application Insights, que testam a app a cada 5 minutos. Notem que na madrugada do dia 26/1 o desempenho melhora significativamente.
Fiz ainda um outro teste. Derrubei os contêineres, e subi do zero. Como os dados estavam em volumes, nada deveria mudar. Foi exatamente o que aconteceu. Confiança total.
Tenho agora alguns outros sites bem pequenos (perto do blog da Lambda3) pra migrar. Vou avaliar como vou entregá-los usando o mesmo host, já que antes o Apache cuidava disso. Provavelmente vou rotear pelo Azure e usar portas diferentes.
A configuração do servidor foi feita com 4 discos SSD em RAID com stripe, utilizando mdadm. Desempenho excepcional, com 4TB de espaço e custo ridiculamente baixo (só pago pelo que uso). O storage do Azure ainda me garantiu replicação em 3 locais diferentes (sem que eu precise fazer nada para isso), com garantias absurdas de precisão e segurança na persistência.
Os logs estão direcionados via fluentd para o OMS, que também roda como SASS no Azure. Aqui, um dos relatórios que ele me dá, entre os diversos logs, alertas, etc. E é super simples de configurar, é uma linha no terminal do host.
E o servidor que hospeda tudo está limpo. Nada de Apache, MariaDb etc instalado. Ele roda somente uma coisa: Docker. E para que precisaria de mais?
***
Este artigo foi produzido em parceria com a Lambda3. Leia outros conteúdos no blog da empresa: blog.lambda3.com.br
De 0 a 10, o quanto você recomendaria este artigo para um amigo?
Arquiteto e desenvolvedor, agilista, pai, filho, escalador, ciclista, quebrador de status quo, Microsoft MVP. Escreve artigos, fundou o .Net Architects, mantém o podcast Tecnoretórica e da Lambda3, um blog e muitos projetos no Github. É agilista, e trouxe os programas da Scrum.org pro Brasil. Criou a Lambda3, que insiste em fazer projetos e consultoria direito.
Fique em dia com as novidades do iMasters! Assine nossa newsletter e receba conteúdos especiais curados por nossa equipe