Cómo crear un proyecto de Laravel 6 en Docker. La magia de Docker-Compose

Si bien es cierto que existen muchas opciones a la hora de crear entornos de desarrollo fáciles de replicar en PHP, Docker y su concepto de contenedores se están convirtiendo en un estándar de la industria, haciendo que conocer su funcionamiento sea imprescindible para cualquier desarrollador.

Primero lo primero. ¿Qué es Docker?

Docker es, básicamente, una herramienta que nos permitirá empaquetar nuestro proyecto, sus dependencias y nuestro entorno completo de trabajo dentro de lo que lo que se conoce como contenedores. Estos contenedores tienen la ventaja de que pueden compartirse fácilmente y que al ejecutarlos generan una réplica exacta de nuestro ambiente de trabajo.

Otra ventaja de los containers es que, como su nombre lo indica, están contenidos, por lo cual su funcionamiento y las dependencias que instalen son totalmente independientes de las tecnologías que tengamos en nuestro equipo y de nuestro sistema operativo.

¿Por qué usar Docker y no Homestead? Sus ventajas

Si bien hay varias diferencias entre un entorno y otro, la principal ventaja que ofrece Docker es su sistema de virtualización. Mientras Homestead se ejecuta en una maquina virtual, consumiendo recursos físicos de nuestro pc, los contenedores interactúan directamente con el sistema operativo, cargando solo las dependencias necesarias para funcionar. Esto significa un ahorro enorme de recursos y una carga mucho más ligera para nuestro sistema. Por otro lado, Docker tiene la ventaja de que sus contenedores pueden ser desplegados en ambientes de producción. Mientras que con Homestead sólo contaremos con un entorno de desarrollo, los contenedores pueden ser deployados fácilmente.

Creando un contenedor con LaraDock

Existen varias formas de crear un contenedor de Laravel, la primera de ellas es mediante Laradock. Esta herramienta fue creada por miembros de la comunidad de Laravel y nos brinda todo lo necesario para tener un entorno de desarrollo PHP completo sin grandes esfuerzos.

Lo primero que haremos será clonar el repositorio de Laradock a nuestro equipo:

git clone https://github.com/Laradock/laradock.git

Nos metemos dentro del repositorio

cd laradock

Ahí encontraremos un archivo .env-example que deberemos duplicar y renombrarlo como .env. Pero ATENCIÓN que este no es el .env de Laravel, sino un archivo de configuración para nuestro contenedor.

Aquí vamos a tener que modificar la variable DOCKER_HOST_IP  con la dirección IP de nuestro host, usualmente es 127.0.0.1.

Dentro del directorio de Laradock nos encontraremos con todos los servicios que éste provee y que podremos usar para incluir en nuestro container.

Para este ejemplo, vamos a usar NGINX, Postgres y PHPMyAdmin.

docker-compose up -d nginx postgres phpmyadmin

Si estás en Linux deberás anteponer sudo. El -d hará que esta tarea se ejecute de forma desatachada y podamos seguir usando la consola cuando docker haya terminado de descargar todas las dependencias del proyecto.

Al culminar la descarga, ya tendremos nuestro contenedor listo y funcionando. Podremos acceder a él mediante

docker-compose exec workspace bash

Estos nos abrirá una terminal dentro de nuestro container y podremos proseguir con la instalación de Laravel y todo lo que necesitemos.

Si este comando falla, deberás cerciorarte del nombre de tu container mediante el comando

docker ps 

Y reemplazarlo en el comando anterior.

Con esto, ya tendrás todo lo necesario para trabajar o compartir tu repositorio. No olvides que a partir de acá vas a tener que crear y configurar tu base de datos, crear tu archivo de entorno (.env), ejecutar migraciones, etc, etc. Supondré que ya sabes cómo hacerlo, pero si tenés dudas con este punto, no dudes en dejarla en los comentarios e intentaré ayudarte.

Creando un contenedor manualmente con Docker-Compose

Otra forma de crear tus contenedores es mediante la creación de un archivo docker-compose. Personalmente prefiero esta segunda opción ya que me da más libertad de elegir qué tecnologías usar, pero es sólo una cuestión de gustos.

Para comenzar, lo primero que haremos será descargar la última versión de Laravel (o la que queramos). Puedes hacerlo desde su repositorio oficial de GitHub mediante el comando

git clone https://github.com/laravel/laravel.git

Una vez clonado, accedemos a él y comenzaremos a incluir los dockerfiles necesarios para crear nuestro entorno.

Para este ejemplo, al igual que el anterior, usaremos NGINX y Postgres, pero le especificaremos que use la imagen de PHP-FPM (FastCGI Process Manager)  el cual mejora considerablemente el uso de recursos al combinarlo con Nginx.

Para esto, dentro de nuestro repositorio, vamos a crear un directorio al que llamaremos docker y dentro de él vamos a crear dos carpetas. Una llamada php-fpm y la otra nginx.

Dentro del directorio php-fpm, vamos a crear un dockerfile. Éste será utilizado por docker-compose para descargar todas las herramientas y dependencias necesarias para tener una PHP dentro del contenedor.

Puedes crear tu archivo dockerfile muy fácilmente con cualquier editor de código. Sólo debes crear un archivo nuevo y colocarle el nombre Dockerfile sin ninguna extensión.

Dentro de ese archivo incluiremos lo siguiente:

FROM php:7.2-fpm

# Instala Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

# instala extensiones de PHP necesarias
RUN apt-get update && \
    apt-get install -y libzip-dev zlib1g-dev libonig-dev zlibc libicu-dev libpq-dev libmemcached-dev locales vim.tiny git

RUN docker-php-ext-install mbstring zip pdo_pgsql

# Genera 'locale' para es_AR
RUN echo "es_AR.UTF-8 UTF-8" >> /etc/locale.gen
RUN locale-gen
RUN echo "es      es_AR.UTF-8" >> /etc/locale.alias

WORKDIR /var/www

Con esto, docker descargará e instalará todo lo necesario para que PHP-FPM y Laravel funcionen. Como verás, estamos usando la versión 7.2 de PHP para poder correr Laravel 6 sin problemas, pero puedes especificar la que necesites.

Lo siguiente será hacer lo mismo con NGINX, para ello, vamos al directorio que creamos y generamos otro archivo llamado Dockerfile.

En él, pondremos lo siguiente:

FROM nginx:latest

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

Esto tomará la última imagen disponible de Nginx y lo incluirá en nuestro container.

Dentro de este mismo directorio vamos a crear otro archivo al que llamaremos vhost.conf y dentro de él escribiremos el siguiente código:

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;
 }
 }

Ahora llegó la hora de crear nuestro archivo docker-compose. Vamos a la raíz de nuestro repositorio y creamos un archivo llamado docker-compose.yml. Dentro de él, vamos a llamar a los dockerfiles que creamos anteriormente y a configurar los puertos que expondremos para acceder a nuestra aplicación y a nuestra base de datos.

Nuestro docker-compose debería quedar así:

version: '3'

services:
  web:
    build:
      context: ./
      dockerfile: docker/nginx/Dockerfile
    volumes:
      - ./:/var/www
    ports:
      - 8095:80
    links:
      - app
  app:
    build:
      context: ./
      dockerfile: docker/php-fpm/Dockerfile
    volumes:
      - ./:/var/www
    ports:
      - 9000:9000
    links:
      - db
    environment:
      - DB_PORT=5432
      - DB_HOST=db
      - DB_CONNECTION=pgsql
  db:
    image: postgres:9-alpine
    environment:
      - POSTGRES_PASSWORD=tupassword
    ports:
      - 5432:5432

En este caso, vamos a mapear el puerto 8095 de nuestra pc con el puerto 80 del contenedor. Esto quiere decir que cuando queramos acceder a nuestra aplicación, lo haremos mediante http://localhost:8095. Por supuesto que esto lo puedes modificar a tu antojo.

La base de datos, por otro lado, será accesible mediante el puerto 5432. Como vez, también está mapeado al puerto 5432 del contenedor y esto lo hacemos para reservar ese puerto y evitar que cada vez que levantemos el container el puerto cambie.

Con todo esto, ya estamos en condiciones que lanzar nuestro contenedor. Para eso, usamos el comando:

docker-compose up

Una vez finalizada la descarga y configuración, ya podremos acceder al contenedor y comenzar a configurar todas las dependencias del proyecto.

Consideraciones finales

Esta fue una guía rápida para construir un contenedor en docker, suponiendo que ya cuentas con una base en el manejo de esta tecnología, como así también, que ya tienes experiencia previa en la construcción de un proyecto de Laravel.

Docker es una herramienta muy poderosa que te simplificará muchas cosas, en especial si trabajas junto a otros desarrolladores en un mismo proyecto, además de que es un skill que te abrirá puertas de cara al mercado laboral.

Si tenés alguna duda o querés que profundice en algún aspecto de este artículo, no dudes de dejarlo en los comentarios.

10 replies on “ Cómo crear un proyecto de Laravel 6 en Docker. La magia de Docker-Compose ”
  1. Excelente, justo buscaba un tutorial de esto, aunque esta casi igual de sencillo en la documentacion de laradock, pero el asunto es que tengo un problema durante la ejecucion del comando: https://i.imgur.com/P2sGCbl.png

    Simplemente , cada vez que ejecuto el docker-compose up -d nginx postgres phpmyadmin se me queda ahi, no sigue mas.

    1. Hola! Hay varias cosas que podés probar. En primer lugar, intenta con docker-compose up -d workspace a ver si logra hacer el build de eso.
      Otra cosa que podés hacer es correr el comando que venías corriendo pero sin el ‘-d’ para ver la salida completa del comando y ver si da algun otro error.
      Otra alternativa sería ejecutar docker-compose down para eliminar el container, eliminar cualquier imagen que haya quedado colgada con docker rmi y el id de la imagen, para luego volver a ejecutar docker-compose up
      NOTA IMPORTANTE: antepone sudo delante de los comandos, por las dudas.
      Avisame cómo te va

    1. Hola! Antes que nada, gracias por leer mi post. Lo que está faltando es un archivo llamado vhost.conf dentro de la carpeta nginx que creaste.
      En ese archivo, coloca lo siguiente:

      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;
      }
      }

      Guardalo, y ejecuta docker-compose down para que elimine todo y luego nuevamente docker-compose up

Deja un comentario

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