Tutorial

Cómo configurar Laravel, Nginx y MySQL con Docker Compose

Published on December 5, 2019
Español
Cómo configurar Laravel, Nginx y MySQL con Docker Compose

El autor seleccionó a The FreeBSD Foundation para recibir una donación como parte del programa Write for DOnations.

Introducción

Durante los últimos años, Docker se ha convertido en una solución de uso frecuente para implementar aplicaciones gracias a la forma en que simplifican el funcionamiento y la implementación de aplicaciones en contenedores efímeros. Cuando se usa una pila de aplicación LEMP, por ejemplo, con PHP, Nginx, MySQL y el framework de Laravel, Docker puede simplificar considerablemente el proceso de configuración.

Docker Compose ha simplificado aún más el proceso de desarrollo al permitir que los desarrolladores definan su infraestructura, incluidos los servicios de aplicación, las redes y los volúmenes, en un único archivo. Docker Compose ofrece una alternativa eficaz para ejecutar varios comandos docker container create y docker container run.

A través de este tutorial, creará una aplicación web utilizando el marco Laravel con Nginx como servidor web y MySQL como base de datos; todo ello dentro de contenedores de Docker. Definirá toda la configuración de pila en un archivo docker-compose, junto con los archivos de configuración para PHP, MySQL y Nginx.

Requisitos previos

Antes de comenzar, necesitará lo siguiente:

Paso 1: Descargar Laravel e instalar dependencias

Como primer paso, obtendremos la versión más reciente de Laravel e instalaremos las dependencias del proyecto. Incluiremos Composer, el administrador de paquetes de nivel de aplicación para PHP. Instalaremos estas dependencias con Docker para evitar la instalación de Composer a nivel global.

Primero, compruebe que se encuentre en su directorio de inicio, clone la última versión de Laravel y dispóngala en un directorio llamado laravel-app:

  1. cd ~
  2. git clone https://github.com/laravel/laravel.git laravel-app

Posiciónese en el directorio laravel-app:

  1. cd ~/laravel-app

A continuación, utilice la imagen de composer de Docker a fin de montar los directorios que necesitará para su proyecto de Laravel y evitar la sobrecarga que implica instalar Composer a nivel global:

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

Mediante los indicadores -v y --rm con docker run se crea un contenedor efímero para el cual se aplica un montaje “bind” a la lista de comandos actual antes de su eliminación. Con esto, se copiará el contenido de su directorio ~/laravel-app al contenedor y también se garantizará que la carpeta vendor creada por Composer dentro del contenedor se copie a su directorio actual.

Como paso final, establezca permisos en el directorio del proyecto para que sea propiedad de su usuario no root:

  1. sudo chown -R $USER:$USER ~/laravel-app

Esto será importante al escribir el Dockerfile para la imagen de su aplicación en el paso 4, ya que le permitirá trabajar con el código de la aplicación y ejecutar procesos en su contenedor como usuario no root.

Una vez establecido el código de su aplicación, puede proceder a definir sus servicios con Docker Compose.

Paso 2: Crear el archivo de Docker Compose

Desarrollar sus aplicaciones con Docker Compose simplifica el proceso de configuración y control de versiones de su infraestructura. Para configurar nuestra aplicación de Laravel, escribiremos un archivo docker-compose que defina nuestro servidor web, nuestra base de datos y nuestros servicios de aplicación.

Abra el archivo:

  1. nano ~/laravel-app/docker-compose.yml

En el archivo docker-compose, definirá tres servicios: app, webserver y db. Agregue el siguiente código al archivo, asegúrese de sustituir la contraseña root de MySQL_ROOT_PASSWORD, definida como una variable de entorno bajo el servicio db, por una contraseña segura de su elección:

