Whale Tale, by Abigail Lynn

¡Feliz año nuevo, querido lector! Espero que hayas pasado unas fantásticas navidades y que la resaca de hoy no sea demasiado dura. Yo, por mi parte, he decidido empezar el año con fuerza y traerte lo que hace unas semanas os prometí por Twitter: un tutorial para desarrollar en WordPress con Docker.

Y es que después de haber usado el típico LAMP (Linux + Apache + MySQL + PHP) y estar harto de pelearme con configuraciones y tener todas las instalaciones conviviendo y compartiendo recursos; después de haber probado Vagrant y haber sufrido su lentitud (supongo que ejecutarlo sobre Virtual Box en un ordenador que pronto cumplirá los 6 añitos no es la mejor idea); después de ver cómo Antonio disfruta desarrollando con Local by Flywheel mientras a mí me tocaba esperar a que se dignaran a sacar una versión para Linux… Después de todas estas penas, decidí que ya había llegado el momento de aprender cómo funciona Docker y cómo montar entornos de desarrollo rápidos, cómodos y multiplataforma con él.

Si quieres aprender un poquito sobre Docker y quieres poder usarlo en tu día a día, sigue leyendo. Te recomiendo que leas toda la entrada, porque no es hasta el final de la misma donde te explicaré cómo uso yo Docker exactamente. ¡Vamos allá!

Docker

Docker es un programa que permite empaquetar software en «contenedores» y ejecutarlos encima de máquinas virtuales. Hasta aquí, no difiere mucho de otras soluciones como Vagrant. La ventaja de esta forma de proceder (la cual podríamos comparar con, por ejemplo, el clásico LAMP o MAMP o WAMP) es que los contenedores se ejecutan en entornos aislados, de tal forma que:

  • un contenedor no puede, en principio, acceder a otro, lo cual aumenta la seguridad del sistema,
  • todas las herramientas, librerías, ficheros de configuración, etc. que necesita el contenedor para funcionar están empaquetados en él mismo, con lo que no «ensucian» nuestro ordenador con software innecesario ni aparecen incompatibilidades entre ellos.

En mi opinión, la ventaja de Docker sobre otros softwares para ejecutar contenedores es que por defecto usa runC como entorno de virtualización, con lo que todo el software que se ejecuta en el contenedor es gestionado por el sistema operativo del anfitrión. En otras palabras, se comparten un montón de recursos entre el anfitrión (nuestro ordenador) y el huésped (el contenedor que ejecutamos) y, por lo tanto, todo es mucho más rápido y eficiente. Ideal para un ordenador de 2013 como el mío ?

Instalación de Docker

Para instalar Docker en Linux (Debian/Ubuntu), lo único que tenemos que hacer es ejecutar el siguiente comando en una consola:

y esperar a que acabe el proceso.

Un pequeño inconveniente de Docker es que, por defecto, para poder usarlo deberás ejecutarlo con permisos de administrador usando sudo. Pero, tal y como nos cuentan en la propia documentación del proyecto, basta con que añadamos nuestro usuario en el grupo docker para no tener que usar sudo cada vez:

cambiando your-user por el nombre de tu usuario (usuario del sistema operativo, ¿eh?). Por cierto, es posible que tengas que cerrar tu sesión en el sistema operativo y volver a iniciarla para que te aparezca el nuevo grupo y puedas usar docker sin sudo.

Cómo instalarlo en Mac o en Windows

Si estás usando alguno de estos otros dos sistemas operativos, aquí te dejo un par de enlaces sobre cómo instalarlo en ellos:

Cómo usar Docker

Vale, ahora que ya tenemos Docker en nuestro ordenador instalado y listo para ser usado es el momento de probarlo. Como te decía, Docker es una herramienta que nos permite lanzar aplicaciones empaquetadas en contenedores. Para ello, deberemos ejecutar el siguiente comando desde un terminal:

Por ejemplo, el primer comando que podemos ejecutar es:

para ver la aplicación clásica de «Hola Mundo» ejecutándose dentro de un contenedor Docker. Si echamos un vistazo a la salida que vemos por terminal, lo primero que veremos es esto:

Lo que nos está diciendo esto es que no teníamos ningún contenedor llamado hello-world en local y, por lo tanto, Docker ha dado por sentado que tenía que ir a buscarlo al repositorio de contenedores que tiene, decargarlo y montarlo en local para ejecutarlo. Y con esto descubrimos uno de los primeros aspectos interesantes de Docker: existe un repositorio de contenedores que podemos usar, parecido a los directorios de plugins o temas que tenemos en WordPress.

Finalmente, vemos que el resto de la salida que tenemos en nuestro terminal es:

el cual se corresponde a la ejecución en sí del contenedor «Hola Mundo». Y si ahora volviéramos a ejecutar el comando anterior, veríamos únicamente el resultado del contenedor (nos ahorraríamos la parte de descargarlo, vaya).

Y esto es así porque, aunque no lo veamos, el contenedor está instalado y configurado en Docker. Si ejecutamos:

veremos cómo aparece creado el contenedor que acabamos de descargarnos y ejecutar (y que, por cierto, ya no está en ejecución):

Para borrarlo, basta con ejecutar:

y listo. Por cierto, fíjate que el numerito que he puesto se corresponde con el CONTAINER ID del contenedor.

Entonces, ahora que ya entiendes un poco cómo funciona Docker, vamos a ver qué es Docker Compose y por qué vamos a usarlo con WordPress.

Docker Compose

Como puedes imaginar, en el repositorio de contenedores de Docker existe un contenedor (varios, de hecho) de WordPress. Dicho contenedor tiene varios inconvenientes:

  • Por un lado, con él sólo no podremos ejecutar WordPress, ya que no incluye la base de datos. Así que si queremos usar WordPress debemos tener corriendo una base de datos en nuestro propio ordenador, en otra máquina o, ¿cómo no?, en otro contenedor.
  • Por otro lado, el contenedor de WordPress dispone de varios parámetros de configuración que debemos especificar para que funcione (por ejemplo, dónde está la base de datos y qué credenciales usar para conectarse a ella).

