Hacer deploy de una aplicación Laravel a Digital Ocean

En este tutorial aprenderás a hacer deployment de tus proyectos Laravel hacia un droplet de Digital Ocean.

¿Digital Ocean? ¿Droplet?

Digital Ocean ofrece uno de los mejores servicios de VPS y a un precio justo.

A diferencia de los hosting tradicionales (aquellos que tienen CPanel), en Digital Ocean puedes configurar tú mismo el stack que tu aplicación requiere. Además, el equipo de soporte responde de forma atenta y en poco tiempo.

Un droplet es una máquina virtual, a la que tendrás acceso por SSH (vía consola).

En Digital Ocean puedes crear tantos droplets como requieras. Incluso puedes tener varias aplicaciones sobre el mismo droplet (lo que resulta muy útil si deseas tener en línea tus primeros proyectos).

Así mismo, en Digital Ocean el pago es por uso.

Eso significa que si a mitad de mes deseas apagar el droplet que creaste, o cancelarlo, podrás hacerlo y así pagar solo por lo que corresponde ?

Entonces, empecemos.

Registro en Digital Ocean (obtén 100$ gratuitos)

El registro en Digital Ocean es muy fácil de seguir, y ahora te explicaré cómo hacerlo paso a paso. Pero antes quiero comentarte algo.

Si te registras en la plataforma por invitación de algún usuario, obtienes 100$ gratuitos de bienvenida. En este caso, yo te invito a registrarte haciendo clic aquí.

Registrarte a través de mi enlace de referidos no te supone ningún costo adicional, pero sí te da un beneficio: obtener 100$ iniciales, que podrás usar para contratar el servicio durante los 2 primeros meses.

Además, si te has registrado a través de mi invitación y tienes alguna duda sobre este tutorial, no dudes en usar la sección de contacto o escribir tu duda en los comentarios, que de seguro te ayudaré.

Tu primer Droplet

Para iniciar, debes dar clic al botón verde superior.

Crear mi primer droplet

Al presionar este botón, cargará una página para configurar los parámetros del droplet a crear.

Lo primero que haremos es definir una imagen.

En nuestro caso usaremos el stack LAMP para no hacer toda la configuración desde 0.

Para ello debes dirigirte a la pestaña Marketplace y seleccionar LAMP on Ubuntu 20.04.

De hecho tienes un buscador, por lo que puedes escribir LAMP para encontrar la imagen más fácilmente:

Stack LAMP

Lo siguiente será definir el tamaño que tendrá nuestro droplet. Cada opción tiene características distintas y suponen un precio a pagar por mes.

Incluso se detalla el precio por hora, porque si decidimos suspender nuestro droplet, solo se nos cobrará por el consumo correspondiente.

Para este ejemplo, vamos a elegir el plan más básico.

Recuerda que es posible escalar fácilmente en un futuro, a un droplet con más recursos, en caso sea necesario.

Tamaño del droplet

Posterior a ello no es necesario cambiar nada más. Aunque si lo deseas también puedes:

  • Usar un datacenter en específico (el más cercano a donde se encuentra tu audiencia).
  • Asignar un nombre a tu droplet (para que sea fácil identificarlo a futuro cuando tengas más).
Escoger un nombre para el droplet

Autenticación

Respecto a la autenticación, Digital Ocean nos ofrece 2 alternativas:

  • Generar llaves SSH
  • Asignar una contraseña a nuestro droplet

Puedes usar la alternativa que prefieras:

  • La primera alternativa deshabilita el inicio de sesión con contraseña, evitando así ataques de "fuerza bruta".
  • Sin embargo si estás aprendiendo, lo más práctico y directo es definir una contraseña.

En esta guía optaremos por la segunda opción:

Usar una contraseña o llaves SSH como autenticación

El último paso es dar clic al botón "Create Droplet".

Pero recuerda:

Éste botón no se habilitará mientras no ingreses una contraseña segura.

Digital Ocean nos exige una contraseña que cumpla con las siguientes condiciones:

  • Tiene al menos 8 caracteres
  • Contiene al menos una letra en mayúsculas (sin contar al primer y último caracter)
  • Contiene al menos un número
  • No termina en número ni en un caracter especial
Escoge una contraseña segura para tu droplet en Digital Ocean

Una vez que hayas ingresado una contraseña, recuerda guardar ésta en un lugar seguro, ya que no recibirás un correo con tus datos de autenticación para el droplet.