~/laravel-app/docker-compose.yml
version: '3'
services:

  #PHP Service
  app:
    build:
      context: .
      dockerfile: Dockerfile
    image: digitalocean.com/php
    container_name: app
    restart: unless-stopped
    tty: true
    environment:
      SERVICE_NAME: app
      SERVICE_TAGS: dev
    working_dir: /var/www
    networks:
      - app-network

  #Nginx Service
  webserver:
    image: nginx:alpine
    container_name: webserver
    restart: unless-stopped
    tty: true
    ports:
      - "80:80"
      - "443:443"
    networks:
      - app-network

  #MySQL Service
  db:
    image: mysql:5.7.22
    container_name: db
    restart: unless-stopped
    tty: true
    ports:
      - "3306:3306"
    environment:
      MYSQL_DATABASE: laravel
      MYSQL_ROOT_PASSWORD: your_mysql_root_password
      SERVICE_TAGS: dev
      SERVICE_NAME: mysql
    networks:
      - app-network

#Docker Networks
networks:
  app-network:
    driver: bridge

Los servicios definidos aquí incluyen lo siguiente:

  • app: esta definición de servicio contiene la aplicación de Laravel y ejecuta una imagen personalizada de Docker, digitalocean.com/php, que usted definirá en el paso 4. También fija /var/www para working_dir en el contenedor.
  • webserver: esta definición de servicio obtiene la imagen nginx:alpine de Docker y expone los puertos 80 y 443.
  • db: esta definición de servicio obtiene la imagen mysql:5.7.22 de Docker y define algunas variables de entorno, incluida una base de datos llamada laravel para su aplicación y la contraseña root para la base de datos. Puede nombrar la base de datos como lo desee y debe sustituir your_mysql_root_password por su propia contraseña segura. Esta definición de servicio también asigna el puerto 3306 en el host al puerto 3306 en el contenedor.

Cada propiedad container_name define un nombre para el contenedor, que corresponde al nombre del servicio. Si no define esta propiedad, Docker asignará un nombre a cada contenedor combinando el nombre de una persona históricamente famosa y una palabra al azar separada por un guión bajo.

Para facilitar la comunicación entre contenedores, los servicios se conectan a una red de puente llamada app-network. Una red de puente utiliza un puente de software que permite que los contenedores conectados a la misma red de puente se comuniquen entre sí. El controlador de puente instala de forma automática reglas en la máquina host para que los contenedores de diferentes redes de puente no puedan comunicarse directamente entre sí. Esto crea un mayor nivel de seguridad para las aplicaciones y garantiza que solo los servicios relacionados puedan comunicarse entre sí. También implica que usted puede definir diferentes redes y servicios que se conectan a funciones relacionadas: los servicios de aplicaciones clientes pueden utilizar una red frontend, por ejemplo, y los servicios de servidor pueden usar una red backend.

Veamos la forma de agregar volúmenes y montajes “bind” a sus definiciones de servicio para persistir los datos de su aplicación.

Paso 3: Persistir datos

Docker tiene características potentes y convenientes para la persistencia de datos. En nuestra aplicación, usaremos volúmenes y montajes bind para persistir la base de datos y los archivos de aplicación y configuración. Los volúmenes ofrecen flexibilidad para los respaldos y la persistencia más allá del ciclo de vida de un contenedor, mientras que los montajes “bind” facilitan los cambios de código durante el desarrollo y realizan cambios en los archivos host o directorios disponibles de inmediato en sus contenedores. En nuestra configuración usaremos ambas opciones.

Advertencia: Al usar montajes “bind”, permite cambiar el sistema de archivos host a través de procesos que se ejecutan en un contenedor. Se incluye la creación, modificación o eliminación de archivos o directorios importantes del sistema. Esta es una poderosa capacidad que tiene consecuencias para la seguridad y podría afectar a los procesos no Docker del sistema host. Use los montajes “bind” con cuidado.

En el archivo docker-compose, defina un volumen llamado dbdata bajo la definición de servicio db para persistir la base de datos de MySQL:

~/laravel-app/docker-compose.yml
...
#MySQL Service
db:
  ...
    volumes:
      - dbdata:/var/lib/mysql
    networks:
      - app-network
  ...

El volumen llamado dbdata persiste el contenido de la carpeta /var/lib/mysql situada dentro del contenedor. Esto le permite detener y reiniciar el servicio db sin perder datos.

