Docker para desarollo

Por David González
Big Data Manager de OpenSistemas

¿Cuanto tiempo invertimos en montar los entornos de desarrollo? Una persona experimentada, puede montar un entorno LAMP en apenas 15 minutos, pero no siempre estamos ante este tipo de perfiles, pudiendo provocarse cuellos de botellas que implican distracciones de tareas más importantes para los miembros senior. Incluso en ocasiones, la complejidad del proyecto es tal, que un perfil de estas características puede necesitar un tiempo para aclimatarse. Supongamos un proyecto que realizamos hace un par de años y que comienza su segunda fase, es necesario recurrir a la documentación (en el mejor de los casos) para ver las librerías y las versiones necesarias, obligando a veces a modificar el entorno actual.

 

No hay que olvidar que muchas personas trabajan en varios proyectos, en este caso la situación  se agrava, supongamos que para uno de los proyectos se utilizan diferentes versiones de PHP y de MySQL, no es tan trivial el manejo, y muchas veces se opta por una versión que no es la indicada porque el desarrollo funciona, esto puede acarrear problemas en el futuro, ya que los desarrollos que realiza podrían no funcionar posteriormente con la versión oficial del proyecto.

Docker al rescate!

En la mayoría de las empresas se desarrolla sobre un control de versiones (me gustaría poder decir que en todas), utilizando todo el equipo un mismo repositorio donde van agregando las funcionalidades. ¿No sería genial que al descargar el repositorio, ya tuviéramos todo lo necesario para trabajar?… ojalá, pero descargarse todo el entorno de desarrollo es demasiado costoso, una imagen que contenga la foto completa puede ocupar cientos de MB. Sin embargo utilizando docker-compose, podemos guardar la “foto” de un entorno completo en pocos MB (incluso < 1MB)… Además, estos ficheros son texto plano, nuestro control de versiones podría informamos de cualquier cambio en la arquitectura. La cosa se pone interesante, manos a la obra:

 

Supongamos el siguiente repositorio git:

+ app

+ test

 

Añadamos nuestra carpeta de docker:

+ app

+ test

+ docker

 

Queremos montar un entorno LAMP, así que vamos a crear una arquitectura de contenedores con Apache, PHP y MySQL. Vamos a definirlo en nuestro docker-compose.yml:

 

version: ‘2’

services:

mysql:

image: mysql

container_name: app_mysql

environment:

MYSQL_ROOT_PASSWORD: root

ports:

– ‘3306:3306′

volumes:

– db:/var/lib/mysql

php:

image: php:7-apache

container_name: app_php

ports:

– ’80:80’

volumes:

– ../app:/var/www/html

depends_on:

– mysql

extra_hosts:

– “local.app.com:127.0.0.1”

volumes:

db:

 

Si ejecutaremos “docker-compose up”, crearíamos dos contenedores, uno con PHP y Apache, y otro con MySQL. Al primero podríamos acceder por el puerto 80 desde nuestro ordenador, y al segundo accederíamos tanto desde nuestro ordenador por el 3306 como desde el primer contenedor.

 

En el primer contenedor hemos montado un volumen, que tiene nuestro código (versionado 😉). Esto es genial porque no es una foto del momento en el que se creó el contenedor, sino una referencia. Es decir, suponiendo que usamos Git, si hacemos un Git Pull, vamos a ver los cambios inmediatamente en nuestro navegador.

 

Por desgracia, esto no sirve de mucho, seguramente necesitemos habilitar algún mod de Apache, o utilizar un virtual host, o cualquier cambio de configuración que no este incluido en la imagen oficial… No os preocupéis, vamos a crear nuestras propias imágenes (mejor, nuestras propias definiciones de imágenes, y también estarán versionadas.

 

Recordemos en que punto estamos, y añadamos un par de carpetas:

 

+ app

+ test
– docker

– docker-compose.yml

+ php

+ mysql

 

Modificamos nuestro docker-compose.yml para decirle que la imagen va a ser construida:

 

version: ‘2’

services:

mysql:

build: ./mysql

container_name: app_mysql

environment:

MYSQL_ROOT_PASSWORD: root

ports:

– ‘3306:3306′

volumes:

– db:/var/lib/mysql

php:

build: ./php

container_name: app_php

ports:

– ’80:80’

volumes:

– ../app:/var/www/html

depends_on:

– mysql

extra_hosts:

– “local.app.com:127.0.0.1”

volumes:

db:

 

Ahora, vamos a por nuestros docker files, empezamos por el sencillo, mysql:

 

FROM mysql:5.7

#COPY ./my.cnf /etc/mysql/conf.d/

 

Este docker file realmente no hace nada, podíamos haber dejado la imagen como estaba, pero si quisierais meter una configuración especial, bastaría con desconectar esa linea y meter el fichero en la carpeta. Ahora vamos con el siguiente php+apache:

 

FROM php:7-apache

ADD app.conf /etc/apache2/sites-enabled/app.conf

COPY php.ini /usr/local/etc/php/

RUN a2enmod rewrite

RUN apt-get update \

&& apt-get install -y libfreetype6-dev libjpeg62-turbo-dev libpng12-dev libmcrypt-dev \

&& docker-php-ext-install pdo_mysql mysqli mbstring gd iconv mcrypt

 

Esto ya es otra historia, veamos que hace cada linea:

  • Añadimos el fichero del virtual host al contenedor
  • Remplazamos el php.ini por uno propio
  • Habilitamos el módulo rewrite
  • Instalamos las librerías necesarias para el correcto funcionamiento de la aplicación.
Finalmente tendríamos la siguiente estructura:

+ app

+ test
– docker
  – docker-compose.yml
  – php

– Dockerfile

– php.ini

– app.conf

– mysql

– Dockerfile

– my.cnf

 

Ahora si, ejecutando “docker-compose up -d” tendremos todo nuestro entorno montado!

 

Espero que os haya gustado, pero sobre todo que os sea de utilidad. Me gustaría acabar el post diciendo los siguientes pasos que se me ocurren, y que pueden ser interesantes. Por un lado, generalizarlo y crear configuraciones específicas para cada tipo e proyecto (LAMP, Node+MongoDB, Niginx…), así al descargar un repositorio vacío de un proyecto X, ya tendríamos el 80% del entorno montado y solo tendriamos que personalizarlo. Y por otro lado, utilizarlo como entorno de desarrollo “no local”, aprovechando los driver que nos ofrece Docker-Machine, haciendo muy sencillo crear la misma infraestructura en la nube.

 

Nota: Prestad atención a los nombres de los ficheros y aseguraos de tener los puertos libres. Aquí podéis descargar una carcasa de la parte de Docker de prueba.