En breve usaremos esta contraseña para conectarnos a nuestro droplet a través de la terminal (conexión SSH).

  • Si te encuentras en Windows puedes usar la herramienta PuTTy para hacer posible esta conexión.
  • En Linux o Mac, la terminal por sí misma soporta el comando ssh para lograr esto.

Configuración del droplet

Para configurar nuestro VPS, e instalar lo necesario para que nuestro proyecto de Laravel funcione, lo primero es que te conectes vía SSH.

Si lo deseas, puedes acompañar este tutorial escrito viendo este otro en formato de video. Pero es opcional.

Una vez conectado al droplet:

Lo primero que haremos será asegurarnos de que todo está correctamente actualizado:

sudo apt-get update
sudo apt-get dist-upgrade

De seguro tu droplet ya está preconfigurado, si escogiste la opción LAMP. Pero estos comandos nos dan la seguridad de tener todo al día.

Una vez que hemos actualizado, activamos el módulo mod_rewrite de Apache con el siguiente comando:

sudo a2enmod rewrite

Este módulo es lo que permite a Laravel definir URLs amigables:

Permite el funcionamiento de las rutas.

Configurando MySQL para producción

Podemos usar el siguiente comando, para iniciar la configuración de MySQL:

mysql_secure_installation

Aquí se nos pedirá ingresar la contraseña (en versiones más recientes no lo solicita; en caso que sí, debemos pegar lo que copiamos antes).

El comando iniciará la configuración, y te preguntará por varios detalles.

Para responder con un sí debes escribir una "y". Cualquier otro caracter se corresponde con un no. Responde según convenga.

En resumen, las preguntas serán las siguientes (y las respuestas que usaremos en este caso son también las siguientes):

  • ¿Desea instalar un plugin para validar la fortaleza de las contraseñas?: No
  • ¿Desea cambiar la contraseña para el usuario principal de la base de datos?: Sí
  • Nueva contraseña: [Aquí debes ingresar la que consideres adecuada; es importante cambiar la contraseña por motivos de seguridad y tenerla guardada en algún lugar importante]
  • Volver a ingresar la contraseña: [Repetimos la nueva contraseña que usaremos en adelante]
  • ¿Desea eliminar los usuarios anónimos? Sí
  • Deshabilitar conexión remota a la base de datos: Sí
  • ¿Desea eliminar las tablas de prueba y sus accesos? Sí
  • ¿Desea recargar los privilegios de las tablas ahora? Sí

Instalación de phpMyAdmin

Instalar phpMyAdmin es un paso opcional.

Vamos a hacerlo como parte de este tutorial ya que la mayoría cuando empieza suele apoyarse bastante de esta herramienta para ejecutar consultas rápidas.

Según lo necesites, recuerda que luego también puedes habilitar una conexión remota y usar el cliente MySQL de tu preferencia. Por ejemplo:

  • Workbench,
  • DataGrip,
  • Sequel Pro,
  • etcétera.

Entonces, para contar con phpMyAdmin, ejecuta el siguiente comando para iniciar con el proceso de instalación:

sudo apt-get install phpmyadmin

El instalador te hará varias preguntas. Tenemos que:

  • Seleccionar Apache2
  • Escoger YES cuando nos pregunte Configure database for phpmyadmin with dbconfig-common?
  • Ingresar nuestra nueva contraseña de MySQL (que configuramos hace instantes)
  • Repetir nuevamente la contraseña

Una vez instalado editamos el archivo de configuración de Apache:

sudo nano /etc/apache2/apache2.conf

Y añadimos esta línea al final de todo:

Include /etc/phpmyadmin/apache.conf

Con ello finalizamos la instalación, y debemos reiniciar Apache antes de continuar:

sudo service apache2 restart

La instalación que hemos hecho hasta ahora nos permitirá administrar nuestras base de datos fácilmente accediendo a /phpmyadmin desde la IP de nuestro droplet.

Hasta aquí, la configuración resulta útil para cualquier proyecto de PHP. Ahora pasaremos a configurar puntos más específicos con relación a Laravel.

Configuración específica para Laravel

Lo primero que haremos será instalar Composer:

curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer

Y luego Git, para que luego podamos hacer deploy a través de un repositorio.

sudo apt-get install git

Nota:

En realidad la imagen LAMP que escogiste (al crear el droplet) ya instala Composer y Git. Pero dejo estos comandos de todas formas para estar seguros.

Llegados a este punto:

Ya tenemos todo listo para clonar nuestro proyecto Laravel, a partir de un repositorio remoto, que se puede encontrar en GitHub, Bitbucket, GitLab u otro.

