Despliegue de aplicación Java en VPS: nivel avanzado con CI/CD, Docker y SSL
En este artículo, veremos el proceso avanzado de despliegue de una aplicación Java en un VPS (Servidor Privado Virtual). No nos detendremos en pasos básicos como instalar JDK o ejecutar un archivo JAR. En su lugar, nos centraremos en la configuración de un pipeline de CI/CD, la contenerización con Docker, el uso de Nginx como proxy inverso, la obtención automática de certificados SSL, así como en el monitoreo y la alta disponibilidad de la aplicación.
Se asume que ya tienes un VPS con Ubuntu 22.04 LTS, un dominio base y estás familiarizado con la línea de comandos de Linux. Todos los ejemplos de código están escritos en Java 17+ usando Spring Boot, pero los principios son aplicables a cualquier framework de Java.
1. Contenerización de la aplicación Java con Docker
El primer paso hacia un despliegue avanzado es empaquetar la aplicación en un contenedor Docker. Esto garantiza la reproducibilidad del entorno y simplifica el despliegue.
Crea un Dockerfile en la raíz del proyecto:
# Usamos multi-stage build para reducir el tamaño de la imagen finalFROM maven:3.9.6-eclipse-temurin-17 AS builderWORKDIR /appCOPY pom.xml .RUN mvn dependency:go-offlineCOPY src ./srcRUN mvn clean package -DskipTests
FROM eclipse-temurin:17-jre-alpineWORKDIR /appCOPY --from=builder /app/target/*.jar app.jarEXPOSE 8080ENTRYPOINT ["java", "-jar", "app.jar"]Archivo docker-compose.yml para ejecutar con base de datos:
version: '3.8'services: app: build: . ports: - "8080:8080" environment: - SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/mydb - SPRING_DATASOURCE_USERNAME=user - SPRING_DATASOURCE_PASSWORD=pass depends_on: - db restart: unless-stopped
db: image: postgres:15-alpine environment: POSTGRES_DB: mydb POSTGRES_USER: user POSTGRES_PASSWORD: pass volumes: - pgdata:/var/lib/postgresql/data restart: unless-stopped
volumes: pgdata:Después de construir la imagen con el comando docker compose build, obtendrás un contenedor listo para desplegar.
2. Configuración del pipeline de CI/CD (GitHub Actions)
La automatización del despliegue es un elemento clave del nivel avanzado. Usamos GitHub Actions para compilar, probar y enviar la imagen al servidor.
Crea el archivo .github/workflows/deploy.yml:
name: Deploy Java App to VPS
on: push: branches: [ main ]
jobs: build-and-deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- name: Set up JDK 17 uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin'
- name: Build with Maven run: mvn clean package
- name: Build Docker image run: docker build -t myapp:latest .
- name: Save Docker image to tar run: docker save myapp:latest | gzip > myapp.tar.gz
- name: Copy image to VPS via SCP uses: appleboy/scp-action@v0.1.7 with: host: ${{ secrets.VPS_HOST }} username: ${{ secrets.VPS_USER }} key: ${{ secrets.VPS_SSH_KEY }} source: "myapp.tar.gz" target: "/opt/app/"
- name: Deploy on VPS uses: appleboy/ssh-action@v1.0.3 with: host: ${{ secrets.VPS_HOST }} username: ${{ secrets.VPS_USER }} key: ${{ secrets.VPS_SSH_KEY }} script: | cd /opt/app docker load < myapp.tar.gz docker compose down docker compose up -d rm myapp.tar.gzNo olvides agregar los secretos VPS_HOST, VPS_USER, VPS_SSH_KEY en la configuración