En esta segunda parte nos enfocaremos en la instalación de Git, la configuración de nuestro Git Hook, la configuración de Laravel y de nuestro entorno de producción para poder servir correctamente nuestra aplicación Laravel.
Los artículos de esta mini-serie son los siguientes:
- Parte I: Instalación y configuración de LEMP Stack
- Parte II: Instalación y configuración de Laravel + Git Hooks (Estamos aquí)
- Parte III: Instalación de certificados SSL gratuitos y ajustes finales de Laravel
Sin más que añadir, continuemos.
10. Instalando Composer
Ya has instalado Composer anteriormente (de lo contrario no tendría mucho sentido que estés leyendo esta guía 🤔), por lo que este paso te resultará conocido. Accedemos por la terminal a nuestro servidor (mediante SSH) y ya en la consola ejecutamos:
cd ~ && curl -sS https://getcomposer.org/installer | phpCon esto tendremos ya el composer.phar en nuestro directorio de inicio, así que es hora de moverlo hacia el bin para
poder ejecutarlo de manera más sencilla simplemente haciendo composer.
sudo mv composer.phar /usr/local/bin/composerPuedes comprobar si todo salió bien ejecutando composer en la consola, debería de mostrarte todos los comandos
disponibles de Composer.
11. Instalando Git
Git no es un desconocido para casi nadie hoy en día y es, básicamente, un estándar. Claro que puedes utilizar otros métodos de gestión de versiones (o incluso subir tus archivos vía SFTP), pero nosotros usaremos Git.
Instalaremos Git en nuestro servidor en un directorio llamado /var/repo/. Empecemos por ahí:
cd /varmkdir repo && cd repoCon esto, notaremos que ahora estamos dentro del directorio /var/repo/. Ejecutamos lo siguiente:
mkdir site.git && cd site.gitgit init --bareEl flag
--barepuede que te resulte nuevo, y esto es porque -por lo general- se utiliza únicamente en servidores. Un repositoriobarees de un tipo especial cuyo único propósito es recibir “pushes” de desarrolladores. Puedes aprender más sobre esto en la documentación oficial.
Con esto tendremos un repositorio Git en /var/repo/site.git, 👏👏.
12. Creando nuestro Git Hook
Conociendo los Hooks
Los repositorios Git tienen una función interesante llamada “hooks” (“ganchos”) que usaremos para mover nuestros archivos luego de ejecutar git push. Lo que hacen los hooks es ejecutar cierta acción cuando estos son activados. Hay tres tipos de hooks del lado del servidor en Git: pre-receive, post-receive y update (más info aquí).
En nuestro caso, haremos uso del post-receive hook, el cual se activará cuando el repositorio haya descargado tus archivos completamente luego de recibir un push.
Configurando nuestro Hook
Para crear nuestro hook necesitamos entrar al directorio hooks que se encuentra dentro de nuestro directorio site.git.
Para hacerlo haremos:
cd /var/repo/site.git/hooksUna vez dentro, crearemos nuestro script post-receive, el cual se ejecutará luego de recibir nuevo código. Esto lo
haremos con ayuda de Nano:
sudo nano post-receiveComo ya sabemos, esto nos abrirá un archivo post-receive en blanco donde podremos añadirle contenido.
Escribimos (o pegamos) lo siguiente:
#!/bin/shgit --work-tree=/var/www/laravel --git-dir=/var/repo/site.git checkout -fPara pegar en la terminal puede que no te funcione el
Ctrl+V; si es así, pruebaShift+Insert.
Ahora guardamos y salimos.
Para guardar los cambios apretaremos primero
Ctrl+X, luego tipeamosYy por último apretamosEnter.
¿Pero qué hemos hecho exactamente? Veamos.
La directiva --work-tree= le indica a Git dónde debe copiar los archivos recibidos luego de haber sido
descargados por completo. Es por eso que le indicamos el directorio que contendrá nuestra app de Laravel. La
directiva --git-dir= le dice a Git dónde está el repositorio bare que ha recibido el código.
Es así de simple.
Luego de guardar el script, necesitamos ejecutar un comando más antes de dejar todo listo para recibir y copiar
el código. El archivo post-receive necesita permisos de ejecución para poder copiar los archivos de un
lado a otro. Para hacer eso ejecutamos lo siguiente (asegúrate de seguir dentro de /var/repo/site.git/hooks/):
sudo chmod +x post-receiveEso es todo. Ahora estamos listos para enviar nuestro código al servidor; este será copiado a nuestro directorio de Laravel, el cual a su vez será leído por Nginx para que pueda servirlo hacia nuestros usuarios 👌.
Hemos acabado por el momento con la configuración de nuestro servidor, ahora necesitamos cerrar nuestra conexión
SSH para volver a nuestra máquina local para el siguiente paso. Para salir, tan solo escribe exit.
exitTu línea de comandos se debe de haber cerrado (PuTTY) o ahora notarás que en la consola figura el nombre
del usuario de tu sistema en lugar de root@localhost#.
13. Subiendo nuestro proyecto al servidor remoto
Configurando nuestro entorno local para subir código
Ahora que nuestro servidor está listo para recibir código, es hora de configurar nuestra computadora local para que apunte hacia este cuando queramos subir nuestros cambios a nuestro entorno de producción (nuestro servidor).
Cuando subimos nuestros archivos a GitHub/GitLab/Bitbucket, configuramos un git remote llamado
origin que representa a nuestro almacén remoto de código (en este caso, GitHub). Así que cuando queremos subir
nuestros cambios hacia GitHub ejecutamos un comando de este estilo: git push origin mi-rama. Esto le dice a Git
que suba la rama (en este caso la rama llamada mi-rama) hacia nuestro origin remoto.
Haremos lo mismo nosotros. Crearemos un nuevo remote, al cual llamaremos production, el cual representará
a nuestro servidor remoto. Nuestra meta es que cuando ejecutemos git push production master, Git suba nuestros
cambios de la rama master a nuestro servidor remoto.
Esto no interfiere en absoluto con la subida de cambios a GitHub/etc., pues seguirá estando disponible el resto de remotes que tengamos configurados en nuestro proyecto, por ejemplo el origin:
git push origin master. Puedes crear tantos remotes como desees: podrías tener uno para tu servidorstaging, otro para el deproduction, etc.
Para crear un nuevo remote vamos al directorio donde tenemos nuestro proyecto, y desde ahí ejecutamos
git remote add:
cd mis-sitios/kennyhorna # modifícalo para tu casogit remote add production ssh://root@MI-DOMINIO-O-IP/var/repo/site.gitAsegúrate de reemplazar MI-DOMINIO-O-IP por tu dominio (o IP). En mi caso, lo cambiaré por la IP de mi servidor,
pues aún no le hemos configurado ningún dominio. Como resultado, en mi caso sería algo así:
git remote add production ssh://root@203.0.113.10/var/repo/site.gitSubiendo nuestro proyecto
Con este comando ejecutado hemos configurado ya nuestro remote de producción. Así que -asumiendo que nuestro código está listo para ser subido- podemos proceder a subir nuestro código.
git push production masterVerificando que nuestro Git Hook funcione
Tenemos que comprobar que nuestro Hook funciona, de lo contrario, todo esto habría sido en vano ;). Para esto, vamos a volver a acceder a nuestro servidor mediante SSH:
ssh root@203.0.113.10 # adáptalo a tus parámetrosAhora listaremos los archivos que contiene nuestro directorio especial de Laravel:
ls /var/www/laravelLo que hace el comando
lses listar los archivos y directorios que contiene el directorio desde donde se ejecuta.
Por tanto, si todo salió bien, deberíamos ver todos nuestros archivos de Laravel 🎉🎉.

