Build a Markdown-based Blog with Spring Boot - Part 6
Tags: java, springboot, thymeleaf, heroku
Published: 2021-07-02 08:04:31

<p>This will be the final part of this series. For previous parts, please check: <a href="https://www.roshanadhikary.com.np/2021/05/build-a-markdown-based-blog-with-spring-boot-part-1.html" target="">Part 1</a> | <a href="https://www.roshanadhikary.com.np/2021/05/build-a-markdown-based-blog-with-spring-boot-part-2.html" target="">Part 2</a> | <a href="https://www.roshanadhikary.com.np/2021/05/build-a-markdown-based-blog-with-spring-boot-part-3.html" target="">Part 3</a> | <a href="https://www.roshanadhikary.com.np/2021/05/build-a-markdown-based-blog-with-spring-boot-part-4.html" target="">Part 4</a> | <a href="https://www.roshanadhikary.com.np/2021/07/build-a-markdown-based-blog-with-spring-boot-part-5.html">Part 5</a></p><h3 style="text-align: left;">Recap</h3><p style="text-align: left;">By now, we have a complete blogging system set up. We add Markdown files to the <em>resources/posts</em> directory and our <em>ContextEventListener</em> class, upon a <em>ContextRefreshedEvent</em>, populates the database with the content from new Markdown files. Then, on the client side, when we request for a specific blog post by its ID, the <em>PostController.getPostById</em>&nbsp;method adds the respective post as a model attribute and returns the appropriate view to render.</p><h3 style="text-align: left;">What now?</h3><p style="text-align: left;">We need to host our database in RemoteMySQL, push our repository to GitHub,and then deploy the repository to Heroku. But before that, let's add some new files to our repository.</p><h3 style="text-align: left;">Specify the Java Runtime</h3><p style="text-align: left;">We need to specify the Java Runtime version to be used for our application. In the root directory of our project, create a new file <em>system.properties</em>&nbsp;and specify the Runtime version as 11.</p>
<p>
  {% gist https://gist.github.com/roshanadh/af73874b408ae684d9bac547dd77e6e7.js %}
</p>
<h3 style="text-align: left;">Create a Heroku profile</h3><p style="text-align: left;">We used the application.properties file for our development environment; but for deployment to Heroku, we will need a new set of properties. Create a <em>application-heroku.properties</em>&nbsp;file inside the <em>resources</em> directory.</p>
<p>
  {% gist https://gist.github.com/roshanadh/be86d6f58b58b9f69105634337255843.js %}
</p>
<p style="text-align: left;">We specify the datasource URL, username, and password as environment variables from within our Heroku environment. We also set the automatic database initialization provided by Hibernate to <em>update</em>; so, Hibernate checks for the tables and if a table doesn't exist, then it creates new tables.</p><p style="text-align: left;">So basically, we will provide four configuration variables (or Config Vars) to our Heroku deployment.</p><p style="text-align: left;"></p><ul style="text-align: left;"><li>DATASOURCE_URL</li></ul><p></p><ul style="text-align: left;"><li>DATASOURCE_USERNAME</li></ul><p></p><ul style="text-align: left;"><li>DATASOURCE_PASSWORD</li></ul><p></p><ul style="text-align: left;"><li>spring_profiles_active</li></ul><p></p><p style="text-align: left;">If we set the variable <em>spring_profiles_active</em>&nbsp;to Heroku, Spring Boot automatically loads the appropriate properties file (i.e., <em>application-heroku.properties</em>).</p><h3 style="text-align: left;">RemoteMySQL</h3><p style="text-align: left;">Now onto our production database, register for an account in <a href="https://remotemysql.com/login.php" rel="nofollow" target="_blank">RemoteMySQL</a>. After you are a registered user, you can create a new database; after which RemoteMySQL provides you with details about your credentials, including the username, database name, password, port, host, etc. Keep these secure as we need to pass these as Config Vars to our Heroku deployment.</p><p style="text-align: left;">In the DATABASES section, go to the Action tab of your database (the one you created just now), and click on <em>phpMyAdmin</em>. RemoteMySQL provided a GUI for interacting with our relations.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-c_ZNYNQsMWs/YN66jZCA-_I/AAAAAAAAHYk/wQ2lvF8RUT8bnMBpo4Nu1foYnZA_7siIACLcBGAsYHQ/s1919/phpmyadmin.png" style="margin-left: 1em; margin-right: 1em;"><img alt="Action to open phpMyAdmin" border="0" data-original-height="1020" data-original-width="1919" src="https://1.bp.blogspot.com/-c_ZNYNQsMWs/YN66jZCA-_I/AAAAAAAAHYk/wQ2lvF8RUT8bnMBpo4Nu1foYnZA_7siIACLcBGAsYHQ/s16000/phpmyadmin.png" title="Action to open phpMyAdmin" /></a></div><p style="text-align: left;">In the phpMyAdmin page, login with username and password that you received just now.</p><h3 style="text-align: left;">GitHub</h3><p style="text-align: left;">Before proceeding any further, make sure you've committed your changes and pushed them to the remote repository.</p><h3 style="text-align: left;">Heroku</h3><p style="text-align: left;">If you're new to Heroku, first register for an account. Then, from the dashboard, create a new application with <em>New</em>&nbsp;<em>&gt; Create new app</em>.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-dLVAblWN4ac/YN66vrIgXJI/AAAAAAAAHYo/Gz45_fxGvK4vCaYdnAn0sejVVlXIRbq4QCLcBGAsYHQ/s1276/github-heroku.png" style="margin-left: 1em; margin-right: 1em;"><img alt="Create a new application" border="0" data-original-height="640" data-original-width="1276" src="https://1.bp.blogspot.com/-dLVAblWN4ac/YN66vrIgXJI/AAAAAAAAHYo/Gz45_fxGvK4vCaYdnAn0sejVVlXIRbq4QCLcBGAsYHQ/s16000/github-heroku.png" title="Create a new application" /></a></div><p style="text-align: left;">Now we can specify our deployment method. In the following page, select GitHub as the deployment method and select the repository and connect it to Heroku. Then just below, select the branch to trigger automatic deployment and click the <em>Enable Automatic Deploys</em>&nbsp;button. For me, it is the <em>main</em>&nbsp;branch.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-30v9VEQ04kU/YN68GN8DtcI/AAAAAAAAHY0/XxJ_atagXeEL8QWXXfd_VMXhuC42IuiFgCLcBGAsYHQ/s1851/automatic-deploys.png" style="margin-left: 1em; margin-right: 1em;"><img alt="Enable automatic deploys in Heroku" border="0" data-original-height="800" data-original-width="1851" src="https://1.bp.blogspot.com/-30v9VEQ04kU/YN68GN8DtcI/AAAAAAAAHY0/XxJ_atagXeEL8QWXXfd_VMXhuC42IuiFgCLcBGAsYHQ/s16000/automatic-deploys.png" title="Enable automatic deploys in Heroku" /></a></div><p style="text-align: left;">This means that whenever I push something (for instance a new Markdown file inside <em>resources/posts</em>&nbsp;directory), Heroku reflects those changes in the deployed application. We do not need to redeploy the application.</p><p style="text-align: left;">Following this, go to the <em>Settings</em> tab and click the <em>Reveal Config Vars</em>&nbsp;button. Now we can add all the required configuration variables we discussed above.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-_m5s_e7A3K4/YN69xt7y33I/AAAAAAAAHY8/pQu-jF7dxXgI9VBFktQn9_n1FfCwWH4aQCLcBGAsYHQ/s1206/configvars.png" style="margin-left: 1em; margin-right: 1em;"><img alt="Set the config variables in Heroku" border="0" data-original-height="530" data-original-width="1206" src="https://1.bp.blogspot.com/-_m5s_e7A3K4/YN69xt7y33I/AAAAAAAAHY8/pQu-jF7dxXgI9VBFktQn9_n1FfCwWH4aQCLcBGAsYHQ/s16000/configvars.png" title="Set the config variables in Heroku" /></a></div><p style="text-align: left;"></p><p style="text-align: left;"></p><ul style="text-align: left;"><li>Set the <em>DATASOURCE_URL</em>&nbsp;variable as <em>jdbc:mysql://remotemysql.com:3306/your-database-name</em></li></ul><ul style="text-align: left;"><li>Set the <em>DATASOURCE_USERNAME</em>&nbsp;variable as the username you received from RemoteMySQL.</li></ul><ul style="text-align: left;"><li>Set the <em>DATASOURCE_PASSWORD</em>&nbsp;variable as the password you received from RemoteMySQL.</li></ul><ul style="text-align: left;"><li>Set <em>spring_profiles_active</em>&nbsp;variable as <em>heroku</em></li></ul><p></p><p></p><p style="text-align: left;">Finally, go back to the <em>Deploy</em>&nbsp;and click on the <em>Deploy Branch</em>&nbsp;button to manually deploy the application for the first time.</p><h3 style="text-align: left;">Live deployment</h3><p style="text-align: left;">If the build process didn't end up in an error, you should be able to open the application and see your blog posts live.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-3voQgpn1cus/YN7Cghrc9jI/AAAAAAAAHZE/nz4t__DaneY3GVASEc0HZi0YQZ5Z5MRfwCLcBGAsYHQ/s1919/live.png" style="margin-left: 1em; margin-right: 1em;"><img alt="Deployed application" border="0" data-original-height="1020" data-original-width="1919" src="https://1.bp.blogspot.com/-3voQgpn1cus/YN7Cghrc9jI/AAAAAAAAHZE/nz4t__DaneY3GVASEc0HZi0YQZ5Z5MRfwCLcBGAsYHQ/s16000/live.png" title="Deployed application" /></a></div><h3 style="text-align: left;">Adding new blog posts</h3><p style="text-align: left;">Too see if the deployment mechanism works, let us create a new Markdown file,&nbsp;<em>6_After_Deployment_Blog.md</em>,&nbsp;inside the <em>resources/posts</em>&nbsp;directory in our local repository.</p>
<p>
  {% gist https://gist.github.com/roshanadh/054f3feaa33a9dc00d9c61f5b640066b.js %}
</p>
<p style="text-align: left;">Now, commit the change and push it to the remote repository's <em>main</em> branch. Note that I am pushing to my <em>main</em> branch because that's the branch I set to trigger automatic deploys in Heroku. If you had set another branch, then you should push your changes to that branch.</p><p style="text-align: left;">After you've pushed your changes, you should see a "Build started by ..." message in the logs of your Heroku application. This means that our application's automatic deployment feature is working as intended.</p><p style="text-align: left;">To check the logs of your application, go to <em>dashboard.heroku.com/apps/&lt;your-app-name&gt;/logs</em></p><p style="text-align: left;">After the build completes, open your deployment to see if the new post is available. In my case, it is.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-IIkpnQeTnQ0/YN7FvmNlhxI/AAAAAAAAHZM/Yd6RVe4enNgSi3Oh41mph3LL5avI39mKACLcBGAsYHQ/s1919/new%2Bpost.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="New post" border="0" data-original-height="1020" data-original-width="1919" src="https://1.bp.blogspot.com/-IIkpnQeTnQ0/YN7FvmNlhxI/AAAAAAAAHZM/Yd6RVe4enNgSi3Oh41mph3LL5avI39mKACLcBGAsYHQ/s16000/new%2Bpost.png" title="New post" /></a></div><h3 style="text-align: left;">Wrapping up</h3><p style="text-align: left;">This concludes the series. We have built a blog application that reads Markdown files and populates the database with its content. Whenever we push a new Markdown file to our GitHub repository, Heroku automatically deploys the changes in our application.</p><p style="text-align: left;">Note that there are several limitations with the free database we use from RemoteMySQL. Read them <a href="https://remotemysql.com/faq.html" rel="nofollow" target="_blank">here</a>.</p><p style="text-align: left;">All of the code associated with the project have been published in the GitHub <a href="https://github.com/roshanadh/markdown-blog" rel="nofollow" target="_blank">repository</a>.</p><p style="text-align: left;">The blog is deployed <a href="https://github-blog-demo.herokuapp.com/" rel="nofollow" target="_blank">here</a>, if you want to take a look.</p>