Esta guía está basada en la realizada por J.A. Curtis hace un par de años, la cual me ayudó mucho en su momento.
Para facilitar la lectura, he dividido esta guía en tres partes:
- Parte I: Instalación y configuración de LEMP Stack (Estamos aquí)
- Parte II: Instalación y configuración de Laravel + Git Hooks
- Parte III: Instalación de certificados SSL gratuitos y ajustes finales de Laravel
En esta primera parte nos enfocaremos en la creación y configuración de nuestro VPS, así como también en la instalación y configuración de LEMP Stack.
Aclaraciones previas
LEMP
“LEMP” son las iniciales de Linux, Engine-X (Nginx), MySQL y PHP. Es un término popular pues esta pila de tecnologías nos ayuda a hacer disponible al mundo nuestra aplicación.
- Linux: El sistema operativo donde estará montado nuestro servidor. Emplearemos la distribución Ubuntu (18.04).
- Nginx: Es el servidor web.
- MySQL: El gestor de base de datos que utilizaremos.
- PHP: El lenguaje principal en el que está escrita nuestra aplicación (Laravel).
¿LEMP o LAMP?
La diferencia entre uno y otro es el servidor web: Nginx (LEMP) vs Apache (LAMP). Personalmente siempre utilizo Nginx, pero es más por temas de preferencia/familiaridad que porque uno sea mejor o peor que el otro. Está en tus manos investigar sobre sus diferentes bondades/debilidades y escoger el que más te convenga.
Para fines de esta guía, emplearemos Nginx.
¿Dónde debería alojar mi aplicación?
La respuesta correcta es: donde prefieras. Esta guía está basada en la instalación de una aplicación Laravel en un VPS (Virtual Private Server). El modo por el cual interactuaremos con nuestro servidor será vía SSH, por tanto, da igual donde lo tengas alojado pues el proceso será el mismo.
En este tutorial instalaremos nuestra aplicación en DigitalOcean. Otros sitios recomendados en donde pueden alojar sus aplicaciones son: Vultr, Linode, Heroku, entre muchos otros.
Comencemos
1. Configurando nuestro VPS
Esto va a depender de donde decidas alojar tu servidor. Dado que en esta guía emplearemos DigitalOcean, las imágenes serán las de este servicio. Sin embargo, los pasos son similares en los otros servicios listados.
Creamos una cuenta en el servicio -o accedemos si es que ya contamos con una cuenta- y accedemos a la creación de nuestra instancia. En DigitalOcean, las instancias reciben el nombre de “Droplets”.
Una vez en el panel de creación, vamos a seleccionar las características de nuestro droplet. Para comenzar seleccionaremos el sistema operativo, en nuestro caso la versión estable más reciente de Ubuntu: 18.04.3.

Paso seguido seleccionaremos el tamaño/potencia de nuestro droplet. Esto se hace a través de la elección del plan en el que esté nuestro droplet. Dado que es para una demo, escogeremos la opción más modesta que cuesta USD $5/mes. Este tamaño es suficiente para realizar pruebas o para sitios simples que no reciban mucho tráfico.
Ten en cuenta que puedes aumentar la capacidad de tu droplet en cualquier momento desde el panel de configuración de tu servicio.

A continuación, nos preguntará si le queremos asignar un bloque de almacenamiento y la región en donde se encontrará nuestro droplet. Los bloques de almacenamiento son una suerte de “discos locales” que pueden ser accedidos por varios de tus droplets (que se encuentren en la misma región). Dado que no tenemos configurado ninguno, omitiremos este paso.
Para la región seleccionaré New York 1 pues es la más “cercana” a mi ubicación y por ende, menor ping/latencia. En tu caso selecciona la que más te convenga.

Llaves SSH
Entraremos ahora a la sección de Autenticación.
Te recomiendo fuertemente que configures tus llaves SSH en esta sección. Para esto, puedes añadir una llave nueva (tu llave pública), o seleccionar una existente en caso ya hayas añadido alguna previamente.

Como ajustes finales, le daremos un nombre y también algunas etiquetas (opcional).

Por último, le daremos en “Crear Droplet”.
Opcionalmente, podemos activar las copias de respaldo automáticas (semanales), útiles si no gestionas esto en tu app. Ten en cuenta que esto añade $1/mes al costo.
Esperamos unos segundos hasta que se cree nuestro droplet. Una vez terminado, lo veremos listado en nuestros recursos, desde donde visualizaremos la IP de nuestro servidor.
2. Accediendo mediante SSH
Accederemos ahora a nuestro servidor mediante nuestro cliente SSH.
Para Linux y macOS no es necesario añadir nada, tienen clientes SSH nativos en el terminal. Para Windows en cambio, podemos hacer uso de PuTTY. Puedes descargar PuTTY desde aquí.
ssh root@XXX.XXX.XXX.XXXEn donde XXX.XXX.XXX.XXX es la IP de nuestro servidor. En mi caso utilizaré la IP del servidor que
acabo de crear (203.0.113.10), resultando: ssh root@203.0.113.10.
Al ser primera vez que nos conectamos a este servidor, nos preguntará si confiamos en esta dirección IP o si queremos guardar en caché el registro. Aceptamos y continuamos.
Como podemos ver, ya hemos accedido remotamente al servidor a través de una interfaz de línea de comandos. Ya tenemos control total de nuestro VPS.
3. Actualizando el instalador de paquetes
Utilizaremos APT para la gestión de nuestros paquetes, por lo que es importante mantenerlo actualizado. Para esto ejecutaremos:
sudo apt-get updateUna vez ejecutado este comando, te irá detallando el proceso que está realizando a medida que va actualizando el listado de paquetes.
Puedes ver más detalle de este comando, y en cómo se diferencia de este otro,
apt-get upgrade, en este artículo.
4. Instalando Nginx
Procederemos a instalar Nginx, para esto ejecutaremos ahora:
sudo apt-get install nginxNos preguntará si queremos continuar, presionamos Enter para que proceda a instalarse.
Tan simple como esto. De hecho, ahora que tenemos nuestro servidor web instalado, si accedemos a la IP
de nuestro servidor desde nuestro navegador, veremos que Nginx nos da la bienvenida :).
Deberías ver algo similar a lo siguiente:

5. Instalando y asegurando MySQL
Las bases de datos son piezas clave en aplicaciones web. Nos permiten almacenar la información y acceder a ella. Una aplicación sin base de datos, salvo excepciones, prácticamente no tiene mucho sentido. Debido a esto instalaremos MySQL.
De más está decir que puedes instalar el gestor de base de datos que prefieras (Oracle, MongoDB, MS SQL Server, Neo4j, PostgreSQL, etc). En mi caso escogí MySQL.
Instalación
Para instalarlo, volveremos a utilizar APT. A la fecha de este artículo, la versión es la v5.7.27.
Escribimos en consola (y apretamos Enter para aceptar):
sudo apt-get install mysql-serverAsegurando nuestra instalación
MySQL tiene la reputación de ser inseguro. Esto no es porque realmente lo sea, sino que las personas que lo configuran dejan la configuración por defecto y esta no es segura para nada. Tomando el caso de mi entorno local, mi configuración de MySQL ni siquiera tiene clave y el único usuario es root. Esto está bien para un entorno local, pero es imperdonable en un entorno de producción o siquiera en uno de staging.
Felizmente, MySQL tiene un helper que nos ayudará a librarnos de estos detalles. Nos obligará, por ejemplo, a que nuestro usuario root tenga una contraseña. Desactiva también el acceso remoto en modo root. Para aplicar estos ajustes solo ejecuta:
sudo mysql_secure_installationNos preguntará si queremos activar el plugin que valida la seguridad/fortaleza de nuestras contraseñas. Dado
que nosotros gestionaremos esto conscientemente, podemos omitir esto. Escribimos n y le damos Enter.
Acto seguido nos pedirá que establezcamos una contraseña (y que la verifiquemos) para el usuario root.
No te preocupes si no aparece nada en pantalla mientras la escribes: por seguridad, la terminal oculta la contraseña.

Acto seguido preguntará si queremos remover “usuarios anónimos”. Escribimos y (+ Enter).
Luego, nos preguntará si queremos “desactivar el acceso remoto en modo root”. Escribimos y (+ Enter).
A continuación nos preguntará si queremos remover “las bases de datos de prueba”. Escribimos y (+ Enter).
Por último, nos consulta si queremos “recargar la tabla de privilegios”. Nuevamente, escribimos y (+ Enter).
Si todo marchó correctamente, la terminal te mostrará el mensaje “All done!”

6. Instalando y configurando PHP
Instalación
En realidad, Ubuntu ya trae una versión de PHP. Lo que necesitamos, sin embargo, es PHP para procesamiento. Esto es posible gracias al plugin llamado PHP-FPM.
PHP-FPM (FastCGI Process Manager) nos ayuda a interconectar programas interactivos con un servidor web. Es la implementación alternativa de PHP FastCGI más popular con características adicionales que son realmente útiles para sitios web de alto tráfico. Puedes aprender más sobre PHP-FPM en este artículo.
Para instalarlo ejecutamos:
sudo apt-get install php-fpm php-mysql php-mbstringPodemos verificar la versión de PHP que estamos corriendo con el siguiente comando:
php -vAl momento de publicado este artículo, la versión por defecto que nos trae es la
7.2.19.
Con esto ya tendremos todo el LEMP stack instalado y listo para poder servir nuestra aplicación :)

Configurar PHP
Procederemos a configurar todo lo necesario para hacer funcionar nuestra aplicación. Del lado de PHP, no hay mucho que configurar más allá de un ajuste de configuración que debemos hacer.
Nuevamente volvemos a la terminal para editar el archivo php.ini en el editor de tu preferencia. En
nuestro caso emplearemos Nano en esta guía.
sudo nano /etc/php/7.2/fpm/php.iniEn caso utilices una versión distinta de PHP, solo cambia la versión en la ruta, por ejemplo para PHP
7.3haríamos:sudo nano /etc/php/7.3/fpm/php.ini
La línea que necesitamos editar es la siguiente:
;cgi.fix_pathinfo=1Puedes buscarla manualmente, o si es que utilizamos Nano, podemos apretar Ctrl + W e ingresar
cgi.fix_pathinfo= para finalmente apretar Enter.
Como consejo: Si es que buscas pegar texto en la consola, podrás notar que
Ctrl+Vno funciona, en cambio podemos utilizarShift+Insert.
Esto nos llevará hasta la línea correcta. Si nos fijamos, está comentada (al inicio de la línea hay un
;) y tiene como valor 1. Así que vamos a modificarla para que quede de este modo:
cgi.fix_pathinfo=0
Para guardar los cambios apretaremos primero Ctrl + X, luego tipeamos Y y por último apretamos Enter.
Para que los cambios surtan efecto, reiniciaremos php-fpm de la siguiente manera:
sudo systemctl restart php7.2-fpm7. Configurando Nginx
Siempre es delicado configurar Nginx, así que mucha atención a partir de ahora.
Vamos a proceder a modificar el archivo de configuración por defecto de Nginx del siguiente modo:
sudo nano /etc/nginx/sites-available/defaultVerás muchas líneas que inician con #, todos estos son comentarios. Por motivos de simplicidad vamos
a ignorar estos de momento. Tendrá la siguiente forma:
server { listen 80 default_server; listen [::]:80 default_server;
root /var/www/html; index index.html index.htm index.nginx-debian.html;
server_name _;
location / { try_files $uri $uri/ =404; }}Añadiremos index.php adelante de index.html en el listado de archivos índice de modo que
quedaría así:
index index.php index.html index.htm index.nginx-debian.html;
A continuación cambiaremos el server_name y colocaremos acá la IP de nuestro VPS. Esto le dice
a Nginx a qué dominio debe de responder. Dado que de momento accedemos a nuestro servidor mediante
la dirección IP, será lo que colocaremos. Sin embargo, en caso tengamos un dominio que queramos
utilizar para nuestra aplicación, podemos añadirlo acá también.
server_name 203.0.113.10;Ahora le indicaremos a Nginx que utilice la extensión que instalamos anteriormente: php-fpm.
Si nos fijamos en el formato de configuración del archivo que estamos editando, notaremos que cada
servidor está estructurado por distintas directivas. Una de estas son las location. Si observamos,
tenemos tres bloques que inician con location: el inicial y dos comentados (inician con #):

Entonces, para activar php-fpm, vamos a quitarle los comentarios al primer bloque comentado (el
segundo en el archivo) y a modificar la versión de PHP a utilizar.
Asimismo, procederemos a quitarle los comentarios al segundo bloque comentado (el tercero en el archivo),
esto le dirá a Nginx que ignore los archivos .htaccess. Esto es porque estos archivos son para Apache,
y dado que nosotros estamos utilizando Nginx no tiene mucho sentido utilizarlos.
Aplicando estos cambios resulta lo siguiente:
# ...
location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php7.2-fpm.sock;}
location ~ /\.ht { deny all;}Nota: Ten en cuenta que esta línea debe seguir comentada:
fastcgi_pass 127.0.0.1:9000;

Ahora guardaremos nuestros cambios (Ctrl + X, luego tipeamos Y y por último apretamos Enter)
para poder validar si nuestra configuración es correcta. Para hacer esto ingresamos:
sudo nginx -tSi es que no cometimos algún error, el resultado del comando anterior debería devolvernos algo así:

Con esto configurado, ya estamos listos para desplegar nuestra aplicación PHP.
8. Creando un directorio para nuestro Laravel
Ahora que nuestro servidor está listo para “servir” archivos, le cargaremos nuestro proyecto de Laravel
para que pueda cumplir su tarea. Por defecto Nginx va a buscar en el directorio /var/www/ como la raíz
desde donde leer nuestros archivos. Crearemos un directorio dentro de este y le llamaremos laravel (o
lo que prefieras).
sudo mkdir -p /var/www/laravelLo siguiente es decirle a Nginx que busque en esta carpeta, y no solo eso, sino especificarle dónde se
encuentra el archivo por defecto de nuestro sitio. En el caso de Laravel, este archivo es el index.php
que encontramos dentro del directorio /public. Este archivo es el de entrada y hacia donde se dirigen
todos los requests que llegan a nuestra aplicación, ya sea mediante API, etc. Por tanto, este archivo
recibe también todos los parámetros adicionales que llegan con cada request.
Para hacer esto, nuevamente editaremos nuestra configuración de Nginx:
sudo nano /etc/nginx/sites-available/defaultEn esta ocasión, nuestro foco estará en la directiva root, que es la que especifica el directorio raíz
de este servidor. Ahí la actualizaremos por /var/www/laravel/public. Es la única línea a editar:
server { listen 80 default_server; listen [::]:80 default_server ipv6only=on;
root /var/www/laravel/public; index index.php index.html index.htm;
# ...
Más arriba, comenté que el archivo index.php recoge también los parámetros adicionales que llegan con cada
request (el payload), por tanto debemos decirle a nuestro servidor que también envíe esta data a Laravel.
Para esto volveremos a modificar Nginx actualizando lo siguiente:
server_name 203.0.113.10;
location / { try_files $uri $uri/ /index.php?$query_string;}
Guardaremos nuestros cambios (Ctrl + X, luego tipeamos Y y por último apretamos Enter). Luego de esto,
procederemos a reiniciar Nginx para que los cambios surtan efecto.
sudo service nginx restartSi es que ahora nos dirigimos hacia la URL de nuestro dominio (o en nuestro caso, a nuestra IP), veremos
este error 404 en lugar de la página de bienvenida que retornaba previamente:

9. Creando un archivo Swap (Opcional)
Antes de instalar Composer o Laravel, necesitamos tener en cuenta la memoria de nuestro VPS. Instalar estas aplicaciones requiere una descarga alta de archivos (en comparación con la instalación de simples paquetes) y podría terminar consumiendo toda la memoria RAM de nuestro servidor, sobre todo si estamos en una instancia pequeña de 1GB o menos (como en nuestro caso). Si cuentas con una instancia más poderosa, puedes omitir este paso.
Un archivo Swap le permite al sistema operativo liberar data de la memoria RAM y almacenarla en el SSD para cuando necesita más espacio del disponible.
Por tanto, crearemos un archivo Swap de 1GB de capacidad en nuestro SSD:
sudo fallocate -l 1G /swapfileA continuación le diremos a Ubuntu que formatee este espacio:
sudo mkswap /swapfilePor último, le diremos que lo comience a utilizar haciendo:
sudo swapon /swapfileCierre
Con todo esto realizado ya tenemos todo listo para subir, instalar y configurar nuestra aplicación Laravel en nuestro recientemente configurado VPS. Estos pasos los realizaremos en la siguiente parte de esta mini-serie 😃: