Despliegue JEE (Servlet + HTML/JS) + MySQL en Docker

Levantar una aplicación Java (Servlet) desplegada en Tomcat y conectada a MySQL, todo en contenedores Docker, sin frameworks y sin docker-compose.

Requisitos

  • Docker instalado y funcionando.
  • Tu aplicación empaquetada como WAR (ej: miapp.war).
  • Una carpeta de proyecto en tu PC (host).

Estructura del proyecto (en el host)

Crea una carpeta de trabajo, por ejemplo:

mkdir -p ~/proyecto-jee-docker
cd ~/proyecto-jee-docker
mkdir -p deploy

Copia tu WAR dentro de deploy/:

cp /RUTA/AL/WAR/miapp.war ./deploy/

Crear una red Docker para que se vean por nombre

Esto permite que Tomcat encuentre MySQL usando el nombre del contenedor.

docker network create red-jee

Levantar MySQL con volumen (persistencia)

2.1 Crear volumen para MySQL

docker volume create mysql_data

2.2 Lanzar el contenedor MySQL

⚠️ Cambia passwords y nombre de BD si quieres, pero respeta la idea.

docker run -d \
  --name mysql-jee \
  --network red-jee \
  -e MYSQL_ROOT_PASSWORD=root1234 \
  -e MYSQL_DATABASE=appdb \
  -e MYSQL_USER=appuser \
  -e MYSQL_PASSWORD=app1234 \
  -v mysql_data:/var/lib/mysql \
  -p 3307:3306 \
  mysql:8.0

Qué hace esto:

  • --network red-jee → MySQL estará accesible desde Tomcat por hostname mysql-jee
  • -v mysql_data:/var/lib/mysql → los datos sobreviven aunque borres el contenedor
  • -p 3307:3306 → MySQL será accesible desde tu PC en localhost:3307 (evita conflictos si tu 3306 está ocupado)

2.3 Comprobar que MySQL está arriba

docker psdocker logs mysql-jee --tail30

Crear tablas y datos de prueba (dentro del contenedor)

Entra a MySQL dentro del contenedor:

docker exec -it mysql-jee mysql -u root -p

Escribe la contraseña root1234.

Luego (ejemplo genérico), crea una tabla y mete algo.


Preparar el contenedor Tomcat y desplegar el WAR

Ejecutar Tomcat y montar tu WAR (sin construir imagen propia)

Opción simple: montas la carpeta deploy en webapps.

docker run -d \
  --name tomcat-jee \
  --network red-jee \
  -p 8080:8080 \
  -v "$PWD/deploy:/usr/local/tomcat/webapps" \
  tomcat:10.1-jdk17

Qué hace esto:

  • -p 8080:8080 → accedes en http://localhost:8080
  • -v .../webapps → Tomcat “ve” tu WAR y lo despliega al arrancar

4.2 Ver logs de Tomcat (muy importante)

docker logs -f tomcat-jee

Busca líneas tipo “Deploying web application archive … miapp.war”.


5) Configurar la conexión a MySQL en tu Java (punto clave)

Dentro de Docker, NO uses localhost para MySQL desde Tomcat.
Debes usar el nombre del contenedor:

  • Host: mysql-jee
  • Puerto interno: 3306
  • BD: appdb
  • User: appuser
  • Pass: app1234

Ejemplo de URL JDBC:

jdbc:mysql://mysql-jee:3306/appdb?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC

✅ Si tu app usa un fichero de configuración (properties), ajusta eso.

Ejemplo (si usas Properties):

db.url=jdbc:mysql://mysql-jee:3306/appdb?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
db.user=appuser
db.pass=app1234

Nota: si tu WAR ya estaba compilado con localhost, toca recompilar con mysql-jee.


6) Probar la aplicación desde el navegador

  1. Entra a tu app (depende del nombre del WAR):
  • Si el WAR se llama miapp.war, normalmente será:
    • http://localhost:8080/miapp/
  1. Prueba el endpoint del servlet que devuelve JSON:
  • Ejemplo:
    • http://localhost:8080/miapp/api/items

7) Verificar el fetch() y el DOM (JS)

Tu JavaScript hará algo así:

fetch('/miapp/api/items')
  .then(r => r.json())
  .then(data => {
    // pintar DOM
  });

Errores típicos

  • 404 en fetch → la ruta no coincide con el url-pattern del servlet.
  • El fetch devuelve HTML en vez de JSON → estás pegando a una ruta que devuelve una página, no el endpoint.
  • CORS: si sirves el HTML desde Tomcat y llamas al servlet en el mismo host/puerto, normalmente no hay CORS.
    CORS aparece si llamas a otro host/puerto distinto.

8) Comandos útiles de operación (vida real)

Ver contenedores

docker ps
docker ps-a

Parar / arrancar

docker stop tomcat-jee mysql-jee
docker start mysql-jee
docker start tomcat-jee

Entrar a un contenedor

docker exec -it tomcat-jee bash
docker exec -it mysql-jee bash

Ver redes y comprobar nombres

docker network ls
docker network inspect red-jee

9) Reinicio limpio (sin perder datos)

Si quieres borrar Tomcat y recrearlo (sin perder DB):

docker rm -f tomcat-jee
docker run -d \
  --name tomcat-jee \
  --network red-jee \
  -p 8080:8080 \
  -v "$PWD/deploy:/usr/local/tomcat/webapps" \
  tomcat:10.1-jdk17

La BD se conserva porque está en el volumen mysql_data.

Resumen de pasos a realizar:

  • He creado red-jee
  • He creado el volumen mysql_data
  • He levantado mysql-jee y responde
  • He creado tablas y datos en appdb
  • He levantado tomcat-jee con el WAR montado
  • La app carga en http://localhost:8080/...
  • El servlet devuelve JSON válido
  • El fetch() recibe JSON y pinta en el DOM