VPS 5: Desplegando una app full-stack
Posted on February 3, 2025 • 10 minutes • 2016 words • Other languages: English
Esta es la quinta y última parte de mi serie de blogs sobre VPS .
- ¿Qué es “Roundest Pokémon”?
- ¿Qué vamos a necesitar?
- Agregar recurso de PostgreSQL
- pgAdmin
- Crear una aplicación de GitHub en Coolify
- Desplegar usando GitHub App
- Uso de recursos del VPS
- Una conclusión sentimental al viaje del VPS
¿Qué es “Roundest Pokémon”?
“Roundest Pokémon” es un ejercicio clásico de programación que consiste en un juego interactivo de votación para decidir cuál Pokémon es el más redondo.
Le vamos a agregar un giro: la capacidad de elegir qué sistema backend procesa el voto.
Esta funcionalidad nos va a ayudar a ilustrar cómo distintos sistemas se pueden desplegar y trabajar en conjunto sin problemas, todo bajo un proyecto Coolify en el VPS.
¿Qué vamos a necesitar?
- Una base de datos (yo voy a usar Postgres
)
- Un administrador de base de datos: No es crucial para la app en sí, pero es necesario para crear y editar esquemas si no querés depender de la función DDL Auto de Hibernate . Voy a usar pgAdmin .
- La app frontend (usé Next.js).
- Las distintas aplicaciones backend:
Yo programé todas las apps. Se vienen blogs sobre cada una en el futuro.
Agregar recurso de PostgreSQL
- Crear un nuevo proyecto:
- Hacé clic en Projects en el menú de la izquierda.
- Hacé clic en Add a new project.
- Poné el nombre “roundest_pokemon”.
- Hacé clic en Create. Deberías ver creado el proyecto “roundest_pokemon”.
- Agregar un nuevo recurso de PostgreSQL:
- Entrá a tu proyecto “roundest_pokemon”.
- Hacé clic en + New.
- Bajo Databases, seleccioná Postgres.
- Seleccioná la opción por defecto, ya que solo necesitamos una base de datos SQL simple.
- Dejá todo como está y hacé clic en Start.
¿Cómo podemos gestionar la base de datos?
- Exponer la base de datos a internet: es una opción totalmente válida, pero implicaría:
- Cambiar las configuraciones del firewall para exponer un nuevo puerto.
- Estar expuesto a ataques de fuerza bruta contra contraseña.
- Usar una interfaz web para gestionar la base sin exponerla públicamente: mantiene la base de datos privada y te permite correr consultas en la red interna.
Vamos a optar por esta última alternativa.
pgAdmin
Agregar el recurso de Docker
-
Entrá a tu proyecto “roundest_pokemon”.
- Es crucial que estés dentro del mismo proyecto, si no pgAdmin no podrá conectarse a la base que ya creamos.
-
Hacé clic en + New.
-
Bajo Docker Based, seleccioná Docker Image.
-
Te van a pedir que ingreses el nombre de una imagen. Escribí
dpage/pgadmin4
y hacé clic en Save. -
Asignale un dominio (por ejemplo,
https://pgadmin4.tudominio.com
) y hacé clic en Save. -
En Environment Variables agregá las credenciales que vas a usar para loguearte en pgAdmin:
PGADMIN_DEFAULT_EMAIL
PGADMIN_DEFAULT_PASSWORD
(mantenela alfanumérica, sin símbolos)
Agregar un nuevo servidor
-
Entrá a
pgadmin4.tudominio.com
y logueate con las credenciales que pusiste en las variables de entorno dedpage/pgadmin4
. -
Una vez dentro, clickeá en Add new server.
-
En General, podés asignarle el nombre que quieras.
-
En Connection, tenés que completar:
- Host name/address: el hostname de la URL interna de PostgreSQL (se encuentra entre
@
y:5432
). - Port: por defecto es
5432
. - Username: el usuario configurado en PostgreSQL.
- Host name/address: el hostname de la URL interna de PostgreSQL (se encuentra entre
-
Al guardar, se te pedirá la contraseña.
Ahora vas a poder ejecutar consultas en la base manteniéndola segura dentro de la red interna.
Poblar datos iniciales
-
En la barra lateral izquierda, bajo Servers → el servidor que recién agregaste → Databases → Schemas, hacé clic derecho y seleccioná Query Tool. Se abrirá la consola de consultas.
-
Pegá y ejecutá este script SQL que crea una tabla para los Pokémon e inserta la primera generación con 0 votos iniciales.
-
Consultá los datos creados para confirmar que todo está OK.
SELECT * FROM pokemons;
Crear un usuario específico para tu aplicación
Crear un usuario específico para tu aplicación (en lugar de usar el superusuario postgres u otras cuentas de admin) es una práctica recomendada desde el punto de vista de seguridad y operación.
Acá tenés un script para crear un usuario con acceso limitado al esquema público:
-- Crear backend_app_user
CREATE USER backend_app_user WITH PASSWORD 'tu_contraseña_segura_aquí';
-- Conceder permisos básicos de conexión
GRANT CONNECT ON DATABASE postgres TO backend_app_user;
-- Conceder permisos sobre el esquema
GRANT USAGE ON SCHEMA public TO backend_app_user;
-- Conceder permisos sobre las tablas existentes
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO backend_app_user;
-- Conceder permisos por defecto para futuras tablas
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO backend_app_user;
-- Conceder permisos sobre secuencias existentes
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO backend_app_user;
-- Conceder permisos por defecto para futuras secuencias
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT USAGE, SELECT ON SEQUENCES TO backend_app_user;
Crear una aplicación de GitHub en Coolify
¿Por qué?
- Para desplegar repositorios privados.
- Para habilitar despliegues automáticos a través de webhooks.
¿Cómo?
-
Acceder a Sources en Coolify:
- Navegá a Sources en el panel de Coolify.
- Hacé clic en Add para crear una nueva aplicación de GitHub.
-
Configurar la aplicación de GitHub:
- Poné un nombre único para tu app de GitHub (por ejemplo,
coolify-pollito-tech
). El nombre tiene que ser único a nivel global en GitHub. - Configurá el Webhook Endpoint con la URL HTTPS de tu instancia de Coolify (usar HTTP puede causar problemas con la entrega del webhook).
- Hacé clic en Register Now para continuar hacia GitHub.
- Poné un nombre único para tu app de GitHub (por ejemplo,
-
Configurar el acceso a repositorios en GitHub:
- Seguí el principio de “menor privilegio”, otorgando acceso solo a los repositorios que vas a desplegar.
- Hacé clic en Install para finalizar la configuración de la app en GitHub.
-
Verificar permisos en Coolify:
- Volvé a Coolify y hacé clic en Refetch para confirmar que la app de GitHub tiene los permisos correctos.
- Una configuración exitosa mostrará que la app tiene acceso a los repositorios seleccionados.
Si después querés agregar repositorios nuevos, hacé clic en Update Repositories. Esto te redirigirá a GitHub para actualizar el acceso a repositorios.
Desplegar usando GitHub App
Spring Boot
Vamos a desplegar una de las aplicaciones backend.
- Entrá a tu proyecto “roundest_pokemon”.
- Es crucial que estés dentro del mismo proyecto, si no la aplicación no podrá conectarse a la base que ya creamos.
- Hacé clic en + New.
- Bajo Git Based, seleccioná Private Repository (with GitHub App).
- Elegí el repositorio que contiene la aplicación.
- Podés dejar todo lo demás como está, ya que lo vas a configurar en el siguiente paso.
- Configurar los ajustes de la aplicación:
- Application Type: Este repositorio cuenta con un Dockerfile que yo ya probé bien y hasta ahora anda de 10. Así que seleccioná Dockerfile.
- Agregá tu dominio custom (por ejemplo,
app.tu-dominio.com
) - Bajando un poco, vas a encontrar la sección Network. Para estas apps backend, en Ports exposes poné
8080
. El puerto puede variar según el tipo de aplicación. - En Environment Variables agregá todas las que la app necesite. En este caso particular, necesito la dirección de la base de datos: host, puerto, nombre de la base, usuario y contraseña. Recordá usar el usuario y contraseña específicos que creamos antes.
- Desplegá. Coolify va a:
- Clonar tu repositorio.
- Construir la imagen Docker usando tu Dockerfile.
- Desplegar el contenedor con el dominio y las variables de entorno que configuraste.
Visitá https://app.tu-dominio.com
para confirmar que la app esté en línea.
Bailá y repetí el proceso para todas las apps Spring Boot similares.
Next.js
El proceso de despliegue para aplicaciones Next.js es casi idéntico al del backend Spring Boot, con un único cambio en la configuración:
- Entrá a tu proyecto (por ejemplo, “roundest_pokemon”).
- Se aplica la misma condición de proyecto, para asegurar que el frontend pueda comunicarse con los servicios backend.
- Hacé clic en + New → Private Repository (with GitHub App).
- Seleccioná tu repositorio de Next.js.
- Configurar los ajustes de la aplicación:
- Application Type: Seleccioná Nixpacks . Detecta automáticamente Next.js y maneja las optimizaciones de la compilación.
- Agregá tu dominio para el frontend (por ejemplo,
vote.tu-dominio.com
). - En la sección Network: Establecé el puerto expuesto en
3000
(puerto por defecto de Next.js). - Agregá las Environment Variables que hagan falta.
- Desplegá.
Podés interactuar con mi resultado final acá . No prometo mantenerla activa para siempre, ya que puede que use este VPS para otro proyecto que requiera la potencia del servidor.
Uso de recursos del VPS
Esta captura de pantalla muestra el VPS en estado inactivo, exhibiendo varias métricas de recursos.
Recordemos que este VPS está corriendo:
- Una app Next.js.
- Una app en Java.
- Una app en Kotlin.
- Una app en Groovy.
- Una base de datos (Postgres).
- Un administrador de base de datos (pgAdmin).
- Glances (para monitoreo).
- Coolify, el panel administrativo desde donde gestionamos las apps.
Resumen del sistema
- CPU: El sistema está usando alrededor del 8.1% de CPU, con la mayor parte del uso viniendo de procesos en segundo plano.
- Memoria: Se está usando el 34.3% de la RAM, con algo de swap asignado, pero que no se utiliza activamente.
- Load Average: La carga del sistema se mantiene baja, con un promedio a 15 minutos de 0.26, indicando poca actividad.
- I/O de disco: No hay operaciones significativas de lectura/escritura, lo que significa que no se está usando intensivamente el disco.
- Red: Actividad mínima en la red, con solo unos pocos kilobytes de datos siendo transferidos.
Actividad de los contenedores y procesos
- Están corriendo múltiples contenedores Docker, pero en su mayoría se encuentran inactivos.
- Los procesos que más CPU consumen incluyen:
python3
corriendoglances
para monitoreo.dockerd
gestionando los contenedores.- Servicios en segundo plano como
redis-server
yphp-fpm
, necesarios para Coolify. - Procesos de
java
(los sistemas backend).
Alertas críticas
El sistema ha registrado alertas de alto uso de CPU en el pasado debido a procesos de java
, python3
y dockerd
. Esto ocurrió durante el despliegue de los servicios backend.
Una conclusión sentimental al viaje del VPS
Esta se ha convertido en la serie de blogs que más me ha gustado escribir.
Quiero tomarme un momento para reflexionar sobre lo lejos que llegamos juntos. Cuando empezamos preguntándonos, “¿Qué es un VPS?”
- En Parte 1, reconocimos el atractivo de lo serverless mientras abrazábamos el valor de tener el control sobre nuestro propio servidor. No hace falta construir el próximo Facebook para merecer una infraestructura confiable, flexible y que sea tuya.
- En Parte 2, nos arremangamos y construimos la base: elegí un proveedor, reforzamos la seguridad y sentamos las bases para lo que estaba por venir. No fue algo glamuroso, pero como plantar un árbol, puso raíces para el crecimiento.
- Luego vino Parte 3, donde Coolify entró en escena, transformando el VPS de un lienzo en blanco a una herramienta poderosa. Con proxies, HTTPS y firewalls, simplificamos la complejidad, demostrando que la administración moderna de servidores puede ser robusta y accesible.
- Parte 4 le dio vida a nuestro servidor con Glances, un dashboard en tiempo real asegurado por Caddy.
- Finalmente, en Parte 5 desplegamos una app full-stack con base de datos.
Esta serie trata sobre la alegría de crear un espacio que es totalmente tuyo, sin depender de los caprichos de precios opacos en la nube o soluciones de talla única. Se trata de tener esa confianza silenciosa: saber que, aunque tu app se mantenga chiquita, va a funcionar sin problemas, de forma segura y a tu manera.
A medida que avanzás, recordá que todo experto fue alguna vez un principiante conectándose por ssh por primera vez. Tu servidor es un compañero, no un crítico. Experimentá, rompé cosas (¡y después arreglalas!) y celebrá cada hito, ya sea clavar una regla en el firewall o desplegar esa primera app.
Si seguiste el camino, ahora estás armado no solo con un VPS, sino con el conocimiento para moldearlo según lo que tus proyectos pidan. Seguí experimentando, aprendiendo y, sobre todo, construyendo cosas que te importen.
¡Te deseo un feliz hosting! ~Pollito <🐤/>