Configurar correo en Spring Boot con Docker


Aprende cómo configurar y probar el envío de correos en Spring Boot usando JavaMail, SMTP, SSL/TLS y testConnection paso a paso

oscar Escrito por oscar 05 December 2025 33 0

En este post realizaremos una prueba integral de conexión del proveedor de correos electrónicos desde una aplicación desarrollada en Java con Spring Boot, empaquetada en una imagen Docker.

El objetivo principal es verificar que el probeedor de correos se conecte correctamente en cada nivel de la infraestructura, desde la aplicación hasta la conectividad con el servidor SMTP, así como identificar y analizar posibles errores que puedan presentarse durante el proceso.

A lo largo del post abordaremos los siguientes puntos:

Como proveedor de correo utilizaremos Gmail, lo que nos permitirá revisar consideraciones importantes como autenticación, seguridad y políticas de acceso.

Pasos para crear aplicación Java con docker

Crear aplicacion Java Spring Boot

Procedemos a crear una aplicación de spring boot con las siguientes características:

Mas informacion sobre aplicaciones spring boot en cómo crear un Entorno de trabajo para Spring boot en eclipse

Procedemos a cargar el proyecto en eclipse o el IDE que prefieras trabajar con spring boot, en el link anterior explico como hacer la carga del proyecto.

Crear proyecto en Java

Procedemos a crear la siguiente estructura de de directorios, paquetes y clases en Java

Estructura del proyecto Email Java
Estructura del proyecto Email Java

Crear clase principal

Procedemos a crear la clase controller EmailController.java donde colocaremos el siguiente codigo

package com.example.demo.controller;

import java.util.Properties;

import javax.mail.MessagingException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mail.MailSendException;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class EmailController {

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	@GetMapping("/send-email")
	public String sendEmail() {

		logger.info("sendEmail()");

		JavaMailSenderImpl mailSender = new JavaMailSenderImpl();

		mailSender.setHost("<HOST_DEL_EMAIL>");
		mailSender.setUsername("<EMAIL>");
		mailSender.setPassword("<PASSWORD>");

		mailSender.setPort(Integer.valueOf("465"));
		mailSender.setDefaultEncoding("UTF-8");

		Properties properties = new Properties();

		properties.put("mail.smtp.auth", "true");
		properties.put("mail.smtp.connectiontimeout", "10000");
		properties.put("mail.smtp.ssl.enable", "true");
		properties.put("mail.smtp.ssl.trust", "*");
		properties.put("mail.smtp.starttls.enable", "false");
		properties.put("mail.smtp.timeout", "10000");
		properties.put("mail.imap.ssl.trust", "*");
		properties.put("mail.imap.ssl.enable", "true");
		properties.put("mail.imap.timeout", "10000");
		properties.put("mail.imap.connectiontimeout", "10000");
		properties.put("mail.store.protocol", "smtp");
		properties.put("mail.debug", "true");

		if (properties.size() > 0) {
			mailSender.setJavaMailProperties(properties);
		}

		try {
			logger.info("sendEmail(Inicia testConnection)");
			mailSender.testConnection();
			logger.info("sendEmail(Fin testConnection)");
		} catch (MailSendException ex) {
			logger.error("MailSendException {}", ex.getMessage());
			ex.printStackTrace();
			return "Error MailSendException";
		} catch (MessagingException e) {
			logger.error("MessagingException {}", e.getMessage());
			e.printStackTrace();
			return "Error MessagingException";
		}
		logger.info("sendEmail(Fin prueba)");
		return "Correo enviado!";
	}

}

Que hace el código anterior:

1️⃣ Instancia el cliente SMTP en Java.

JavaMailSenderImpl mailSender = new JavaMailSenderImpl();

En lugar de usar application.properties, aquí todo se configura programáticamente.

2️⃣ Credenciales del servidor SMTP:

mailSender.setHost("<HOST_DEL_EMAIL>");
mailSender.setUsername("<EMAIL>");
mailSender.setPassword("<PASSWORD>");

3️⃣ Puerto SMTP:

mailSender.setPort(Integer.valueOf("465"));

4️⃣ Este método define la codificación de caracteres (ej. UTF-8).

mailSender.setDefaultEncoding("UTF-8");

5️⃣ Inicializamos el objeto properties

Properties properties = new Properties();

Objeto donde se definen parámetros de bajo nivel para JavaMail.

6️⃣ Habilita autenticación SMTP

properties.put("mail.smtp.auth", "true");

7️⃣ Tiempo máximo de espera (ms) para:

properties.put("mail.smtp.connectiontimeout", "10000");
properties.put("mail.smtp.timeout", "10000");

Tiempo máximo de espera (ms) para:

Evita bloqueos indefinidos.

8️⃣ Configuramos las propiedades de mail

SSL / TLS

properties.put("mail.smtp.ssl.enable", "true");

Activa SSL (requerido para puerto 465).

 Desactiva STARTTLS.

properties.put("mail.smtp.starttls.enable", "false");

Confía en todos los certificados SSL.

properties.put("mail.smtp.ssl.trust", "*");

Propiedades IMAP (no necesarias aquí)

