Desarrollando con Docker

¿Alguna vez habéis utilizado Docker para desarrollar aplicaciones? Como apasionado de Docker he leído muchos artículos hablando de cómo desplegar aplicaciones a producción, cómo escalar utilizando Docker Swarm, y temáticas similares, pero he encontrado pocos artículos dedicados a usar Docker para desarrollarlas.

Pues bien, en el departamento de desarrollo de Irontec hace tiempo que venimos utilizando Docker para desarrollar aplicaciones web (sobre todo backends en php) y nos gustaría compartir con vosotros algo de lo aprendido por el camino.

En este artículo vamos a montar un entorno de desarrollo basado en Docker para un ‘Hola mundo’ en php corriendo sobre php-fmp, apache2 y mysql.

No vamos a entrar en la instalación de Docker ni Docker Compose ni vamos a explicar qué son. Damos por hecho que sabéis lo que es o, por lo menos, os suena. Si queréis saber más podéis entrar en los siguientes enlaces:

El camino hacia Docker

La vida en la gestión de proyectos de desarrollo

En Irontec siempre hemos intentado huir de la frase “en mi equipo funciona”. En el ciclo de vida de los proyectos, una de las cosas que más tiempo consume son los pases a producción. La diferencia entre las versiones utilizadas para desarrollar y las versiones instaladas en producción nos han dado más de un dolor de cabeza. Es por eso que ya antes de Docker utilizábamos Vagrant con Ansible y Virtualbox para disponer de entornos de desarrollo uniformes. Esto nos permitía desarrollar utilizando las versiones concretas de las aplicaciones (apache, php, mysql…) que íbamos a tener en producción, evitando así los típicos problemas relacionados con las versiones de software.

En la gestión de proyectos de desarrollo es muy importante tener la capacidad de que cualquier desarrollador pueda unirse a un desarrollo sin tener que perder el tiempo en preparar el entorno. Para esto Vagrant nos resultaba muy útil, ya que con un simple “vagrant up” teníamos, en cuestión de minutos, todo el entorno listo para desarrollar.

El problema que teníamos con este sistema es que consumía muchos recursos y no podías trabajar en dos proyectos a la vez porque se ralentizaba mucho el equipo.

Cuando apareció Docker nos gustó mucho. Venía a solucionar de un plumazo los problemas con las versiones ya que, en teoría, lo que corre en desarrollo es lo mismo que corre en preproducción y producción: las imágenes sobre las que corren los contenedores son idénticas en todos los entornos.

Pero el cambio de paradigma era demasiado grande para hacerlo de golpe, así que empezamos a utilizar Vagrant con Docker como provider. Lo hicimos a nuestra manera, ya que no seguíamos la filosofía de Docker de un servicio – un contenedor, sino que utilizábamos los contenedores como si fueran máquinas virtuales, pero mucho más ligeras. Podéis ver una presentación que preparé a modo de curso para el departamento de desarrollo pinchando aquí.

Según se extendía el uso de Docker nos empapamos de su filosofía pero nos surgían ciertas dudas:

  • ¿Tenemos que levantar un contenedor por cada servicio que corra nuestra aplicación?
  • ¿Tenemos que ejecutar un comando de 3 líneas por cada contenedor para que compartan volúmenes y se vean entre ellos dentro de su red?
  • ¿No podemos automatizar todo esto?

Como utilizábamos Vagrant por aquel entonces, empezamos a automatizar la creación de los contenedores en el vagrantfile. Sin embargo, se hacía bastante complejo dejarlo bien definido.

Entonces llegó “el pulpo” con sus tentáculos para hacernos la vida más fácil. Estoy hablando, como no, de Docker ComposePor fin teníamos una forma fácil de definir todas las necesidades de cada uno de los contenedores y de lanzarlos todos con un solo comando: docker-compose up .

Nos dio mucha pena pero desde entonces abandonamos nuestro querido Vagrant y empezamos a definir nuestros entornos de desarrollo utilizando únicamente Docker y Docker Compose.

 

Al grano

El “grano” es un hola mundo que se ejecuta sobre php-fpm y que consume datos de una base de datos en mysql. Como frontal hemos elegido apache2 porque lo conocemos muy bien, aunque podríamos haber elegido nginx perfectamente.

Lo primero que tenemos que hacer para montar el entorno de desarrollo es pensar cómo se va a estructurar nuestra aplicación para ver cuántos servicios vamos a necesitar que ejecute nuestra aplicación.

