Generación del esqueleto y primer arranque
Comprender la estructura de un proyecto Spring Boot generando el esqueleto de MULTAGAL, levantando sus tres servicios de datos en Docker y comprobando que arranca correctamente.
1Generar el esqueleto con Spring Initializr
start.spring.io genera el proyecto Maven con la estructura base.
| Campo | Valor |
|---|---|
| Project | Maven |
| Language | Java |
| Spring Boot | 4.x (última estable) |
| Group | es.edu.multagal |
| Artifact | multagal |
| Java | 25 |
| Packaging | Jar |
| Dependencias | Spring Web, Spring Boot DevTools, Lombok (opcional), Validation |
curl https://start.spring.io/starter.zip \
-d type=maven-project -d language=java -d bootVersion=3.4.1 \
-d groupId=es.edu.multagal -d artifactId=multagal \
-d name=multagal -d packageName=es.edu.multagal \
-d javaVersion=25 -d dependencies=web,devtools,lombok,validation \
-o multagal.zip
unzip multagal.zip -d multagal
Estructura de paquetes obligatoria dentro de es.edu.multagal, con dependencias que fluyen en un solo sentido (controller nunca llama a repository; domain no depende de nada):
es.edu.multagal/
├── MultagalApplication.java
├── config/ ← @Configuration y @ConfigurationProperties
├── domain/
│ ├── model/ ← entidades, records, enums, VOs
│ └── exception/ ← jerarquía MultagalException
├── repository/ ← interfaces + implementaciones de acceso a datos
├── service/ ← lógica de negocio
├── controller/ ← puntos de entrada HTTP
└── dto/ ← objetos de transferencia
2compose.yaml y variables de entorno
Tres gestores de bases de datos (MariaDB para UD3, PostgreSQL+PostGIS para UD5, MongoDB para UD6) levantados con un fichero y un comando.
name: multagal
services:
# ─── UD3: MariaDB ──────────────────────
mariadb:
image: mariadb:11
container_name: multagal-mariadb
restart: unless-stopped
environment:
MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD}
MARIADB_DATABASE: multagal
MARIADB_USER: ${MARIADB_USER}
MARIADB_PASSWORD: ${MARIADB_PASSWORD}
ports:
- "3306:3306"
volumes:
- mariadb-data:/var/lib/mysql
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 5
# ─── UD5: PostgreSQL + PostGIS ─────────
postgres:
image: postgis/postgis:16-3.4
container_name: multagal-postgres
restart: unless-stopped
environment:
POSTGRES_DB: multagal
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
ports:
- "5432:5432"
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d multagal"]
interval: 10s
timeout: 5s
retries: 5
# ─── UD6: MongoDB ──────────────────────
mongo:
image: mongo:7
container_name: multagal-mongo
restart: unless-stopped
environment:
MONGO_INITDB_ROOT_USERNAME: ${MONGO_USER}
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_PASSWORD}
MONGO_INITDB_DATABASE: multagal
ports:
- "27017:27017"
volumes:
- mongo-data:/data/db
healthcheck:
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
interval: 10s
timeout: 5s
retries: 5
volumes:
mariadb-data:
postgres-data:
mongo-data:
| Propiedad | Propósito |
|---|---|
image | Versión fija (nunca latest, para reproducibilidad) |
ports | "host:contenedor" — permite conexión externa |
volumes | Persistencia de datos crítica |
healthcheck | Verifica que el servicio responde realmente |
$$ en healthcheck | Escapa la interpolación de Compose (variable local del contenedor) |
# .env (NO se sube al repositorio)
MARIADB_ROOT_PASSWORD=cambiaEstaClaveRoot
MARIADB_USER=multagal
MARIADB_PASSWORD=cambiaEstaClave
POSTGRES_USER=multagal
POSTGRES_PASSWORD=cambiaEstaClave
MONGO_USER=multagal
MONGO_PASSWORD=cambiaEstaClave
# .env.example (SÍ se sube, con valores vacíos)
MARIADB_ROOT_PASSWORD=
MARIADB_USER=multagal
MARIADB_PASSWORD=
POSTGRES_USER=multagal
POSTGRES_PASSWORD=
MONGO_USER=multagal
MONGO_PASSWORD=
.gitignore antes del primer commit. Las contraseñas commiteadas penalizan y no se eliminan del historial aunque se borren después.3application.yml y perfiles
Un perfil por entorno permite ejecutar el mismo código en desarrollo y producción.
# application.yml
spring:
application:
name: multagal
profiles:
default: dev
server:
port: 8080
logging:
level:
es.edu.multagal: DEBUG
# application-dev.yml
spring:
datasource:
url: jdbc:h2:mem:multagal;DB_CLOSE_DELAY=-1
username: sa
password:
h2:
console:
enabled: true
# application-prod.yml
spring:
datasource:
url: jdbc:mariadb://localhost:3306/multagal
username: ${MARIADB_USER}
password: ${MARIADB_PASSWORD}
logging:
level:
root: WARN
--server.port=9090) > variables de entorno (SERVER_PORT=9090) > application-{perfil}.yml > application.yml > valores por defecto en código.4Primer arranque y verificación
@SpringBootApplication combina @SpringBootConfiguration + @ComponentScan + @EnableAutoConfiguration: el Condition Evaluation Report muestra qué autoconfiguraciones se activan según lo que hay en el classpath.
./mvnw spring-boot:run
docker compose up -d
docker compose ps
./mvnw spring-boot:run -Dspring-boot.run.arguments=--debug
--debug, busca la sección Positive matches (autoconfiguraciones activadas) y Negative matches (desactivadas, con la condición que faltó). Necesitas localizar tres activadas y una desactivada con su justificación.5Entregable: ADR de autoconfiguración
Formato ADR simplificado en docs/adr/, registrando decisión, alternativas descartadas y consecuencias.
## ADR-000 — [Nombre de la autoconfiguración]
**Fecha:** AAAA-MM-DD
**Estado:** aceptada
### Contexto
¿Qué condición del classpath o de la configuración la activa o desactiva?
### Decisión
[Activada / Desactivada] porque...
### Consecuencias
...
!Problemas frecuentes
--server.port=8081.compose.yaml (por ejemplo "3307:3306") o para el servicio nativo.docker compose down -v && docker compose up -d (borra los datos).C:\Users\<usuario>\.wslconfig con [wsl2], memory=6GB, processors=4, y ejecuta wsl --shutdown.✓Criterios de aceptación
./mvnw clean packagetermina sin errores- La aplicación arranca registrando el perfil
devactivo docker compose psmuestra los tres servicioshealthy- Sin contraseñas en
compose.yamlni en el código - Informe de autoconfiguración correctamente interpretado
Adaptado de apartado d — Docker y servicios de datos y apartado e — Anatomía de un proyecto Spring Boot.