Ejemplo de trabajo.
Este no es un tutorial de arranque de primavera. Es la respuesta actualizada a una pregunta sobre cómo ejecutar una compilación de Maven dentro de un contenedor Docker.
Pregunta publicada originalmente hace 4 años.
1. Genere una aplicación
Utilice el inicializador de primavera para generar una aplicación de demostración
https://start.spring.io/
Extraiga el archivo zip localmente
2. Crea un Dockerfile
#
# Build stage
#
FROM maven:3.6.0-jdk-11-slim AS build
COPY src /home/app/src
COPY pom.xml /home/app
RUN mvn -f /home/app/pom.xml clean package
#
# Package stage
#
FROM openjdk:11-jre-slim
COPY --from=build /home/app/target/demo-0.0.1-SNAPSHOT.jar /usr/local/lib/demo.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/usr/local/lib/demo.jar"]
Nota
- Este ejemplo utiliza una compilación de varias etapas . La primera etapa se usa para construir el código. La segunda etapa solo contiene el jar construido y un JRE para ejecutarlo (observe cómo se copia jar entre etapas).
3. Construye la imagen
docker build -t demo .
4. Ejecute la imagen
$ docker run --rm -it demo:latest
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.3.RELEASE)
2019-02-22 17:18:57.835 INFO 1 --- [ main] com.example.demo.DemoApplication : Starting DemoApplication v0.0.1-SNAPSHOT on f4e67677c9a9 with PID 1 (/usr/local/bin/demo.jar started by root in /)
2019-02-22 17:18:57.837 INFO 1 --- [ main] com.example.demo.DemoApplication : No active profile set, falling back to default profiles: default
2019-02-22 17:18:58.294 INFO 1 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 0.711 seconds (JVM running for 1.035)
Misc
Lea la documentación del centro de Docker sobre cómo se puede optimizar la compilación de Maven para usar un repositorio local para almacenar archivos en caché.
Actualización (2019-02-07)
Esta pregunta tiene ahora 4 años y en ese momento es justo decir que la creación de aplicaciones con Docker ha experimentado un cambio significativo.
Opción 1: construcción de varias etapas
Este nuevo estilo le permite crear imágenes más livianas que no encapsulan sus herramientas de compilación y código fuente.
El ejemplo aquí nuevamente usa la imagen base oficial de Maven para ejecutar la primera etapa de la compilación usando una versión deseada de Maven. La segunda parte del archivo define cómo se ensambla el jar construido en la imagen de salida final.
FROM maven:3.5-jdk-8 AS build
COPY src /usr/src/app/src
COPY pom.xml /usr/src/app
RUN mvn -f /usr/src/app/pom.xml clean package
FROM gcr.io/distroless/java
COPY --from=build /usr/src/app/target/helloworld-1.0.0-SNAPSHOT.jar /usr/app/helloworld-1.0.0-SNAPSHOT.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/usr/app/helloworld-1.0.0-SNAPSHOT.jar"]
Nota:
- Estoy usando la imagen base sin distribución de Google , que se esfuerza por proporcionar el tiempo de ejecución suficiente para una aplicación Java.
Opción 2: foque
No he usado este enfoque, pero parece digno de investigación, ya que te permite crear imágenes sin tener que crear cosas desagradables como Dockerfiles :-)
https://github.com/GoogleContainerTools/jib
El proyecto tiene un complemento de Maven que integra el empaquetado de su código directamente en su flujo de trabajo de Maven.
Respuesta original (incluida para completar, pero escrita hace mucho tiempo)
Intenta usar las nuevas imágenes oficiales, hay una para Maven
https://registry.hub.docker.com/_/maven/
La imagen se puede usar para ejecutar Maven en el momento de la compilación para crear una aplicación compilada o, como en los siguientes ejemplos, para ejecutar una compilación de Maven dentro de un contenedor.
Ejemplo 1: Maven ejecutándose dentro de un contenedor
El siguiente comando ejecuta su compilación de Maven dentro de un contenedor:
docker run -it --rm \
-v "$(pwd)":/opt/maven \
-w /opt/maven \
maven:3.2-jdk-7 \
mvn clean install
Notas:
- Lo bueno de este enfoque es que todo el software se instala y se ejecuta dentro del contenedor. Solo necesita Docker en la máquina host.
- Ver Dockerfile para esta versión
Ejemplo 2: usar Nexus para almacenar archivos en caché
Ejecuta el contenedor Nexus
docker run -d -p 8081:8081 --name nexus sonatype/nexus
Cree un archivo "settings.xml":
<settings>
<mirrors>
<mirror>
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<url>http://nexus:8081/content/groups/public/</url>
</mirror>
</mirrors>
</settings>
Ahora ejecute Maven vinculando al contenedor nexus, para que las dependencias se almacenen en caché
docker run -it --rm \
-v "$(pwd)":/opt/maven \
-w /opt/maven \
--link nexus:nexus \
maven:3.2-jdk-7 \
mvn -s settings.xml clean install
Notas:
- Una ventaja de ejecutar Nexus en segundo plano es que otros repositorios de terceros se pueden administrar a través de la URL del administrador de forma transparente para las compilaciones de Maven que se ejecutan en contenedores locales.
mavenCentral()
Reemplacé en mis dependencias gradle conmaven {url "http://nexus:8081..."
y ahora solo tengo problemas de resolución.