En la parte inferior del archivo, agregue la definición para el volumen dbdata:

~/laravel-app/docker-compose.yml
...
#Volumes
volumes:
  dbdata:
    driver: local

Una vez implementada esta definición, podrá utilizar este volumen en todos los servicios.

A continuación, agregue un montaje “bind” al servicio db para los archivos de configuración de MySQL que creará en el paso 7:

~/laravel-app/docker-compose.yml
...
#MySQL Service
db:
  ...
    volumes:
      - dbdata:/var/lib/mysql
      - ./mysql/my.cnf:/etc/mysql/my.cnf
  ...

Este montaje “bind” vincula ~/laravel-app/mysql/my.cnf a /etc/mysql/my.cnf en el contenedor.

A continuación, agregue montajes “bind” al servicio webserver. Habrá dos: uno para el código de su aplicación y otro para la definición de configuración de Nginx que creará en el paso 6:

~/laravel-app/docker-compose.yml
#Nginx Service
webserver:
  ...
  volumes:
      - ./:/var/www
      - ./nginx/conf.d/:/etc/nginx/conf.d/
  networks:
      - app-network

El primer montaje “bind” vincula el código de la aplicación situado en el directorio ~/laravel-app al directorio /var/www dentro del contenedor. El archivo de configuración que agregará a ~/laravel-app/nginx/conf.d/ también se montará a /etc/nginx/conf.d/ en el contenedor, lo que le permitirá agregar o modificar el contenido del directorio de configuración cuando sea necesario.

Por último, agregue los siguientes montajes “bind” al servicio app para el código de la aplicación y los archivos de configuración:

~/laravel-app/docker-compose.yml
#PHP Service
app:
  ...
  volumes:
       - ./:/var/www
       - ./php/local.ini:/usr/local/etc/php/conf.d/local.ini
  networks:
      - app-network

El servicio app vincula mediante montaje “bind” la carpeta ~/laravel-app, que contiene el código de la aplicación, a la carpeta /var/www en el contenedor. Esto acelerará el proceso de desarrollo, ya que los cambios realizados en el directorio de su aplicación local se reflejarán de inmediato dentro del contenedor. También vinculará su archivo de configuración PHP, ~/laravel-app/php/local.ini, a /usr/local/etc/php/conf.d/local.ini, dentro del contenedor. Creará el archivo de configuración de PHP local en el paso 5.

Ahora, su archivo docker-compose tendrá el siguiente aspecto:

~/laravel-app/docker-compose.yml
version: '3'
services:

  #PHP Service
  app:
    build:
      context: .
      dockerfile: Dockerfile
    image: digitalocean.com/php
    container_name: app
    restart: unless-stopped
    tty: true
    environment:
      SERVICE_NAME: app
      SERVICE_TAGS: dev
    working_dir: /var/www
    volumes:
      - ./:/var/www
      - ./php/local.ini:/usr/local/etc/php/conf.d/local.ini
    networks:
      - app-network

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

  #MySQL Service
  db:
    image: mysql:5.7.22
    container_name: db
    restart: unless-stopped
    tty: true
    ports:
      - "3306:3306"
    environment:
      MYSQL_DATABASE: laravel
      MYSQL_ROOT_PASSWORD: your_mysql_root_password
      SERVICE_TAGS: dev
      SERVICE_NAME: mysql
    volumes:
      - dbdata:/var/lib/mysql/
      - ./mysql/my.cnf:/etc/mysql/my.cnf
    networks:
      - app-network

#Docker Networks
networks:
  app-network:
    driver: bridge
#Volumes
volumes:
  dbdata:
    driver: local

Guarde el archivo y cierre su editor cuando termine de realizar cambios.

Ahora que su archivo docker-compose está escrito, podrá crear la imagen personalizada para su aplicación.

Paso 4: Crear el Dockerfile

Docker le permite especificar el entorno dentro de contenedores individuales con un Dockerfile. Un Dockerfile le permite crear imágenes personalizadas que puede emplear para instalar el software requerido por su aplicación y configurar los ajustes según sus requisitos. Puede introducir en Docker Hub o en cualquier registro privado las imágenes personalizadas que cree.

Nuestro Dockerfile se ubicará en nuestro directorio ~/laravel-app. Cree el archivo:

  1. nano ~/laravel-app/Dockerfile

Este Dockerfile establecerá la imagen de base y especificará los comandos y las instrucciones que se necesitan para crear la imagen de aplicación de Laravel. Agregue el siguiente código al archivo:

~/laravel-app/php/Dockerfile
FROM php:7.2-fpm

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

# Set working directory
WORKDIR /var/www

# Install dependencies
RUN apt-get update && apt-get install -y \
    build-essential \
    libpng-dev \
    libjpeg62-turbo-dev \
    libfreetype6-dev \
    locales \
    zip \
    jpegoptim optipng pngquant gifsicle \
    vim \
    unzip \
    git \
    curl

# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

# Install extensions
RUN docker-php-ext-install pdo_mysql mbstring zip exif pcntl
RUN docker-php-ext-configure gd --with-gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ --with-png-dir=/usr/include/
RUN docker-php-ext-install gd

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

# Add user for laravel application
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www

# Copy existing application directory contents
COPY . /var/www

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

# Change current user to www
USER www

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

Primero, el Dockerfile crea una imagen en la parte superior de la imagen de Docker php:7.2-fpm. Esta es una imagen basada en Debian que tiene instalada la implementación PHP-FPM de PHP FastCGI. El archivo también instala con composer los paquetes previos para Laravel: mcrypt, pdo_mysql, mbstring e imagick.

La directiva RUN especifica los comandos para actualizar, instalar y configurar los ajustes dentro del contenedor. Esto incluye la creación de un usuario dedicado y un grupo llamado www. La instrucción WORKDIR especifica el directorio /var/www como directorio de trabajo para la aplicación.

Crear un usuario dedicado y un grupo con permisos restringidos mitiga la vulnerabilidad inherente al ejecutar contenedores de Docker, que se funcionan por defecto como root. En lugar de ejecutar este contenedor como root, creamos el usuario www, que tiene acceso de lectura y escritura a la carpeta /var/www gracias a la instrucción COPY que usaremos con el indicador --chown para copiar los permisos de la carpeta de la aplicación.

Por último, el comando EXPOSE expone un puerto del contenedor, el 9000, para el servidor php-fpm. CMD especifica el comando que debe ejecutarse una vez que se cree el contenedor. Aquí, el CMD especifica “php-fpm”, que iniciará el servidor.

Guarde el archivo y cierre su editor cuando termine de realizar cambios.

Ahora podrá definir su configuración de PHP.

Paso 5: Configurar PHP

Ahora que definió su infraestructura en el archivo docker-compose, puede configurar el servicio PHP para que funciones como procesador PHP para solicitudes entrantes de Nginx.

Para configurar PHP, creará el archivo local.ini dentro de la carpeta php. Este es el archivo que vinculó mediante montaje “bind” a /usr/local/etc/php/conf.d/local.ini dentro del contenedor en el paso 2. Crear este archivo le permitirá anular el archivo php.ini predeterminado que PHP lee al iniciarse.

Cree el directorio php:

  1. mkdir ~/laravel-app/php

A continuación, abra el archivo local.ini:

  1. nano ~/laravel-app/php/local.ini

Con el propósito de demostrar cómo configurar PHP, agregaremos el siguiente código para establecer limitaciones de tamaño para archivos cargados:

~/laravel-app/php/local.ini
upload_max_filesize=40M
post_max_size=40M

Las directivas upload_max_filesize y post_max_size establecen el tamaño máximo permitido para los archivos cargados y demuestran la forma en que puede configurar parámetros php.ini desde su archivo local.ini. Puede disponer cualquier configuración específica de PHP que desee anular en el archivo local.ini.

Guarde el archivo y cierre el editor.

Una vez preparado su archivo PHP local.ini, podrá configurar Nginx.

Paso 6: Configurar Nginx

