{"id":1974,"date":"2021-05-20T12:00:00","date_gmt":"2021-05-20T10:00:00","guid":{"rendered":"https:\/\/kindsonthegenius.com\/blog\/introduction-to-docker-compose-with-spring-boot-example\/"},"modified":"2026-07-06T18:42:31","modified_gmt":"2026-07-06T16:42:31","slug":"introduction-to-docker-compose-with-spring-boot-example","status":"publish","type":"post","link":"https:\/\/kindsonthegenius.com\/blog\/introduction-to-docker-compose-with-spring-boot-example\/","title":{"rendered":"Introduction to Docker-Compose \u2013 With Spring Boot Example"},"content":{"rendered":"<p>This is a beginner tutorial on how to build and deploy microservices using Docker-Compose. But first, we&#8217;ll learn what docker-compose is and what it&#8217;s used for.<\/p>\n<ol>\n<li><a href=\"&quot;#t1\">Introduction to Docker Compose<\/a><\/li>\n<li><a href=\"&quot;#t2\">Create the Spring Boot API<\/a><\/li>\n<li><a href=\"&quot;#t3\">Create the Spring Boot UI with Thymeleaf<\/a><\/li>\n<li><a href=\"&quot;#t4\">Create the Packages<\/a><\/li>\n<li><a href=\"&quot;#t5\">Create the Docker File<\/a><\/li>\n<li><a href=\"&quot;#t6\">Create the Docker Compose File<\/a><\/li>\n<li><a href=\"&quot;#t7\">Fire Up the Containers!<\/a><\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<h5><strong id=\"t1\">1. Introduction to Docker-Compose<\/strong><\/h5>\n<p>In the previous tutorial, we learnt how to Dockerize our Spring application. That was just a single spring boot application.<\/p>\n<p>What if you have two or more application where one depends on the other. For example, there&#8217;s an API for the backend. Then you also have a frontend UI application create with Thymeleaf that fetches data from the API backend.<\/p>\n<p>Using Docker-compose, you can create this two images at the same time and run the containers as well.<\/p>\n<p>Let&#8217;s now take a demo using Spring Boot.<\/p>\n<p>&nbsp;<\/p>\n<h5><strong id=\"t2\">2. Create Spring Boot API<\/strong><\/h5>\n<p>You can get the complete API application<a href=\"https:\/\/github.com\/KindsonTheGenius\/docker-compose-tutorial-api\" target=\"_blank\" rel=\"noopener\"> here in my Github repository<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<h5><strong id=\"t3\">3. Create a Spring Boot UI using Thymeleaf<\/strong><\/h5>\n<p>I already created this application. So you can just get it from <a href=\"https:\/\/github.com\/KindsonTheGenius\/docker-compose-tutorial-ui\" target=\"_blank\" rel=\"noopener\">my Github repository here<\/a>.<\/p>\n<p>So once you have these application, start the API (backend) and then start the UI. You&#8217;ll have a list of names displayed on the UI. This list is coming from the backend.<\/p>\n<p>Here&#8217;s the controller endpoint that fetches data from the backend:<\/p>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #555555; font-weight: bold;\">@GetMapping<\/span><span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"\/home\"<\/span><span style=\"color: #333333;\">)<\/span>\r\n<span style=\"color: #008800; font-weight: bold;\">public<\/span>  String <span style=\"color: #0066bb; font-weight: bold;\">home<\/span><span style=\"color: #333333;\">(<\/span>Model model<span style=\"color: #333333;\">){<\/span>\r\n    Object<span style=\"color: #333333;\">[]<\/span> objects <span style=\"color: #333333;\">=<\/span>  restTemplate<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">getForObject<\/span><span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"http:\/\/apihost:8080\/friends\"<\/span><span style=\"color: #333333;\">,<\/span> Object<span style=\"color: #333333;\">[].<\/span><span style=\"color: #0000cc;\">class<\/span><span style=\"color: #333333;\">);<\/span>\r\n    List<span style=\"color: #333333;\">&lt;<\/span>Object<span style=\"color: #333333;\">&gt;<\/span> friends <span style=\"color: #333333;\">=<\/span> Arrays<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">asList<\/span><span style=\"color: #333333;\">(<\/span>objects<span style=\"color: #333333;\">);<\/span>\r\n    model<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">addAttribute<\/span><span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"friends\"<\/span><span style=\"color: #333333;\">,<\/span> friends<span style=\"color: #333333;\">);<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">return<\/span> <span style=\"background-color: #fff0f0;\">\"index\"<\/span><span style=\"color: #333333;\">;<\/span>\r\n<span style=\"color: #333333;\">}<\/span>\r\n<\/pre>\n<p>Note the hostname <em>apihost<\/em> used for making the request. This is the name of the container for the api application. We&#8217;ll talk about this when we create the docker-compose.yaml file.<\/p>\n<p>&nbsp;<\/p>\n<h5><strong id=\"t4\">4. Create the Packages (Jar files)<\/strong><\/h5>\n<p>We would need to then create the jar files for both applications using the command below:<\/p>\n<pre style=\"margin: 0; line-height: 125%;\">mvn clean install\r\n<\/pre>\n<p>You&#8217;ll have to do this for both application. After this command executes, you&#8217;ll see the jar file available in the target folder. The file names will be:<\/p>\n<ul>\n<li>compose-api-0.0.1-SNAPSHOT<\/li>\n<li>compose-ui-0.0.1-SNAPSHOT<\/li>\n<\/ul>\n<p><strong>For fun<\/strong>: you can create the docker files for both applications and start them separately. <a href=\"https:\/\/kindsonthegenius.com\/blog\/introduction-to-dockerfile-with-spring-boot-how-to-dockerize-springboot-app\/\" target=\"_blank\" rel=\"noopener\">See the steps here.<\/a><\/p>\n<p>&nbsp;<\/p>\n<h5><strong id=\"t5\">5. Create the Docker Files<\/strong><\/h5>\n<p>Now, you need to create the Docker files for both applications. The content of the docker files would almost be the same as shown below:<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<pre style=\"margin: 0; line-height: 125%;\">FROM adoptopenjdk\/openjdk11:alpine-jre\r\nEXPOSE 8080\r\nARG JAR_FILE=target\/compose-api-0.0.1-SNAPSHOT.jar\r\nADD ${JAR_FILE} app.jar\r\nENTRYPOINT [\"java\",\"-jar\",\"\/app.jar\"]\r\n<\/pre>\n<p>For the ui app, you simply need to change the name of the jar file in line 3.<\/p>\n<p>At this point,\u00a0 you can create the images of both applications separately and it works just fine.<\/p>\n<p>&nbsp;<\/p>\n<h5><strong id=\"t6\">6. Create the Docker Compose File<\/strong><\/h5>\n<p>You need to create the <em>docker-compose.yml<\/em> file in any of the applications.<\/p>\n<p>So create a third directory that would hold the docker compose. For clarity, I have moved the Dockerfiles and jar files of each application into a separate directory. This is shown below (watch the video to see a step by step on how to do this):<\/p>\n<figure id=\"attachment_14623\" aria-describedby=\"caption-attachment-14623\" style=\"width: 300px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.kindsonthegenius.com\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-20-at-23.49.29.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-14623\" src=\"https:\/\/www.kindsonthegenius.com\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-20-at-23.49.29-300x257.png\" alt=\"Docker-compose tutorial -directory structure\" width=\"300\" height=\"257\" srcset=\"https:\/\/www.kindsonthegenius.com\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-20-at-23.49.29-300x257.png 300w, https:\/\/www.kindsonthegenius.com\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-20-at-23.49.29-768x657.png 768w, https:\/\/www.kindsonthegenius.com\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-20-at-23.49.29-600x513.png 600w, https:\/\/www.kindsonthegenius.com\/wp-content\/uploads\/2021\/05\/Screenshot-2021-05-20-at-23.49.29.png 954w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-14623\" class=\"wp-caption-text\">Docker-compose tutorial -directory structure<\/figcaption><\/figure>\n<p>&nbsp;<\/p>\n<p>The docker-compose file is shown below. Note that it is placed inside the docker-compose folder.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<pre style=\"margin: 0; line-height: 125%;\">version: <span style=\"background-color: #fff0f0;\">'3'<\/span>\r\nservices:\r\n  compose-api:\r\n    container_name: apihost\r\n    image: <span style=\"background-color: #fff0f0;\">\"compose-api\"<\/span>\r\n    build: api\/\r\n    ports:\r\n    - <span style=\"background-color: #fff0f0;\">\"8080:8080\"<\/span>\r\n  compose-ui:\r\n    image: <span style=\"background-color: #fff0f0;\">\"compose-ui\"<\/span>\r\n    build: ui\/\r\n    ports:\r\n    - <span style=\"background-color: #fff0f0;\">\"8081:8081\"<\/span>\r\n    depends_on:\r\n      - compose-api\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Note two things:<\/p>\n<ul>\n<li>the container name for this api is given as apihost. This is same as we used with the restTemplate<\/li>\n<li>the compose-ui service depends on the compose-api service<\/li>\n<\/ul>\n<p>You can get a clearer explanation from the video on <a href=\"https:\/\/www.youtube.com\/c\/KindsonTheTechPro\" target=\"_blank\" rel=\"noopener\">my YouTube Channel<\/a><\/p>\n<p>&nbsp;<\/p>\n<h5><strong id=\"t7\">7. Fire up the Containers!<\/strong><\/h5>\n<p>Finally, you need to fire up the containers. To do that, in your terminal, navigate to the location of the docker-compose file and run the command below:<br \/>\n<!-- HTML generated using hilite.me --><\/p>\n<pre style=\"margin: 0; line-height: 125%;\">docker-compose up --build\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Next steps <\/strong>&#8211; If you came this far and got it working, thumbs up to you. What about using a database? In the next tutorial, we would add a third container, which would spin up an image of a PostgreSQL. Do subscribe to <a href=\"https:\/\/www.youtube.com\/c\/KindsonTheTechPro\" target=\"_blank\" rel=\"noopener\">my YouTube Channel<\/a> to get updates.<\/p>\n<p>Thanks for learning!<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is a beginner tutorial on how to build and deploy microservices using Docker-Compose. But first, we&#8217;ll learn what docker-compose is and what it&#8217;s used &hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"pagelayer_contact_templates":[],"_pagelayer_content":"","footnotes":""},"categories":[414],"tags":[],"class_list":["post-1974","post","type-post","status-publish","format-standard","hentry","category-programming"],"_links":{"self":[{"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/posts\/1974","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/comments?post=1974"}],"version-history":[{"count":2,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/posts\/1974\/revisions"}],"predecessor-version":[{"id":2200,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/posts\/1974\/revisions\/2200"}],"wp:attachment":[{"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/media?parent=1974"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/categories?post=1974"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/tags?post=1974"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}