Instalar WordPress en un VPS mediante Docker

En este artículo te voy a explicar como puedes montar una o varias páginas webs en WordPress en un VPS no administrado.

A diferencia de este otro artículo que explico cómo montarlo instalando con Nginx y MySQL, en esta ocasión vamos a ver cómo hacerlo mediante Docker.

Usar Docker tiene varias ventajas, como la rapidez para crear una nueva instalación de WordPress. Tan solo necesitas un archivo de configuración.

Además, también te ofrece mayor seguridad, ya que tus instalaciones están aisladas unas de otras mediante contenedores.

Para este proceso vamos a utilizar la consola de comandos. No necesitas conocimientos, solo copiar y pegar comandos.

Lo que sí necesitas es un acceso al servidor por SSH. Si no lo tienes, en el panel de tu proveedor podrás encontrarlo.

¿Aún no tienes un VPS? Mira nuestra guía: Montar un VPS paso a paso

Instalar Docker

El primer paso será instalar Docker. Con estos dos comandos lo tenemos:

sudo apt install curl
sudo /bin/bash -c "$(curl -fsSL https://get.docker.com)"

Instalar Docker Compose

Docker Compose es una herramienta para definir y ejecutar aplicaciones de Docker de manera eficiente. Nos simplifica la manera de trabajar con los contenedores de Docker.

Para asegurarnos que instalamos la última versión, vamos a descargarla desde el repositorio oficial de Github. En el momento de escribir este artículo es la 2.14.0.

Lo descargamos y almacenamos en ~/.docker/cli-plugins/.

mkdir -p ~/.docker/cli-plugins/
curl -SL https://github.com/docker/compose/releases/download/v2.14.0/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose

Ahora asignamos los permisos para hacer ejecutable el archivo descargado.

chmod +x ~/.docker/cli-plugins/docker-compose

Y verificamos la instalación con este comando:

docker compose version

Debe aparecerte un mensaje como este:

Comando para comprobar la versión de Docker Compose instalada

Crear proxy inverso con Nginx

Nginx es un servidor web y un proxy inverso de alto rendimiento. Se utiliza a menudo para manejar cargas altas de tráfico en sitios web y aplicaciones en línea. Nginx es conocido por su facilidad de uso y su capacidad para manejar miles de solicitudes simultáneamente de manera eficiente.

En este caso Nginx lo vamos a utilizar como proxy inverso. Este se va a encargar de gestionar el tráfico que llegue al VPS y mandarlo al contenedor de Docker que corresponda.

Por ejemplo, si solicitamos la URL dominio1.com. El proxy inverso se encargará de mandarlo al contenedor que corresponda, en este caso el Contenedor1, siguiendo el siguiente esquema:

En lugar de montar nosotros el servidor Nginx y configurarlo, vamos a utilizar una imagen de Docker ya preparada específicamente para esto.

En términos simples, una imagen de Docker es un archivo que contiene todo lo necesario para ejecutar una aplicación en un contenedor de Docker. Estas imágenes suelen incluir el código de la aplicación, así como todas las dependencias y librerías necesarias para que la aplicación funcione.

La imagen que vamos a utilizar es Nginx Proxy Manager. Entre otra muchas cosas, viene con un panel de administración desde el cual podremos instalar los certificados SSL con un clic.

Vamos con la instalación.

Para ser ordenados, vamos a crear una carpeta para organizar los archivos de Nginx Proxy Manager.

mkdir nginx-proxy-manager && cd nginx-proxy-manager

Ahora crearemos el archivo de configuración de Docker Compose para Nginx Proxy Manager.

nano docker-compose.yml

Y pegamos el siguiente texto:

version: '3'
services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: unless-stopped
    ports:
      - '80:80'
      - '81:81'
      - '443:443'
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt

Con Ctrl + O guardamos. Pulsa a Enter. Y Ctrl + S para salir.

Ya tenemos el proxy montado, lo ejecutamos con el siguiente comando:

sudo docker compose up -d

La primera vez es algo lento porque tiene que descargar la imagen de internet.

Ahora podemos verificar que tenemos un contenedor corriendo:

sudo docker ps
Contenedor Nginx Proxy Manager corriendo en Ubuntu

Si pones la IP de tu servidor en el navegador, verás que ya tienes el servidor Nginx corriendo.

👉  Solucionar el error: pyrsistent requires Python '>=3.5' but the running Python is 2.7.17
Pantalla de bienvenida de Nginx Proxy Manager

Si entras por el puerto 81, accederás al panel de administración (ej.: 220.25.264.25:81).

Pantalla de login de Nginx Proxy Manager
Pantalla de login de Nginx Proxy Manager

Utiliza las siguientes credenciales por defecto para entrar:

Email: admin@example.com
Password: changeme

Cuando accedas te pedirá que las cambies.

Panel de administración de Nginx Proxy Manager

Ya que tenemos listo el proxy inverso, vamos con la instalación de WordPress.

Instalación de WordPress

Para instalar WordPress utilizaremos una imagen de Docker ya configurada, en lugar de nosotros tener que configurarlo todo. Lo mismo que hemos hecho con el proxy inverso.

De nuevo, para ser ordenados, creamos un directorio para todas las webs y dentro crearemos un directorio por cada sitio web diferente. Sustituye dominio1.com por el que te corresponda.

cd ~ 
mkdir -p webs/dominio1.com
cd webs/dominio1.com

Ahora creamos el archivo docker-compose.yml correspondiente.

nano docker-compose.yml

Y añadimos el siguiente contenido:

version: '3.1'

services:

  wordpress:
    image: wordpress:latest
    depends_on:
      - db
    restart: always
    ports:
      - 8080:80
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: exampleuser
      WORDPRESS_DB_PASSWORD: examplepass
      WORDPRESS_DB_NAME: exampledb
    volumes:
      - wordpress:/var/www/html

  db:
    image: mysql:latest
    restart: always
    environment:
      MYSQL_DATABASE: exampledb
      MYSQL_USER: exampleuser
      MYSQL_PASSWORD: examplepass
      MYSQL_RANDOM_ROOT_PASSWORD: '1'
    volumes:
      - db:/var/lib/mysql

volumes:
  wordpress:
  db:

Te recomiendo cambiar el usuario y contraseña que aparecen en el archivo de configuración. WORDPRESS_DB_USER debe ser igual que MYSQL_USER y WORDPRESS_DB_PASSWORD igual que MYSQL_PASSWORD.

Sin entrar en muchos detalles, lo que estamos definiendo en el archivo son dos servicios. Uno que se encargará de ejecutar el contenedor que tendrá WordPress y otro que alojará la base de datos (MySQL) que necesita WordPress para funcionar.

Levantamos los contenedores:

sudo docker compose up -d

Vamos a ver si se están ejecutando con:

sudo docker ps

Verás que ahora hay dos nuevos contenedores corriendo.

Ahora, si accedes desde el navegador la IP del servidor seguida del puerto 8080 (así lo hemos definido en el docker-compose.yml), verás página de instalación de WordPress.

Pero antes de instalar WordPress, vamos a apuntar el dominio al contenedor de Docker.

Página de instalación de WordPress

Como no queremos acceder a nuestra web a través de la IP, vamos a configurar el dominio que le corresponde en el panel de Nginx Proxy Manager.

Antes de nada, deberás haber apuntado tu dominio al servidor VPS. Para ello debes añadir un registro A a tus DNS con la IP de tu servidor.

Accedemos al panel y vamos a Hosts -> Proxy Host -> Add Proxy Host.

Introducimos los datos como en la siguiente imagen. Cambiando dominio1.com por el que te corresponda. Y XXX.XX.XX.XXX por la IP de tu servidor. Asegúrate de que el resto de campos están igual que en la imagen.

Panel para añadir nuevo proxy host en Nginx Proxy Manager.
Añadir nuevo proxy host en Nginx Proxy Manager.

A continuación nos vamos a la pestaña SSL para emitir un certificado.

Introduce tu correo y guarda.

Panel para emitir crear un certificado SSL en Nginx Proxy Manager.

Ahora ya podemos acceder a nuestra web mediante el nombre de dominio. Si lo escribes en el navegador, deberá aparecerte el asistente de instalación de WordPress.

Con esto ya estaría. Ya tenemos nuestra web WordPress corriendo en el VPS con un dominio personalizado y con certificado SSL.

Si quisieras añadir una nueva web, tan solo tendría que repetir el paso de Instalación de WordPress.

La primera vez que lo haces parece un poco tedioso y complejo, pero cuando lo tienes ya todo montado, instalar un nuevo WordPress son 2 pasos:

  • Crear archivo de configuración docker-compose.yml
  • Dar de alta el dominio en el panel de Nginx Proxy Manager

También puedes añadir cualquier otro CMS o aplicación a tu VPS, no solo WordPress. Echa un vistazo a este tutorial sobre cómo instalar n8n en un VPS, quizá te interese.

Espero que el tutorial te haya servido de ayuda. Cualquier duda puedes dejarla en los comentarios.

Problemas comunes

En esta sección iré añadiendo problema comunes que me vaya encontrando en la instalación de WordPress en el VPS.

Aumentar el tamaño máximo de subida de archivo

Si tratas de subir a tu WP un archivo superior a 2 MB verás que obtienes un error. Esto es porque por defecto, el tamaño máximo de subida de archivo está limitado a este valor. Vamos a ver cómo podemos aumentarlo.

👉  Nameservers de Cloudflare

En primer lugar, creamos un nuevo archivo uploads.ini junto al docker-compose.yml de la instalación de WordPress.

nano uploads.ini

Añadimos este contenido y guardamos.

file_uploads = On
memory_limit = 512M
upload_max_filesize = 512M
post_max_size = 512M
max_execution_time = 600

En este caso estamos asignando un valor de 512 MB. Puedes modificar este valor con el que consideres.

Ahora solo nos queda decirle a WordPress que utilice esta nueva configuración. Para ello, añadimos una nueva línea al archivo docker-compose.yml en la etiqueta volumes, quedándonos así:

volumes:
      - wordpress:/var/www/html
      - ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini

Ahora solo tenemos que reiniciar el contenedor y ya tendremos los cambios aplicados.

sudo docker compose stop
sudo docker compose up -d

Desde la página Salud del Sitio de WP /wp-admin/site-health.php, puedes verificar que los cambios se han aplicado correctamente.

Copiar un archivo en el directorio de WordPress

Seguramente te surja la necesidad de subir un archivo al directorio donde está instalado WordPress. Esto puede ocurrir por ejemplo si queremos verificar la propiedad del dominio en Search Console mediante el archivo HTML que nos proporciona.

Hay muchas formas de hacer esto. La que vamos a ver es para un caso puntual. Si necesitas constantemente copiar archivos en tu instalación de WordPress y acceder a ellos, hay opciones mucho más óptimas.

En primer lugar subimos el archivo al servidor mediante el comando SCP.

scp archivo-a-copiar.html usuario@XXX.XX.XX.XXX:~

Nos cambiamos al usuario root para poder escribir el archivo en la instalación de WordPress.

sudo su

Ahora necesitamos copiar el archivo en el volumen de Docker que corresponde.

Los volúmenes de Docker los tenemos en el directorio /var/lib/docker/volumes/.

En ese directorio tendrás una carpeta para tu instalación de WordPress según el nombre que le pusiste al directorio que creamos en el paso instalación de WordPress. En mi caso yo tengo la carpeta dominio1com_wordpress.

Estando situados en el directorio del archivo subido, finalmente copiamos el archivo al destino:

mv ./archivo-a-copiar.html /var/lib/docker/volumes/dominio1com_wordpress/_data/

Instalar extensión SOAP de PHP

La imagen de WordPress que hemos utilizado para montar nuestra web no viene con SOAP habilitado.

Esta extensión de PHP es necesaria para el funcionamiento de algunos plugins como el archiconocido AAWP.

Para habilitarla podríamos entrar en el contendor de nuestro WordPress, instalarla con apt-get y habilitarla en el archivo php.ini. El problema de esto es que los cambios se perderían si paramos e iniciamos el contendor.

Para que los cambios sean persistentes, tenemos que crear una nueva imagen a partir de la ya existente y añadirle la extensión SOAP.

Esto puede parecer muy complicado, pero apenas son unas líneas de código que solo tienes que copiar y pegar. ¡Vamos a ello!

En primer lugar crearemos un archivo Dockerfile (sin extensión) en la misma ubicación que tenemos el docker-compose.yml.

FROM wordpress:latest

ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/

RUN chmod +x /usr/local/bin/install-php-extensions && \
    install-php-extensions soap

Lo que hacemos con este código es crear una imagen personalizada a partir de una ya existente. Usamos como base la última imagen oficial de WP (wordpress:latest).

Después instalamos y habilitamos SOAP en nuestra nueva imagen. Esto se puede hacer de muchas maneras, pero lo he simplificado usando un script de Github que ya está preparado para esto.

Si quisiera instalar otra extensión, cambia en la última línea «soap» por la extensión que necesites. Consulta aquí todas las extensiones que soporta dicho script.

Por último necesitamos usar la imagen creada. Para ello modificamos el archivo docker-compose.yml y lo sustituimos por este.

version: '3.1'

services:

  wordpress:
    build: .
    depends_on:
      - db
    restart: always
    ports:
      - 8080:80
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: exampleuser
      WORDPRESS_DB_PASSWORD: examplepass
      WORDPRESS_DB_NAME: exampledb
    volumes:
      - wordpress:/var/www/html

  db:
    image: mysql:latest
    restart: always
    environment:
      MYSQL_DATABASE: exampledb
      MYSQL_USER: exampleuser
      MYSQL_PASSWORD: examplepass
      MYSQL_RANDOM_ROOT_PASSWORD: '1'
    volumes:
      - db:/var/lib/mysql

volumes:
  wordpress:
  db:

Si te fijas, el único cambio está en la línea 6, donde hemos reemplazado «image: wordpress:latest» por «build: .». Esto le indica que construya una imagen a partir del directorio actual. Para ello utilizará el archivo Dockerfile que creamos anteriormente.

Ahora solo queda detener e iniciar de nuevo el contendor y ya tendremos el servidor de WP con SOAP habilitado.

sudo docker compose stop
sudo docker compose up -d

👇Tu comentario