Desde el punto de vista tradicional de sistemas esta aplicación necesitaría:

  • Una máquina con php-fmp instalado, configurado y corriendo.
  • Una máquina (podría ser la misma) con apache2 instalado, configurado y corriendo.
  • Una máquina (podría ser la misma) con mysql instalado, configurado y corriendo.

Habría que configurar apache para que las peticiones de archivos *.php sean entregadas a la máquina donde está corriendo php-fpm y que ésta le devuelva la página ya renderizada a la máquina de apache para servirla.

Además, habría que configurar nuestra aplicación para que las llamadas a la base de datos en mysql se hagan a la máquina donde está mysql.

Una vez que tenemos claro el esquema de nuestra aplicación, hay que trasladarlo a servicios en el archivo docker-compose.yaml.

En este caso nuestra aplicación tendrá tres servicios, uno por cada máquina de nuestro esquema tradicional: un servicio para apache, otro para php y otro para mysql.

 

docker-compose.yaml

Este es el archivo donde vamos a  definir la estructura de nuestra aplicación y el que va a utilizar Docker Compose para lanzar todos los contenedores que necesitemos con los comandos adecuados según su configuración. Este archivo puede estar en cualquier carpeta, tanto dentro como fuera de nuestro proyecto. No obstante, por cuestiones prácticas, a la hora de montar volúmenes lo mejor es que esté en la raíz de nuestro proyecto.

Lo primero que tenemos que saber de este archivo es que existen dos versiones, la 1 y la 2. En la versión 1 cada clave principal era un servicio, pero en la versión 2 se introdujeron los volúmenes y las redes, por lo que cambió la estructura del archivo y los servicios pasaron a definirse dentro de la clave principal “services”. Para indicar que queremos utilizar la versión 2, dado que tiene más opciones, lo primero que hay que hacer es poner, en la primera línea, version: "2" .

A parte de la clave de versión, este archivo puede tener otras tres claves principales:

  • services: dentro de esta clave se definen los servicios que va a tener nuestra aplicación.
  • volumes: dentro de esta clave se definen los volúmenes que va a tener nuestra aplicación.
  • networks: dentro de esta clave se definen las redes que se van a crear y se van a usar por la aplicación.

Los volúmenes se pueden definir también de manera dinámica dentro de los servicios, por lo que para este ejemplo no vamos a utilizarlos.

Docker Compose crea una red por defecto para cada grupo de servicios que forman la aplicación si no se define la clave principal “networks”. Todos los contenedores que forman la aplicación estarán en la misma red y serán accesibles a través de su IP. Por este motivo en este ejemplo no la vamos a utilizar.

services

Según lo comentado anteriormente nuestra aplicación tendrá tres servicios, uno para apache, otro para php y otro para mysql. Para definirlos ponemos en nuestro docker-compose.yaml lo siguiente:

Los nombres de los servicios pueden ser los que se quieran, aunque si se usa algo lógico mejor. En este caso no nos hemos comido la cabeza y hemos llamado a cada servicio por su nombre.

Ya tenemos los servicios creados, pero ahora hay que configurarlos. Por cada servicio se creará un contenedor, y cada contenedor se tiene que basar en una imagen. Por lo general, a mi me gusta utilizar imágenes oficiales de dockerhub y si no encuentro una que me sirva para mi objetivo lo que hago es basarme en una oficial, modificarla utilizando el Dockerfile y comitearlo a nuestro repositorio para luego utilizarlo. Pero esto ya lo explicaremos en otro artículo. Ahora vamos a configurar nuestros servicios uno a uno utilizando la imágen que más nos convenga para cada caso.

MySQL

Para este servicio, después de hacer una búsqueda en dockerhub, hemos elegido la imágen oficial “mysql“. Cada versión de mysql es un tag de la imagen en dockerhub. Nosotros hemos elegido la 5.6.35 por lo que el servicio quedaría definido de la siguiente manera:

Según la documentación de MySQL en dockerhub, necesitamos definir un par de variables de entorno para que el servicio de mysql se configure correctamente al arrancar. Nosotros hemos elegido la siguiente configuración:

  • MYSQL_ROOT_PASSWORD:  Define la contraseña para el usuario root.
  • MYSQL_DATABASE: Crea la base de datos que le indiquemos al arrancar.

