Search code examples
javaxmldockermaven

Build Dockerfile with Java and maven with CodeArtifact dependency


I'm trying to build my project using Docker, it has some Java REST APIs, I'm using Maven and Spring Boot on a multiservice architecture. I have a "slave" module called "common-utilities", it has all the generic entities and some Calendar utilities that I need and this module is used as dependency on all my other modules.

I was having a problem where Docker couldn't build since it doesn't find my own slave module as a dependency for the other one, since it's looking on Maven Central for it, after some searching I've found that I could manually copy this dependency's .jar to docker build's .m2 folder but, not happy with that solution. I then found that I could upload the slave module's .jar to a private repository, tried Nexus but since I'll use AWS soon, I moved to AWS Code Artifact.

Now the problem is, how to set the token from outside AWS's infrastructure that my settings.xml needs to download this dependency?


Solution

  • After searching a lot I've found a way to do this. I tried the RUN command but since it's execution can't save the result into an usable variable to be captured by settings.xml, I had to take another approach. This is my Dockerfile:

    ###############################################################
    # Build stage
    # Maven image to build the application
    FROM maven:3.9.6-amazoncorretto-17-al2023 AS build-stage
    
    # Creating the directory
    RUN mkdir -p /usr/src/app
    # Setting the working directory.
    WORKDIR /usr/src/app
    # Adding the source code to the build stage.
    ADD . /usr/src/app
    
    # And here comes the Amazon configuration step!
    RUN yum install aws-cli -y
    RUN aws configure set aws_access_key_id 'YOUR KEY'
    RUN aws configure set aws_secret_access_key 'YOUR SECRET ACCESS KEY'
    RUN aws configure set aws_region 'YOUR REGION'
    RUN aws configure set aws_output_format json
    
    # Then I execute the command to get Code Artifact's token and save it into a file called "result" located in "./"
    RUN aws codeartifact get-authorization-token --domain YOUR-DOMAIN --domain-owner YOUR-OWNER-ID --region YOUR-REGION --query authorizationToken --output text >> ./result
    
    # So now I execute the maven install command passing the settings.xml WITH the property "token", which is a cat command to read from the file that has the token and to be used inside the XML file.
    RUN mvn -Dtoken=${cat ./result} -s settings.xml install -U
    
    ###############################################################
    # Production step. Now it's done, it works!
    FROM openjdk:17-alpine AS production-stage
    COPY --from=build-stage /usr/src/app/target/*.jar my-api.jar
    EXPOSE 8788
    ENTRYPOINT ["java", "-Dspring.profiles.active=prod", "-Xmx256m", "-Xms128m", "-jar", "my-api.jar"]
    

    And this is my settings.xml

    <?xml version="1.0" encoding="UTF-8"?>
    
    <settings xmlns="http://maven.apache.org/SETTINGS/1.2.0"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.2.0 
    https://maven.apache.org/xsd/settings-1.2.0.xsd">
    <servers>
      <server>
        <id>domain-name</id>
        <username>aws</username>
        <password>${token}</password>
      </server>
    </servers>
    
    <profiles>
      <profile>
      <id>domain-name</id>
      <activation>
      <activeByDefault>true</activeByDefault>
      </activation>
        <repositories>
          <repository>
               <id>domain-name</id>
               <url>repo-url</url>
          </repository>
        </repositories>
      </profile>
    </profiles>
    </settings>
    

    I'm not sure if it's the right way but it works!! So I wanted to share this info with you guys cause I couldn't for the love of me find any info about how to do this.