Tuesday, June 30, 2015

Integrando o Docker com Maven e Gradle

Para otimizar o processo de build em aplicações Java é possível incluir no ciclo de construção uma etapa para construir imagens do Docker. Isso pode ser feito no Maven ou Gradle através de plugins.

Docker no build do Maven

Trecho do pom.xml com o plugin do Docker:
...

<properties>
  <docker.image.prefix>yaw</docker.image.prefix>
</properties>

...

<build>
  <plugins>
    <plugin>
      <groupId>com.spotify</groupId>
      <artifactId>docker-maven-plugin</artifactId>
      <version>0.2.3</version>
      <configuration>
        <imageName>${docker.image.prefix}/${project.artifactId}</imageName>
        <dockerDirectory>src/main/docker</dockerDirectory>
        <resources>
          <resource>
            <targetPath>/</targetPath>
            <directory>${project.build.directory}</directory>
            <include>${project.build.finalName}.jar</include>
          </resource>
        </resources>
      </configuration>
    </plugin>
  </plugins>
</build>

O pessoal do Spotify desenvolveu o plugin docker-maven-plugin. A propriedade docker.image.prefix é usada como prefixo para o nome da imagem, nesse caso yaw. O restante é o próprio nome do artefato. Na tag dockerDirectory indico o diretório aonde fica contido o arquivo Dockerfile, com as diretrizes para geração da imagem. Na tag resources indicamos os recursos que são compartilhados na execução do Docker.

Para criar a imagem Docker, a partir do ciclo de build do Maven, executamos o seguinte comando:
mvn clean package docker:build

Nesse caso a imagem é gerada após a construção do artefato (package). Outra abordagem seria configurar o Maven para construir a imagem implicitamente a partir do mvn package. Para isso é necessário customizar a tag execution com phase e goals.

A pŕoxima etapa seria criar o Container Docker e executar a aplicação. Vou demonstrar isso depois de apresentar o plugin do Gradle.

Docker no build do Gradle

Trecho do build.grade com plugin do Docker:
buildscript {
  ...
  dependencies {
    ...
    classpath('se.transmode.gradle:gradle-docker:1.2')
  }
}

...

group = 'yaw'
apply plugin: 'docker'

task buildDocker(type: Docker, dependsOn: build) {
  push = false
  applicationName = jar.baseName
  dockerfile = file('src/main/docker/Dockerfile')
  doFirst {
    copy {
      from jar
      into stageDir
    }
  }
}

No Gradle usei o plugin gradle-docker. Nele indico o caminho do Dockerfile, o prefixo e o nome da imagem. A próxima etapa é gerar a imagem em conjunto com o build Gradle:
gradle build buildDocker

Como referência é possível visualizar exemplos desses dois builds no projeto querydsl-spring-data, no meu Github. Esse projeto utiliza o Spring Boot, com Tomcat embutido. A seguir eu coloco o conteúdo do Dockfile utilizado para construir a imagem para executar esse projeto:
FROM edermag/ubuntu-java-8-dev

VOLUME /tmp
ADD querydsl-spring-data.jar app.jar
RUN bash -c 'touch /app.jar'
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

A imagem herda a estrutura com o JDK 8 da Oracle no Ubuntu 14.04, e faz o startup do projeto com Spring Boot. A última etapa é criar o Container a partir da imagem construida via Maven ou Gradle. Execute a instrução:
docker run -p 8080:8080 -t yaw/querydsl-spring-data

A aplicação será inicializada (Spring Boot) dentro do Container Docker, usando a porta 8080. Para encerrar o Container será necessário executar o comando docker stop indicando o apelido do Container.

Como referência indico o guia do Spring IO, descrevendo como usar o Docker com Spring Boot.

www.yaw.com.br

No comments: