<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Lucas León</title>
    <description>The latest articles on Forem by Lucas León (@lucasleon).</description>
    <link>https://forem.com/lucasleon</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F19251%2F0b79bbe1-b3e9-4dc9-8961-099958a88dc8.jpg</url>
      <title>Forem: Lucas León</title>
      <link>https://forem.com/lucasleon</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/lucasleon"/>
    <language>en</language>
    <item>
      <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.</title>
      <dc:creator>Lucas León</dc:creator>
      <pubDate>Tue, 30 Aug 2022 06:34:35 +0000</pubDate>
      <link>https://forem.com/lucasleon/heroku-is-not-free-anymore-so-ill-teach-you-how-to-deploy-your-spring-boot-services-to-rendercom-with-maven-and-docker-aca</link>
      <guid>https://forem.com/lucasleon/heroku-is-not-free-anymore-so-ill-teach-you-how-to-deploy-your-spring-boot-services-to-rendercom-with-maven-and-docker-aca</guid>
      <description>&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; openjdk:8-jdk-alpine&lt;/span&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; JAR_FILE=target/*.jar&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ${JAR_FILE} app.jar&lt;/span&gt;
&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; ["java","-jar","/app.jar"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fefxsfupufq3hpcum4jk1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fefxsfupufq3hpcum4jk1.png" alt="Render log error"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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 &lt;code&gt;mvn install&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So, what can you do next? There are two ways to solve this issue:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Use the Maven Docker image
&lt;/h3&gt;

&lt;p&gt;Since Render doesn't have Maven installed, you have to install it on your container like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;maven:3.8.6-jdk-8-slim&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;MAVEN_TOOL_CHAIN&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; pom.xml /tmp/&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; src /tmp/src/WORKDIR /tmp/&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;mvn package FROM openjdk:8-jdk-alpine
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=MAVEN_TOOL_CHAIN  /tmp/target/*.jar app.jar&lt;/span&gt;
&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; ["java","-jar","/app.jar"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it. Once you push this Dockerfile, your application will start.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Use the Maven wrapper
&lt;/h3&gt;

&lt;p&gt;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:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn &lt;span class="nt"&gt;-N&lt;/span&gt; wrapper:wrapper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And you'll notice these files added to your project:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqliys41wgfnnmdqe4xv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqliys41wgfnnmdqe4xv.png" alt="Maven wrapper files"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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 &lt;code&gt;.gitignore&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;And now you have to modify your Dockerfile like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;openjdk:8-jdk-alpine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /workspace/app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; mvnw .&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; .mvn .mvn&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; pom.xml .&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; src src&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;./mvnw &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-DskipTests&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; target/dependency &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;target/dependency&lt;span class="p"&gt;;&lt;/span&gt; jar &lt;span class="nt"&gt;-xf&lt;/span&gt; ../&lt;span class="k"&gt;*&lt;/span&gt;.jar&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; openjdk:8-jdk-alpine&lt;/span&gt;
&lt;span class="k"&gt;VOLUME&lt;/span&gt;&lt;span class="s"&gt; /tmp&lt;/span&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; DEPENDENCY=/workspace/app/target/dependency&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build ${DEPENDENCY}/META-INF /app/META-INF&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build ${DEPENDENCY}/BOOT-INF/classes /app&lt;/span&gt;
&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; ["java","-cp","app:app/lib/*","com.package.Application"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure to replace &lt;code&gt;"com.package.Application"&lt;/code&gt; with your package and main class name, and suffix it with &lt;code&gt;Kt&lt;/code&gt; if it's a Kotlin application, like this: &lt;code&gt;"com.package.ApplicationKt"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Push your changes, and you'll see your application running on Render.&lt;/p&gt;

&lt;p&gt;And that's all you need to deploy your Spring Boot on Render.com.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;I hope I have been helpful, and thanks for reading.&lt;/p&gt;

</description>
      <category>java</category>
      <category>springboot</category>
      <category>docker</category>
      <category>heroku</category>
    </item>
  </channel>
</rss>
