Heroku is not free anymore, so I'll teach you how to deploy your Spring Boot services to Render.com with Maven and Docker.
Tags: java, springboot, docker, heroku
Published: 2022-08-30 06:34:35

---
title: Heroku is not free anymore, so I'll teach you how to deploy your Spring Boot services to Render.com with Maven and Docker.
published: true
tags: Java, SpringBoot, Docker, Heroku
cover_image: https://render.com/images/render-banner.png
# Use a ratio of 100:42 for best results.
---

We all received the bad news that Heroku won't have a free tier anymore. Luckily there's a great alternative called Render that also has a great developer experience, and it also could be over 50% cheaper if you want to deploy your service to production.

If you go to their website, you'll see that they don't have support for Java applications out of the box, but they do for Docker. But if you are a beginner with Docker like me, you'll think: Ok, that's not a problem. I'll grab a Dockerfile from the internet and deploy my service with that. So you go to Google, search for a Spring Boot Dockerfile, and you'll maybe get something that looks like this:

```dockerfile
FROM openjdk:8-jdk-alpine
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
```
Piece of cake, you'll say. Then you push your code, and Render detects the changes, you check the logs, and… Oh, no. You get an error:


![Render log error](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/efxsfupufq3hpcum4jk1.png)

So, what happened here? As I mentioned earlier, Render does not have support for Java applications, and this Dockerfile assumes that you have Maven installed in the host and you ran `mvn install`

So, what can you do next? There are two ways to solve this issue:

###1. Use the Maven Docker image
Since Render doesn't have Maven installed, you have to install it on your container like this:

```dockerfile
FROM maven:3.8.6-jdk-8-slim AS MAVEN_TOOL_CHAIN
COPY pom.xml /tmp/
COPY src /tmp/src/WORKDIR /tmp/
RUN mvn package FROM openjdk:8-jdk-alpine
COPY --from=MAVEN_TOOL_CHAIN  /tmp/target/*.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
```
And that's it. Once you push this Dockerfile, your application will start.

###2. Use the Maven wrapper
For the second way, you'll need to have Maven installed on your local machine and run this command on the root of your project:
```sh
mvn -N wrapper:wrapper
```
And you'll notice these files added to your project:


![Maven wrapper files](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sqliys41wgfnnmdqe4xv.png)

That command will embed Maven into your project. That way, you'll be able to run Maven commands without having it installed. Just make sure to don't include those files in your `.gitignore` file.

And now you have to modify your Dockerfile like this:

```dockerfile
FROM openjdk:8-jdk-alpine as build
WORKDIR /workspace/app
COPY mvnw .
COPY .mvn .mvn
COPY pom.xml .
COPY src src
RUN ./mvnw install -DskipTests
RUN mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar)
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG DEPENDENCY=/workspace/app/target/dependency
COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","com.package.Application"]
```
Make sure to replace `"com.package.Application"` with your package and main class name, and suffix it with `Kt` if it's a Kotlin application, like this: `"com.package.ApplicationKt"`.

Push your changes, and you'll see your application running on Render.

And that's all you need to deploy your Spring Boot on Render.com.

I'm pretty sure there are more ways to optimize the Dockerfiles I presented in this blog post, but as I mentioned, I'm still not a Docker expert, so feel free to post any suggestions in the comment section.

I hope I have been helpful, and thanks for reading.