Gestionar docker a pelo es un poco tedioso: tienes que levantar los contenedores en orden, meter los parámetros de configuración por línea de comandos, etc. Por suerte, existe una herramienta llamada docker-compose que nos permite crear un fichero de configuración con todos los contenedores que queremos levantar, establecer las dependencias entre ellos y configurarlos individualmente. Veamos un ejemplo sencillo.

Empecemos por crear un directorio vacío donde meter el fichero de configuración. Por ejemplo, crea el directorio ~/docker/test y añade un fichero de texto plano llamado docker-compose.yml con el siguiente contenido:

No te asustes, que se trata de un fichero muy sencillo. Fíjate bien. En él definimos dos servicios: mysql y wordpress. En el primer servicio (mysql) indicamos la imagen que queremos descargarnos (un MySQL versión 5.7) y algunos parámetros de configuración. Los más relevantes son la redirección de puertos (del 8081 del anfitrión al 3306 del huésped) y parámetros de la base de datos en sí (usuario, contraseña, etc).

El segundo servicio es WordPress (wordpress) y sigue un patrón parecido. Aquí, por ejemplo, indicamos que queremos usar el puerto 8080 para acceder a nuestro WordPress. También especificamos que mysql es una dependencia de WordPress (este contenedor no puede funcionar sin el otro). Y también indicamos parámetros adicionales como, por ejemplo, dónde está la base de datos y cómo acceder a ella.

Una vez tenemos el fichero listo, ejecutamos:

y Docker se descargará las imágenes de WordPress y MySQL (si no las tenemos ya) y pondrá en marcha nuestro WordPress.

Cuando esté listo (dale un momento, porque a veces tarda un poco en tenerlo todo en marcha), podremos ir a nuestro navegador web y en la dirección http://localhost:8080 (fíjate que es el mismo puerto que hemos puesto en el fichero de configuración) encontraremos nuestro WordPress esperándonos para completar su instalación:

Instalar WordPress en un contenedor Docker
Instalar WordPress en un contenedor Docker.

A partir de este punto, si quieres nuevos WordPress en paralelo, sencillamente tendrías que repetir el proceso. Es decir, creas un nuevo directorio en ~/docker/, añades el fichero docker-compose.yml, cambias los puertos para acceder a él (por ejemplo, 8082 para WordPress y 8083 para MySQL) para que no colisione con el contenedor que ya tenemos en marcha y lo pones a correr también.

Cuando acabes de trabajar, puedes ejecutar:

para detener la instancia. ¡Cuidado! Si en lugar de stop usaras down:

también detendrías la instancia pero, además, se eliminaría, con lo que la próxima vez que hicieras el docker-compose up empezaría todo el proceso de cero (base de datos vacía, WordPress sin instalar, etc).

Docker y el desarrollo en WordPress

Llegados a este punto, ya casi tienes todo lo necesario para desarrollar un plugin o un tema WordPress con Docker. Espero que las explicaciones que te he dado hasta aquí te hayan ayudado a entender un poco mejor cómo funciona Docker.

Ahora, pues, es hora de que te presente exactamente la configuración que uso yo para desarrollar en WordPress con Docker. En concreto, se trata de una configuración que soluciona los dos únicos puntos que quedan por tratar:

  • ¿Cómo puedo hacer que el proyecto en el que estoy trabajando esté dentro del contenedor Docker?
  • ¿Puedo usar nombres de dominio del tipo http://content.local en lugar de http://localhost:puerto con Docker?

Pues vamos a responder estas dos cuestiones y, ahora sí, ya tendrás todos los ingredientes para crear entornos de desarrollo WordPress en Docker como un campeón.

Cómo meter mi proyecto dentro de Docker

En mi caso, cuando monto un entorno de desarrollo en WordPress es para desarrollar un nuevo plugin. En este caso, lo que a mí me gustaría es que mi plugin estuviera dentro de la carpeta wp-content/plugins/ del entorno de desarrollo. Por desgracia, aún no hemos visto cómo hacer que el directorio (que, recordemos, está dentro del contenedor huésped) esté visible desde el sistema de archivos de mi ordenador anfitrión.

Aunque hay varias opciones sobre qué contenidos del contenedor están mapeados a una carpeta de mi ordenador (que los tengo disponibles, vaya), la que más me gusta a mí es la que mapea la carpeta de mi plugin a una carpeta del plugin dentro del contenedor. Veamos cómo lograrlo.

Supongamos que estoy desarrollando mi plugin en ~/dev/nelio-content/. Como quiero poder usar mi plugin Nelio Content en un entorno de desarrollo Docker, lo primero que haré será añadir el ya famoso fichero docker-compose.yml con todo lo que hemos visto hasta ahora. Pero ojo, esta vez tendrá algún parámetro de configuración extra:

¿Ves cuál es la diferencia? Sencillamente he añadido una nueva opción en el servicio WordPress llamada volumes en la que le digo el directorio actual (identificado por el punto .) lo tienes que mapear (indicado por los dos puntos :) al directorio /var/www/html/wp-content/plugins/nelio-content (que es donde está instalado WordPress, seguido de wp-content/plugins/ y seguido del nombre de mi propio plugin). Fíjate que la sintaxis es la misma que cuando mapeábamos los puertos.

Y ya está, haciendo esto conseguimos que nuestro plugin aparezca dentro del WordPress que acabamos de «crear». Yendo al Escritorio » Plugins podemos activarlo y ver qué tal funciona en un entorno seguro y aislado.

Cómo usar nombres de dominio

Entrar en las instalaciones de desarollo usando localhost y números de puerto es bastante pesado; es muchísimo más cómo usar un nombre de dominio del tipo http://content.local. Para ello necesitaremos realizar algunos pasos extra, pero una vez lo tengas montado ya todo será muy sencillo.

Lo primero que necesitamos es decirle al ordenador que un cierto nombre de dominio (por ejemplo, content.local) está en el propio ordenador. Para ello, editamos el fichero /etc/hosts (como sudo) y añadimos la línea que indica esto:

A continuación necesitamos un proxy que sepa que cuando nos llega una petición a http://content.local, queremos que sea atendida por http://localhost:8080. Esto es muy sencillo de montar (en serio). Sencillamente crea una nueva carpeta ~/docker/proxy con el siguiente fichero de configuración docker-compose.yml:

A continuación, ejecuta docker network create proxy y pon en marcha el nuevo contenedor con docker-compose up -d. Esto creará una nueva red que todos nuestros proyectos usarán (en un par de párrafos te explico qué es esto) y pondrá en marcha el contenedor que traduce nombres bonitos a localhost con puerto.

Finalmente, lo único que tenemos que hacer es modificar la configuración de nuestro proyecto (el que habíamos creado en el apartado anterior) para que, cuando se ponga en marcha, avise a nuestro proxy de que está disponible para atender peticiones y bajo qué dominio lo va a hacer:

Soy consciente de que parece un poco magia negra, pero no lo es. Si te fijas, lo único que hemos añadido en nuestro Docker son las siguientes cosas:

  • En la configuración de WordPress, en el apartado environment, hemos añadido dos nuevos parámetros: VIRTUAL_HOST y VIRTUAL_PORT. Estos dos atributos son los que se le pasarán al contenedor del proxy para que se pueda auto-configurar y sepa que las peticiones a http://content.local tienen que ir a http://localhost:8080.
  • Como queremos que WordPress pueda comunicarse con el proxy, tenemos que meter a los dos en la misma red. Esto lo hacemos metiendo la opción networks en el servicio WordPress e indicando que WordPress está en la red llamada frontend (podría haberle puesto el nombre que me diera la gana). Por otro lado, al final del documento docker-compose.yml especificamos que dicha red es externa y su nombre (proxy), lo cual se corresponde con la red que habíamos metido en el contenedor que hemos creado en ~/docker/proxy y que hemos llamado proxy.
  • Finalmente, metemos a la base de datos y al propio WordPress en otra red privada para ellos dos, que hemos llamado backend. Esto permite que WordPress se comunique con MySQL pero que nadie se meta en medio.

¡Y eso es todo! Espero que te haya gustado la entrada de hoy y, si tienes cualquier duda o te atascas en cualquier punto, aproveches la sección de comentarios para preguntar.

Imagen destacada de Abigail Lynn.

