Introducción
Desarrollar una aplicación Java es solo la mitad del trabajo. La segunda parte, igualmente importante, es un despliegue competente en un servidor de producción. Muchos desarrolladores enfrentan dificultades al transferir una aplicación de una máquina local a un VPS: configuración del entorno, compilación, ejecución en segundo plano, garantía de seguridad. En este artículo, analizaremos el proceso completo de despliegue de una aplicación Java en un VPS (Virtual Private Server), desde la compra del servidor hasta la configuración de HTTPS. Todos los pasos estarán acompañados de ejemplos de código y configuraciones.
Usaremos Ubuntu 22.04 LTS como sistema operativo del VPS, y como ejemplo de aplicación Java, una simple aplicación Spring Boot REST empaquetada en un archivo JAR. Si usas otro framework (Jakarta EE, Micronaut, Quarkus), los principios generales seguirán siendo los mismos.
1. Preparación del VPS e instalación de Java
1.1. Conexión al servidor
Después de comprar el VPS, recibirás una dirección IP, un nombre de usuario (generalmente root) y una contraseña o clave SSH. Conéctate al servidor a través de la terminal:
ssh root@tu-ip-del-servidorSi usas una clave SSH, especifica la ruta a ella:
ssh -i /path/to/private_key root@tu-ip-del-servidor1.2. Actualización del sistema e instalación de Java
Primero, actualicemos el gestor de paquetes e instalemos el Java Development Kit (JDK). Para la mayoría de las aplicaciones Java modernas, OpenJDK 17 o 21 es suficiente:
apt update && apt upgrade -yapt install openjdk-17-jdk -yVerifica la instalación:
java -versionDeberías ver algo como:
openjdk version "17.0.10" 2024-01-16 LTSOpenJDK Runtime Environment (build 17.0.10+7-Ubuntu-122.04.1)OpenJDK 64-Bit Server VM (build 17.0.10+7-Ubuntu-122.04.1, mixed mode, sharing)1.3. Configuración de variables de entorno (opcional)
Si tu aplicación requiere variables específicas (por ejemplo, JAVA_HOME), agrégalas al archivo ~/.bashrc o /etc/environment:
echo "export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64" >> ~/.bashrcsource ~/.bashrc2. Compilación y carga de la aplicación al servidor
2.1. Compilación del JAR/WAR en la máquina local
Supongamos que tienes un proyecto Maven. Ejecuta la compilación:
mvn clean package -DskipTestsComo resultado, en la carpeta target/ aparecerá un archivo myapp-0.0.1-SNAPSHOT.jar (o .war para aplicaciones web).
2.2. Carga del archivo JAR al VPS
Usa scp para copiar el archivo al servidor:
scp target/myapp-0.0.1-SNAPSHOT.jar root@tu-ip-del-servidor:/opt/myapp/Crea un directorio para la aplicación en el servidor si no existe:
mkdir -p /opt/myapp2.3. Verificación de la estructura en el servidor
Después de la carga, verifica que el archivo esté en su lugar:
ls -la /opt/myapp/Deberías ver myapp-0.0.1-SNAPSHOT.jar.
3. Configuración del inicio de la aplicación (systemd + Nginx)
3.1. Ejecución manual del archivo JAR (prueba)
Antes de configurar la ejecución permanente, asegúrate de que la aplicación se inicie correctamente:
java -jar /opt/myapp/myapp-0.0.1-SNAPSHOT.jar --server.port=8080Si la aplicación se inicia sin errores, pasamos a crear el servicio systemd.
3.2. Creación del servicio systemd
Systemd permite ejecutar la aplicación Java como un demonio (en segundo plano) y reiniciarla automáticamente si falla o cuando se reinicia el servidor.
Crea el archivo de servicio:
nano /etc/systemd/system/myapp.serviceInserta la siguiente configuración:
[Unit]Description=My Java ApplicationAfter=network.target
[Service]Type=simpleUser=rootWorkingDirectory=/opt/myappExecStart=/usr/bin/java -jar /opt/myapp/myapp-0.0.1-SNAPSHOT.jar --server.port=8080Restart=on-failureRestartSec=10
[Install]WantedBy=multi-user.targetGuarda el archivo y recarga systemd:
systemctl daemon-reloadsystemctl enable myapp.servicesystemctl start myapp.serviceVerifica el estado del servicio:
systemctl status myapp.serviceDeberías ver que el servicio está activo (running).
3.3. Configuración de Nginx como proxy inverso
Nginx actuará como proxy inverso, redirigiendo las solicitudes del puerto 80 (HTTP) al puerto 8080 donde se ejecuta tu aplicación Java.
Instala Nginx:
apt install nginx -yCrea un archivo de configuración para tu aplicación:
nano /etc/nginx/sites-available/myappInserta la siguiente configuración:
server { listen 80; server_name tu-dominio.com www.tu-dominio.com;
location / { proxy_pass http://localhost:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }}Habilita el sitio y reinicia Nginx:
ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/nginx -tsystemctl restart nginx4. Configuración de HTTPS con Let's Encrypt
4.1. Instalación de Certbot
Certbot es una herramienta para obtener certificados SSL/TLS gratuitos de Let's Encrypt.
apt install certbot python3-certbot-nginx -y4.2. Obtención del certificado
Ejecuta Certbot para obtener e instalar automáticamente el certificado:
certbot --nginx -d tu-dominio.com -d www.tu-dominio.comSigue las instrucciones en pantalla. Certbot modificará automáticamente la configuración de Nginx para usar HTTPS.
4.3. Verificación de la renovación automática
Los certificados de Let's Encrypt son válidos por 90 días. Certbot configura automáticamente la renovación. Puedes verificar que funcione:
certbot renew --dry-run5. Configuración del firewall (UFW)
Para mayor seguridad, configura un firewall para permitir solo el tráfico necesario:
ufw allow 22/tcp # SSHufw allow 80/tcp # HTTPufw allow 443/tcp # HTTPSufw enableVerifica el estado del firewall:
ufw status6. Monitoreo y logs
6.1. Visualización de logs de la aplicación
Para ver los logs de tu aplicación Java en tiempo real:
journalctl -u myapp.service -f6.2. Logs de Nginx
Los logs de acceso y errores de Nginx se encuentran en:
/var/log/nginx/access.log/var/log/nginx/error.logConclusión
Hemos cubierto el proceso completo de despliegue de una aplicación Java en un VPS: desde la preparación del servidor y la instalación de Java, hasta la configuración de systemd, Nginx, HTTPS y el firewall. Siguiendo estos pasos, tendrás tu aplicación Java funcionando de manera segura y confiable en producción.
Recuerda que este es un proceso iterativo. Dependiendo de las necesidades específicas de tu aplicación, es posible que necesites ajustar configuraciones adicionales como la gestión de bases de datos, la configuración de memoria JVM, o la implementación de estrategias de balanceo de carga.