Una vez configurado el servicio PHP, podrá modificar el servicio Nginx para usar PHP-FPM como servidor de FastCGI para proporcionar contenido dinámico. El servidor FastCGI se basa en un protocolo binario para interconectar programas interactivos con un servidor web. Para obtener más información, consulte este artículo sobre Comprensión e implementación de proxy de FastCGI en Nginx.

Para configurar Nginx, creará un archivo app.conf con la configuración del servicio en la carpeta ~/laravel-app/nginx/conf.d/.

Primero, cree el directorio nginx/conf.d/:

  1. mkdir -p ~/laravel-app/nginx/conf.d

Luego, cree el archivo de configuración app.conf:

  1. nano ~/laravel-app/nginx/conf.d/app.conf

Agregue el siguiente código al archivo para especificar su configuración de Nginx:

~/laravel-app/nginx/conf.d/app.conf
server {
    listen 80;
    index index.php index.html;
    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /var/www/public;
    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;
    }
    location / {
        try_files $uri $uri/ /index.php?$query_string;
        gzip_static on;
    }
}

El bloque de servidor define la configuración para el servidor web de Nginx con las siguientes directivas:

  • listen: esta directiva define el puerto en el cual el servidor escuchará las solicitudes entrantes.
  • error_log y access_log: estas directivas definen los archivos para escribir registros.
  • root: esta directiva establece la ruta de la carpeta root y forma la ruta para cualquier archivo solicitado en el sistema de archivos local.

En el bloque de ubicación php, la directiva fastcgi_pass especifica que el servicio de app escuchando en un socket TCP del puerto 9000. Esto hace que el servidor PHP-FPM escuche a través de la red en lugar de hacerlo en un socket de Unix. Aunque un socket de Unix tiene una ligera ventaja de velocidad con respecto a un socket de TCP, no cuenta con un protocolo de red y, por lo tanto, omite la pila de red. Para los casos en los cuales los hosts están ubicados en una máquina, puede tener sentido la presencia de un socket de Unix. Sin embargo, en los casos en los que tenga servicios ejecutándose en diferentes hosts, un socket de TCP le ofrece la ventaja de permitirle conectarse a servicios distribuidos. Debido a que nuestro contenedor app se ejecuta en un host diferente del de nuestro contenedor webserver, un socket de TCP es la opción que más sentido tiene para nuestro tipo de configuración.

Guarde el archivo y cierre su editor cuando termine de realizar cambios.

Gracias al montaje “bind” mount que creó en el paso 2, cualquier cambio que realice dentro de la carpeta nginx/conf.d/ se reflejará directamente dentro del contenedor webserver.

A continuación, observaremos nuestras configuraciones de MySQL.

Paso 7: Configurar MySQL

Una vez configurados PHP y Nginx, podrá habilitar MySQL para que actúe como base de datos para su aplicación.

Para configurar MySQL, creará el archivo my.cnf en la carpeta mysql. Este es el archivo que vinculó mediante montaje “bind” a /etc/mysql/my.cnf dentro del contenedor en el paso 2. Este montaje “bind” le permite anular los ajustes de my.cnf según sea necesario.

Para demostrar cómo funciona esto, agregaremos al archivo my.cnf ajustes que habiliten el registro general de consulta y especifiquen el archivo de registro.

Primero, cree el directorio mysql:

  1. mkdir ~/laravel-app/mysql

A continuación, cree el archivo my.cnf:

  1. nano ~/laravel-app/mysql/my.cnf

En el archivo, agregue el siguiente código para habilitar el registro de consulta y establecer la ubicación del archivo de registro:

~/laravel-app/mysql/my.cnf
[mysqld]
general_log = 1
general_log_file = /var/lib/mysql/general.log

Este archivo my.cnf habilita los registros y define la configuración de general_log con el valor 1 para permitir registros generales. La configuración general_log_file especifica dónde se almacenarán los registros.

Guarde el archivo y cierre el editor.

Nuestro siguiente paso será iniciar los contenedores.

Paso 8: Modificar la configuración del entorno y ejecutar los contenedores