Para ello nos ubicamos en /var/www de la siguiente manera:

Carpeta var/www

¡Y clonamos nuestro repositorio!

En mi caso usaré:

git clone https://github.com/JCarlosR/gestion-incidencias.git

Como mi proyecto se llama gestion-incidencias, voy a verificar que esta carpeta se haya creado correctamente ingresando con cd y luego consultando su contenido con ls.

Así como lo muestra la imagen:

Carpeta creada

Nuestra carpeta se ha creado. Pero recuerda:

Un proyecto Laravel tiene dependencias sobre otros paquetes. Estas dependencias se encuentran declaradas en el archivo composer.json.

Entonces para instalar lo necesario ejecutamos el siguiente comando:

composer install

La descarga de las dependencias probablemente tarde un par de minutos, dependiendo del proyecto.

Nota:

Si no puedes instalar las dependencias por no contar con las extensiones de php requeridas por Laravel, y usas php7.4, puedes instalarlas usando:

sudo apt-get install php7.4-curl php7.4-gd php7.4-json php7.4-mbstring php7.4-intl php7.4-mysql php7.4-xml php7.4-zip

El comando composer install creará una carpeta vendor dentro de la carpeta de tu proyecto Laravel, con las dependencias que han sido descargadas.

Una vez que haya finalizado esta descarga de dependencias, debemos dar permisos a la carpeta storage.

Para ello ejecutamos:

sudo chown -R www-data: storage
sudo chmod -R 755 storage

Apuntar a la carpeta /public

¡Ánimos! Estamos muy cerca del final.

Lo que nos falta es que nuestro host reconozca a la carpeta public como la ruta base de nuestro proyecto.

Para ello tenemos que editar un archivo de configuración de Apache con el siguiente comando:

nano /etc/apache2/sites-enabled/000-default.conf

Aquí tenemos que reemplazar estas lineas:

DocumentRoot /var/www/html

<Directory /var/www/html/>

Por estas 2, respectivamente:

DocumentRoot /var/www/gestion-incidencias/public

<Directory /var/www/gestion-incidencias/public/>

Y agregar estas 2 líneas dentro de la etiqueta Directory:

RewriteEngine On
RewriteBase /var/www/gestion-incidencias/public

Guardamos los cambios en el archivo, y reiniciamos Apache una última vez:

sudo service apache2 restart

Creando nuestro archivo de configuración .env

Nuestro servidor ya está configurado, pero recordemos que todo proyecto Laravel se basa en un archivo .env para guardar allí las credenciales que usa nuestro sistema.

Este archivo .env forma parte de nuestro .gitignore por lo que (como se espera) no fue clonado y tenemos que crearlo.

Para ello tenemos 2 alternativas:

  1. Copiar el archivo de ejemplo que viene con Laravel y reemplazar allí las credenciales.

  2. Crear un archivo nuevo vacío y pegar allí el contenido de nuestro archivo .env local.

A fin de cuentas el resultado es el mismo.

Si optas por la alternativa (1) puedes usar los siguientes 2 comandos. Si optas por la anternativa (2) sólo usa el 2do y el archivo estará vacío.

cp .env.example .env
nano .env

Ten en cuenta que:

Vamos a tener una configuración distinta para producción y desarrollo. Es decir, nuestros archivos .env serán distintos.

Un ejemplo simple para que se entienda esto es lo siguiente:

De forma local no uso contraseña para conectarme a MySQL, pero en producción es indispensable definir una.

Base de datos, Migraciones y Seeders

En mi archivo .env la variable DB_DATABASE tiene como valor incidencias. Eso significa que ese es el nombre de la base de datos que usa mi proyecto.

Lo que haré entonces será crear esta base de datos.

Tú debes hacer lo mismo:

Crear la base de datos que tu proyecto requiere.

  • Lo puedes hacer desde phpMyAdmin,
  • o desde la consola misma (CREATE DATABASE incidencias;).

Esta base de datos estará totalmente vacía, pero las migraciones harán magia y crearán las tablas:

php artisan migrate

Si tus seeders solo contienen datos de prueba que usas de forma local, no será necesario ejecutarlos aquí.

Pero si tus seeders agregan datos iniciales importantes para el funcionamiento de tu aplicación, entonces puedes ejecutarlos con:

php artisan db:seed

O en su defecto, usar el siguiente comando (equivalente a los 2 anteriores).

php artisan migrate --seed

Y eso es todo.

¿No puedes iniciar sesión en phpMyAdmin o Laravel falla al ejecutar las migraciones?