14. Configurando nuestra Base de Datos
En la primera parte de esta guía instalamos MySQL, pero no hicimos mayor configuración. Aún ni siquiera hemos creado la base de datos que utilizará nuestro proyecto. Resolvamos esto de una vez.
Accederemos a la consola de MySQL con el siguiente comando:
mysql -u root -p'tu-clave'Asegúrate de reemplazar
tu-clavepor la clave que estableciste en tu base de datos. Observación: nota que no hay espacio entre lapy el primer'.
Si todo marchó bien, deberías ver que la línea de comandos ahora empieza con mysql>:

Esto nos indica que accedimos a MySQL, por lo tanto, ya podemos crear nuestra base de datos.
Dado que estoy subiendo un proyecto de prueba, mi base de datos se llamará my_site. Ajusta esto
a tus necesidades:
CREATE DATABASE my_site;Para validar que nuestra DB ha sido creada, podemos ejecutar:
SHOW DATABASES;
Con esto, ya podemos salir de MySQL. Ingresamos exit y le damos a Enter.
exit15. Configurando Laravel
Instalando nuestras dependencias
Para comenzar, debemos instalar las dependencias de nuestra aplicación pues, de lo contrario, no funcionará como se debe. Para esto, haremos uso de Composer, herramienta que instalamos al inicio de este artículo.
Nos situaremos dentro de la carpeta que contiene nuestro proyecto (cd /var/www/laravel) y desde ahí ejecutaremos:
composer install --no-devEl flag
--no-devle indicará a Composer que ignore las dependencias de desarrollo. Dado que nuestro entorno remoto está pensado para ser usado en producción, tiene todo el sentido del mundo hacer esto.
Estableciendo permisos
Para poder correr como se debe, Nginx necesita ciertos permisos sobre nuestro directorio Laravel. En primer lugar, necesitamos cambiar el grupo dueño de nuestro directorio de Laravel a nuestro grupo web.
sudo chown -R :www-data /var/www/laravelAhora el grupo web es dueño de los archivos, en lugar del usuario root. A continuación, necesitamos darle permisos
de escritura a nuestro grupo web sobre el directorio storage de tal modo que pueda escribir sobre este folder. Es aquí
donde almacenamos nuestros logs, cache, entre otras cosas. Para hacer esto hacemos:
sudo chmod -R 775 /var/www/laravel/storageDel mismo modo, también debemos darle permiso de escritura sobre el directorio bootstrap/cache:
sudo chmod -R 775 /var/www/laravel/bootstrap/cacheOk, ahora nuestros directorios son “writables”. Aún nos quedan cosas por hacer, pero nos estamos acercando bastante a completar una instalación exitosa ;)
16. Configurando nuestro entorno remoto de Laravel
Todo lo que nos falta hacer por ahora es configurar nuestra aplicación Laravel. Esto lo haremos de la misma
manera que lo haríamos en un entorno local. Utilizaremos los archivos que están dentro de config y
también configuraremos nuestro archivo .env.
Como ya sabrás, todos los archivos que están listados en nuestro .gitignore serán ignorados por Git, por
tanto acá es donde incluimos archivos/carpetas que no queremos que nuestro VCS gestione, ya sea por motivos
de seguridad o de facilidad.

Un ejemplo es el directorio /vendor: este directorio tiene todas las dependencias que nuestra aplicación
necesita. Sin embargo, dado que sí incluimos composer.json y composer.lock en nuestro VCS, Composer
podrá saber qué dependencias y qué versión específica de cada una de ellas necesita nuestra aplicación para
poder instalarlas, por tanto incluir esta carpeta se hace un poco redundante. Es por eso que la ignoramos.
Lo mismo sucede con el directorio node_modules, gestionado de manera análoga por los archivos
package.json y package-lock.json.
Entonces, en resumen: todo lo que consideremos vital para nuestra aplicación no debería de estar listado en
nuestro .gitignore.
Entendiendo el archivo .env
El .env contiene (o debería contener) todas las llaves y detalles de la configuración de nuestra aplicación.
Esto incluye: detalles de nuestra aplicación y entorno, la llave de encriptación de nuestra app, la configuración
de nuestra(s) base(s) de datos, la configuración de nuestro servidor de emails y mucho más.
Ahora te preguntarás: ¿por qué aparece el .env en nuestro .gitignore, si es tan clave para Laravel? La
respuesta es simple: muchas de estas configuraciones son específicas de cada entorno (de ahí su nombre: env
es diminutivo de environment, que significa ambiente/entorno). Veamos un ejemplo.
En nuestro entorno local puede que utilicemos un motor de base de datos más simple como SQLite; con esta base de
datos trabajamos y todo bien. Puede que nuestra aplicación, en el entorno real de producción, necesite un motor de
base de datos distinto -como por ejemplo MySQL o SQL Server- entonces, para poder hacer realidad esto de manera simple,
podríamos tener definido un driver y una conexión a base de datos en nuestro entorno remoto que difiera de los de
nuestro entorno local. ¿Dónde haríamos estas diferencias? Estás en lo correcto: en nuestro .env.
Si no fuera de este modo, cada vez que hicieras cambios en tu aplicación, tendrías que cambiar tus llaves de SQLite
por las del otro motor de base de datos para luego recién subir tus cambios al servidor (y viceversa para cuando
quieras hacer pruebas locales). Por tanto, utilizando el .env podemos hacer los mismos cambios en dos entornos
distintos y cada uno funcionará dependiendo de la configuración específica que tenga en su correspondiente entorno.
Magnífico.
Ahora que ya sabemos el motivo del uso de los .env, vamos a proceder a crear uno.
Creando nuestro archivo .env
Si nos fijamos (ls -A /var/www/laravel) veremos que si bien no tenemos el .env, sí que tenemos uno similar:
.env.example. Podemos utilizar este otro fichero como modelo para crear nuestro .env.
Tal vez hayas notado que incluimos el flag
-Aal listar los archivos del directorio laravel (ls -A /var/www/laravel): lo que hace este argumento es incluir en el listado los archivos ocultos.
Entonces, lo que haremos será copiar el .env.example como .env y colocar en este último los
parámetros de nuestra aplicación, como por ejemplo, la conexión a la base de datos que creamos en uno de los pasos
anteriores. Nos situaremos dentro de nuestra carpeta de Laravel:
cd /var/www/laravelcp .env.example .envCon esto ya tendremos nuestro .env clonado. Ahora procederemos a personalizarlo con ayuda de Nano.
nano .envAl hacer esto nos mostrará algo parecido a lo siguiente:

