Cómo instalar Laravel en un VPS con Debian
Para comenzar con la instalacion, se debe tener:
- Un servidor con Sistema Operativo debian 11.
- Acceso al servidor con un usuario con permisos para instalar y actualizar paquetes.
Instalar apache
apt-get install apache2 -y
Se puede verificar la instalacion con el siguiente comando:
apache2ctl -v
# resultado
Server version: Apache/2.4.48 (Debian)
Instalar PHP y otras extensiones requeridas
apt-get install apt-transport-https gnupg2 ca-certificates -y
Luego, añadimos el repositorio necesario para instalar php 8.0.:
wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
sh -c 'echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'
Luego actualizamos el repositorio e instalamos php y otras extensiones:
apt-get update -y
apt-get install libapache2-mod-php php php-common php-xml php-gd php8.0-opcache php-mbstring php-tokenizer php-json php-bcmath php-zip php-curl unzip curl -y php-mysql
Verificamos que php se haya instalado correctamente:
php --version
# resultado
PHP 8.0.11 (cli) (built: Sep 23 2021 22:04:05) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.11, Copyright (c) Zend Technologies
with Zend OPcache v8.0.11, Copyright (c), by Zend Technologies
Ahora procedemos a editar el archivo php.ini
.
nano /etc/php/8.0/apache2/php.ini
Eliminamos el punto y coma de las siguientes extensiones para habilitarlas:
- extension=pdo_mysql
Instalamos composer
Ahora instalaremos composer para poder agregar las dependencias de laravel.
curl -sS https://getcomposer.org/installer | php
# resultado
All settings correct for using Composer
Downloading...
Composer (version 2.1.6) successfully installed to: /root/composer.phar
Use it: php composer.phar
Ahora moveremos el archivo a los binarios del S.O. para que podamos ejecutarlo directamente:
mv composer.phar /usr/local/bin/composer
Verificamos la instalación:
composer --version
# resultado
Composer version 2.1.6 2021-08-19 17:11:08
Instalar mysql/mariadb
Procedemos a instalar mariadb como motor de base de datos. En la terminal:
apt install mariadb-server
# resultado
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
galera-4 gawk libconfig-inifiles-perl libdbi-perl libmariadb3 libmpfr6 libsigsegv2 libsnappy1v5 mariadb-client-10.5 mariadb-client-core-10.5 mariadb-common
...
Podemos verificar la versión instalada con el siguiente comando:
mariadb --version
# resultado
mariadb Ver 15.1 Distrib 10.5.11-MariaDB, for debian-linux-gnu (x86_64) using
Verificamos el status del servicio:
systemctl status mariadb
# resultado
● mariadb.service - MariaDB 10.5.11 database server
Loaded: loaded (/lib/systemd/system/mariadb.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2021-08-17 23:38:11 CEST; 21min ago
Docs: man:mariadbd(8)
https://mariadb.com/kb/en/library/systemd/
...
Si por alguna razón la base de datos no está corriendo, iniciarla con el comando:
systemctl start mariadb
Ahora ejecutamos la consola de mariadb como root
para crear un usuario de base de datos nuevo:
mysql -u root -p
# resultado
password:
# Presionamos ENTER ya que no hemos configurado una contraseña para el usuario root.
Creamos un usuario nuevo, en este caso lo llamamos codalas
ya que será el usuario destinado para acceder a la base de datos del sistema.
create user codalas@localhost identified by 'password';
Le damos todos los privilegios:
GRANT ALL PRIVILEGES ON *.* TO 'codalas'@localhost IDENTIFIED BY 'password';
Actualizamos los privilegios de la base de datos:
FLUSH PRIVILEGES;
Advertencia
Para sistemas en producción es recomendable dar solo los privilegios necesarios.
Ahora creamos la base de datos que usaremos para el sistema:
CREATE DATABASE laravel;
Crear usuario no root para administrar la aplicación (en caso de que no se tenga)
En la consola del sistema operativo, crearemos un usuario no root, de ejemplo llamado codalas
, utilizando el siguiente comando:
adduser codalas
Llenamos la información que solicita como la contraseña, nombre, etc. El objetivo de crear un usuario no root es para poder instalar las dependencias de laravel de forma segura.
Instalar git (opcional)
Instalamos git dependiendo del ambiente para poder clonar y mantener el proyecto al día con los cambios durante la etapa de desarrollo.
Actualizamos el índice de paquetes del SO:
sudo apt update
Instalamos git:
sudo apt install git
Verificamos la instalación:
git --version
# resultado
git version 2.30.2
Asumiendo que el proyecto fue clonado a la carpeta /var/www/html/
, de ejemplo usaremos como carpeta laravel
, procedemos a administrar los permisos de las carpetas:
Agregamos el usuario no root al grupo del usuario del servidor www-data
. Esto para poder ejecutar comandos dentro del proyecto sin interferir con los permisos de propiedad que necesita el servidor sobre las carpetas de vendor
, storage
y bootstrap
.
usermod -a -G www-data codalas
Luego cambiamos la propiedad de todos los archivos en la carpeta del proyecto a codalas
con grupo www-data
:
cd html
chown -R codalas:www-data laravel
Actualizamos los permisos de las carpetas:
chmod -R 775 laravel
Una vez completamos esto, podemos proceder a realizar el resto de funciones con el usuario nuevo creado. Esto puede ser iniciando sesión con el usuario nuevo o desde el usuario root
, ejecutar comandos en nombre del usuario no root.
Como usuario root, podemos ejecutar comandos a nombre del usuario creado usando:
sudo -u codalas bash
Esto nos iniciará una terminal como usuario codalas
.
Procedemos a crear el archivo con las variables de entorno:
Creamos un archivo con variables de entorno llamado .env
con la siguiente información:
APP_NAME="Laravel"
APP_ENV=local
APP_DEBUG=true
APP_URL=https://localhost
APP_KEY=
LOG_CHANNEL=stack
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=codalas
DB_PASSWORD=password
MAIL_MAILER=smtp
MAIL_FROM_ADDRESS=
MAIL_FROM_NAME=
MAIL_HOST=
MAIL_PORT=587
MAIL_ENCRYPTION=tls
MAIL_USERNAME=
MAIL_PASSWORD=
BROADCAST_DRIVER=log
CACHE_DRIVER=file
FILESYSTEM_DRIVER=local
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
Instalar dependencias del sistema
Ejecutamos composer install
para instalar las dependencias del sistema.
composer install
# resultado
Installing dependencies from lock file (including require-dev)
Verifying lock file contents can be installed on current platform.
Package operations: 117 installs, 0 updates, 0 removals
- Installing doctrine/inflector (2.0.3): Extracting archive
- Installing doctrine/lexer (1.2.1): Extracting archive
- Installing symfony/polyfill-ctype (v1.23.0): Extracting archive
- Installing webmozart/assert (1.10.0): Extracting archive
- Installing dragonmantank/cron-expression (v3.1.0): Extracting archive
- Installing symfony/polyfill-php80 (v1.23.1): Extracting archive
- Installing symfony/polyfill-mbstring (v1.23.1): Extracting archive
...
Refrescar la configuración
Procedemos a refrescar el cache de la aplicación:
php artisan config:cache
# resultado
Configuration cache cleared!
Configuration cached successfully!
php artisan route:cache
# resultado
Route cache cleared!
Routes cached successfully!
php artisan view:cache
# resultado
Compiled views cleared!
Blade templates cached successfully!
Migraciones
Corremos las migraciones para crear las tablas en la base de datos:
php artisan migrate
Configurar apache
Utilizando el usuario root
, crearemos una configuración virtual host
para la aplicación.
Creamos un archivo de configuración nuevo para laravel
:
nano /etc/apache2/sites-available/laravel.conf
Modificamos el archivo con el siguiente contenido:
<VirtualHost *:80>
ServerName http://localhost
ServerAdmin example@example.com
DocumentRoot /var/www/html/laravel/public
<Directory /var/www/html/laravel>
Options +Indexes +MultiViews
AllowOverride None
Require all granted
</Directory>
<Directory /var/www/html/laravel/public>
Options +Indexes +MultiViews
AllowOverride None
Require all granted
<IfModule mod_rewrite.c>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Send Requests To Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Consejo
Actualizar las propiedades de ServerName
, ServerAdmin
, DocumentRoot
y Directory
de acuerdo a la configuración del servidor.
Verificamos que la configuración esté correcta:
apachectl configtest
# resultado
Syntax OK
Habilitamos el virtual host creado y el módulo rewrite:
a2enmod rewrite
a2ensite laravel.conf
Consejo
La consola indicará que debe reiniciar el servidor después de cada comando para que tenga efecto. Puede reiniciar el servidor luego de ejecutar ambos.
Reiniciamos el servidor:
systemctl restart apache2
Configurar firewall
Por defecto, el servidor solo tiene abierto el puerto 22, el cual es usado para la conexión ssh. Como la aplicación se ejecuta en el puerto 80, debemos abrirlo para que la aplicación sea accesible externamente.
Verificamos el status del firewall:
ufw status
# resultado
Status: active
To Action From
-- ------ ----
22 ALLOW Anywhere
Habilitamos el puerto 80:
ufw allow 80
Si verificamos el status nuevamente, debe mostrarse el puerto nuevo:
ufw status
# Resultado
Status: active
To Action From
-- ------ ----
22 ALLOW Anywhere
80 ALLOW Anywhere
80 (v6) ALLOW Anywhere (v6)
Pasos finales
Luego, ejecutar los siguientes comandos en la raíz del proyecto para actualizar los permisos de las carpetas.
sudo chown -R codalas:www-data storage
sudo chmod 775 -R storage
Generamos el identificador único usado para generar tokens de autenticación.
php artisan key:generate
Refrescamos la configuración de la aplicación.
php artisan config:cache
# resultado
Configuration cache cleared!
Configuration cached successfully!
php artisan route:cache
# resultado
Route cache cleared!
Routes cached successfully!
php artisan view:cache
# resultado
Compiled views cleared!
Blade templates cached successfully!
Accedemos a la dirección del servidor en el puerto 80, ya sea por la IP o si tiene un URL asignado. Ejemplo http://localhost