← Poner el backend en producción

Sesión 12

La base de datos del backend publicado

Antes de empezar. Servidor ya ha preparado JPA, PostgreSQL y pruebas de repositorio. CI utiliza una base aislada. Hoy publicamos esa versión con PostgreSQL en la EC2 de la sesión 8, conservando datos ficticios en su disco.

Se explica

25 minutos · explicación y demostración

Una base privada para una API pública

El cliente accede a la API, no directamente a PostgreSQL. La base escucha en localhost:5432 y no se abre ese puerto en el grupo de seguridad. Usamos una base y un usuario exclusivos del proyecto, distintos de desarrollo y CI. La aplicación no utiliza el superusuario postgres.

API y base comparten máquina para reducir coste y complejidad del taller. Esta decisión no proporciona alta disponibilidad: una avería o retirada del disco afecta a ambas. Detener EC2 conserva el disco; terminarla puede eliminarlo. Persistencia tras reinicio tampoco equivale a copia recuperable.

Presupuesto y duración

PostgreSQL instalado en la EC2 se detiene con ella. No se crea un RDS que pueda seguir consumiendo entre sesiones. El disco y la IPv4 pública cuando esté asignada tienen costes propios. Revisa el presupuesto, que puede actualizarse con retraso. El entorno no garantiza conservar datos después del final de la clase ni al agotar el presupuesto.

Se trabaja

140 minutos · trabajo guiado sobre el producto compartido

Bloque A · Preparar PostgreSQL en la EC2

Conecta por SSH con el procedimiento de la sesión 8. Estos comandos se ejecutan en Ubuntu, no en PowerShell. Si no recuerdas dónde estás, ejecuta whoami; debe responder ubuntu. La plantilla ya instaló PostgreSQL. Primero consulta el estado del servicio y los puertos:

sudo systemctl status postgresql --no-pager
sudo ss -lnt

Es normal que el servicio general postgresql aparezca como active (exited): Ubuntu lo utiliza para gestionar los clústeres. Comprueba también el puerto 5432 en la salida de ss; una conexión SQL correcta en el siguiente paso confirma que la base responde. Debe escuchar en 127.0.0.1:5432 o [::1]:5432, que son direcciones del propio equipo, no en 0.0.0.0:5432. Si aparece en todas las interfaces, revisa la configuración con el docente antes de continuar.

Ahora ejecuta sudo -u postgres psql. Entras en otro programa: el indicador cambia a postgres=#. sudo -u postgres ejecuta el cliente como administrador de PostgreSQL; no cambia permanentemente el usuario SSH. Introduce las líneas siguientes una a una. Las sentencias SQL terminan con punto y coma; las órdenes que empiezan por barra inversa no lo necesitan:

CREATE ROLE intermodular LOGIN;
\password intermodular
CREATE DATABASE intermodular OWNER intermodular;
\q

Son comandos de primera instalación. Si la base existe, inspecciónala y reutilízala: no la borres ni repitas su creación a ciegas. El ejemplo presupone un proyecto por instancia; un servidor compartido necesita usuarios, bases y permisos propios por proyecto.

Qué debes ver: CREATE ROLE tras crear el usuario y CREATE DATABASE tras crear la base. \password intermodular solicita dos veces la nueva contraseña: es normal que no aparezcan caracteres al escribir. Guárdala de forma privada porque la necesitarás en el bloque siguiente. \q sale de psql y te devuelve al indicador ubuntu@...$. Si te equivocas y psql queda esperando completar una sentencia, cancélala con Ctrl+C antes de volver a escribirla; no pegues comandos Linux en el indicador SQL.

Bloque B · Configuración externa del servicio

En la terminal Ubuntu, fuera de psql, ejecuta sudo nano /etc/intermodular.env. Abres un editor de texto dentro de la terminal; ya no estás escribiendo órdenes del sistema. El archivo puede estar vacío porque lo creó la plantilla. Pega estas cinco líneas:

SPRING_DATASOURCE_URL=jdbc:postgresql://127.0.0.1:5432/intermodular
SPRING_DATASOURCE_USERNAME=intermodular
SPRING_DATASOURCE_PASSWORD=CONTRASENA_REAL_SOLO_EN_EL_SERVIDOR
SPRING_JPA_HIBERNATE_DDL_AUTO=validate
SPRING_SQL_INIT_MODE=never

Sustituye el marcador por la contraseña real; para este ejercicio utiliza una contraseña aleatoria larga con letras y números. Conserva propietario root y permisos 600. El repositorio solo contiene una plantilla ficticia. No muestres el archivo en capturas ni incidencias.

La contraseña debe ser la misma que acabas de asignar a intermodular; no generes una distinta para este archivo. No pegues las marcas del bloque de código ni espacios alrededor del signo =. En nano, guarda con Ctrl+O, confirma el nombre con Enter y sal con Ctrl+X. Para revisar permisos sin mostrar los secretos, ejecuta sudo stat -c '%U %a' /etc/intermodular.env: debe indicar root 600. Editar el archivo no actualiza por sí solo el proceso; lo reiniciarás después de preparar el esquema.

La conexión utiliza loopback dentro del mismo sistema; no atraviesa Internet. Esta arquitectura no valida TLS de base de datos. Si más adelante separas PostgreSQL o usas RDS, revisa red, permisos y TLS: no reutilices sin cambios esta URL.

Bloque C · Crear el esquema de forma controlada

  1. Revisa y prueba el esquema de la versión de Servidor en una base vacía de ensayo. Con pg_dump exporta estructura sin propietarios ni privilegios. En PowerShell, desde el repositorio:
pg_dump --host=localhost --port=5432 --username=postgres --schema-only --no-owner --no-privileges --file=docs/esquema-inicial.sql gestor_db

Comprueba que no contiene contraseñas ni datos y revísalo mediante PR. El PostgreSQL del servidor debe admitir la versión del volcado; adapta exportación o herramientas si el proyecto utiliza una versión posterior, sin editar a ciegas un volcado incompatible.

Aquí vuelves al equipo local: abre una segunda pestaña PowerShell en la carpeta de tu repositorio, conservando la sesión SSH en la primera. Comprueba que existe la carpeta docs y sustituye gestor_db por tu base de desarrollo real. Este localhost es tu portátil; el localhost escrito dentro de SSH es la EC2. Si PowerShell no reconoce pg_dump, utiliza la ruta de las herramientas PostgreSQL preparadas para Servidor con ayuda del docente.

  1. Copia el script aprobado a /home/ubuntu/esquema-inicial.sql con scp, como el artefacto. Confirma que la base de destino está vacía y aplícalo como el usuario del proyecto:

En la pestaña PowerShell local, desde el repositorio, copia:

scp -i "RUTA_A_LA_CLAVE.pem" ./docs/esquema-inicial.sql ubuntu@IP_ACTUAL:/home/ubuntu/

Vuelve a la pestaña SSH de Ubuntu. Primero ejecuta psql -h 127.0.0.1 -U intermodular -d intermodular -W -c '\dt'. En una base nueva debe indicar que no hay relaciones. Si ya hay tablas, detente y revisa qué se instaló; no borres nada para forzar que el ejemplo encaje. Solo para la primera instalación en una base vacía:

psql -h 127.0.0.1 -U intermodular -d intermodular -W -v ON_ERROR_STOP=1 --single-transaction -f /home/ubuntu/esquema-inicial.sql

La contraseña se introduce cuando se solicita, no en el comando. No vuelvas a aplicar el esquema inicial sobre tablas con datos.

-U elige usuario, -d elige base, -W pide contraseña y -f lee el archivo SQL. El comando termina y vuelve al shell. Se detiene ante el primer error y utiliza una transacción para evitar dejar medio esquema aplicado. Repite la consulta \dt para comprobar las tablas antes de arrancar el backend.

  1. Publica el JAR del CI correcto de main con la sesión 8 y reinicia intermodular. Comprueba en journalctl que valida el esquema. Corrige las discrepancias revisando versiones; no sustituyas validate por update o create-drop.
  2. Para cambios posteriores prepara scripts incrementales revisados y ensayados sobre una copia. No sustituyas la API de Servidor por la demo docente.

Bloque D · Verificar persistencia y conservar una copia

  1. Crea un dato ficticio con la colección contra la URL publicada y guarda el identificador. Si la ruta necesita autenticación, utiliza HTTPS ya validado.
  2. Reinicia el backend con sudo systemctl restart intermodular. Espera su arranque y consulta el identificador: debe seguir presente.
  3. En Ubuntu ejecuta primero sudo systemctl restart postgresql y después sudo systemctl restart intermodular. Espera el arranque y repite la consulta desde la colección del equipo local. Registra qué reiniciaste y el resultado; esto no demuestra recuperación de un disco perdido.
  4. En una comprobación acordada con el docente, detén e inicia EC2. Espera el arranque, actualiza IP y DNS si han cambiado y consulta de nuevo. No termines la instancia ni uses Reset.
  5. Genera una copia con el usuario del proyecto y descárgala a una carpeta privada fuera del repositorio:
pg_dump -h 127.0.0.1 -U intermodular -W -d intermodular -Fc -f /home/ubuntu/intermodular.dump
chmod 600 /home/ubuntu/intermodular.dump

Desde el equipo local descarga con scp -i "RUTA_A_LA_CLAVE.pem" ubuntu@IP_ACTUAL:/home/ubuntu/intermodular.dump .. Para acreditar recuperación, restaura en una base vacía de ensayo y consulta el identificador. Una copia sin prueba de restauración solo acredita la exportación.

Cierre

15 minutos · comprobación del resultado

Entrega JAR/commit, petición pública y comprobaciones antes y después del reinicio. Añade ubicación privada de la copia y resultado de restauración si lo has realizado. Se evalúa persistencia comprobada durante las sesiones, sin exigir disponibilidad permanente. Ninguna contraseña ni clave SSH forma parte de la entrega.

Si Servidor aún no termina la persistencia, prepara base, esquema revisado y variables. Ejecuta las comprobaciones cuando esté disponible la versión persistente; la entrega del trimestre requiere realizarlas. No inventes resultados ni sustituyas el producto por un ejemplo independiente.