Dado que estamos en un entorno de producción, podemos hacer unos cambios iniciales como:
APP_NAME="El nombre de mi App"APP_ENV=productionAPP_DEBUG=falseAPP_URL=http://mi-dominio-o-mi-ipAPP_NAME y APP_URL se describen solos. APP_ENV le indica a Laravel que estamos en un entorno
de producción. APP_DEBUG le indica si debe mostrar los errores extensos o si, en cambio, queremos
que se manejen de una manera más humana (que es lo que queremos en un entorno de producción, dado que serán
nuestros usuarios quienes vean estos mensajes).
Habrás notado que ignoramos la llave
APP_KEY; descuida, esto lo generaremos con un comando más adelante.
Paso seguido, pondremos los detalles de nuestra base de datos, para que Laravel pueda acceder sin problemas.
Para esto modificaremos las siguientes llaves:
DB_HOST=localhostDB_DATABASE=my_siteDB_USERNAME=rootDB_PASSWORD=*******Estas llaves también son simples de deducir. DB_HOST le indica a Laravel el host donde está alojada nuestra
base de datos. Si nuestra base de datos estuviera en otro servidor, podríamos indicarle ahí el dominio (o IP) al que
apuntar. DB_DATABASE es el nombre de la base de datos que creamos más arriba, en mi caso my_site. Dado
que estoy usando el usuario root en mi base de datos, colocaremos esto en DB_USERNAME y, por tanto, en
DB_PASSWORD colocaremos la clave de este usuario.
Tal vez querrás ajustar la configuración de tus drivers de cache, queue, session, etc. Todo esto lo podrás hacer en este archivo, por ejemplo la configuración del servidor que manejará los emails.
Así que nuestro .env quedaría de la siguiente forma (grosso modo):
APP_NAME="Mi nueva App"APP_ENV=productionAPP_KEY=APP_DEBUG=falseAPP_URL=http://203.0.113.10
LOG_CHANNEL=stack
DB_CONNECTION=mysqlDB_HOST=localhostDB_PORT=3306DB_DATABASE=my_siteDB_USERNAME=rootDB_PASSWORD=*******
BROADCAST_DRIVER=logCACHE_DRIVER=fileQUEUE_CONNECTION=syncSESSION_DRIVER=fileSESSION_LIFETIME=120
REDIS_HOST=127.0.0.1REDIS_PASSWORD=nullREDIS_PORT=6379
MAIL_DRIVER=smtpMAIL_HOST=smtp.mailtrap.ioMAIL_PORT=2525MAIL_USERNAME=nullMAIL_PASSWORD=nullMAIL_ENCRYPTION=nullGenerando nuestra llave de encriptación
Tal como mencioné anteriormente, vamos a generar nuestra llave de encriptación con ayuda de un comando del propio Laravel. Para esto ejecutamos:
php artisan key:generateCon esto, Laravel generará y almacenará automáticamente nuestra llave en nuestro .env bajo APP_KEY.
Hay muchos otros ajustes que podemos configurar en nuestra aplicación; no en vano tenemos un directorio específico
para todos los archivos de configuración de nuestra app: config. Dado que estos archivos sí están considerados
por Git, podemos modificarlos en nuestro entorno local, hacer un commit con estos cambios y subirlos a nuestro
servidor remoto haciendo un push a production.
Guardando en caché nuestra configuración
Dado que hay muchos apartados de configuración, es buena idea guardar en caché estos valores. Para esto podemos hacer:
php artisan config:cacheTen en cuenta que luego de cada modificación que hagamos a la configuración deberemos limpiar esta caché, de lo contrario Laravel ignorará estos cambios. Para hacer esto podemos volver a ejecutar el mismo comando, el cual limpiará cualquier caché existente y la regenerará.
php artisan config:cache # Regenera la caché tomando los cambios17. Migrando nuestra base de datos
Ahora que tenemos nuestra configuración lista, podemos proceder a migrar nuestra base de datos. Para esto ejecutamos, como ya sabemos:
php artisan migrateNos preguntará si estamos seguros de correr este comando pues estamos en un entorno de producción; escribimos
yesy damosEnter.

Dado que estoy subiendo una instalación fresca de Laravel, en mi caso solo migrará las tablas por defecto que trae:
users, password_resets y failed_jobs.
Poblando nuestra base de datos
Podemos poblar nuestra base de datos mediante Seeders. Si tuvieras configurados tus seeders para poblar tus tablas maestras, es buen momento de correrlos. Para esto haríamos:
php artisan db:seedSi -tal como en mi caso- no tienes configurados Seeders, podemos hacer uso de Tinker para agregarle un usuario a nuestra app. Para acceder a Tinker hacemos:
php artisan tinkerCon Tinker podemos ejecutar comandos de Laravel de manera automática y simple. Entonces, ahora crearemos una nueva
instancia del -en mi caso- modelo User, que es el que tengo como tabla principal. Le añadiremos datos y por
último la guardaremos en la base de datos:
$u = new App\User;$u->name = 'Mesut Özil';$u->email = 'mesut.ozil@arsenal.com';$u->password = Hash::make('assist-king');$u->save();
exitCon esto habremos creado nuestro usuario con éxito.

Podrás notar que para el campo
passwordle apliqué un “hasheo” a la contraseña. Esto es para darle una capa adicional de seguridad a nuestro sistema. Por defecto, al hacer un intento de login, Laravel comparará la contraseña que le brindemos (luego de haberla “hasheado”) con la que tengamos en nuestra base de datos. Estas deberían de coincidir.Para hacer Hashing, Laravel usa bcrypt por defecto, que le agrega una sal distinta a cada contraseña. La llave
APP_KEYde nuestro.envno interviene aquí: Laravel la usa para encriptar datos, como las cookies y la sesión.
Cierre
🎉🎉🎉🎊 ¡Felicidades! 🎊🎉🎉🎉, con esto ya tenemos nuestro VPS configurado con todo en orden para poder utilizar nuestra aplicación Laravel y subir cambios hacia esta de manera rápida y simple. Podemos comprobarlo dirigiéndonos hacia nuestro dominio (o en mi caso, hacia nuestra IP): deberíamos ver la página de bienvenida de Laravel.
Como hemos podido ver, el proceso es un poco largo, pero he tratado de incluir el máximo detalle posible para que quede claro qué hacemos en cada paso.
Es importante saber el QUÉ, pero más importante aún, saber el POR QUÉ de lo que hacemos.
Ya tenemos nuestra aplicación funcionando. Solo nos queda configurar nuestro dominio en nuestra app y agregarle un certificado SSL. Esto lo veremos en la tercera -y última- parte:
Si tienes dudas sobre los pasos anteriores, visita la Parte I (Instalación y configuración de LEMP Stack) de la guía.
Cualquier comentario, observación, pregunta y/o aclaración es bien recibida así que… nos vemos 💪😉.