Workspace con Docker y Laravel

Publicado

Estuve algunas horas investigando como armar un entorno de desarrollo con Docker, para proyectos en Laravel. La idea es poder dockerizar todo el stack tecnológico necesario para correr una aplicación Laravel, esto incluye PHP, Nginx, MySQL.

Comparativa de Virtualización con Máquinas Virtuales contra Docker

Comparativa de Virtualización con Máquinas Virtuales contra Docker

Después de leer posts al respecto, llegué a una solución que se adapta perfectamente al entorno que necesito: php7, nginx, mysql y composer completamente dockerizados, permitiendo que el único requerimiento al momento de desarrollar una aplicación sea el contar con Docker funcionando en el sistema.

Servidor NGINX y PHP

La parte mas importante es la conexión entre el servidor web, y el runner PHP. Para esto defino 2 servicios nuevos en un archivo docker-compose.yml (en la raíz del proyecto):

web:
    build:
        context: ./
        dockerfile: deploy/web.docker
    volumes:
        - ./:/var/www
    ports:
        - "80:80"
    links:
        - app

app:
    build:
        context: ./
        dockerfile: deploy/app.docker
    volumes:
        - ./:/var/www

Y también, cada uno de los dockerfiles correspondientes (guardados en una carpeta deploy/ para organizar un poco mejor las cosas)

archivo web.docker:

FROM nginx:1.10

ADD ./deploy/vhost.conf /etc/nginx/conf.d/default.conf
WORKDIR /var/www

archivo app.docker:

FROM php:7-fpm

RUN apt-get update && apt-get install -y libmcrypt-dev mysql-client freetds-dev \
    && ln -s /usr/lib/x86_64-linux-gnu/libsybdb.so /usr/lib/libsybdb.so \
    && docker-php-ext-install mcrypt pdo_mysql pdo_dblib

ADD ./deploy/freetds.conf /etc/freetds/freetds.conf

WORKDIR /var/www

archivo vhost.conf:

server {
    listen 80;
    index index.php index.html;
    root /var/www/public;

    location / {
        try_files $uri /index.php?$args;
    }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass app:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

archivo freetds.conf:

[global]
tds version=7.0
client charset=UTF-8

Composer

Para correr composer, puedo utilizar la docker image oficial, y especificar directamente el comando que quiero ejecutar. Esto lo puedo hacer de la siguiente manera:

docker run --rm -v $(pwd):/app composer/composer

Por ejemplo, para descargar las dependencias del proyecto, en la raíz del mismo ejecuto el comando

docker run --rm -v $(pwd):/app composer/composer install

Agregando MySQL

Para agregar una base de datos al proyecto, voy a utilizar la docker image oficial de MySQL, para esto agrego al docker-compose.yml lo siguiente:

	database:
		image: mysql:5.7
		volumes:
			- dbdata:/var/lib/mysql
		environment:
			- "MYSQL_DATABASE=homestead"
			- "MYSQL_USER=homestead"
			- "MYSQL_PASSWORD=secret"
			- "MYSQL_ROOT_PASSWORD=secret"
		ports:
			- "33061:3306"

volumes:
	dbdata:

y al servicio web agregarle info de la base de datos:

app:
	build:
		context: ./
		dockerfile: deploy/app.docker
	volumes:
		- ./:/var/www
	environment:
		- "DB_PORT=3306"
		- "DB_HOST=database"

Agregando Queue Worker

Viendo el repositorio de ejemplo de uno de los posts, encontré un pull request que agregaba esta funcionalidad. En ese mismo momento la agregué a mi proyecto.

Decidí reutilizar la imagen de php, donde ya tengo todas las extensiones necesarias instaladas. Para que esto funcione, al docker-compose.yml agregar el siguiente servicio:

queue:
	build:
		context: ./
		dockerfile: deploy/app.docker
	volumes:
		- ./:/var/www
	command: ["/bin/sh", "./deploy/queue.sh"]
	environment:
		- "DB_PORT=3306"
		- "DB_HOST=database"

También hizo falta crear el script queue.sh con el que iniciar el queue worker:

#!/bin/sh
while true;
do
	php artisan queue:work --daemon --sleep=3 --tries=3
done

Más adelante prometo agregar detalles, y más información al respecto.

Saludos!

(Actualización) Imágenes de Docker Publicadas

Actualización del 02 de Abril de 2018: Para colaborar con un proyecto de desarrollo en común junto a otro equipo de desarrollo es que desde Molotec decidimos compartir las imágenes de docker que creamos siguiendo el procedimiento que acá detalle.

Ahora las imágenes de Docker se pueden encontrar (y utilizar, libremente) en gitlab.com/molotec/docker-images