Para que un contenedor tenga las variables de entorno definidas al arrancar hay que indicarlo en el docker-compose.yaml de la siguiente manera:

 

Con esto ya tenemos nuestro servicio de mysql configurado. Por supuesto que se pueden añadir más opciones, pero de momento sigamos con el siguiente servicio.

php

Para este servicio vamos a utilizar la imagen oficial de php 7.0-fpm, por lo que nuestra configuración quedaría de la siguiente forma:

Sin embargo, en este caso no nos basta con esto. Como hemos dicho al principio la estructura de nuestra aplicación requiere que el contenedor de php sepa conectarse con el de mysql, pero no sabemos que IP le va a asignar docker a cada contenedor, por lo que no podemos usarla en la configuración de nuestra aplicación.

Para solucionar este problema tenemos la opción “links”. Con esta opción le decimos a docker que añada una línea en el /etc/hosts del contenedor desde el que queremos conectar con la IP del contenedor al que queremos conectar y con el nombre que le especifiquemos. De esta manera, cuando hagamos un docker-compose up  docker detectará que necesita la IP del contenedor al que queremos conectar y levantará primero éste para asignarle una IP y después meter en el /etc/hosts la línea con la IP y nombre correspondientes.

Para llegar a este punto, la configuración quedaría de la siguiente forma:

Con esta línea le estamos diciendo que meta en el archivo /etc/hosts del contenedor de php una línea con la IP del contenedor de mysql y con el nombre “mysqldb”. De esta manera podemos utilizar en el código de nuestra aplicación el nombre de mysqldb que sabrá resolver la IP correspondiente.

Pero esta configuración tampoco es suficiente para desarrollar, ya que php necesita procesar nuestros archivos *.php. El problema es que estos archivos no están dentro del contenedor, por lo que le resulta imposible. Para solucionar este problema lo que necesitamos es que nuestro código esté disponible dentro del contenedor. Para ello utilizamos los volúmenes, con los que le decimos a Docker que una ruta concreta de nuestro equipo tiene que estar disponible en una ruta concreta del contenedor.

La configuración quedaría así:

En este caso lo que conseguimos es que la raíz de nuestro proyecto (recordad que el docker-compose.yaml se encuentra en la raíz de nuestro proyecto) esté disponible dentro del contenedor en la ruta /var/www/html. Hemos elegido esta ruta por mantener la estructura de directorios que se crearía en un servidor web por defecto.

Ahora ya sí podemos pasar a la configuración del servicio apache.

apache

En este caso, apache necesita conectarse con el contenedor php y necesita también tener acceso al código de nuestra aplicación para servir los archivos que no sean *.php. La configuración sería la siguiente:

Aquí vemos otra vez la opción “links” para que apache sepa como conectarse con php, y la opción “volumes” con la que hacemos que nuestro código esté disponible dentro del contenedor de apache.

Vemos además que no está la opción “image” y sin embargo sí otra opción llamada “build”. Esto se debe a que para este servicio no hemos encontrado una imagen oficial de apache que utilizar. Lo que hemos hecho ha sido crear una. Para ello necesitamos utilizar el Dockerfile, y con esta opción le estamos diciendo a Docker que utilice el archivo Dockerfile que está en la ruta docker/dockerfiles/apache/ . A mi me gusta organizar todos los archivos necesarios para que Docker monte la aplicación dentro de una carpeta llamada docker en la raíz de la aplicación, pero cada uno puede hacerlo como quiera.

 

Dockerfile

El archivo Dockerfile es el archivo que utilizamos para automatizar la creación de imágenes. En este archivo vamos indicando los pasos a realizar para crear la imagen. No voy a entrar en definiciones ni explicaciones, ya que no entra dentro del objetivo de este artículo. Si queréis saber más podéis visitar la documentación oficial de docker aquí.

Para instalar apache2 en una imagen no basta con hacer apt-get install apache2-common, ya que si lo haces así e intentas levantar un contenedor sobre esa imagen verás que aparece una serie de errores relativos a definición de variables de entorno. Para no volvernos locos, lo que hemos hecho ha sido fijarnos en alguien que ya lo haya hecho y coger la parte que nos interesa. En este caso nos hemos basado en el Dockerfile de php:7.0.14-apache ya que parece que lo instalan y lo configuran correctamente. El Dockerfile resultante es el siguiente:

Desde la línea 3 hasta la 41 está todo copiado del Dockerfile de php.  Tienen comentarios que explican lo que hace cada bloque, por lo que solo voy a explicar brevemente cada uno de los comandos que aparecen:

1.  FROM debian:jessie

Le estamos diciendo a Docker que se descargue la imagen de debian:jessie y que el resto de pasos los haga sobre esta imagen.

2. RUN apt-get update && apt-get install -y apache2-bin apache2.2-common --no-install-recommends && rm -rf /var/lib/apt/lists/*

El comando RUN se encargar de ejecutar en una shell lo que se le indique. En este caso instala los paquetes necesarios para tener apache.

3. ENV APACHE_CONFDIR /etc/apache2

El comando ENV define variables de entorno que estarán disponibles dentro del contenedor que se ejecute sobre la imagen resultante.

4. COPY 000-default.conf /etc/apache2/sites-enabled/000-default.conf

El comando COPY copia un archivo de tu equipo a la ruta especificada dentro de la imagen.

En este caso lo que hacemos es copiar la configuración del host virtual que definimos nosotros para reemplazar la que viene por defecto. De hecho, necesitamos hacerlo para poder configurar la comunicación de apache con phpfpm.

Este comando solo puede acceder a archivos que estén en la misma carpeta que el Dockerfile o subcarpetas. Las rutas son relativas desde la carpeta donde está el archivo Dockerfile.

5. RUN a2enmod proxy proxy_fcgi

Este comando ya lo hemos visto, pero vuelvo a referirlo porque lo que hace es habilitar los módulos de apache “proxy” y “proxy_fcgi” necesarios para la comunicación entre apache y phpfpm

5. WORKDIR /var/www/html

El comando WORKDIR hace que cualquier comando ejecutado desde su definición, ya sea dentro del Dockerfile o dentro de los contenedores que se creen a partir de la imagen resultante, se ejecutarán desde el directorio indicado.

6. EXPOSE 80

El comando EXPOSE indica que los contenedores levantados sobre esta imagen tendrán expuesto el puerto 80. Este puerto es necesario para que apache acepte conexiones.

7. CMD ["apache2-foreground"]

El comando CMD indica que, cuando se levante un contenedor sobre esta imagen sin especificar un comando a ejecutar, el que se ejecute será el definido aquí.

El “comando” apache2-foreground es un archivo que tenemos que tener en la carpeta del archivo Dockerfile y que hemos copiado de aquí.

 

El archivo del host virtual que se indica en el punto 4 tiene la siguiente configuración:

Como podemos ver este archivo es el que crea apache por defecto. Lo que hemos hecho ha sido cambiar un par de cosas:

1. DocumentRoot /var/www/html/public

Aquí le estamos indicando a apache cual es la raíz del host virtual, es decir, la carpeta “public”.

2. <Directory /var/www/html/public>

Aquí estamos definiendo las opciones de la carpeta public. Estas son las opciones por defecto de apache.

3. ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://phpfpm:9000/var/www/html/public$1

Esta es la línea que hace que se comunique con phpfpn. Lo que hace es que cualquier archivo que le pidan que tenga como extensión .php hace un proxy pass al contenedor donde está corriendo el php-fpm. Como recordaréis, php-fpm en el docker-compose.yaml está definido en el servicio php, y éste está enlazado con el servicio apache con el nombre de “phpfpm”. Es por esto que en la ruta fcgi aparece el host “phpfpm”. El puerto que aparece es el que utiliza por defecto la imagen de php-fpm y, por lo tanto, nuestro contenedor que corre sobre esta imagen.

La ruta que hay después del puerto es la ruta a nuestra aplicación para que php-fmp pueda encontrar el archivo en cuestión y procesarlo.

 

En marcha

Ya tenemos todo listo, así que vamos a lanzar los contenedores. ¿Cómo lo hacemos? Con un simple docker-compose up  desde la raíz del proyecto o desde alguna subcarpeta.

Veamos que pasa:

Vemos que lo primero que hace es crear una red para utilizar con nuestra aplicación utilizando el driver “default”. Para más información sobre redes y drivers consultar la documentación oficial aquí.

Lo siguiente que hace es crear la imagen apache. Vemos cómo hace todos los pasos indicados en el Dockerfile y da información sobre el resultado de cada paso. Parece que todo ha ido bien y se ha creado la imagen correctamente.

Lo siguiente que vemos es que se crean los tres contenedores que necesitamos: desarrollandocondocker_mysql_1, desarrollandocondocker_php_1 y desarrollandocondocker_apache_1.

Hay que tener en cuenta que, si los contenedores tienen que correr sobre imágenes que no tenemos descargadas, Docker las descargará automáticamente y veréis el progreso de descarga.

A continuación, lo que hace Docker es “conectarse” con la salida estándar de cada uno de los contenedores y mostrar toda la información que van soltando cada uno de ellos.

A los logs de cada uno de los contenedores se les añade el prefijo del nombre del servicio y un número. En nuestro caso las líneas que empiezan por “mysql_1 |” son los logs de nuestro mysql, las que empiezan por “php_1 |” son los logs de nuestros php y las que empiezan por “apache_1 |” son los logs de nuestro apache.

Si agrupamos los logs por cada servicio vemos lo siguiente:

MySQL

Vemos como arranca mysql y vemos que ha arrancado bien ya que en la anteúltima línea pone que está preparado para recibir conexiones y da información sobre el servidor en la última.

php

Aquí también vemos que php está listo para manejar conexiones.

apache

 

En el caso de apache parece que las cosas no han ido tan bien. Nos han salido dos Warnings diciendo que no existe el DocumentRoot /var/www/html/public.

En el archivo del virtual host de apache hemos puesto que nuestro document root iba a estar en /var/www/html/public. Como recordaréis, esta ruta forma parte del volumen que definimos en el docker-compose.yaml, es decir, /var/www/html/ es la raíz de nuestra aplicación, por lo que si creamos la carpeta public ahí estará automáticamente disponible en /var/www/html/public.

 

Reiniciando contenedores

Una vez creada la carpeta public vamos a reiniciar los contenedores para ver que nos cuenta esta vez apache. Para hacerlo, lo primero que hay que hacer es recuperar el prompt de la terminal ya que como hemos lanzado el comando docker-compose up  sin el parámetro  -d  los contenedores está corriendo en primer plano.

Al hacer crtl+c se paran todos los contenedores.

Después ejecutamos docker-compose up -d . Esta vez lo hacemos con la opción  -d  para que los contenedores se ejecuten en background y nos devuelva el prompt. De esta manera no vemos ninguna información de los contenedores, por lo que si queremos ver los logs debemos decírselo a docker-compose mediante docker-compose logs -f --tail=20 .

El comando docker-compose logs muestra los logs de todos los contenedores. Al añadir el parámetro  -f  lo que hacemos es que, una vez llegado al final del archivo se mantenga observando para que cuando lleguen más logs los muestre. El parámetro  --tail=20  lo que hace es decirle que no lea todo el archivo sino que lea solo las últimas 20 líneas. Esto es útil para contenedores que llevan mucho tiempo en marcha y tienen muchos logs.

Una vez ejecutado el comando, si nos fijamos solo en los logs de apache vemos lo siguiente:

Ya no nos da ningún warning y parece que todo va bien, así que… ¡¡¡¡Ya podemos ver nuestra web!!!!

 

Accediendo a contenedores

Pero… ¿Cómo vemos la web? ¿Dónde está?

Como ya hemos comentado, Docker crea una interfaz de red para cada aplicación y le da a cada servicio una IP, solo que no sabemos cuál. Para averiguarlo, hay que inspeccionar nuestro contenedor, que hace de frontal de la aplicación. En nuestro caso, el que tiene corriendo Apache.

Para hacerlo necesitamos saber el nombre de nuestro contenedor. Esto lo podemos averiguar de dos maneras:

  1. docker ps
  2. docker-compose ps

La primera muestra la lista de todos los contenedores que tenemos corriendo en nuestra máquina, mientras que la segunda muestra los contenedores que tenemos corriendo solo para nuestra aplicación. Yo personalmente prefiero utilizar la segunda porque tengo bastantes contenedores corriendo en mi máquina y me cuesta más encontrar el que busco con la primera opción. Sin embargo, con la segunda opción, lo que obtengo es lo siguiente:

En este caso el nombre de nuestro contenedor es desarrollandocondocker_apache_1 .

Ahora que ya lo tenemos, vamos a obtener la IP. Docker Compose no tiene la opción de “inspeccionar” contenedores, por lo que lo que tenemos que hacer es:

docker inspect desarrollandocondocker_apache_1

Esto nos devuelve toda la información del contenedor. No voy a entrar en detalles, solo voy a fijarme en lo que me interesa en este momento, que es:

Como vemos en la salida del comando, la IP de nuestro contenedor es:  172.22.0.4 , por lo que si abrimos un navegador y escribimos  http://172.22.0.4/  veremos un mensaje que dice “file not found”. Esto es normal, porque hemos creado la carpeta public pero nuestro proyecto no tiene código todavía.

 

ATENCIÓN

Esto no funciona en macOS. Podéis ver más información aquí.

Para acceder a los contenedores en macOS lo que tenemos que hacer es mapear puertos. En linux también se puede hacer. Sin embargo, yo no soy partidario de ello, ya que cuando trabajamos con varias aplicaciones a la vez hay que identificar qué puertos tenemos ocupados. De otra forma,  la aplicación no se levanta.

Para mapear puertos habría que configurarlo de la siguietne manera:

Mediante la opción “ports” podemos mapear todos los puertos que queramos. En este caso estamos mapeando el puerto 9000 de nuestro equipo local con el puerto 80 del contenedor con nuestro apache. De esta manera podemos acceder a la aplicación mediante la ruta:  http://localhost:9000 .

 

Desarrollando nuestra aplicación

Ahora que está todo listo, ya podemos desarrollar nuestra aplicación. Como ya hemos comentado, nuestra aplicación va a consistir en un simple hola mundo.

Vamos a crear un archivo index.html en public con el siguiente contenido:

Si recargamos la página vemos ya nuestro hola mundo.

Si ejecutamos  docker-compose logs -f --tail=20  y recargamos la página vemos que quien responde es apache. Esto es porque estamos pidiendo una página en html y puede servirla apache directamente, no necesita de php.

 

Ahora cambiemos nuestro index.html por index.php y pongamos lo siguiente:

 

Si recargamos la página viendo los logs veremos cómo apache le ha pasado la petición al contenedor de php, este le ha contestado con un 200 y apache nos ha servido la página que le ha pasado php ya renderizada.

 

Ahora vamos a complicarlo un poquito más y vamos a conectarnos a la base de datos en el contenedor de mysql. Para esto modificamos nuestro index.php y lo dejamos así:

En este código lo único que hacemos es intentar conectarnos con la base de datos en mysql. Si nos fijamos, el host es mysqldb, que es el nombre que le hemos dado al enlace entre nuestro php y nuestro mysql.

Si recargamos la página vemos cómo nos da un error. Esto se debe a que la imagen de php que utilizamos no tiene la extensión de mysql instalada.

 

Instalando extensiones en las imágenes oficiales de php

Dado que estamos utilizando la imagen oficial de php, lo primero que tenemos que hacer es leernos su documentación. En el apartado “How to install more PHP extensions” nos explica de forma muy clara cómo tenemos que hacerlo.

Así que vamos a crear un Dockerfile para crear la imagen en php con las extensiones que queremos, en nuestro caso “mysqli”. Para esto tenemos que modificar el archivo docker-compose.yaml de tal manera que use un Dockerfile para crear la imágen.

Ahora le hemos dicho que lea el Dockerfile que está en “docker/dockerfiles/php/”, así que vamos a crearlo de la siguiente manera:

Para rehacer la imagen de php lo que hay que hacer es primer eliminar los contenedores que están levantados ahora mismo y después levantarlos otra vez indicándole a Docker que queremos que se rehaga la imagen:

Si vemos los logs vemos que en nuestro contenedor de php se ha instalado la extensión de mysqli.

Al recargar la página ahora vemos que se ha conectado correctamente a la base de datos.

 

Todavía más

Esto es solo un pequeño ejemplo muy muy básico de cómo desarrollar con Docker. Por supuesto que una aplicación real supone muchas más cosas, como un framework (Zend, Symfony,…), muchas extensiones de php necesarias, la instalación de librerías mediante composer, etc.

En una aplicación real todo se complica mucho, y más si tenemos en cuenta que uno de los objetivos de desarrollar con Docker (quedándonos solo con el punto de vista de desarrollo) es que cualquier persona que quiera incorporarse al proyecto no tenga que preocuparse de instalar las extensiones, dependencias, etc… Se trata de que solo tenga que hacer un docker-compose up para poder ponerse a programar en cuestión de pocos minutos.

Desde el punto de vista de gestión de proyectos es muy importante que cualquier desarrollador pueda incorporarse a cualquier proyecto sin tener que pasar unas cuantas horas configurando el entorno.

 

Próximamente

En un próximo artículo intentaré explicar como montar el entorno de desarrollo para una aplicación compleja, con Symfony, MongoDb y Apache y automatizar la instalación de dependencias, limpieza de cache, etc. ¡No os lo perdáis!

 

 

 



¿Te gusta este post? Es solo un ejemplo de cómo podemos ayudar a tu empresa...
Sobre Luis Felipe García

Departamento de desarrollo de Irontec. Apasionado de la informática, GNU/Linux, Software Libre y de mi familia.

1 Comentario

¿Por qué no comentas tú también?


  • Excelente! me quedo jugando con esto hasta que salga como componer un entorno con symfony!
    No me quedo claro lo siguiente… entiendo que luego de bajar cada servicio, se vuelve a 0 la imagen. Donde se están guardando los datos de la imagen con servicio de mysql ? No veo que se monte ninguna carpeta de la maquina host como para mantener el estado.

    Saludos!

    Rodrigo Hace 1 año Responde


    • Gracias.

      En este ejemplo no persisten los datos de mysql. Esto pensaba explicarlo en el siguiente post pero, como adelanto, si quieres persistir los datos (nosotros en desarrollo lo solemos hacer aunque luego en producción suele ir contra una base de datos externa) bastaría con añadir al docker-compose.yaml, en el servicio mysql, el volumen adecuado.

      Según la documentación de la imagen oficial de mysql (en la sección “Where to Store Data”) hay que montar un volumen local mapeado a la ruta /var/lib/mysql. Nosotros solemos meter los volúmenes que vamos a usar dentro de la carpeta docker/volumes/[nombre_de_servicio] dentro de la carpeta raíz del proyecto, aunque esto es a gusto del consumidor.

      El docker-compose.yaml quedaría así:


      version: "2"
      services:
        mysql:
          image: 'mysql:5.6.35'
          environment:
            MYSQL_ROOT_PASSWORD: "password"
            MYSQL_DATABASE: docker
          volumes:
            - ./docker/volumes/mysql:/var/lib/mysql

      Un saludo.

      Luis Felipe García Hace 1 año Responde


  • Muchas gracias por compartir toda esta informacion. En este momento estoy trabajando sobre un proyecto utilizando cakePhp, pero no tengo idea de como hacerlo. te agradezco si me puedes colaborar con los pasos a seguir para hacerlo.

    Carlos Hace 1 año Responde


    • La verdad es que no he utilizado nunca cackePhp por lo que no sabría decirte. En cualquier caso, nuestro equipo de desarrollo tiene una amplia experiencia desarrollando en PHP por lo que si te pones en contacto con nuestro departamento comercial podríamos ver como podemos ayudarte.

      Luis Felipe García Hace 7 meses Responde


  • Luis Felipe para cuando la segunda parte?

    bumiga Hace 1 año Responde


    • El día a día ha hecho que me retrase bastante en la segunda entrega, pero intentaré retomarlo y publicarlo lo antes posible.

      Luis Felipe García Hace 7 meses Responde


  • Muy bueno! Me gustaría saber cómo hacen debug de la aplicación servida luego de levantar los servicios. 🙂

    Jonathan Hace 9 meses Responde


    • Para debugear usamos XDebug instalado en el contenedor de php y configurando el IDE para que apunte a la IP o el puerto mapeado del contenedor.
      En el siguiente artículo intentaré poner un ejemplo.

      Luis Felipe García Hace 7 meses Responde


  • ¿Hay fecha sobre el artículo anunciado al final de éste relacionado sobre una configuración de Docker con Symphony, MongoDB, Apache y otras opciones automatizadas? ¿Acaso ya se ha realizado? Si es así, ¿me pasas el enlace? Gracias, saludos.

    Yo Hace 8 meses Responde


    • Todavía no hay fecha para el siguiente artículo, pero intentaré hacerlo lo antes posible. Estate atento…!!!

      Luis Felipe García Hace 7 meses Responde


  • Impresionante, excelente, maravilloso, etc…

    Me veo en la obligación de implementar Docker en un proyecto la diferencia es que solo necesito de PHP ya que los demas servicios ya existen en el servidor, vamos a ver que pasa.

    Muchas gracias por este post.

    Cristhian Alexis Galeano Ruiz Hace 7 meses Responde


Queremos tu opinión :)