En este post vamos a crear, paso a paso, un entorno de desarrollo local con Docker optimizado para WordPress y así poder trabajar cualquier proyecto de WordPress con el sistema de contenedores que nos proporciona Docker.
¡Vamos al lío!
Lo primero, quiero definir el stack de tecnologías que vamos a usar para orquestar el proyecto con docker-compose, usaremos una por contenedor:
NGINX
PHP-FPM
MARIA DB
PHP Myadmin
La ventaja de trabajar con docker-compose es que podemos distribuir el stack del proyecto por servicios y tener un control más preciso por cada contenedor.
Una vez teniendo claras las tecnologías necesarias, vamos declarar un servicio por cada una de ellas en nuestro docker-compose:
mkdir dockerwp
cd dockerwp
touch docker-compose.yml
El primer servicio que definimos es el de nginx para que actúe como servidor web, fíjate que el nombre del servicio es dockerwp_nginx y todos sus parámetros van indentados bajo él, y a su vez, todo el bloque va indentado bajo services.
Es muy importante que mantengas una correcta indentación en la estructura de tu archivo ya que de lo contrario es muy probable que tengas fallos al levantar el proyecto. También dependiendo de la versión de docker-compose que declares deberás seguir una sintaxis u otra.
Voy a ir definiendo para qué sirve cada parámetro del bloque de servicio:
Build: Aquí indico el Dockerfile que quiero que use para la imagen del contenedor que va a crear el servicio. También se puede utilizar image en vez de build y utilizar una imagen de Docker Hub directamente, para este servicio y el de php vamos a utilizar un Dockerfile para descargar la imagen.
Para ello, en la raíz del proyecto crea una carpeta llamada nginx y a continuación crea un fichero dentro llamado Dockerfile con la siguiente información:
FROM nginx:latest
Lo que hacemos con el parámetro build es indicarle el Dockerfile que tiene que usar para descargar la imagen.
Container_name: Nos sirve para dar un nombre al contenedor que crea el servicio, de esta manera nos será más fácil reconocer el contenedor en los logs o cuando hagamos un docker-compose ps.
Siempre soy partidario de mantener la integridad en los nombres de los servicios y contenedores, y por ello nombro el contenedor con el mismo nombre que el servicio. Ahora en cuanto acabemos de definir este primer servicio veremos cómo optimizar esto de los nombres
Volumes: Aquí vamos indicando qué carpetas de nuestro proyecto queremos mapear con qué carpetas del contenedor nuestra_maquina:contenedor.
Los volúmenes nos sirven para que los datos que se guardan en ellos no se borren cuando bajemos o borremos los contenedores.
En este caso definimos un volumen para almacenar los datos de nuestra instalación de WordPress y que no se pierdan cuando el contenedor se elimine.
Ports: En este parámetro mapeamos los puertos del mismo modo que los volúmenes nuestra_maquina:contenedor y le decimos a Docker que todo el tráfico del puerto 80 del contenedor nos lo deje ver por el puerto 8000 de nuestra máquina.
Archivo .env
Antes hemos comentado la importancia de mantener una integridad con los nombres de servicios y contenedores, bien, para hacer esto más llevadero y seguro, utilizaremos el archivo .env para definir variables de entorno que podremos utilizar en el archivo docker-compose.
Creamos el archivo en la raíz de nuestro proyecto:
Date cuenta que he metido en el archivo todas las variables que voy a utilizar en el proyecto separadas por servicios. Bien, ahora vamos a utilizar las variables PROJECT_NAME y NGINX_HTTP_PORT para reemplazarlas por los valores correspondientes en el docker-compose, quedando así el servicio de nginx:
Tal y como hemos hecho para la compilación de imagen el servicio de nginx, creamos una carpeta llamada php con un fichero Dockerfile que tenga la siguiente información:
FROM php:7.3-fpm
RUN docker-php-ext-install mysqli
En este caso vamos a instalar una imagen de PHP-FMP en su versión 7.3, y a parte instalamos la extensión mysqli de Docker para que esté disponible en el momento de crearse el contenedor de PHP.
Bien, con estos dos servicios creados ya tendríamos un servidor web capaz de interpretar php, pero aún nos falta decirle a nginx qué contenedor va a ser el encargado de procesar php. Esto lo conseguimos con un archivo de configuración para Nginx, crea una carpeta llamada conf en la carpeta nginx que has creado antes.
Dentro de conf, crea el archivo default.conf con este contenido:
No quiero profundizar en la confección del archivo de configuración para nginx ya que puede variar dependiendo de las necesidades del proyecto, pero sí que quiero que te fijes en el parámetro fastcgi_pass que apunta a dockerwp_php por el puerto 9000, así es cómo estamos estableciendo la comunicación entre estos dos contenedores.
Ahora sólo nos queda mapear en la sección de volúmenes del servicio de nginx el archivo de configuración para que esté disponible cuando arranque el contenedor, quedando el servicio de la siguiente forma:
Ok, seguro que te has dado cuenta y dirás: Ey! ¿Qué demonios es eso de depends_on? Con esta directiva hacemos este servicio dependiente de otros, es decir, si esos servicios de los que depende no están definidos, el proyecto dará error.
Muy bien, llegados a este punto, nuestro docker-compose debe verse así:
En este servicio vas a ver un par de secciones que no hemos visto en los anteriores, y son:
image: Este parámetro sirve para , en vez de con build, descargar la imagen directamente de Docker Hub
environment: Aquí es donde definimos variables de entorno que pasan al contenedor en el momento de crearse necesarias para su configuración.
Fíjate que este servicio crea un volumen llamado db, ahí es donde persiste la base de datos para no perderla cuando se borren los contenedores.
Servicio para PHP Myadmin
Este servicio no es necesario para que funcione el proyecto pero lo añadimos por si tenemos que hacer algún cambio en Base de datos y no hacerlo desde la consola.
Date cuenta que le pasamos una variable de entorno con el nombre del servicio de la base de datos: dockerwp_db.
Vuelve a detener y borrar los contenedores que estén corriendo y levanta el stack de nuevo con docker-compose up –build, pero ahora accede a localhost con el puerto 8002 (es el que hay definido en el .env):
Estamos en la página de phpMyAdmin, donde podemos ver el nombre del servidor Mariadb y la base de datos que utilizaremos.
Como sabes, estos datos son necesarios para la instalación de WordPress, donde el servidor de bases de datos es el servicio que hemos definido en el docker-compose y el nombre de base de datos lo definimos en el .env y lo pasamos como variable de entorno.
Instalando WordPress
Ya tenemos el entorno listo para trabajar WordPress, así que consigue un zip con la última versión de WordPress y lo descomprimes en la carpeta www/ de la raíz del proyecto, acto seguido accede a http://localhost:8000:
Los datos que introducimos en esta parte de la instalación para que WordPress pueda conectar con la base de datos los cogemos de:
Servidor de base de datos: El nombre del servicio de base de datos que hemos definido en el docker-compose
Nombre de BD, usuario y contraseña: Son las que definimos en el .env
Prefijo de tabla: Esto se define en esta misma pantalla, asegúrate de cambiarlo por seguridad. Quién sabe si esta base de datos llega a producción 🙂
Completa la instalación con los datos necesarios y ya lo tienes:
Conslusión
Como has visto, es muy fácil crear proyectos de WordPress con Docker, y una de las ventajas que tiene trabajar de esta manera es que tenemos un entorno para este proyecto aislado de otros proyectos.
Podemos montar un stack de tecnologías según las necesidades (en este caso de WordPress) sin depender de un servidor que sirve a otros proyectos, por lo tanto es más fácil instalar dependencias y cambiar versiones que en un servidor web convencional.
Código realizado en el post
Te dejo un enlace al repositorio con el código completo: