En este tutorial aprenderás como configurar un entorno de despliegue automático (Continuous Deployment), y una configuracion sencilla de Continous Integration/Continuous Deployment (CI/CD) para aplicaciones desarrolladas en Nextjs, todo esto usando un servicio de Github, llamado Github Actions.
Basicamente lo que haremos sera crear un proyecto de next, subirlo a github, configurar un servidor, configurar Github action en ese servidor, añadir un dominio ademas de SSL.
Aunque en este ejemplo usaremos Nextjs, si usas otro framework similar como Nuxtjs, tambien podras aplicar practicamente los mismos pasos
Requerimientos
Antes de empezar es necesario que cuentes con los siguientes Requerimientos, para que puedas seguir el tutorial comodamente:
- Nextjs. Necesistas conocer las bases de Nextjs, este no es un curso de Nextjs, asi que espero que conozcas los comandos basicos como
npm run build
. - Git, Debes conocer las bases de Git para que puedas entender como vamos a subir el proyecto a github
- Tener una cuenta de Github
- Conocer comandos basicos de terminal como
ls
ocd
Con estas conceptos en mente, te será mas sencillo entender ejemplo práctico.
¿Que vamos a Hacer?
En resumidas cuentas esto es lo que vamos a crear:
- Crearemos un proyecto de Nextjs
- Moficaremos el proyecto
- Subiremos el proyecto a Github
- Configuraremos un VPS en Digitalocean
- configuraremos un workflow de Github action
- configuraremos un runner de Github Action
- Configuraremos nginx como Servidor Proxy
- Añadiremos un dominio a nuestra aplicacion más SSL gratuito.
y Adicionalmente un bonus adicional para los que estan unidos al canal FaztCode:
- Configuraremos un firewall de ufw, mas mejores accesos de SSH para nuestros usuarios.
Creacion del proyecto
Primero vamos a crear un proyecto con create-next-app
npx create-next-app nextgh-tutorial
cd next-gh-tutorial
npm run dev
Modifiquemos el proyecto de Nextjs para que nos pueda mostrar un texto Hello World, ve al archivo pages/index.js
y añade un simple con un texto:
<h1>Hello World</h1>
Creando Repositorio
Una vez tenemos nuestro proyecto creado, vamos a subirlo a un Repositorio en Github.
git init
git add .
git commit -m "Hello World"
Para crear un respositorio puedes usar la web, o puedes usar el CLI de Github, en lo peronal voy a usar este el CLI al ser mucho mas rapido que dar clis, pero es lo msimo al final.
gh repo create myproject --private --source=. --remote=upstream
Este comano creara un repo en tu cuenta y te permitira subirlo simplemente con git push:
git push origin master # usa main en lugar de master si tienes esa rama
Configuracion de VPS
Con nuestro proyecto subido a Github ahora vamos a configurar nuestro Propio Servidor. En nuestro cao vamos a configurar un VPS usando DigitalOcean, el cual este servicio le llama Droplet.
En la realidad puedes usar cualquier servicio como AWS, Google Cloud Platform y otros. Solo que en lo personal se me hace mas facil usar DigitalOcean
Si es la primer vez que creas una cuenta puedes usar este enlace:
Usando este enlace podras registrarte y recibir 200$ de pruebas para que crees servidores y practiques.
Estos son los pasos que vamos a hacer
- Entra en tu cuenta de DigitalOcean
- Crear un Proyecto nuevo, vamos a llamarlo: Web Project
- Crea un Droplet, con las siguientes caracteristicas:
- Sistema operativo : Ubuntu 22.04
- CPU: Shared CPU
- RAM - 1GB Minimo Requerido, esto es necesario ya que vamos estar haciendo build de nextjs y puede que nos quedemos sin memoria.
- CPU Options: Regular with SSD ($4 al mes)
- Añade una llave SSH
- Hotname: next-server
Una vez creado conectate a tu servidor usando ssh y la direccion IP de tu servidor. Por ejemplo la conexion seria algo así:
ssh root@165.224.180.213
Configuracion del servidor
Una vez conectados vamos a actualizar el servidor de Ubuntu, usando:
sudo apt update && sudo apt upgrade -y
Luego vamos a crear un servidor para no usar el usuario root, y crear un usaurio dedicado para nuestro despliegue.
En mi caso voy a crear un usuario con el nombre fazt
adduser fazt
Coloca tu contraseña y algun nombre y crealo.
Luego vamos a otorgarle permisos de superusuario a este nuevo usuario.
usermod -ag sudo fazt
Luego vamos a usar este usuario:
su - fazt
Listo, ya tenemos nestro servidor preparado para empezar a configurar github actions.
Creando un workflow
Para configurar un runner vamos a ir a la seccion Actions, escoge un workflow de Nodejs y usa la siguiente configuracion:
name: Node.js CI
on:
push:
branches: [ "master" ]
jobs:
build:
runs-on: self-hosted
strategy:
matrix:
node-version: [16.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
# cache: 'npm'
- run: npm i
- run: npm run build --if-present
- run: pm2 reload 0
Luego da un click en el boton Start Commit y guarda este archivo.
Ahora hagamos un pull:
git pull origin master # o main si usas esa rama
esto creara una carpeta .github/workflows
en tu proyecto con un archivo node.js.yaml
Creando Runner
Desde la pagina de tu repositorio en Github, ve a la seccion Settings, luego en Actions y despues en Runner. Da un click en New Self hosted runner
Luego desde esta pagina ejecuta todos los comandos que menciona y finalmente desde tu servidor ejecuta:
./run.sh
Instlando PM2
Para instalar nvm puedes ir a su documentacion: https://github.com/nvm-sh/nvm
npm install -g pm2
pm2 --version
pm2 start npm -- start
ya puedes visitart http://tuip:3000
SVC
name: Node.js CI
on:
push:
branches: [ "master" ]
jobs:
build:
runs-on: self-hosted
strategy:
matrix:
node-version: [16.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
# cache: 'npm'
- run: npm i
- run: npm run build --if-present
- run: pm2 reload 0
sudo ./svc.sh status
sudo ./svc.sh install
sudo ./svc.sh start
Instalando Nginx
sudo apt install nginx
luego añade esta configuracion en /etc/nginx/sites-available/next
server {
listen 80;
listen [::]:80;
server_name _;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Luego simplemente enlace el archivo en la carpeta /etc/nginx/sites-enabled/next
sudo ln -s /etc/nginx/site-available/next /etc/nginx/site-enabled/next
Modificacion final
git push origin master
Con este push si subes tus cambios deberias verlos reflejados en tu sitio web
Añadiendo Dominio
Para poder añadir un dominio, puedes usar cualquiera que tengas adquirido en alguna plataforma de venta de dominios. En mi caso voy a estar usando Namecheap al ser la plataforma que más uso.
Una vez tengas tu domini añade estas configuraciones a tu Custom DNS:
ns1.digitalocean.com
ns2.digitalocean.com
ns3.digitalocean.com
Luego ve en digitalocean, en la seccion Manage DNS y crea lo siguiente:
@ next-server www next-server
Una vez tengas esto, ya puedes ir a tu configuracion de Nginx y actualizarla a lo siguiente:
server {
listen 80;
listen [::]:80;
server_name www.fazt.site fazt.site;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Una vez tenga esto, solo basta con reiniciar Nginx.
sudo service nginx restart
y finalmente si visitas tu sitio web, este estará disponible en tudominio.xyz, y tambien en www.tudominio.xyz.
Añadir SSL con Let's Encrypt
Finalmente vamos a aprender a añadir SSL usando un programa llamado Let's encrypt. Este ofrece SSL gratuito.
Para esto tenemos que usar un bot llamado cerbot:
sudo snap install --classic certbot
este comando creara un certificado SSL, y atambien te permitira renovar automaticamente el certificado cuando expire:
sudo certbot --nginx -d fazt.site -d www.fazt.site
Listo con esto ya tienes tu sitio ahora con SSL.
Más Recursos
- https://www.willandskill.se/en/articles/setup-a-next-js-project-with-pm2-nginx-and-yarn-on-ubuntu-18-04
- https://stackoverflow.com/questions/69644460/github-actions-pm2-command-not-found
- https://www.digitalocean.com/community/tutorials/how-to-set-up-a-node-js-application-for-production-on-ubuntu-20-04#step-4-setting-up-nginx-as-a-reverse-proxy-server
- https://www.digitalocean.com/community/tutorials/nginx-reverse-proxy-node-angular