Dockerizando Laravel con Nginx MySQL y Docker Compose en Ubuntu 18.04 LTS

Laravel es un framework PHP gratuito y de código abierto que implementa el patrón de diseño MVC (Modelo-Vista-Controlador). Está diseñado con facilidad de uso y permite a los desarrolladores crear aplicaciones tanto simples como complejas en poco tiempo. Laravel fue creado por Taylor Otwell en 2011, como un intento de proporcionar una alternativa avanzada al framework CodeIgniter (CI). En 2011, Laravel lanzó la versión 1 y la versión 2, y la última versión 5.6 viene con más y mejores características como el soporte de la línea de comandos (CLI) llamado ‘artisan’, soporte para diferentes sistemas de bases de datos, mejoras en Route, etc.

En esta guía, vamos a mostrarte cómo Dockerizar el proyecto Laravel con PHP-FPM, la base de datos MySQL y el servidor web Nginx utilizando el Docker Compose en el servidor Ubuntu 18.04. Vamos a crear una nueva imagen docker para el proyecto Laravel, y luego crearemos el script docker-compose.yml que contiene algunos servicios incluyendo, la propia App/Laravel, el servidor web Nginx, y la base de datos MySQL.

Requisitos previos

  • Ubuntu 18.04
  • Privilegios de root

Qué vamos a hacer

  1. Instalar Docker y Docker Compose
  2. Descargar Laravel e instalar las dependencias
  3. Dockerizar el proyecto Laravel
    • Definir el servicio de la aplicación Laravel
    • Definir el servicio HTTP de Nginx
    • Definir el servicio de base de datos MySQL
    • Crear un host virtual Nginx para Laravel
    • Crear un archivo Docker para la aplicación Laravel
  4. Construir el proyecto Laravel
  5. Post-Instalación de Laravel

Paso 1 – Instalar Docker y Docker Compose

En primer lugar, vamos a instalar los paquetes Docker y Docker Compose en el sistema Ubuntu. Y vamos a utilizar los paquetes Docker del repositorio oficial de Ubuntu.

Antes de seguir adelante, tenemos que actualizar los repositorios en el sistema Ubuntu. Simplemente ejecutando el siguiente comando.

sudo apt update

Ahora instala los paquetes Docker y Docker Compose utilizando el comando apt que aparece a continuación.

sudo apt install docker.io -y
sudo apt install docker-compose -y

Los paquetes Docker y Docker Compose deberían estar ahora instalados en el sistema, compruébalo utilizando los siguientes comandos.

docker version
docker-compose version

Como resultado, obtendrás la versión de Docker y Docker Compose en el sistema.

Comprueba la versión de Docker

A continuación, tenemos que asignar el usuario no root al grupo docker para poder ejecutar el contenedor Docker para usuarios no root.

Para este caso, vamos a añadir el usuario llamado ‘hakase’ al grupo docker ejecutando el siguiente comando.

usermod -a -G docker hakase

Y después, entra en el shell del usuario ‘hakase’ y ejecuta el comando docker ‘hello-world’.

su - hakase
docker run hello-world

Ahora aparecerá el mensaje ‘Hello World’ de Docker, y la instalación de Docker se habrá completado.

Añade un usuario Docker

Paso 2 – Descargar Laravel e instalar las dependencias

En este paso, vamos a descargar el marco web Laravel en el directorio de inicio ‘hakase’ y luego instalaremos las dependencias de Laravel utilizando la imagen docker PHP ‘composer’. Para ello, asegúrate de que has iniciado sesión en el servidor como usuario no root.

Descarga el proyecto Laravel en el directorio ‘myapp’ y entra en él.

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

Ahora ejecuta el siguiente comando docker para instalar las dependencias de Laravel.

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

Con el comando anterior, vamos a ejecutar un nuevo contenedor docker temporal y montar el directorio del proyecto ‘myapp’ en el directorio ‘/app’ del contenedor. El contenedor se basa en la imagen docker ‘composer’, y vamos a instalar las dependencias de Laravel utilizando el comando ‘composer’ dentro de ese contenedor temporal.

Conseguir Laravel Framework

Una vez terminada la instalación de las dependencias de Laravel, debemos cambiar el propietario del directorio ‘myapp’ por nuestro propio usuario utilizando el comando sudo que aparece a continuación.

sudo chown -R $USER:$USER ~/myapp

Cambiar el propietario del directorio de la aplicación

Paso 3 – Dockerizar el proyecto Laravel

Después de descargar Laravel e instalar sus dependencias, vamos a crear un nuevo script docker-compose.yml y crear un nuevo Dockerfile para el proyecto Laravel.

cd myapp/
vim docker-compose.yml

– Definir el servicio de la aplicación Laravel

En primer lugar, vamos a definir el propio proyecto Laravel y a construir la imagen docker para el proyecto Laravel utilizando el Dockerfile.

Pega en él el script docker compose.

version: '3'
services:

  #Laravel App
  app:
    build:
      context: .
      dockerfile: Dockerfile
    image: hakase-labs/laravel
    container_name: app
    restart: unless-stopped
    tty: true
    environment:
      SERVICE_NAME: app
      SERVICE_TAGS: dev
    working_dir: /var/www/html
    volumes:
      - ./:/var/www/html
    networks:
      - mynet

