How to setup AWS ECS + dockerfile-maven-plugin?

5.5k views Asked by At

I am trying to setup my project's pom.xml and Maven's settings.xml to automate the process of generating a Docker image and pushing it to my AWS ECS private Docker repository.

In my pom.xml, I added the dockerfile-maven-plugin and configured it as follows:

<plugin>
    <groupId>com.spotify</groupId>
    <artifactId>dockerfile-maven-plugin</artifactId>
    <version>1.3.6</version>
    <executions>
        <execution>
            <id>default</id>
            <goals>
                <goal>build</goal>
                <goal>push</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <finalName>myproject/server</finalName>
        <repository>137037344249.dkr.ecr.us-east-2.amazonaws.com/myproject/server</repository>
        <tag>${docker.image.tag}</tag>
        <serverId>ecs-docker</serverId>
        <useMavenSettingsForAuth>true</useMavenSettingsForAuth>
        <buildArgs>
            <VERSION>${project.version}</VERSION>
            <BUILD_NUMBER>${buildNumber}</BUILD_NUMBER>
            <WAR_FILE>${project.build.finalName}.war</WAR_FILE>
        </buildArgs>
    </configuration>
</plugin>

Per the instructions given by dockerfile-maven-plugin, I need to add configurations for my ECS server authentication, but I don't know what username / password I need to provide. I doubt it's my AWS login user/pass.

<servers>
    <server>
        <id>ecs-docker</id>
        <username>where_to_get_this</username>
        <password>where_to_get_this</password>
    </server>
</servers>

Also, any suggestions to automate this Docker image generation / pushing to my repo in a better way are welcome.

3

There are 3 answers

0
Govind Kalyankar On

I did not configure anything in my maven settings file. I usually login using below command

$(aws ecr get-login --no-include-email --region my-region)

then I run the maven commands (docker commands are embedded as a part of maven goals) and it works fine.

For your reference , This is my pom file setup using docker plugin

    <plugin>
            <groupId>com.spotify</groupId>
            <artifactId>docker-maven-plugin</artifactId>
            <version>1.1.1</version>
            <configuration>
                <imageName>${docker.image.prefix}/${project.artifactId}:${project.version}</imageName>
                <dockerDirectory>docker</dockerDirectory>
               <!--  <serverId>docker-hub</serverId> -->
                <registryUrl>https://${docker.image.prefix}</registryUrl>
                 <forceTags>true</forceTags>
                <resources>
                    <resource>
                        <targetPath>/</targetPath>
                        <directory>${project.build.directory}</directory>
                        <include>${project.build.finalName}.jar</include>
                    </resource>
                </resources>
            </configuration>
            <executions>
                <execution>
                    <id>tag-image</id>
                    <phase>package</phase>
                    <goals>
                        <goal>build</goal>
                    </goals>
                </execution>
                <execution>
                    <id>push-image</id>
                    <phase>deploy</phase>
                    <goals>
                        <goal>push</goal>
                    </goals>
                    <configuration>
                        <imageName>${docker.image.prefix}/${project.artifactId}:${project.version}</imageName>
                    </configuration>
                </execution>
            </executions>
        </plugin>
0
Romain Prévost On

To login on ECR, you must use the AWS command-line to generate a docker login command, and then login your docker daemon with it. I don't think this use case is handled by any docker maven plugin.

What I do on my project is login my docker daemon before doing the push :

logstring=`aws --profile my-aws-profile ecr get-login --registry-ids my-registry-id`
`$logstring`

This manual step is required in my case because we have a single AWS account that is secured with a hardware token that generate one time use codes, but it is not a problem, since we only need to do it once a day (ECR login lasts for 12 hours), on the days we deploy to ECR (as opposed to those where we only test locally).

So the solutions:

  • Login manually to ECR, so that your docker pushes work without needing to login from maven.
  • Add a login step that scripts the external login directly in your pom
  • Try AWS CodePipeline to build your code directly when you commit, and deploy to ECR (what I recommend if you are not otherwise restricted)

Have fun!

0
Cepr0 On

To build the docker image and push it to AWS ECR with Spotify dockerfile-maven-plugin you should:

  1. Install amazon-ecr-credential-helper
go get -u github.com/awslabs/amazon-ecr-credential-helper/ecr-login/cli/docker-credential-ecr-login 
  1. Move it to some folder that is already in the execution PATH:
mv ~/go/bin/docker-credential-ecr-login ~/bin/
  1. Add credHelpers section to ~/.docker/config.json file for your Amazon ECR docker repo ID:
{
  "credHelpers": {
    "<ecr-id>.dkr.ecr.<aws-region>.amazonaws.com": "ecr-login"
  },
  //...
}

(on Windows remove line "credsStore": "wincred",, if it exists, from this file)

  1. Check that ~/.aws/config has your region
[default]
region = <aws-region>

and ~/.aws/credentials has your keys

[ecr-push-user]
aws_access_key_id = <id>
aws_secret_access_key = <secret>

(More info...)

  1. Add Spotify dockerfile-maven-plugin to your pom.xml:
    <properties>
        <docker.image.prefix>xxxxxxxxxxxx.dkr.ecr.rrrrrrr.amazonaws.com</docker.image.prefix>
        <docker.image.name>${project.artifactId}</docker.image.name>
        <docker.image.tag>${project.version}</docker.image.tag>
        <docker.file>Dockerfile</docker.file>
    </properties>

    <build>
      <finalName>service</finalName>

      <plugins>
          <!-- Docker image mastering -->
          <plugin>
              <groupId>com.spotify</groupId>
              <artifactId>dockerfile-maven-plugin</artifactId>
              <version>1.4.10</version>
              <configuration>
                  <repository>${docker.image.prefix}/${docker.image.name}</repository>
                  <tag>${docker.image.tag}</tag>
                  <dockerfile>${docker.file}</dockerfile>
              </configuration>
              <executions>
                  <execution>
                      <id>default</id>
                      <phase>package</phase>
                      <goals>
                          <goal>build</goal>
                          <goal>push</goal>
                      </goals>
                  </execution>
              </executions>
          </plugin>
      </plugins>
    </build>
  1. Make sure that Dockerfile exists, for example:
FROM openjdk:11-jre-slim
VOLUME /tmp
WORKDIR /service
COPY target/service.jar service.jar
ENTRYPOINT exec java -server \
-Djava.security.egd=file:/dev/./urandom \
$JAVA_OPTS \
-jar service.jar
  1. Build and push the image with one command:
mvn package