- 4 minutes read

I didn't expect it to be so easy! The internet has many tutorials covering how to deploy Spring Boot on Fargate, and they all have one thing in common: they consist of many screenshots. You can follow their recipes step-by-step, but it doesn't seem trivial. AWS CDK takes the sting out of it. Look:

const vpc = new ec2.Vpc(this, 'SpringBootOnFargateVpc', { maxAzs: 3, }); const cluster = new ecs.Cluster(this, 'SpringBootOnFargateCluster', { vpc: vpc }); const fargate = new ecs_patterns.ApplicationLoadBalancedFargateService(this, 'SpringBootOnFargateService', { cluster: cluster, memoryLimitMiB: 2048, desiredCount: 1, taskImageOptions: { image: ecs.ContainerImage.fromAsset(path.join(__dirname, '../../src/main/docker/')), environment: { "name": "Spring Boot on Fargate", }, }, });

The full source code is available on https://github.com/stephanrauh/SpringBoot/tree/main/ExploringSpringBootAndFargate.

Pitfalls

Like so often, the final source code is simple. But it took me two days to get there. Sometimes it's good to have an old-fashioned computer. Try as I might, my fancy M1 MacBook wouldn't deploy my Spring Boot application. Or rather, it did deploy it, but the application wouldn't start. To make things even more confusing, this Node.js example ran at first try without any problems. I'm still puzzled how that's possible, because my laptop seems to be the culprit, and I was using the same laptop for both Node.js and Spring Boot.

By default, Docker builds your images using the host system's processor architecture. For M1 users, that's the ARM architecture. Too bad AWS doesn't support that, and you need to pin the processor architecture of your Docker image.

That, in turn, means a very promising Maven plugin won't get you anywhere.

Jib

Jib is a nice Maven plugin allowing you to convert a Spring Boot application into a Docker image without further ado. It just works. Highly recommended!

Unless you're using a modern MacBook, of course. Jib creates your Docker image automagically. That's awesome, but the downside of this particular magic is you can't determine the target processor architecture.

Luckily, CDK makes creating your Docker image so simple you don't need the nice abstraction layer Job provides.

Let the CDK build the Docker image

The method ecs.ContainerImage.fromAsset() allows you to delegate building the Docker file to the CDK.

FROM --platform=linux/amd64 openjdk:17-jdk-alpine COPY ./app.jar app.jar EXPOSE 80 ENTRYPOINT ["java","-jar","/app.jar"]

Troubleshooting

The annoying thing about the CDK is it simply stalls when there's a problem with Fargate. Usually, this means the Docker container runs into trouble when booting.

If this happens, you'll want to look at the Cloudformation events first. If everything starts fine except for the Fargate service, look at the Cloudwatch log groups. To learn which log group you're interested in,

  • navigate in the AWS management console to your AWS ECS cluster,
  • open the "Tasks" tab, open the detail view, click on the small caret in front of "web" in the table at the bottom of the page,
  • and scroll down until you see the hyperlink "View logs in CloudWatch". Following the link should reveal the cause of your issue.

If there's only a single line saying "standard_init_linux.go:228: exec user process caused: exec format error", you're probably using the wrong processor architecture. That's not the only cause of this error message, but if you're using a contemporary Mac, that's the most probable cause. But, like so often, StackOverflow has it it's not the only cause of the error message.

Wrapping it up

It took me two days, but the final solution was surprisingly simple. AWS CDK makes it easy to publish your Spring Boot application on Fargate. All you need to do is to clone my GitHub repository and to be more practiced than me in troubleshooting AWS. Hopefully, this article gives you a head start!


Comments