POLITICA DE COOKIES

Q2BSTUDIO.COM utiliza cookies técnicas, analíticas, de sesión y de publicidad con la finalidad de prestar un mejor servicio. No obstante, necesitamos su consentimiento explícito para poder utilizarlas. Así mismo puede cambiar la configuración de las cookies u obtener más información aquí .

Despliegues sin tiempo de inactividad con Jenkins, Docker y Hostinger (Gradle + React + MySQL)

Guía reproducible de despliegues blue-green con swap atómico y rollback por healthcheck en Gradle Spring Boot y React

Publicado el 09/09/2025

Los hackathons son divertidos pero estresantes, sobre todo cuando tu sitio debe permanecer en línea hasta que termine la evaluación. Aquí tienes una guía completa en pasos reproducibles para despliegues con tiempo mínimo de inactividad, rollback seguro y builds deterministas. Está diseñada para un backend Gradle con Spring Boot, frontend React servido por Nginx, base de datos MySQL, builds Docker multietapa, integración continua con Jenkins y despliegue a un VPS Hostinger sobre Ubuntu usando una estrategia tipo blue green con swap atómico y rollback basado en salud.

Lo que hace única esta aproximación:

Etiquetas deterministas para imágenes con formato YYYYmmddHHMM-gitshort, por ejemplo 202509041530-1a2b3c4

Swap atómico de release: Jenkins despliega en /opt/chattingo/releases/TAG y luego hace un swap atómico a /opt/chattingo/current

Rollback condicionado por healthcheck: si la nueva release no pasa /actuator/health en 60 segundos, se revierte automáticamente

Cache busting en frontend: el build Docker inyecta BUILD_ID único en index.html

Tiempo de inactividad mínimo: los usuarios no ven una app rota

Reproducible y transparente: todos los scripts, configuraciones y Jenkinsfile se almacenan en el repo

Requisitos previos antes de empezar, sustituye los marcadores por tus valores: YOUR_DOCKERHUB_USER, YOUR_DOMAIN, YOUR_VPS_IP, SSH_USER, GIT_BRANCH, JENKINS_CRED_IDS.

Configuración Docker y Compose: a continuación se describen los Dockerfile y la plantilla docker compose. Añade la cadena __BUILD_ID__ dentro de public/index.html para evitar caches obsoletos.

Dockerfile frontend multietapa ejemplo:

FROM node:18-alpine AS build

WORKDIR /app

COPY package*.json ./

RUN npm ci

COPY . .

ARG BUILD_ID

RUN if [ -f public/index.html ] ; then sed -i s/__BUILD_ID__/${BUILD_ID}/g public/index.html || true ; fi

RUN npm run build

FROM nginx:stable-alpine

COPY --from=build /app/build /usr/share/nginx/html

COPY nginx.frontend.conf /etc/nginx/conf.d/default.conf

EXPOSE 80

CMD nginx -g daemon off;

Dockerfile backend Gradle multietapa ejemplo:

FROM gradle:8.3-jdk17 AS builder

WORKDIR /app

COPY build.gradle settings.gradle ./

COPY gradle ./gradle

COPY src ./src

RUN gradle clean build -x test --no-daemon

FROM eclipse-temurin:17-jre-jammy

WORKDIR /app