Ahora que definió todos sus servicios en su archivo docker-compose y creó los archivos de configuración para estos servicios, puede iniciar los contenedores. Sin embargo, como paso final, crearemos una copia del archivo .env.example que Laravel incluye por defecto y daremos a la copia el nombre .env, que corresponde al archivo que Laravel prevé que definirá su entorno:

  1. cp .env.example .env

Ahora puede modificar el archivo .env en el contenedor app para incluir detalles específicos sobre su configuración.

Abra este archivo utilzando nano o el editor de texto que prefiera:

  1. nano .env

Busque el bloque que especifica DB_CONNECTION y actualícelo para reflejar los detalles de su configuración. Cambiará los siguientes campos:

  • DB_HOST será su contenedor de base de datos db.
  • DB_DATABASE será la base de datos laravel.
  • DB_USERNAME será el nombre de usuario que usará para su base de datos. En este caso, usaremos laraveluser.
  • DB_PASSWORD será la contraseña segura que desee utilizar para esta cuenta de usuario.
/var/www/.env
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=laraveluser
DB_PASSWORD=your_laravel_db_password

Guarde sus cambios y cierre el editor.

Una vez definidos todos sus servicios en su archivo docker-compose, solo deberá emitir un comando para iniciar todos los contenedores, crear los volúmenes y configurar y conectar las redes:

  1. docker-compose up -d

Cuando ejecute docker-compose por primera vez, descargará todas las imágenes de Docker necesarias, lo cual podría tardar un tiempo. Una vez que las imágenes se descarguen y se almacenen en su máquina local, Compose creará sus contenedores. El indicador -d agrega un demonio al proceso y ejecuta sus contenedores en segundo plano.

Una vez que el proceso esté completo, use el siguiente comando para enumerar todos los contenedores en ejecución:

  1. docker ps

Verá el siguiente resultado con detalles sobre sus contenedores app, webserver y db:

Output
CONTAINER ID NAMES IMAGE STATUS PORTS c31b7b3251e0 db mysql:5.7.22 Up 2 seconds 0.0.0.0:3306->3306/tcp ed5a69704580 app digitalocean.com/php Up 2 seconds 9000/tcp 5ce4ee31d7c0 webserver nginx:alpine Up 2 seconds 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp

CONTAINER ID en este resultado es un identificador único para cada contenedor, mientras que NAMES enumera el nombre de servicio asociado con cada una. Puede usar ambos identificadores para acceder a los contenedores. IMAGE define el nombre de imagen para cada contenedor, mientras que STATUS proporciona información sobre el su estado: en ejecución, en proceso de reinicio o detenido.

Ahora, usaremos docker-compose exec para establecer la clave de la aplicación de Laravel. El comando docker-compose exec le permite ejecutar comandos específicos en contenedores.

El siguiente comando generará una clave y la copiará a su archivo .env; esto garantizará que las sesiones y los datos cifrados de su usuario permanezcan seguros:

  1. docker-compose exec app php artisan key:generate

Con esto, dispondrá de los ajustes de entorno necesarios para ejecutar su aplicación. Para almacenar en caché estos ajustes en un archivo, lo cual aumentará la velocidad de carga de su aplicación, ejecute lo siguiente:

  1. docker-compose exec app php artisan config:cache

Sus ajustes de configuración se cargarán en /var/www/bootstrap/cache/config.php en el contenedor.

Como paso final, visite http://your_server_ip en el navegador. Verá la siguiente página de inicio para su aplicación Laravel:

Página de inicio de Laravel

Con sus contenedores en ejecución y la información de su configuración lista, podrá configurar la información de usuario para la base de datos laravel en el contenedor db.

Paso 9: Crear un usuario para MySQL

La instalación predeterminada de MySQL solo crea la cuenta administrativa root, que tiene privilegios ilimitados en el servidor de base de datos. Por lo general, es mejor evitar el uso de la cuenta administrativa root al interactuar con la base de datos. En su lugar, crearemos un usuario de base de datos dedicado para la base de datos de nuestra aplicación de Laravel.

