[Reto] – Dockerizar app JEE (Tomcat 10 + MySQL)

Contexto: JEE sin frameworks, sin Maven, WAR exportado desde Eclipse (Dynamic Web Project).
Front: HTML/JS con fetch consumiendo JSON.

Requisitos

  • Docker instalado (Docker Desktop o Engine)
  • Tener el .war exportado desde Eclipse
  • Driver MySQL dentro del WAR en WEB-INF/lib (esto es clave sin Maven)

Preparar el WAR desde Eclipse

  1. Click derecho al proyecto → Export…
  2. Web → WAR file
  3. Guarda TuApp.war (lo usaremos en ambos métodos)

Checklist rápido:

  • Abre el WAR como zip → existe WEB-INF/lib/mysql-connector-*.jar

PARTE 1 — Docker SIN Compose (a mano, entendiendo todo)

1.1 Crear una red Docker (para que “se vean” por nombre)

docker network create jee-net

1.2 Crear un volumen para MySQL (persistencia real)

docker volume create jee-mysql-data

1.3 Levantar MySQL en contenedor

docker run -d \
--name jee-mysql \
--network jee-net \
-e MYSQL_ROOT_PASSWORD=root1234 \
-e MYSQL_DATABASE=jee_app \
-e MYSQL_USER=jee \
-e MYSQL_PASSWORD=jee1234 \
-v jee-mysql-data:/var/lib/mysql \
-p 3306:3306 \
mysql:8.0 \
--default-authentication-plugin=mysql_native_password

Verificar logs:

docker logs -f jee-mysql

(espera a que salga algo tipo “ready for connections”.)

1.4 Crear base/tablas (opción guiada en vivo)

Entrar a MySQL:

docker exec -it jee-mysql mysql -u jee -pjee1234 jee_app

Ejemplo de SQL (hazlo con tus tablas reales):

CREATE TABLE IF NOT EXISTS alumnos (
id INT AUTO_INCREMENT PRIMARY KEY,
nombre VARCHAR(100) NOT NULL
);INSERT INTO alumnos(nombre) VALUES ('Ada'), ('Alan');
SELECT * FROM alumnos;

Salir:

exit

1.5 Preparar Tomcat 10 con tu WAR (sin construir imagen)

Aquí hay dos formas. La más didáctica es montar el WAR como volumen.

Crea carpeta local:

mkdir -p app
cp TuApp.war app/ROOT.war

Levanta Tomcat 10 y monta el WAR:

docker run -d \
--name jee-tomcat \
--network jee-net \
-p 8080:8080 \
-e DB_HOST=jee-mysql \
-e DB_PORT=3306 \
-e DB_NAME=jee_app \
-e DB_USER=jee \
-e DB_PASS=jee1234 \
-v "$(pwd)/app/ROOT.war:/usr/local/tomcat/webapps/ROOT.war:ro" \
tomcat:10.1-jdk17-temurin

Logs:

docker logs -f jee-tomcat

1.6 Punto crucial: JDBC en Docker (host ≠ localhost)

En tu código, la URL debe usar el nombre del contenedor:

  • localhost
  • jee-mysql (porque ese es el --name del contenedor en la misma red)

1.7 Probar la API

curl http://localhost:8080/tu-endpoint

o en navegador.

1.8 Parar y limpiar (para enseñar “ciclo de vida”)

Parar:

docker stop jee-tomcat jee-mysql

Borrar contenedores:

docker rm jee-tomcat jee-mysql

Volumen (¡ojo, borra datos!):

docker volume rm jee-mysql-data

PARTE 2 — Docker CON Compose (modo “un comando y listo”)

Aquí el objetivo es:
✅ 1 carpeta, ✅ 1 compose, ✅ build opcional, ✅ init automático con SQL.

2.1 Estructura

taller-compose/
├─ docker-compose.yml
├─ app/
│ ├─ Dockerfile
│ └─ ROOT.war
└─ db/
└─ init.sql

Copia tu WAR:

mkdir -p taller-compose/app taller-compose/db
cp TuApp.war taller-compose/app/ROOT.war

2.2 app/Dockerfile (Tomcat 10 + WAR)

FROM tomcat:10.1-jdk17-temurin

RUN rm -rf /usr/local/tomcat/webapps/*

COPY ROOT.war /usr/local/tomcat/webapps/ROOT.war

EXPOSE 8080

2.3 db/init.sql (carga automática al primer arranque)

CREATE TABLE IF NOT EXISTS alumnos (
id INT AUTO_INCREMENT PRIMARY KEY,
nombre VARCHAR(100) NOT NULL
);INSERT INTO alumnos(nombre) VALUES ('Ada'), ('Alan');

2.4 docker-compose.yml (MySQL + Tomcat)

services:
  db:
    image: mysql:8.0
    container_name: jee-mysql

    environment:
      MYSQL_ROOT_PASSWORD: root1234
      MYSQL_DATABASE: jee_app
      MYSQL_USER: jee
      MYSQL_PASSWORD: jee1234

    ports:
      - "3306:3306"

    volumes:
      - dbdata:/var/lib/mysql
      - ./db/init.sql:/docker-entrypoint-initdb.d/01_init.sql:ro

    command: --default-authentication-plugin=mysql_native_password

  app:
    build: ./app
    container_name: jee-tomcat

    depends_on:
      - db

    ports:
      - "8080:8080"

    environment:
      DB_HOST: db
      DB_PORT: 3306
      DB_NAME: jee_app
      DB_USER: jee
      DB_PASS: jee1234

volumes:
  dbdata:

Ojo al detalle nerd importante:
En Compose, el hostname correcto es db (nombre del servicio), no el container_name.

2.5 Arranque

Dentro de taller-compose/:

docker compose up -d --build
docker compose ps

Logs:

docker compose logs -f db
docker compose logs -f app

2.6 Probar

curl http://localhost:8080/tu-endpoint

2.7 Parar

docker compose down

Parar y borrar volúmenes (reinicio total):

docker compose down -v