Detalles del servicio de contenedores de Laravel:

  • El servicio de contenedores Laravel se llamará ‘app’. Se basa en nuestra imagen docker personalizada que se creará con nuestro ‘Dockerfile’, y la nueva imagen se llamará ‘hakase-labs/laravel’.
  • Queremos montar el directorio del proyecto ‘myapp’ en ‘/var/www/html’ dentro del servicio de contenedores.
  • Vamos a utilizar la red docker personalizada para nuestra configuración, la red se llamará ‘mynet’.

– Definir el servicio HTTP de Nginx

Ahora definiremos el servicio de contenedor nginx.

Pega la siguiente configuración después de la línea del servicio de contenedor ‘app’.

  #Nginx Service
  nginx:
    image: nginx:alpine
    container_name: nginx
    restart: unless-stopped
    tty: true
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./:/var/www/html
      - ./nginx/conf.d/:/etc/nginx/conf.d/
      - ./nginx/ssl/:/etc/nginx/ssl/
    networks:
      - mynet

Detalles de la configuración del servicio de contenedores nginx:

  • Queremos crear un nuevo contenedor llamado ‘nginx’ basado en la imagen docker ‘nginx:alpine’.
  • El servicio contenedor abrirá los puertos HTTP y HTTPS.
  • El contenedor montará tres volúmenes diferentes. El directorio del proyecto ‘myapp’ en el directorio ‘/var/www/html’, la configuración del host virtual nginx ‘nginx/conf.d/’ en el directorio ‘/etc/nginx/conf.d’, y montará los archivos del certificado ‘nginx/ssl/’ en el directorio ‘/etc/nginx/ssl’ del contenedor.
  • El servicio del contenedor utilizará la misma red llamada ‘mynet’.

– Definir el servicio de base de datos MySQL

Y por último, definimos el servicio de base de datos MySQL.

Pega la siguiente configuración después de la línea del servicio del contenedor ‘nginx’.

  #MySQL Service
  db:
    image: mysql:5.7
    container_name: db
    restart: unless-stopped
    tty: true
    ports:
      - "3306:3306"
    environment:
      MYSQL_DATABASE: laraveldb
      MYSQL_USER: laravel
      MYSQL_PASSWORD: laravelpassworddb
      MYSQL_ROOT_PASSWORD: rootpasswordmysql
    volumes:
      - mysqldata:/var/lib/mysql/
    networks:
      - mynet

#Docker Networks
networks:
  mynet:
    driver: bridge
#Volumes
volumes:
  mysqldata:
    driver: local

Guarda y cierra la configuración.

Detalla el servicio contenedor MySQL:

  • El servicio contenedor de MySQL se llamará ‘db’, basándose en la imagen docker ‘mysql:5.7’.
  • El servicio ‘db’ abrirá el puerto por defecto de MySQL ‘3306’.
  • El proyecto Laravel utilizará la base de datos, el usuario y la contraseña basados en la variable de entorno del servicio ‘db’.
  • El servicio ‘db’ de MySQL montará el volumen llamado ‘mysqldata’, y tendrá la misma red ‘mynet’.
  • Y definimos la red personalizada ‘mynet’ con el controlador ‘bridge’, y el volumen ‘mysqldata’ utilizará el controlador ‘local’.

A continuación se muestra la configuración completa de ‘docker-compose.yml’:

version: '3'
services:

  #Laravel App
  app:
    build:
      context: .
      dockerfile: Dockerfile
    image: hakase-labs/laravel
    container_name: app
    restart: unless-stopped
    tty: true
    environment:
      SERVICE_NAME: app
      SERVICE_TAGS: dev
    working_dir: /var/www/html
    volumes:
      - ./:/var/www/html
    networks:
      - mynet

  #Nginx Service
  nginx:
    image: nginx:alpine
    container_name: nginx
    restart: unless-stopped
    tty: true
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./:/var/www/html
      - ./nginx/conf.d/:/etc/nginx/conf.d/
      - ./nginx/ssl/:/etc/nginx/ssl/
    networks:
      - mynet

  #MySQL Service
  db:
    image: mysql:5.7
    container_name: db
    restart: unless-stopped
    tty: true
    ports:
      - "3306:3306"
    environment:
      MYSQL_DATABASE: laraveldb
      MYSQL_USER: laravel
      MYSQL_PASSWORD: laravelpassworddb
      MYSQL_ROOT_PASSWORD: rootpasswordmysql
    volumes:
      - mysqldata:/var/lib/mysql/
    networks:
      - mynet

#Docker Networks
networks:
  mynet:
    driver: bridge
#Volumes
volumes:
  mysqldata:
    driver: local

– Crea un host virtual Nginx para Laravel

Dentro del directorio del proyecto ‘myapp’, crea un nuevo directorio llamado ‘nginx’ que contendrá otros dos directorios ‘conf.d’ y ‘ssl’. A continuación, crea una nueva configuración de host virtual nginx ‘laravel.conf’ dentro del directorio ‘conf.d’.