properties.put("mail.imap.ssl.enable", "true");
properties.put("mail.imap.ssl.trust", "*");
properties.put("mail.imap.timeout", "10000");
properties.put("mail.imap.connectiontimeout", "10000");

Activa logs detallados de JavaMail.

properties.put("mail.debug", "true");

Muy útil para:

9️⃣ Asignación de propiedades

if (properties.size() > 0) {
    mailSender.setJavaMailProperties(properties);
}

🔟 Prueba de conexión SMTP

mailSender.testConnection();

No envía correos, solo:

Ideal para:

Procedemos a ejecutar, compilar 

Tenemos dos opciones, si esta trabajando con eclipse o sts4 puede usar las opciones de compilar y ejecutar del mismo IDE

Nota: tambien puede hacerlo desde la terminal de comandos ejecutado el compilador de maven y luego empaquetar la aplicación:

mvn clean package

Luego ejecutar  como una aplicacion java de la siguiente forma

java -jar target/tu-proyecto-1.0.0.jar

Ejecutamos en el navegador o por curl

Para probar que este funcionado la validación del correo, realizamos la ejecución en el navegador accediendo por la url http://localhost:8080/send-email

Tambien podemos hacer el llamado por medio del comando curl.

curl "http://localhost:8080/send-email"

Al revisar los logs que genera Spring Boot, mostrara lo siguiente

DEBUG: Jakarta Mail version 1.6.7
DEBUG: successfully loaded resource: /META-INF/javamail.default.providers
DEBUG: Tables of loaded providers
DEBUG: Providers Listed By Class Name: {com.sun.mail.smtp.SMTPTransport=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle], com.sun.mail.imap.IMAPSSLStore=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle], com.sun.mail.pop3.POP3Store=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Oracle], com.sun.mail.smtp.SMTPSSLTransport=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle], com.sun.mail.imap.IMAPStore=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Oracle], com.sun.mail.pop3.POP3SSLStore=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Oracle]}
DEBUG: Providers Listed By Protocol: {imap=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Oracle], smtp=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle], pop3=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Oracle], imaps=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle], smtps=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle], pop3s=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Oracle]}
DEBUG: successfully loaded resource: /META-INF/javamail.default.address.map
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "smtp.gmail.com", port 465, isSSL true
220 smtp.gmail.com ESMTP 00721157ae682-79482761800sm2854017b3.4 - gsmtp
DEBUG SMTP: connected to host "smtp.gmail.com", port: 465
EHLO DESKTOP-1801MLQ
250-smtp.gmail.com at your service, [200.118.238.95]
250-SIZE 35882577
250-8BITMIME
250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-CHUNKING
250 SMTPUTF8
DEBUG SMTP: Found extension "SIZE", arg "35882577"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH"
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "CHUNKING", arg ""
DEBUG SMTP: Found extension "SMTPUTF8", arg ""
DEBUG SMTP: protocolConnect login, host=smtp.gmail.com, user=CORREO_ELECTRONICO@gmail.com, password=<non-null>
DEBUG SMTP: Attempt to authenticate using mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM XOAUTH2 
DEBUG SMTP: Using mechanism LOGIN
DEBUG SMTP: AUTH LOGIN command trace suppressed
DEBUG SMTP: AUTH LOGIN succeeded
QUIT
221 2.0.0 closing connection 00721157ae682-79482761800sm2854017b3.4 - gsmtp

Crear una imagen Docker

Vamos a crear la siguiente estructura

demo/
├── Dockerfile
├── pom.xml
└── target/
    └── demo-0.0.1-SNAPSHOT.jar

Crear archivo Dockerfile

Procedemos a crear el archivo Dockerfile

# ---------- STAGE 1: BUILD ----------
FROM maven:3.9.6-eclipse-temurin-17 AS builder

WORKDIR /build

# Copiamos solo lo necesario para aprovechar cache
COPY pom.xml .
RUN mvn -B -q dependency:go-offline

COPY src ./src
RUN mvn -B -q clean package -DskipTests


# ---------- STAGE 2: RUNTIME ----------
FROM eclipse-temurin:17-jre-alpine

# Crear usuario no root (buena práctica)
RUN addgroup -S spring && adduser -S spring -G spring
USER spring:spring

WORKDIR /app

# Copiamos solo el JAR final
COPY --from=builder /build/target/*.jar app.jar

# Puerto típico Spring Boot
EXPOSE 8080

# JVM optimizada para contenedores
ENTRYPOINT ["java","-XX:+UseContainerSupport","-XX:MaxRAMPercentage=75","-jar","app.jar"]

🔹 Multi-stage build

🔹 Imagen base

eclipse-temurin:17-jre-alpine

✔ OpenJDK oficial
✔ Alpine → liviano
✔ Ideal para Kubernetes y Cloud Run

🔹 Usuario no root

USER spring:spring

🔹 JVM flags

-XX:+UseContainerSupport -XX:MaxRAMPercentage=75

Construcción de la imagen

docker build -t springboot-email:1.0 .

Ejecución local

docker run -p 8080:8080 springboot-email:1.0 

Prueba:

http://localhost:8080/send-email


Comentario

Debe aceptar antes de enviar