COPY --from=builder /app/build/libs/*.jar app.jar

EXPOSE 8080

HEALTHCHECK --interval=15s --timeout=5s --start-period=10s --retries=5 CMD curl -f https://localhost:8080/actuator/health || exit 1

ENTRYPOINT java -jar /app/app.jar

No es necesario instalar Gradle en Jenkins ya que la compilación ocurre dentro del contenedor builder.

Plantilla docker compose release ejemplo:

version: 3.8

services:

db:

image: mysql:8

environment:

MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-rootpass}

MYSQL_DATABASE: ${MYSQL_DATABASE:-chattingo}

volumes:

- db_data:/var/lib/mysql

restart: unless-stopped

backend:

image: YOUR_DOCKERHUB_USER/chattingo-backend:PLACEHOLDER_TAG

environment:

SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/${MYSQL_DATABASE}

SPRING_DATASOURCE_USERNAME: root

SPRING_DATASOURCE_PASSWORD: ${MYSQL_ROOT_PASSWORD}

depends_on:

- db

ports:

- 8080:8080

restart: unless-stopped

frontend:

image: YOUR_DOCKERHUB_USER/chattingo-frontend:PLACEHOLDER_TAG

depends_on:

- backend

ports:

- 3001:80

restart: unless-stopped

volumes:

db_data:

Jenkins se encargará de reemplazar PLACEHOLDER_TAG por la etiqueta única TAG generada en pipeline.

Pipeline Jenkins, flujo resumido: checkout del repo; cálculo de TAG determinista con fecha y git short; build de imagen frontend pasando BUILD_ID; build de imagen backend usando el Dockerfile Gradle; push de ambas imágenes a DockerHub; despliegue al VPS copiando docker compose y ejecutando script de despliegue.

Ejemplo de pasos clave del pipeline:

Generar TAG con fecha y SHA corto

docker build --build-arg BUILD_ID=${TAG} -t IMAGE_PREFIX/chattingo-frontend:${TAG} ./frontend

docker build -t IMAGE_PREFIX/chattingo-backend:${TAG} ./backend

docker login y docker push de ambas imágenes

scp docker-compose.yml al VPS y ejecutar deploy_release.sh con el TAG

Script de despliegue atómico en VPS, guardar como /usr/local/bin/deploy_release.sh y dar permisos de ejecución:

#!/usr/bin/env bash

set -euo pipefail

TAG=$1

RELEASE_DIR=/opt/chattingo/releases/${TAG}

CURRENT_DIR=/opt/chattingo/current

PREV_DIR=/opt/chattingo/previous

TIMEOUT=60

HEALTH_URL=https://YOUR_DOMAIN/actuator/health

if [ ! -d ${RELEASE_DIR} ] ; then exit 2 ; fi

if [ -d ${CURRENT_DIR} ] ; then mv ${CURRENT_DIR} ${PREV_DIR} ; fi

cp -r ${RELEASE_DIR} ${CURRENT_DIR}

cd ${CURRENT_DIR}

docker compose up -d --remove-orphans

SECONDS=0

until curl -fsS ${HEALTH_URL} > /dev/null ; do sleep 5 ; if [ $SECONDS -ge $TIMEOUT ] ; then docker compose down || true ; if [ -d ${PREV_DIR} ] ; then mv ${PREV_DIR} ${CURRENT_DIR} ; cd ${CURRENT_DIR} ; docker compose up -d ; fi ; exit 3 ; fi ; done

rm -rf ${PREV_DIR}

Este flujo garantiza rollback instantáneo si la nueva versión no pasa el healthcheck en el tiempo definido.

Configuración Nginx reverso en /etc/nginx/sites-available/chattingo ejemplo:

server { listen 80 ; server_name YOUR_DOMAIN ; return 301 https:// $host$request_uri ; }

server { listen 443 ssl ; server_name YOUR_DOMAIN ; ssl_certificate /etc/letsencrypt/live/YOUR_DOMAIN/fullchain.pem ; ssl_certificate_key /etc/letsencrypt/live/YOUR_DOMAIN/privkey.pem ; location / { proxy_pass https://127.0.0.1:3001/ ; } location /api/ { proxy_pass https://127.0.0.1:8080/api/ ; } }

Luego crear enlace simbólico a sites-enabled, probar configuración y recargar nginx.

Buenas prácticas y recomendaciones: usar SSL con LetsEncrypt, almacenar secretos en Jenkins Credentials, usar health endpoints robustos, mantener volúmenes de datos persistentes y automatizar backups de MySQL, custodiar credenciales DockerHub y acceso SSH, y versionar todos los scripts de despliegue en el repositorio para trazabilidad.

Sobre Q2BSTUDIO: somos una empresa de desarrollo de software especializada en aplicaciones a medida y software a medida, con experiencia en inteligencia artificial, ciberseguridad y servicios cloud. Si buscas desarrollar productos robustos y escalables, podemos ayudarte desde la arquitectura hasta la puesta en producción. Conectamos la ingeniería DevOps con soluciones a medida, incluyendo servicios de desarrollo de aplicaciones y software a medida y migraciones o despliegues en la nube con servicios cloud AWS y Azure.

Palabras clave incorporadas naturalmente: aplicaciones a medida, software a medida, inteligencia artificial, ciberseguridad, servicios cloud aws y azure, servicios inteligencia de negocio, ia para empresas, agentes IA, power bi. Ofrecemos también servicios de Business Intelligence y Power BI, automatización de procesos, agentes IA y consultoría en ciberseguridad para garantizar despliegues seguros y resilientes.

Si necesitas que preparemos los archivos listos para clonar en tu repositorio y adaptar los scripts a tu infraestructura, contacta con Q2BSTUDIO y te acompañamos en el diseño de pipelines, seguridad y operación en producción.

Fin del artículo, inicio de la diversión
Construyendo software juntos

Dando vida a tus ideas desde 2008

Diseñamos aplicaciones móviles y de escritorio innovadoras que cumplen con tus requisitos específicos y mejoran la eficiencia operativa.
Más info
Cuéntanos tu visión
Sea cual sea el alcance, podemos convertir tu idea en realidad. Envíanosla y charlemos sobre tu proyecto o una colaboración futura.
Contáctanos
artículos destacados
Live Chat
Enviado correctamente.

Gracias por confiar en Q2BStudio