Ejecuta el siguiente comando.

mkdir -p nginx/{conf.d,ssl}
vim nginx/conf.d/laravel.conf
server {
    listen 80;
    server_name laravel.hakase-labs.io;

    return 301 https://laravel.hakase-labs.io$request_uri;
}


server {
    listen 443 ssl http2;
    server_name laravel.hakase-labs.io;

    ssl_certificate /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;

    # Log files for Debug
    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;

    # Laravel web root directory
    root /var/www/html/public;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
        gzip_static on;
    }

    # Nginx Pass requests to PHP-FPM
    location ~ \.php$ {
        try_files $uri =404;
        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;
    }
}

Guarda y cierra.

Después, copia tu archivo de certificado ssl en el directorio ‘nginx/ssl/’.

sudo cp /path/to/ssl/fullchain.pem nginx/ssl/
sudo cp /path/to/ssl/privkey.pem nginx/ssl/

– Crea un Dockerfile para la aplicación Laravel

A continuación, crea un nuevo Dockerfile para el proyecto Laravel.

Ejecuta el siguiente comando.

vim Dockerfile

Pega la configuración de abajo.

# Set master image
FROM php:7.2-fpm-alpine

# Copy composer.lock and composer.json
COPY composer.lock composer.json /var/www/html/

# Set working directory
WORKDIR /var/www/html

# Install Additional dependencies
RUN apk update && apk add --no-cache \
    build-base shadow vim curl \
    php7 \
    php7-fpm \
    php7-common \
    php7-pdo \
    php7-pdo_mysql \
    php7-mysqli \
    php7-mcrypt \
    php7-mbstring \
    php7-xml \
    php7-openssl \
    php7-json \
    php7-phar \
    php7-zip \
    php7-gd \
    php7-dom \
    php7-session \
    php7-zlib

# Add and Enable PHP-PDO Extenstions
RUN docker-php-ext-install pdo pdo_mysql
RUN docker-php-ext-enable pdo_mysql

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

# Remove Cache
RUN rm -rf /var/cache/apk/*

# Add UID '1000' to www-data
RUN usermod -u 1000 www-data

# Copy existing application directory permissions
COPY --chown=www-data:www-data . /var/www/html

# Change current user to www
USER www-data

# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]

Guarda y cierra la configuración.

Y ya estamos listos para construir el proyecto Laravel ‘myapp’ y ejecutar los servicios del contenedor que hemos definido.

Paso 4 – Construir Laravel con los servicios Nginx y MySQL

Construye la imagen docker personalizada para nuestro proyecto Laravel utilizando el siguiente comando.

docker-compose build

Construir Laravel con servicios Nginx y MySQL

A continuación, ejecuta de nuevo el siguiente comando.

docker-compose up -d

Descargará todas las imágenes docker que necesitemos y luego construirá los servicios de contenedor basándose en la configuración ‘docker-compose.yml’.

Descargar imágenes Docker

Cuando se haya completado, verifícalo utilizando el comando docker-compose que aparece a continuación.

docker-compose ps

Y como resultado, obtendrás que los tres servicios de contenedor están en marcha. La ‘app’ que se ejecuta en el puerto por defecto ‘9000’ PHP-FPM, el servicio ‘nginx’ está en los puertos HTTP y HTTPS, y el servicio ‘db’ MySQL en el puerto por defecto MySQL ‘3306’.

Después de esto, verifica de nuevo todas las imágenes docker disponibles y los puertos abiertos en el sistema.

docker-compose images
netstat -plntu

Tendrás la imagen docker personalizada ‘hakase-labs/laravel’ en la lista, y los puertos HTTP y HTTPS están en estado ‘LISTEN’.

Comprueba la configuración de Docker con netstat

Paso 5 – Post-Instalación de Laravel

Hasta esta etapa, el proyecto Laravel está funcionando como un contenedor Docker. Y ahora vamos a crear un nuevo archivo ‘.env’, generar la clave y migrar los datos de Laravel utilizando la línea de comandos de Laravel ‘artisan’.

Copia el ejemplo de archivo ‘.env’ y edítalo dentro del contenedor.

cp .env.example .env
docker-compose exec app vim .env

Cambia la configuración de la base de datos como se indica a continuación.

DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=laraveldb
DB_USERNAME=laravel
DB_PASSWORD=laravelpassworddb

Guarda y cierra.

A continuación, genera la clave de la aplicación Laravel y borra la configuración de la caché.

docker-compose exec app php artisan key:generate
docker-compose exec app php artisan config:cache

Después, migra la base de datos con el siguiente comando.

docker-compose exec app php artisan migrate

Asegúrate de que no hay ningún error.

Instalación del puesto de Laravel

Ahora abre tu navegador web y escribe el nombre de dominio de tu proyecto

http://laravel.hakase-labs.io/

Y serás redirigido a la conexión segura HTTPS y se mostrará la página de inicio de Laravel por defecto como se muestra a continuación.

Laravel con Docker instalado con éxito

Finalmente, la Dockerización del proyecto Laravel con el servidor web Nginx y la base de datos MySQL se ha completado con éxito.

También te podría gustar...