Algunos estudiantes del curso comentaron tener inconvenientes con MySQL.

Lo que sucede es que en versiones más recientes de la imagen LAMP, el droplet incluye una versión más reciente de MySQL, que es la versión 8.

Para esta versión ocurren ciertos cambios importantes:

  • Si usas el comando mysql -u root -p notarás que no necesitas ingresar una contraseña para conectarte como el usuario root de MySQL, incluso luego que hemos definido una contraseña al ejecutar mysql_secure_installation.
  • Esto ocurre porque el método de autenticación por defecto, para el usuario administrador de MySQL, ahora es unix_socket en vez de password.
  • Aunque esto parece un fallo de seguridad, en realidad es todo lo contrario. ¿Por qué? Porque ahora los únicos usuarios capaces de iniciar sesión como root en MySQL somos nosotros, quienes tenemos privilegios de administrador en el droplet.
  • En otras palabras, no es posible conectarnos como usuarios root desde nuestras aplicaciones PHP, sino que ahora debemos definir un usuario de MySQL para este propósito.

Por lo menos en este momento, mientras actualizo este artículo:

La biblioteca PHP para MySQL (llamada mysqlnd) no soporta caching_sha2_authentication, que es el método de autenticación que usa MySQL 8 por defecto.

Por este motivo:

Es necesario definir usuarios de MySQL específicos para nuestras aplicaciones PHP (ahora que contamos con MySQL 8), y asegurarnos de que estos usuarios usen mysql_native_password como método de autenticación.

Veamos cómo hacer ello.

Desde el droplet, conéctate a MySQL ejecutando:

sudo mysql

Una vez que te has conectado, puedes hacer lo siguiente para crear una nueva base de datos.

CREATE DATABASE bd_de_ejemplo;

Ahora, el siguiente comando crea un nuevo usuario llamado usuario_de_ejemplo, usando el método de autenticación mysql_native_password.

La contraseña que estamos definiendo para este usuario es password. Este valor lo debes reemplazar por la contraseña que desees usar:

CREATE USER 'usuario_de_ejemplo'@'%' IDENTIFIED WITH mysql_native_password BY 'password';

Luego asignamos permisos para este usuario, para que pueda hacer cambios sobre la base de datos bd_de_ejemplo:

GRANT ALL ON bd_de_ejemplo.* TO 'usuario_de_ejemplo'@'%';

De esta manera el usuario que hemos creado sólo tiene privilegios sobre la base de datos indicada, y no permisos globales, como ocurre con el usuario root.

Por último hemos de ejecutar exit para salir de MySQL.

Verificar usuario de MySQL

Puedes usar el comando mysql -u usuario_de_ejemplo -p e ingresar la contraseña que definiste en el paso anterior.

Si no ingresas una contraseña no podrás conectarte a MySQL usando dicho usuario.

De esta forma validamos que el usuario se haya creado correctamente.

De hecho, si ejecutas SHOW DATABASES; luego de conectarte a MySQL verás que el usuario no tiene acceso a otras bases de datos, a diferencia de cuando se usa el usuario root.

¿Necesitas un dominio?

Recuerda que Digital Ocean es un proveedor de Cloud Computing, como ellos mismos lo describen en su página oficial. Pero, no son proveedores de nombres de dominio. Si necesitas un dominio .com, .net o con alguna otra extensión, lo puedes adquirir fácilmente en Namecheap.

Comprar un dominio es fácil con Namecheap

Una vez que hayas adquirido el dominio de tu preferencia, lo puedes vincular a tu droplet de Digital Ocean en un par de pasos.

? ¡Te deseo muchos éxitos en tu proyecto!

# laravel # mysql

Logo de Programación y más

Comparte este post si te fue de ayuda 🙂.

Regístrate

Accede a todos los cursos, y resuelve todas tus dudas.

Cursos Recomendados

Imagen para el curso Aprende Laravel

Aprende Laravel

Aprende Laravel desde cero y desarrolla aplicaciones web reales, en tiempo récord, de la mano de Laravel.

Iniciar curso
Imagen para el curso Laravel Upgrade

Laravel Upgrade

Actualiza tus proyectos desde cualquier versión hasta la última versión estable de Laravel.

Iniciar curso
Imagen para el curso Laravel y Vue

Laravel y Vue

Desarrollemos un Messenger! Aprende sobre Channels, Queues, Vuex, JWT, Sesiones, BootstrapVue y mucho más.

Iniciar curso

Espera un momento ...

¿Te gustaría llevar mi curso de Laravel, gratis?

Sólo debes ingresar tus datos: