HelloKoding

Practical coding guides

Spring Boot with Docker Compose and MySQL

This tutorial walks you through the steps of creating a simple Spring Boot web application with NGINX and MySQL running inside Docker containers

What you’ll need

  • Your favorite IDE
  • Docker CE

Stack

  • Docker
  • Spring Boot
  • MySQL
  • NGINX
  • Maven

Init project structure and dependencies

Project structure

├── app
│   ├── src
│   │   └── main
│   │       ├── java
│   │       │   └── com
│   │       │       └── hellokoding
│   │       │           └── springboot
│   │       │               ├── IndexController.java
│   │       │               └── WebApplication.java
│   │       └── resources
│   │           ├── static
│   │           │   ├── css
│   │           │   │   └── main.css
│   │           │   └── js
│   │           │       └── main.js
│   │           ├── templates
│   │           │   └── index.ftl
│   │           └── application.properties
│   ├── Dockerfile
│   └── pom.xml
├── nginx
│   └── conf.d
│       └── app.conf
└── docker-compose.yaml

Application dependencies

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.hellokoding</groupId>
    <artifactId>dockercompose-springboot-mysql</artifactId>
    <description>dockercompose-springboot-mysql-nginx</description>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.7.RELEASE</version>
    </parent>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

Define Controller, View Template and Config

Controller

IndexController.java

package com.hellokoding.springboot;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/")
public class IndexController {
    @GetMapping
    public String index(Model model){
        return "index";
    }
}

FreeMarker View template

index.ftl

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Docker Compose with Spring Boot, MySQL, NGINX</title>
</head>
<body>
    <h1>Docker Compose with Spring Boot, MySQL, NGINX</h1>
    <p></p>
</body>
</html>

Application Configurations

application.properties

spring.freemarker.template-loader-path: classpath:/templates
spring.freemarker.suffix: .ftl

spring.datasource.url=jdbc:mysql://hk-mysql:3306/test?useSSL=false
spring.datasource.username=root
spring.datasource.password=hellokoding
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.jpa.hibernate.ddl-auto=create
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true

spring.datasource.* are common properties of Spring Boot Data Source auto-configuration for MySQL

In the datasource url property, hk-mysql is the Docker Compose service name of MySQL as we’re going to run this Spring Boot application and MySQL server in the Docker containers. You can find it in the docker-compose.yaml file below

WebApplication.java

package com.hellokoding.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class WebApplication {
    public static void main(String[] args) {
        SpringApplication.run(WebApplication.class, args);
    }
}

Dockerize

Dockerfile of Spring Boot web application

Dockerfile

FROM maven:3.5-jdk-8

NGINX config file

app.conf

server {
    listen 80;
    charset utf-8;
    access_log off;

    location / {
        proxy_pass http://app:8080;
        proxy_set_header Host $host:$server_port;
        proxy_set_header X-Forwarded-Host $server_name;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location /static {
        access_log   off;
        expires      30d;

        alias /app/static;
    }
}

Docker Compose

docker-compose.yaml

version: '3'
services:
  hk-nginx:
   container_name: hk-nginx
   image: nginx:1.13
   restart: always
   ports:
   - 80:80
   - 443:443
   volumes:
   - ./nginx/conf.d:/etc/nginx/conf.d
   depends_on:
   - app
 
  hk-mysql:
   container_name: hk-mysql
   image: mysql/mysql-server:5.7
   environment:
    MYSQL_DATABASE: test
    MYSQL_ROOT_PASSWORD: hellokoding
    MYSQL_ROOT_HOST: '%'
   ports:
   - "3306:3306"
   restart: always
  
  app:
    restart: always
    build: ./app
    working_dir: /app
    volumes:
      - ./app:/app
      - ~/.m2:/root/.m2
    expose:
      - "8080"
    command: mvn clean spring-boot:run
    depends_on:
      - hk-mysql

Run and Test

  • Run command docker-compose up
  • Access to http://localhost

Source code

https://github.com/hellokoding/hellokoding-courses/blob/master/docker-examples/dockercompose-springboot-mysql-nginx

Follow HelloKoding