Para crear un nuevo usuario, ejecute un shell bash interactivo en el contenedor db con docker-compose exec:

  1. docker-compose exec db bash

Dentro del contenedor, inicie sesión en la cuenta administrativa root de MySQL:

  1. mysql -u root -p

Se le solicitará la contraseña que estableció para la cuenta root de MySQL durante la instalación en su archivo docker-compose.

Comience revisando la base de datos llamada laravel, que definió en su archivo docker-compose. Ejecute el comando show databases para verificar las bases de datos existentes:

  1. show databases;

Verá la base de datos laravel en el resultado:

Output
+--------------------+ | Database | +--------------------+ | information_schema | | laravel | | mysql | | performance_schema | | sys | +--------------------+ 5 rows in set (0.00 sec)

A continuación, cree la cuenta de usuario que tendrá permisos de acceso a esta base de datos. Nuestro nombre de usuario será laraveluser, aunque puede cambiarlo por otro que prefiera. Asegúrese de que su nombre de usuario y contraseña aquí coincidan con la información que estableció en su archivo .env en el paso anterior:

  1. GRANT ALL ON laravel.* TO 'laraveluser'@'%' IDENTIFIED BY 'your_laravel_db_password';

Elimine los privilegios para notificar los cambios al servidor MySQL:

  1. FLUSH PRIVILEGES;

Cierre MySQL:

  1. EXIT;

Por último, cierre el contenedor:

  1. exit

Con esto, habrá configurado la cuenta de usuario para la base de datos de su aplicación de Laravel y estará listo para migrar sus datos y trabajar con la consola Tinker.

Paso 10: Migrar datos y trabajar con la consola Tinker

Con su aplicación en ejecución, podrá migrar sus datos y experimentar con el comando tinker, que iniciará una consola PsySH con Laravel precargada. PsySH es una consola para desarrolladores de tiempo de ejecución y un depurador interactivo para PHP, y Tinker es un REPL específico para Laravel. Usar el comando tinker le permitirá interactuar con su aplicación de Laravel desde la línea de comandos en un shell interactivo.

Primero, pruebe la conexión con MySQL ejecutando el comando Laravel artisan migrate, que crea una tabla migrations en la base de datos dentro del contenedor:

  1. docker-compose exec app php artisan migrate

Con este comando se migrarán las tablas predeterminadas de Laravel. El resultado que confirme la migración tendrá este aspecto:

Output
Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table Migrating: 2014_10_12_100000_create_password_resets_table Migrated: 2014_10_12_100000_create_password_resets_table

Una vez que la migración esté completa, podrá ejecutar una consulta para verificar si su conexión a la base de datos es correcta usando el comando tinker:

  1. docker-compose exec app php artisan tinker

Pruebe la conexión de MySQL obteniendo los datos que acaba de migrar:

  1. \DB::table('migrations')->get();

Verá un resultado similar a este:

Output
=> Illuminate\Support\Collection {#2856 all: [ {#2862 +"id": 1, +"migration": "2014_10_12_000000_create_users_table", +"batch": 1, }, {#2865 +"id": 2, +"migration": "2014_10_12_100000_create_password_resets_table", +"batch": 1, }, ], }

Puede usar tinker para interactuar con sus bases de datos y experimentar con servicios y modelos.

Una vez implementada su aplicación de Laravel, estará listo para seguir adelante con el desarrollo y la experimentación.

Conclusión

Con esto, dispondrá de una aplicación de pila LEMP en ejecución en su servidor, que probó accediendo a la página de bienvenida de Laravel y creando migraciones de base de datos de MySQL.

La clave de la simplicidad en esta instalación es Docker Compose, que le permite crear un grupo de contenedores de Docker definidos en un solo archivo mediante un comando. Si desea obtener más información sobre cómo realizar una integración continua con Docker Compose, consulte Cómo configurar un entorno de prueba de integración continua con Docker y Docker Compose en Ubuntu 16.04. Si desea simplificar su proceso de implementación de la aplicación de Laravel, resultará pertinente el recurso Cómo implementar de forma automática aplicaciones de Laravel con Deployer en Ubuntu 16.04.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar

Cloud Architect

Principal Engineer | Cloud Architect | Adventurer



Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
6 Comments


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Hola hice todos los pasos pero el nginx tengo esto 403 Forbidden nginx/1.19.8 qué puede estar pasando?

Dockerfile (works for me)

FROM php:7.4-fpm

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

# Set working directory
WORKDIR /var/www

# Install dependencies
RUN apt-get update && apt-get install -y \
    build-essential \
    libpng-dev \
    libjpeg62-turbo-dev \
    libfreetype6-dev \
    libonig-dev \
    libxml2-dev \
    locales \
    zip \
    jpegoptim optipng pngquant gifsicle \
    vim \
    unzip \
    git \
    curl

# Install extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
RUN docker-php-source delete

# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

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

# Add user for laravel application
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www

# Copy existing application directory contents
COPY . /var/www

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

# Change current user to www
USER www

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

Docker-compose.yml

version: '3'
services:

  #PHP Service
  app:
    build:
      context: .
      dockerfile: Dockerfile
    image: digitalocean.com/php
    container_name: laravelapp-app
    restart: unless-stopped
    tty: true
    environment:
      SERVICE_NAME: app
      SERVICE_TAGS: dev
    working_dir: /var/www
    volumes:
      - ./:/var/www
      - ./php/local.ini:/usr/local/etc/php/conf.d/local.ini
    networks:
      - app-network

  #Nginx Service
  webserver:
    image: nginx:alpine
    container_name: laravelapp-webserver
    restart: unless-stopped
    tty: true
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./:/var/www
      - ./nginx/conf.d/:/etc/nginx/conf.d/
    networks:
      - app-network

  #MySQL Service
  db:
    image: mysql:5.7
    container_name: laravelapp-db
    restart: unless-stopped
    tty: true
    ports:
      - "3306:3306"
    environment:
      MYSQL_DATABASE: laravel
      MYSQL_ROOT_PASSWORD: admin1234
      SERVICE_TAGS: dev
      SERVICE_NAME: mysql
    volumes:
      - dbdata:/var/lib/mysql/
      - ./mysql/my.cnf:/etc/mysql/my.cnf
    networks:
      - app-network

#Docker Networks
networks:
  app-network:
    driver: bridge
#Volumes
volumes:
  dbdata:
    driver: local

docker-compose exec app php artisan key:generate

Fatal error: Composer detected issues in your platform: Your Composer dependencies require a PHP version “>= 7.3.0”. You are running 7.2.34. in /var/www/vendor/composer/platform_check.php on line 24

Muy bueno todo, muchas gracias

Great tutorial. Thanks a lot.

Just one thing. Would be great that just having the docker-compose file and the docker file, we could launch the whole app.

How hard do you think it would be to do it?

I tried to run ‘composer create-project laravel/laravel {directory} 4.2 --prefer-dist’ but i faced many problems. I’ll keep working on it.

Hola Faizan!

Soy principiante en Docker y me encontré con las siguientes dudas.

Nota: estoy corriendo Docker en Win10.

Al quere correr la siguiente instrucción docker run --rm -v $(pwd):/app composer install me da el error: docker.exe: invalid reference format.

Supuse por que no seguí el link de Docker composer. Hice: docker pull composer como indica https://hub.docker.com/_/composer

Vuelvo hacer docker run --rm -v $(pwd):/app composer install y me sigue dando el mismo error.

Supuse que es por que no está corriendo composer, ejecuto como indica docker run --rm --interactive --tty \ –volume $PWD:/app \ composer install

En línea: 1 Carácter: 48

  • docker run --rm --interactive --tty \ –volume $PWD:/app \ composer i …
  •                                            ~~~~~
    

La referencia de variable no es válida. El carácter ‘:’ no va seguido de un carácter de nombre de variable válido. Considere la posibilidad de usar ${} para delimitar el nombre. + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : InvalidVariableReferenceWithDrive

je, hasta acá pude hacer.

Espero tu ayuda. Gracias

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Featured on Community

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more