Pollito Blog
February 3, 2025

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”?

“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.

backend-selector

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.

vote-flow

¿Qué vamos a necesitar?

Yo programé todas las apps. Se vienen blogs sobre cada una en el futuro.

Agregar recurso de PostgreSQL

  1. 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”. coolify-projects
  2. Agregar un nuevo recurso de PostgreSQL:
    • Entrá a tu proyecto “roundest_pokemon”.
    • Hacé clic en + New.
    • Bajo Databases, seleccioná Postgres. projects-postgres.png
    • Seleccioná la opción por defecto, ya que solo necesitamos una base de datos SQL simple. postgres-16
    • Dejá todo como está y hacé clic en Start. postgres-start

¿Cómo podemos gestionar la base de datos?

Vamos a optar por esta última alternativa.

pgAdmin

Agregar el recurso de Docker

  1. 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.
  2. Hacé clic en + New.

  3. Bajo Docker Based, seleccioná Docker Image.

  4. Te van a pedir que ingreses el nombre de una imagen. Escribí dpage/pgadmin4 y hacé clic en Save.

  5. Asignale un dominio (por ejemplo, https://pgadmin4.tudominio.com) y hacé clic en Save. docker-image-pgadmin4

  6. 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)

    pgadmin-credentials.png

Agregar un nuevo servidor

  1. Entrá a pgadmin4.tudominio.com y logueate con las credenciales que pusiste en las variables de entorno de dpage/pgadmin4.

  2. Una vez dentro, clickeá en Add new server. pgadmin4.png

  3. En General, podés asignarle el nombre que quieras.

  4. 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. postgres-conf.png

    pgadmin-connection.png

  5. 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

  1. En la barra lateral izquierda, bajo Serversel servidor que recién agregasteDatabasesSchemas, hacé clic derecho y seleccioná Query Tool. Se abrirá la consola de consultas.

    pgadmin-query-tool.png

  2. Pegá y ejecutá este script SQL que crea una tabla para los Pokémon e inserta la primera generación con 0 votos iniciales.

  3. Consultá los datos creados para confirmar que todo está OK.

SELECT * FROM pokemons;

pgadmin-select-pokemon.png

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é?

¿Cómo?

  1. 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.
  2. 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.

    github-app-register.png

  3. 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.
  4. 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.

    github-app-save.png

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.

  1. 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.
  2. Hacé clic en + New.
  3. Bajo Git Based, seleccioná Private Repository (with GitHub App). resource-github-app.png
  4. 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.
  5. 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) roundest-groovy-conf1.png
    • 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. roundest-groovy-conf2.png
    • 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.
  6. 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. roundest-groovy-live.png

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:

  1. 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.
  2. Hacé clic en + NewPrivate Repository (with GitHub App).
  3. Seleccioná tu repositorio de Next.js.
  4. 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). roundest-nextjs-conf1.png
    • En la sección Network: Establecé el puerto expuesto en 3000 (puerto por defecto de Next.js). roundest-nextjs-conf2.png
    • Agregá las Environment Variables que hagan falta.
  5. 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.

stats.png

Recordemos que este VPS está corriendo:

Resumen del sistema

Actividad de los contenedores y procesos

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?”

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.

tequierobro.jpg

¡Te deseo un feliz hosting! ~Pollito <🐤/>

Hey, check me out!

You can find me here