66 respuestas a «Cómo usar Docker para desarrollar en WordPress»

  1. Avatar de Nicolas
    Nicolas

    Buenas David, te comento mi problema, segui paso a paso la guia para poder levantar un sitio WordPress que ya tenia en funcionamiento por lo que agregue el sitio entero en el volumen del container `wordpress`:

    `- .:/var/www/html/`

    Pero al momento de probar tengo el siguiente problema, tenes idea que me esta faltando?

    Warning: require_once(/var/www/html/wp-config.php): failed to open stream: Permission denied in /var/www/html/wp-load.php on line 37

    Fatal error: require_once(): Failed opening required ‘/var/www/html/wp-config.php’ (include_path=’.:/usr/local/lib/php’) in /var/www/html/wp-load.php on line 37

    OS: Mac OS
    Docker version 18.09.0, build 4d60db4
    docker-compose version 1.23.2, build 1110ad01

    Gracias!

    1. Avatar de David Aguilera

      Hola Nicolas,

      Si te he entendido bien, estás metiendo el docker-compose.yml directamente en la raíz de un proyecto WordPress que ya existía. En general, esto no lo recomendaría, porque ahora estás cargando la configuración que ya tenías del WordPress anterior a tu Docker… y además hay problemas de permisos: estás importando en Docker un sistema de ficheros que tiene un propietario (tú) con unos ciertos permisos, pero dentro de Docker ese usuario no existe y se usa uno diferente para el servidor. En fin, que te recomiendo que sigas la guía tal cual o que montes los plugins/temas que quieras uno a uno (añadiendo más líneas en la sección de volumes).

      Un saludo,
      David

  2. Avatar de Darwel
    Darwel

    Hola David, muy sencillo y practico tu post. Pero tengo dudas al respecto de como funciona el contenedor wordpress porque pensé que al usar un dns no habría necesidad de usar puertos en la dirección final de dasarrollo, pero la url queda de la siguiente forma http://content.local:8080 en vez de http://content.local

    1. Avatar de David Aguilera

      Gracias, Darwel; me alegra saber que mi entrada te pudo ayudar.

      En cuanto al tema de los puertos, como te comento necesitas instalar y arrancar una segunda imagen de Docker (la que comento justo al final de mi entrada jwilder/nginx-proxy), que es la que se encarga de hacer la traducción de un nombre de dominio (ejemplo, content.local) a otra máquina y puerto (localhost:8080). Si no hace el paso de arrancar esa imagen y enlazar tu imagen de WordPress con ella, lo único que estarás haciendo es crear un alias de localhost. Presta especial atención a la última sección de la entrada y asegúrate de tener todo el entorno bien montado.

      Ya me dirás qué tal.

      Un saludo,
      David

  3. Avatar de Antonio
    Antonio

    Enhorabuena por el post, sencillo y práctico. Siempre me había parecido un poco engorroso docker pero con este tuto (el cual me guardo en favoritos) parece hasta fácil.

    Para sacar nota, entiendo que al igual que haces con el plugin, podría hacerse con themes, pero, aquí parece que lo haces copiando de local al entorno generando en docker. ¿Podría hacerse haciendo checkout de un repo en git?

    Saludos

    1. Avatar de David Aguilera

      Gracias, Antonio. Me alegra saber que te gusta el tutorial 😉 Y sí, lo que explico es totalmente aplicable a temas.

      En cuanto a lo que preguntas sobre Git… no sé si te entiendo mucho. El proyecto con el que trabajas (ya sea un tema o un plugin) es lo que, obviamente, tienes controlado en el Git. Hasta ahí todo es como siempre: haces pull, aplicas cambios, commit y push. La única diferencia es que tu proyecto incluye un fichero docker-compose.yml que te permite arrancar un contenedor docker con una instancia de WordPress que incluirá tu proyecto. ¿Se entiende?

      Un saludo,
      David

  4. Avatar de Sergio
    Sergio

    Hola, buenas, muchas gracias por este tutorial, pero hay alguna forma de acceder a los archivos creados con el wordpress de manera local.

    También me ha surgido un problema al seguir este tutorial, cuando he intentado apagar los contenedores, no me deja hacerlo y intentando realizar ideas mías, he acabo desinstalando docker y aun así, cuando me conecto al puerto 8080 de localhost, aparece aun el wordpress, cuando no tengo ni siquiera docker instalado. Todo esto lo estoy haciendo sobre una maquina virtual de ubuntu, no me genera muchos problemas ya que he creado otra maquina, pero en la maquina que empecé inicialmente, el puerto 8080 siempre esta conectado al wordpress y no soy capaz de quitarlo.

    Un saludo

    1. Avatar de David Aguilera

      Hola Sergio,

      hay alguna forma de acceder a los archivos creados con el wordpress de manera local

      Sí, claro. Lo más sencillo es poniendo la directiva volumes y mapeando los directorios que te interesen de una máquina a otra. En el tutorial yo explico cómo mapear un plugin en concreto, pero en principio puedes mapear cualquier cosa, incluso la raíz del propio WordPress. Ahora bien, si optas por ello, puedes tener problemas con los permisos de usuario, porque el propietario del directorio de WordPress en Docker puede tener un UID y GID diferentes al de tu usuario en la máquina host.

      cuando he intentado apagar los contenedores, no me deja hacerlo

      Si lo has creado con docker-compose, basta con ejecutar un docker-compose stop desde el directorio donde has iniciado el contenedor. Otra opción es hacer un docker ps para ver todos los contenedores que hay en marcha y pararlos uno a uno con un docker stop {ID_CONTENEDOR}.

  5. Avatar de Elías
    Elías

    Excelente post,

    tengo un problema al momento de levantar el docker del proxy:

    MacBook-Pro-de-Elias:proxy eliasbg$ docker-compose up -d
    Pulling nginx-proxy (jwilder/nginx-proxy:)…
    latest: Pulling from jwilder/nginx-proxy
    a5a6f2f73cd8: Pull complete
    2343eb083a4e: Pull complete
    251439d5b33c: Pull complete
    0150289a3195: Pull complete
    196dcbce1a9b: Pull complete
    8826dc3389ea: Pull complete
    c7a4bc596c6f: Pull complete
    8000a1ad9fc5: Pull complete
    3bea426c29a7: Pull complete
    8378fe8463bb: Pull complete
    ERROR: error pulling image configuration: unexpected EOF

    ¿A qué crees que se deba?

    Gracias por la ayuda de antemano.

    1. Avatar de David Aguilera

      Pues vaya, no sé qué puede pasar. Quizás sea un problema con la versión de docker que tienes en el mac… Prueba con un docker pull jwilder/nginx-proxy y a ver si hay más suerte.

  6. Avatar de ffuentes
    ffuentes

    Un lifehack para que no tengas que cerrar y abrir la sesión cuando agregas a un grupo un usuario. Ejecuta «exec bash» si usas bash o «exec zsh» si usas zsh como yo. Básicamente «exec <nombre_de_la_shell_que_uses".

    Saludos

    1. Avatar de David Aguilera

      Muchas gracias por el tip! Aunque esto sólo consigue que el nuevo grupo esté activo en dicha shell, ¿no? ? Sea como fuere, siempre viene bien tener más trucos en el bolsillo ☺️

  7. Avatar de Miguel Olave
    Miguel Olave

    Hola David.

    Excelente tutorial, me entregó mucho más de lo que esperaba.

    La parte de nginx me parece interesante, pero no me quedó muy claro la parte en la que dices: «Entrar en las instalaciones de desarrollo usando localhost y números de puerto es bastante pesado;». ¿Es simplemente que es incómodo para probar y añadir rutas en las configuraciones o tiene algunas otras desventajas en velocidad y rendimiento?

    No he utilizado, ni configurado nunca ngnix, pero sé que la potencia está cuando se tienen en conexiones recurrentes, pero no sé si eso sea mucha ventaja utilizarlo en desarrollo.

    ¿Hay otras ventajas al añadirlo en el entorno de desarrollo? ¿Puede mejorar de carga en alguna medida?.

    Otra pregunta, específicamente de docker.

    Noté que esta guía permite realizar una instalación de cero, pero en caso de querer trabajar en equipo sería conveniente tener una misma versión de WordPress ya configurada (usuarios creados, theme seleccionado, plugins configurados, etc.)

    ¿En tu experiencia cuál es la mejor forma de conseguir un entorno de desarrollo similar para desarrollo en equipos? ¿Es conveniente dejar el archivo de la base de datos en un volumen que apunte a una carpeta en el proyecto? ¿Qué archivos comunes sería conveniente añadir al proyecto para actualizarlos con git? o tal vez ¿utilizas otro enfoque cómo crear una imagen docker con un WordPress ya configurado? ¿qué te a funcionado a ti cuando has tenido que trabajar en equipo?

    Gracias por compartir y por tus respuestas.

    1. Avatar de David Aguilera

      Gracias, Miguel; me alegra saber que estos tutoriales os son útiles e interesantes 🙂

      ¿Es simplemente que es incómodo para probar y añadir rutas en las configuraciones o tiene algunas otras desventajas en velocidad y rendimiento?

      Como uso Docker para el desarrollo, es, simplemente, una cuestión de comodidad. A mí me resulta más cómodo desarrollar cada uno de nuestros plugins en su propia máquina Docker y luego acceder a cada instalación con una URL (ejemplo, testing.local, content.local o theme.local) y no tener que hacerlo por localhost y puerto. No tiene nada que ver con temas de rendimiento ni cargas ni nada.

      ¿En tu experiencia cuál es la mejor forma de conseguir un entorno de desarrollo similar para desarrollo en equipos? ¿Es conveniente dejar el archivo de la base de datos en un volumen que apunte a una carpeta en el proyecto? ¿Qué archivos comunes sería conveniente añadir al proyecto para actualizarlos con git? o tal vez ¿utilizas otro enfoque cómo crear una imagen docker con un WordPress ya configurado? ¿qué te a funcionado a ti cuando has tenido que trabajar en equipo?

      En principio, nosotros descargamos la imagen de WordPress pelada que comento en la entrada y trabajamos sobre ella. Pero si quieres que todos los miembros del equipo usen exactamente el mismo setup, puedes crear tu propia imagen de WordPress: https://www.howtoforge.com/tutorial/how-to-create-docker-images-with-dockerfile/

      Un saludo,
      David

  8. Avatar de Roberto
    Roberto

    Hola David

    Excelente tutorial, estoy iniciando con docker en windows y todo ha sido muy claro. Solo tuve que correr un docker pull hello-world antes de ejecutar el docker run hello-world del ejemplo, pero bueno ya nos tienes que dejar pensar un poco jejeje.

    David me puedes echar una mano con la configuración del yml para aquellos casos en los que vamos a tener un contenedor de mysql con varias bases de datos. No se si me hago entender, trabajamos con varios sites y creemos que es más eficiente tener un solo contenedor con las bases de datos y luego uno por cada site.

    un saludo y gracias de nuevo

    1. Avatar de David Aguilera

      Una de las ventajas de usar Docker es poder tener cada servicio totalmente aislado de los demás, con lo que yo te recomendaría que iniciaras un contenedor MySQL por cada base de datos que quieras lanzar. Pero si no quieres, con lanzar un Docker una única vez, crea su propdio yml y ponlo en una external network. Luego, añade cada contenedor que tenga que usar MySQL a esa external network también y listo, los contenedores se podrán comunicar con tu MySQL. Esto es algo que explico al final del artículo.

  9. Avatar de Marco
    Marco

    Muy buen post, muchas gracias por compartir este conocimieto.
    Por cierto hay un error ortográfico en este archivo, tiene una w extra en la palabra hello

    https://gist.github.com/davilera/18dd6532b9046d77f1597720261e5721#file-11-docker-hello-world-sh

  10. Avatar de Juan Pico
    Juan Pico

    Hola David , muchas gracias por este blog , me fue de ayuda para comprender Docker. Me surge este error relacionada al archivo .yml . Sabes que solucion tiene ?

    Error:
    root@debian-kiosk:/docker/test# docker-compose up -d
    ERROR: The Compose file ‘./docker-compose.yml’ is invalid because:
    Additional properties are not allowed (‘WORDPRESS_DB_PASSWORD’ was unexpected)

    You might be seeing this error because you’re using the wrong Compose file version. Either specify a version of «2» (or «2.0») and place your service definitions under the `services` key, or omit the `version` key and place your service definitions at the root of the file to use version 1.
    For more on the Compose file format versions, see https://docs.docker.com/compose/compose-file/

    1. Avatar de Juan Pico
      Juan Pico

      YA SOLUCIONE EL PROBLEMA , era un error en el archivo de tipeado

      Pero cuando me dirijo a localhost:8080 me dice que tuvo un error conectandose a la base de datos. Alguna idea de porque puede ser?

      1. Avatar de David Aguilera

        Tienes que asegurarte de que has configurado bien el enlace entre el servicio de WordPress y el de base de datos. Fíjate que en el fichero docker-file.yml especificas el puerto que abres (ejemplo, 8081:3306) y luego en WordPress indicas que usa el servicio MySQL que está en el puerto 3306 (sección environment, con las variables WORDPRESS_DB_*).

        1. Avatar de Juan Pico
          Juan Pico

          Si , ya lo verifique , esta identico el archivo como aparece en el tutorial. Estoy usando un debian metido dentro de un virtual box , tendre que configurar algo de la red de la maquina virtual ?

          1. Avatar de David Aguilera

            En principio no deberías tener ningún problema, pues. La verdad es que no sé qué puede ser, y menos desde la distancia 🙁

  11. Avatar de Félix
    Félix

    Felicidades David. Muy buen trabajo.

    Estoy montando un servidor de WP y de Moodle en casa en una Raspberry 3 mediante dockers.

    ¿Crees que es factible hacerlo a partir de tu ejemplo en local para que funcione en producción?

    Ya tengo los puertos abiertos en el router y rediccionado desde fuera mediante duckdns.org.

    Muchas gracias y saludos !

    1. Avatar de David Aguilera

      Sí, no deberías tener ningún problema. Al final, se trataría (creo) de redireccionar el puerto que toca del router (el 80, por ejemplo) al puerto que ha abierto Docker en el sistema operativo anfitrión (el de la Raspberry, vaya). Prueba y nos cuentas qué tal ?

      1. Avatar de Félix
        Félix

        Sí, lo he probado y funciona perfectamente. Espero que aguante las concurrencias, que no son muchas.

        Por otro lado lo que me toca ahora es migrar mis webs en servidores externos a mi raspberry. Otro reto.

        Muchas gracias

        1. Avatar de David Aguilera

          ¡Genial! Yo también tengo una Raspi en casa y estoy encantado con ella. Son proyectos divertidos 😉 ¡Disfrútala!

  12. Avatar de Antonio
    Antonio

    Hola David,

    Tengo un problema a la hora de hacer correr a la vez 2 instancias de wordpress.

    Después de haber añadido en el archivo hosts

    127.0.0.1 entorno1.local

    Si quieres añadir un segundo entorno ¿cómo lo harías?

    127.0.0.1 entorno2.local

    Porque entiendo que haciendo esto no bastaría, ¿tendrías que ir cambiando el entorno al que hace el mapeo de 127.0.0.1?

    Por otra parte, ¿con lo de nginx no hace falta escribir el puerto?

    Gracias y saludos

    1. Avatar de David Aguilera

      Tal cual lo estás haciendo es perfecto. Simplemente recuerda que el docker-compose.yml de cada una de tus instalaciones debe definir sus propios puertos que no choquen con los de otra instalación. Si lo haces así, la otra máquina que hemos levantado con el proxy se encarga de recibir un cierto nombre de dominio (entorno1.local) y mapearlo a la combinación 127.0.0.1 más puerto que toque.

  13. Avatar de pfsense
    pfsense

    Una entrada muy interesante, al igual que los comentarios.

    Quiero contratar una VPS y quiero desplegar varias cosas tipo, WP, Mastodon etc tengo la duda si en este caso compensa hacerlo mediante Docker o es mejor realizarlo directamente contra el servidor.

    Por otro lado, me gustaría saber cómo se pueden lanzar backups contra las bases de datos que se encuentran dentro de un contenedor que por ejemplo tiene un MySQL.

    Un saludo,

    1. Avatar de David Aguilera

      Muchas gracias.

      En mi opinión, lo mejor es desplegar los servicios usando también Docker. Haciéndolo así, te aseguras de que el entorno donde ejecutas los servicios será exactamente el mismo que el que tienes en tu entorno de desarrollo local. Además, ofrece una capa de seguridad extra: los contenedores están aislados los unos de los otros, con lo que es más difícil que te los tumben todos.

      En cuanto a crear las copias de seguridad, es posible lanzar comandos a un contenedor Docker. Esto incluye, por ejemplo, la posibilidad de pedirle un db-export o incluso entrar en el contenedor por SSHS. Esto es algo que depende de los contenedores específicos que uses… pero seguro que en la documentación encuentras la respuesta.

      ¡Un saludo y gracias por leernos!

  14. Avatar de Santiago Moreno
    Santiago Moreno

    Hola, felicidades por este post tan informativo. Yo también estoy actualmente utilizando Docker para el desarrollo de nuestras aplicaciones y llegué aquí buscando como otros montan su entorno. Solo puntualizar que en la parte a la que te refieres como «Repositorio de Contenedores», probablemente quisiste decir «Repositorio de imágenes [de contenedor]» ya que lo que descargamos son imágenes con las que creamos nuestros contenedores locales.

    1. Avatar de David Aguilera

      Correcto, tienes toda la razón. Gracias por la puntualización, Santiago. ¡Un saludo y gracias por leernos!

  15. Avatar de Mario
    Mario

    Hola, yo tambien uso docker para desarrollar proyectos wordpress.

    Me gustaria saber si usas solo la imagen base o usas alguna de sus variantes ?

    Aca te muestro mi archivo de docker-compose para wordpress.

    1. Avatar de David Aguilera

      Uso la imagen base, como tú. De todas formas, con el nuevo paquete @wordpress/scripts, la creación de un Docker con el que desarrollar se ha simplificado bastante. Quizás escriba una entrad al respecto más adelante.

  16. Avatar de UltimateGross
    UltimateGross

    Arrechísimo compadre!!! créeme que tenía añales de no usar docker, por X o Y, y ahora que estoy metiéndome con desarrollos de wordpress customizado para mis clientes, no me quedó de otra. De tanto tiempo sin usarlo se me olvidó todo, pero con tu post me pude hacer de todo lo que necesitaba. Te adjunto mi yml por si a alguien más le sirve, lo único que hice fue añadirle un phpmyadmin para administrar la base de datos. Lo único que tienes que hacer es cuando abres la página y te pregunta cómo se llama la BD, pones el nombre que le pusiste a la instancia en el yml y listo, claro root y tu contraseña.
    version: ‘2’

    services:
    mysql:
    image: mysql:5.7
    restart: always
    volumes:
    – /root:/home/user/docker/mysql
    ports:
    – 8081:3306
    environment:
    MYSQL_USER: wordpress
    MYSQL_ROOT_PASSWORD: wordpress
    MYSQL_DATABASE: wordpress
    MYSQL_PASSWORD: wordpress

    wordpress:
    depends_on:
    – mysql
    image: wordpress
    ports:
    – 8080:80
    restart: always
    volumes:
    – /root:/home/user/docker/wordpress
    environment:
    WORDPRESS_DB_HOST: mysql:3306
    WORDPRESS_DB_USER: wordpress
    WORDPRESS_DB_PASSWORD: wordpress

    phpmyadmin:
    depends_on:
    – mysql
    image: phpmyadmin/phpmyadmin
    ports:
    – 8082:80
    restart: always
    volumes:
    – /root:/home/user/docker/phpmyadmin
    environment:
    MYSQL_ROOT_PASSWORD: wordpress
    PMA_ARBITRARY: 1

    1. Avatar de David Aguilera

      Un placer poder ayudar y gracias por compartir tu experiencia con nosotros.

    2. Avatar de angel
      angel

      Como abres phpmyadmin en el navegador ,cuando tu dominio solo apunta a la pagina?

      1. Avatar de David Aguilera

        Necesitarías configurar PHPMyAdmin como aplicación alternativa dentro del servidor que tienes en Docker. O, si lo que quieres es desarrollar sin muchas complicaciones, echar un vistazo a Lando.

  17. Avatar de Nof
    Nof

    Muy bueno el articulo. ME funciono perfectamente todo, solo tuve un inconveniente y quizas puedas orientarme, quiero instalarle certificado SSL con certboot, sin docker puedo hacerlo, ya que es dentro de todo sencillo, pero con docker intenté realizarlo y fue un lio.

    Tenes alguna idea al respecto? Gracias!

    1. Avatar de David Aguilera

      Pues no he llegado a implementarlo nunca, aunque imagino que en Internet habrá varios tutoriales que te lo expliquen. En cualquier caso, de un tiempo a esta parte estoy usando Lando, el cual permite configurar tu instalación sobre SSL (con certificado propio) de forma muy sencilla; quizás te sea más cómodo 🙂

  18. Avatar de Camlo
    Camlo

    Hola, es un GRAN hallazgo este artículo, está ESPECTACULAR. Acabo de configurarlo en una notebook del 2010 con Debian 10 lxde y vuela, andá bárbaro.
    Ya me estoy sumergiendo en Docker, es imopresionante. Yo estoy utilizando localWP en otra pc con Ubuntu 20.08 y no lograba hacerlo funcionar en esta máquina.
    Tengo muchas consultas, pero la primera que me surge, ¿la carpeta proxy, debemos usarla dentro del proyecto, o debería ser genérica para todos el proyectos docker? (no tengo ni idea como funciona un proxy).

    Estoy con dudas, pero seguro se puede incluir GIT. (estoy pensando en docker para todos mis proyectos, no solo los basados en wordpress).

    Lo que yo creo que falta a este artículo para que sea PERFECTO, es ¿cómo accedo a un phpmyadmin o algo similar? no lo probé pero se me ocurre que un un adminer.php podría andar directamente.

    Y lo otro que seguro se debe poder hacer pero que no tengo idea como, es poder ver los emails disparados por el sitio, como se puede ver en localWP.

    Te felicito y agradezco, este artículo me alegró el día !!!

  19. Avatar de Camilo
    Camilo

    Bueno, ahora vi tu artículo siguiente:
    https://neliosoftware.com/es/blog/como-usar-lando-para-desarrollar-en-wordpress/

    Con LANDO, es INCREIBLE, todavía mucho más potente para crear mi propio entorno de desarrollo personalizado para cada proyecto. Esto es EXÁCTAMENTE lo que estaba buscando.
    Muchas Gracias, GENIAL aporte.
    Saludos.

    1. Avatar de David Aguilera

      Justo te iba a decir que miraras el artículo sobre Lando. Yo también empecé con Docker pero, para montar entornos de desarrollo rápidamente y sin romperme mucho la cabeza, Lando es mucho más cómodo. ¡A disfrutar, amigo!

  20. Avatar de Xabi13
    Xabi13

    Hola, tengo como exmen final de mi clase de sistemas operativos. instalar una imagen de sistema oprativo android en docker. quisiera saber como hacerlo

    1. Avatar de David Aguilera

      Me consta que hay varios contenedores para Docker con Android, pero no sé si es lo que necesitas para tu examen. Lee los apuntes de tu profesor 😉

  21. Avatar de José Manuel
    José Manuel

    Hola David:

    He creado un docker WordPress con Portainer en un servidor local, sin ningún problema y totalmente operativo desde la red local.

    Ahora quiero acceder a ese wordpress a través de internet. Redirecciono todo lo que entre por mi router a través del puerto 80, o 443, al puerto e IP del servidor que aloja el docker.

    Identifico mi IP pública y la introduzco en el navegador. La redirección de puertos hace que en el navegador conste MiIPublica:puerto. En teoría correcto, pero no accedo a la web WordPress.

    Alguna idea sobre el problema?

    Un saludo y gracias por tu blog.

    1. Avatar de David Aguilera

      Si no recuerdo mal, la última vez que probé algo así me fallaba porque no podía entrar con la IP externa a un ordenador de mi red local desde otro ordenador que también estaba en mi red local. ¿Has probado acceder desde fuera? Y, por supuesto, configura tu servidor para que acepte peticiones de los puertos externos (hay que redirigir el tráfico del router al servidor, pero luego hay que configurar también el tráfico que recibe el servidor para que lo envíe a Docker).

  22. Avatar de Adrian
    Adrian

    Muy buen artículo.

    Pregunta: Hay manera de configurar un proyecto existente de wordpress que está actualmente en producción de manera local importando la base de datos MySQL y puenteando el dominio http://www.midominio.com para que el hosts virtual de docker apunte directo a localhost:8001 por ejemplo?

    1. Avatar de David Aguilera

      Si modificas el fichero /etc/hosts, puedes hacer que (www.)midominio.com sea tu máquina local. Con lo que, mientras desarrollas, digamos que «dejas» de tener acceso al dominio real y haces que el nombre apunte a tu propia máquina. Luego, cuando acabas, quitas/comentas la línea de /etc/hosts y ya vuelves a tener acceso al dominio real.

      ¿Es eso lo que me estás preguntando?

  23. Avatar de Claudio
    Claudio

    Hola Excelente!! muchas gracias, estoy entrando al mundo de docker, me orientas un poco en como entrar al archivo php.ini para poder cambiar los tamaños de subida de archivos por favor y cuando termine de hacer el trabajo en wordpress como lo extraigo para montarlo en un hosting?

    1. Avatar de David Aguilera

      El fichero php.ini no es algo de Docker en si, sino del servidor PHP. En Internet tienes muchos tutoriales donde te explican con más detalle del que puedo poner en un comentario qué directivas debes usar para aumentar el tamaño de subida de ficheros.

      En cuanto a subir tu web a un servidor externo, lo más fácil es generar una copia de seguridad de tu web (existen plugins para ello) y subirla al servidor.

  24. Avatar de Antonio
    Antonio

    Muy buena guia, la tengo como referencia 😉

    Una duda… ¿por qué una vez he hecho docker-compose up -d, si lo paro con docker-compose stop.

    Para volverlo a levantar hago docker-compose up -d pero al acceder en el navegador a http://localhost:32773/ (por ejemplo) me devuelve un error de conexión:

    This site can’t be reachedlocalhost refused to connect.
    Try:

    Checking the connection
    Checking the proxy and the firewall
    ERR_CONNECTION_REFUSED

    Tengo que hacer docker-compose down y empezar de nuevo. ¿sabes por qué es?

    Por cierto, he preguntado en stackoverflow para ver como gestionar los puertos automáticamente (porque mi idea es tener un theme como template con el fichero .yml y de el hacer espejo para cada proyecto que quiera tener) y la solución sería esta, por si te interesa:

    version: ‘3’
    services:
    mysql:
    image: mysql
    ports:
    – 3306
    environment:
    – MYSQL_ROOT_PASSWORD=badpassworddontdothis
    wordpress:
    image: wordpress
    ports:
    – 80

    Si no pones el puerto del host, docker gestiona los puertos y lo asigna automáticamente.

    Haciendo docker-compose ps puedes ver a qué puerto lo ha asignado:

    ❯ docker-compose ps
    Name Command State Ports
    ————————————————————————————————–
    67077886_mysql_1 docker-entrypoint.sh mysqld Up 0.0.0.0:55362->3306/tcp, 33060/tcp
    67077886_wordpress_1 docker-entrypoint.sh apach … Up 0.0.0.0:55361->80/tcp

    Adjunto enlace donde lo explican:
    https://stackoverflow.com/questions/67077886/port-available-to-set-in-docker-compose-yml-for-mysql-and-wordpress

    Gracias y saludos

    1. Avatar de David Aguilera

      Gracias por compartir tu experiencia sobre cómo compartir puertos.

      En cuanto a tu pregunta, me temo que no conozco la respuesta. En principio te diría que lo que estás haciendo debería funcionar… así que ni idea. También te diré que de un tiempo a esta parte llevo usando Lando, una app que se monta encima de Docker y que hace más fácil el proceso de montar servidores para desarrollar en WordPress, con servicios para nombres de dominio, redirección de puertos, etc. Te recomiendo que le eches un vistazo.

  25. Avatar de epic
    epic

    Hola… que sucede si tengo mi instalación de wordpress (bajo docker) en la ruta /var/www/html/pagina , pero luego quieren crear una carpeta ahí dentro con otra planilla (/var/www/html/pagina/propaganda) para que la dirección quede «https://www.pagina.cl/propaganda»

    se debe instalar manualmente wordpress en ese subdirectorio? se debe modificar el docker-compose de alguna manera para que la instalación se haga también desde el comienzo?

    Instale WordPress de manera manual en esa carpeta dentro del contenedor, pero al ingresar a la url la pagina inicial de wordpress no carga bien y sale sin colores

    1. Avatar de David Aguilera

      Las páginas no son carpetas que creas en el directorio donde tienes instalado WordPress. Las páginas las debes generar a través del propio WordPress (que para eso es un gestor de contenidos) y dejar que las rutas a los diferentes contenidos las genere él dinámicamente según tu configuración de enlaces permanentes.

  26. Avatar de Brian
    Brian

    Buenas David he leido este post, creo que lo entiendo pero aun no lo tengo claro. Haber, tengo ahora mismo en ubuntu la instalacion de wordpress sobre compose, pero quiero añadir el archivo «.txt» para subir mi imagen ya desarrollada de local a github. Eso por una parte. Y por otra, tambien quiero añadir un «tema premium» que compre hace mucho tiempo al mismo projecto, pero tengo el mismo lio. Exactamente antes de levantar docker compose, debo crear las carptas: «themes», «plugins», etc?. Por ejemplo dentro del folder del projecto y luego en «volumes» de la imagen de wordpress en docker darle las variables en la ubicacion de la carpeta, para que despues al levantar «docker-compose» las reconozca como directorios dentro projecto, una vez ejecutado por primera vez docker-compose. Si es asi, podrias decirme como declarar esas variables (en volumes, osea para mapear la ruta), uso localhost y el puerto para acceder a la instalacion de wordpress, de momento no uso tu configuracion por url.testing, etc?…

    1. Avatar de David Aguilera

      Docker monta una máquina virtual con todo lo necesario dentro (un servidor web, una base de datos, una instalación de WordPress, etc). A través de los volúmenes compartidos, puedes decirle a Docker «oye, esta carpeta de mi ordenador (que contiene un plugin que estoy desarrollando), métela dentro de .../wp-content/plugins/» y, con ello, puedes ver en el WordPress de Docker una carpeta que está en tu ordenador. Este proceso lo puedes repetir las veces que quieras: una para un tema concreto, otra para un plugin concreto… o incluso lo podrías hacer para las carpetas themes/ y plugins/.

      De todas formas, si lo que quieres es levantar un WordPress y tener acceso a todo fácilmente, te recomiendo que eches un vistazo a Lando. Personalmente, hace tiempo que para desarrollar en local dejé de usar Docker y uso Lando; es más cómodo 🙂

  27. Avatar de pablo
    pablo

    Hola, muy bueno tu articulo. Te tiro una consulta quizás tengas algún dato para aportar. Conoces alguna forma de hacer en un solo docker-compose.yml que funcione con varios servicios y una misma db. Ejemplo meter en un mismo archivo un wordpress y un moodle y que ambos tengan su db en un mariadb?.

    1. Avatar de David Aguilera

      Uf, hace tiempo que no uso Docker directamente para mis desarrollos y que me apoyo en Lando. De todas formas, si te fijas en los docker-compose.yml que pongo en la entrada, puedes meter más de un servicio en el mismo. O sea, que si en mi ejemplo está mysql y wordpress (este último con una dependencia a mysql), entiendo que podrías añadir un tercer servicio que fuera moodle que también dependiera de mysql (o mariadb), ¿no?

  28. Avatar de Lino H
    Lino H

    Hola David.

    Seguí las recomendaciones de tu guía y logré correr un wordpress, pero tengo un problema.

    A ver, tengo un wordpress funcionando local, pero quiero migrarlo a Docker(digo si cabe la palabra migrar).

    Me ayudas?
    Gracias

    1. Avatar de David Aguilera

      Lo más fácil probablemente sea exportar el contenido de uno e importarlo en el otro. Hay varios plugins para ello.

  29. Avatar de Jose Velázquez-Gaztelu
    Jose Velázquez-Gaztelu

    Hola David:

    Mi sincera enhorabuena. Soy novato con esto de Docker y me he visto un par de videotutoriales y guías. Pero nada tan claro, conciso y bien explicado como este post.

    Gracias miles!!

    1. Avatar de David Aguilera

      Nada, hombre. Gracias a ti por pasarte por nuestra web y dejar un comentario tan positivo 🙂 ¡Un saludo!

  30. Avatar de Walter
    Walter

    Gracias por este exclente aporte, consulta. Como puedo hacer para cambiar la contraseña por default del root de mysql? Gracias de antemano sus comentarios y aportes.

    1. Avatar de Ruth Raventós

      Gracias, Walter, por leernos.
      En este artículo encontrarás cómo cambiar la contraseña.
      ¡Saludos!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

He leído y acepto la política de privacidad de Nelio Software

Tus datos personales se almacenarán en SiteGround y serán usados por Nelio Software con el único objetivo de publicar tu comentario aquí. Con el envío de este comentario, nos das el consentimiento expreso para ello. Escríbenos para acceder, rectificar, limitar o eliminar tus datos personales.