Spring Boot Development Environment
Tags: devops, docker, mongodb, java
Published: 2022-07-27 03:19:15

## Introduction

For health development, the best practice is to have a homogeneous setting across the different environments, in what the best way to do it if not using **Docker**. 

Here below I'll explain how to configure an environment for development using Spring Boot and Mongo Database, however, you can use another database without problem.

We need do three main things to be able to develop using docker, the steps are:
1. Create a **Project** using the standard means to do it.
2. Configurate **pom.xml** to package **.jar** files.
3. Create **Docker** files (Dockerfile, and docker-compose.yml).
4. Configurate the Debugger in the **IDE**, here we will use **Intellij**.

## Create Project
When creating the Spring Boot project using the [web site](https://start.spring.io/), we will configure it like below:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kfs2tfh668y5lfbrm2uj.png)

You can change some configurations if needed, the only important things here are:
- **Project**: Maven
- **Language**: Java
- **Packaging**: Jar

Make sure that your pom.xml has the path to the **main class** and the option repackages set, it will be necessary to generate the **.jar** file.

```xml
<build>  
   <plugins>  
      <plugin>  
         <groupId>org.springframework.boot</groupId>  
         <artifactId>spring-boot-maven-plugin</artifactId>  
         <executions>  
            <execution>  
               <configuration>  
                  <mainClass>com.trantorinc.spring-boot-local-dev-docker.Application</mainClass>  
               </configuration>  
            </execution>  
            <execution>  
               <goals>  
                  <goal>repackage</goal>  
               </goals>  
            </execution>  
         </executions>  
        </plugin>  
   </plugins>  
</build>
```

## Configure Environment
We will need two types of docker files, **Dockerfile** and **docker-compose.yml**, for setting up the development environment:

#### Dockerfile
```dockerfile
FROM maven:3.8.4-jdk-11  
  
ENV JAVA_TOOL_OPTIONS -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005  
ENV JAVA_DEBUG true
```

Above you can see that we are using the official image of **Maven** and have two variables, that are necessary for configuring the debugger, what it basically does is expose java debug options into the 5005 port.

#### docker-compose
1. **Spring Boot**
```yml
version: '3.8'  
services:  
  my-app:  
    container_name: my-spring-boot-app
    build:  
      context: .  
      dockerfile: Dockerfile  
    command: java -jar target/myapplicationname-0.0.1-SNAPSHOT.jar  
    ports:  
      - 8080:8080  
      - 5005:5005  
    volumes:  
      - .:/usr/src/mymaven:rw  
    working_dir: /usr/src/mymaven  
```

What is being done above?  First, we build the **docker image** and then execute a command to execute the **.jar** that was generated. It also needs to expose two ports to this work perfectly, the port **8080** is for accessing the localhost Restful API, and the port **5005** is for accessing the debug option. Besides that, we configure a volume and working directly for accept changes from our local project.

2. **Mongo**
```yml
  mongodb:  
    image: mongo  
    container_name: mongodb  
    ports:  
      - 27017:27017  
    volumes:  
      - /data
    environment:  
      - MONGO_INITDB_ROOT_USERNAME=rootuser 
      - MONGO_INITDB_ROOT_PASSWORD=rootpass
      - MONGO_INITDB_DATABASE=mydatabasename
volumes:  
  data: { }  
  
networks:  
  default:  
    name: mongodb_network
```
Above we simply create a service to run the mongo image and configure the parameters of the database. After it, we create a network to connect the two containers created.
We also can create a service for mongo express if needed:

```yml
  mongo-express:  
    image: mongo-express:0.54  
    container_name: mongo-express  
    restart: always  
    ports:  
      - 8081:8081  
    environment:  
      - ME_CONFIG_MONGODB_ADMINUSERNAME=rootuser  
      - ME_CONFIG_MONGODB_ADMINPASSWORD=rootpass
      - ME_CONFIG_MONGODB_SERVER=mongodb
```

After finishing this part we need one more configuration, in **src/main/resources** we open the file **application.properties** and paste the following information:

```yml
spring.data.mongodb.authentication-database=admin  
spring.data.mongodb.username=rootuser  
spring.data.mongodb.password=rootpass  
spring.data.mongodb.database=mydatabasename  
spring.data.mongodb.port=27017  
spring.data.mongodb.host=mongodb  
spring.data.mongodb.auto-index-creation=true
```

In case you need to initialize values you can execute commands in mongo when starting up the environment. It just needs to make some adjustments.
- Add the following line in the volumes of **mongodb** service:
	- ``./devops/dev/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:r``.
- Inside the **.js** file should have something like this:

```js
db = new Mongo().getDB('mydatabase'); 
db.createCollection('users'); 
db.users.insertMany([ 
	{ 
		username: 'user01', 
		password: '123456', 
		email: 'user01@email.com' 
	}, 
	{ 
		username: 'user02', 
		password: '654321', 
		email: 'user02@email.com' }, 
	{ 
		username: 'user03', 
		password: '456456', 
		email: 'user03@email.com' 
	} 
]);
```

## Configure Debug
Now to connect it to your IDE and be possible to debug set it, here we will use **Intellij**. So what you need to do is create one **Remote JVM Debug**.

1. Click on Edit Configuration:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y6962o7fm5u6hecupboi.png)

2. Create a Remote JVM Debug and configure below:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e52iev967vctd4rivxht.png)

## Execution
1. Execute follow command to **run** environment
```shell
docker-compose up -d
```

2. Click the symbol **debug** button:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4exllu12n0gn6sl65yoa.png)

## Conclusion
After a long day configuring it, I thought that a manual would be of good use for the community because I face several problems trying to configure it until arrive at this solution. Any questions I will be glad to try to answer them. 
[Access te files here](https://bit.ly/3zzwBok)!

Enjoy!