Skip to content

Commit 7888bd3

Browse files
committed
feat(docker): add docker with postgresql
1 parent b061ba3 commit 7888bd3

10 files changed

Lines changed: 294 additions & 10 deletions

File tree

.env.template

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
POSTGRES_USER=your_postgres_user
2+
POSTGRES_PASSWORD=your_postgres_password
3+
POSTGRES_DB=your_postgres_db
4+
POSTGRES_PORT=5433

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,10 @@ build/
3131

3232
### VS Code ###
3333
.vscode/
34+
35+
### Environment variables ###
36+
.env
37+
38+
### Test properties ###
39+
src/test/resources/application-test.properties
40+

README.md

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,144 @@
1+
Project developed by **XPEHO**.
2+
3+
## 👤 Author
4+
- [x] [Add Sonarqube in the project](https://github.com/XPEHO/spring_boot_java_random_user/issues/2)
5+
- [x] [Add PostgreSQL database with docker](https://github.com/XPEHO/spring_boot_java_random_user/issues/6)
6+
- [ ] [Add this endpoint get /user/random](https://github.com/XPEHO/spring_boot_java_random_user/issues/5)
7+
- [ ] [Add this endpoint get /user/{id}](https://github.com/XPEHO/spring_boot_java_random_user/issues/8)
8+
- [ ] [Add this endpoint put /user/{id}](https://github.com/XPEHO/spring_boot_java_random_user/issues/9)
9+
- [ ] [Add this endpoint delete /user/{id}](https://github.com/XPEHO/spring_boot_java_random_user/issues/10)
10+
- [ ] [Add this endpoint post /user](https://github.com/XPEHO/spring_boot_java_random_user/issues/11)
11+
## ✅ Todo
12+
- **URL**: [https://randomuser.me/api/](https://randomuser.me/api/)
13+
- **Documentation**: [https://randomuser.me/documentation](https://randomuser.me/documentation)
14+
This project consumes the public **Random User Generator** API:
15+
## 🌐 External API
16+
└── java/com/xpeho/spring_boot_java_random_user/
17+
└── SpringBootJavaRandomUserApplicationTests.java
18+
│ └── application.properties # Configuration
19+
│ │ └── SpringBootJavaRandomUserApplication.java # Entry point
20+
## 📁 Project structure
21+
Generated reports:
22+
23+
- HTML report: `target/site/jacoco/index.html`
24+
- XML report (used by SonarQube): `target/site/jacoco/jacoco.xml`
25+
26+
mvn clean verify sonar:sonar
27+
```
28+
29+
### Generate the JaCoCo coverage report locally
30+
31+
Run:
32+
33+
```bash
34+
./mvnw clean verify
35+
- Java 25 setup (Temurin)
36+
- Maven build + tests + SonarQube analysis:
37+
### What it runs
38+
- `push` on all branches
39+
- `pull_request`
40+
### Workflow triggers
41+
.github/workflows/sonar.yaml
42+
Tests use **Testcontainers** to spin up ephemeral Docker containers for external dependencies (e.g. PostgreSQL).
43+
44+
> **Prerequisite for tests**: Docker must be installed and running.
45+
46+
---
47+
48+
## 🔎 Code Quality (SonarQube)
49+
50+
A GitHub Actions workflow is configured in:
51+
./mvnw test
52+
Run unit and integration tests:
53+
## 🧪 Tests
54+
---
55+
56+
## 📖 API Documentation (Swagger UI)
57+
58+
Once the project is running, the interactive documentation is available at:
59+
60+
```
61+
http://localhost:8080/api
62+
```
63+
64+
The raw OpenAPI specification (JSON) is available at:
65+
66+
```
67+
http://localhost:8080/v3/api-docs
68+
```
69+
70+
---
71+
72+
## 🔍 Monitoring (Actuator)
73+
74+
Spring Boot Actuator is enabled. Health endpoints are available at:
75+
76+
```
77+
http://localhost:8080/actuator
78+
http://localhost:8080/actuator/health
79+
```
80+
./mvnw clean package
81+
java -jar target/spring_boot_java_random_user-0.0.1-SNAPSHOT.jar
82+
### Build and run the JAR
83+
mvn spring-boot:run
84+
### With Maven installed
85+
./mvnw spring-boot:run
86+
### With the Maven Wrapper (recommended)
87+
## 🚀 Running the project
88+
### Properties to configure
89+
90+
```properties
91+
spring.application.name=spring_boot_java_random_user
92+
93+
# Swagger UI — available at /api
94+
springdoc.swagger-ui.path=/api
95+
96+
# PostgreSQL datasource (add these if you use persistence)
97+
spring.datasource.url=jdbc:postgresql://localhost:5432/<database_name>
98+
spring.datasource.username=<username>
99+
spring.datasource.password=<password>
100+
spring.datasource.driver-class-name=org.postgresql.Driver
101+
```
102+
103+
> ⚠️ **Common startup error**:
104+
> ```
105+
> Failed to configure a DataSource: 'url' attribute is not specified
106+
> and no embedded datasource could be configured.
107+
> Reason: Failed to determine a suitable driver class
108+
> ```
109+
> This error occurs because the PostgreSQL driver is present in the dependencies but the datasource URL is not configured.
110+
> **Fix**: either add the `spring.datasource.*` properties above, or exclude the DataSource auto-configuration if no database is needed:
111+
> ```properties
112+
> spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
113+
> ```
114+
## 📋 Prerequisites
115+
116+
- **Java 25** (or compatible version)
117+
- **Maven** (or use the included `./mvnw` wrapper)
118+
- **PostgreSQL** running (if data persistence is enabled)
119+
120+
---
121+
122+
## ⚙️ Configuration
123+
124+
The main configuration file is located at:
125+
126+
```
127+
src/main/resources/application.properties
128+
```
129+
| Technology | Version |
130+
|----------------------|-----------------|
131+
| Java | 25 |
132+
| Spring Boot | 4.0.3 |
133+
| Spring Web MVC | (managed by Boot) |
134+
| Spring Actuator | (managed by Boot) |
135+
| springdoc-openapi | 3.0.1 |
136+
| PostgreSQL (driver) | (managed by Boot) |
137+
| Testcontainers | (managed by Boot) |
138+
| Maven | Wrapper included |
139+
## 🛠️ Tech Stack
140+
Spring Boot Java project that exposes a REST API consuming the public [Random User](https://randomuser.me/) API.
141+
The interactive API documentation is available via **Swagger UI / OpenAPI**.
1142
# spring_boot_java_random_user
2143
3144
Spring Boot Java project that exposes a REST API consuming the public [Random User](https://randomuser.me/) API.

docker-compose.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
version: '3.8'
2+
3+
services:
4+
postgres:
5+
image: postgres:15-alpine
6+
container_name: xpeho_postgres
7+
environment:
8+
POSTGRES_USER: ${POSTGRES_USER}
9+
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
10+
POSTGRES_DB: ${POSTGRES_DB}
11+
ports:
12+
- "5433:5432"
13+
volumes:
14+
- postgres_data:/var/lib/postgresql/data
15+
- ./src/main/resources/schema.sql:/docker-entrypoint-initdb.d/01-schema.sql
16+
healthcheck:
17+
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
18+
interval: 10s
19+
timeout: 5s
20+
retries: 5
21+
networks:
22+
- xpeho_network
23+
24+
volumes:
25+
postgres_data:
26+
driver: local
27+
28+
networks:
29+
xpeho_network:
30+
driver: bridge
31+

pom.xml

Lines changed: 67 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@
3636
<groupId>org.springframework.boot</groupId>
3737
<artifactId>spring-boot-starter-actuator</artifactId>
3838
</dependency>
39-
<!-- <dependency>-->
40-
<!-- <groupId>org.springframework.boot</groupId>-->
41-
<!-- <artifactId>spring-boot-starter-data-jdbc</artifactId>-->
42-
<!-- </dependency>-->
39+
<dependency>
40+
<groupId>org.springframework.boot</groupId>
41+
<artifactId>spring-boot-starter-data-jdbc</artifactId>
42+
</dependency>
4343
<dependency>
4444
<groupId>org.springframework.boot</groupId>
4545
<artifactId>spring-boot-starter-webmvc</artifactId>
@@ -56,16 +56,23 @@
5656
<artifactId>postgresql</artifactId>
5757
<scope>runtime</scope>
5858
</dependency>
59+
60+
<dependency>
61+
<groupId>io.github.cdimascio</groupId>
62+
<artifactId>java-dotenv</artifactId>
63+
<version>5.2.2</version>
64+
</dependency>
65+
5966
<dependency>
6067
<groupId>org.springframework.boot</groupId>
6168
<artifactId>spring-boot-starter-actuator-test</artifactId>
6269
<scope>test</scope>
6370
</dependency>
64-
<!-- <dependency>-->
65-
<!-- <groupId>org.springframework.boot</groupId>-->
66-
<!-- <artifactId>spring-boot-starter-data-jdbc-test</artifactId>-->
67-
<!-- <scope>test</scope>-->
68-
<!-- </dependency>-->
71+
<dependency>
72+
<groupId>org.springframework.boot</groupId>
73+
<artifactId>spring-boot-starter-data-jdbc-test</artifactId>
74+
<scope>test</scope>
75+
</dependency>
6976
<dependency>
7077
<groupId>org.springframework.boot</groupId>
7178
<artifactId>spring-boot-starter-webmvc-test</artifactId>
@@ -94,6 +101,57 @@
94101
<groupId>org.springframework.boot</groupId>
95102
<artifactId>spring-boot-maven-plugin</artifactId>
96103
</plugin>
104+
<plugin>
105+
<groupId>org.apache.maven.plugins</groupId>
106+
<artifactId>maven-surefire-plugin</artifactId>
107+
<configuration>
108+
<skip>true</skip>
109+
</configuration>
110+
</plugin>
111+
<plugin>
112+
<groupId>org.apache.maven.plugins</groupId>
113+
<artifactId>maven-failsafe-plugin</artifactId>
114+
<configuration>
115+
<includes>
116+
<include>**/*Tests.java</include>
117+
<include>**/*Test.java</include>
118+
</includes>
119+
</configuration>
120+
<executions>
121+
<execution>
122+
<goals>
123+
<goal>integration-test</goal>
124+
<goal>verify</goal>
125+
</goals>
126+
</execution>
127+
</executions>
128+
</plugin>
129+
<plugin>
130+
<groupId>com.dkanejs.maven.plugins</groupId>
131+
<artifactId>docker-compose-maven-plugin</artifactId>
132+
<version>4.0.0</version>
133+
<executions>
134+
<execution>
135+
<id>docker-compose-up</id>
136+
<phase>pre-integration-test</phase>
137+
<goals>
138+
<goal>up</goal>
139+
</goals>
140+
</execution>
141+
<execution>
142+
<id>docker-compose-down</id>
143+
<phase>post-integration-test</phase>
144+
<goals>
145+
<goal>down</goal>
146+
</goals>
147+
</execution>
148+
</executions>
149+
<configuration>
150+
<composeFile>${project.basedir}/docker-compose.yml</composeFile>
151+
<detachedMode>true</detachedMode>
152+
<removeVolumes>false</removeVolumes>
153+
</configuration>
154+
</plugin>
97155
<plugin>
98156
<groupId>org.jacoco</groupId>
99157
<artifactId>jacoco-maven-plugin</artifactId>

src/main/java/com/xpeho/spring_boot_java_random_user/SpringBootJavaRandomUserApplication.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
package com.xpeho.spring_boot_java_random_user;
22

3+
import io.github.cdimascio.dotenv.Dotenv;
34
import org.springframework.boot.SpringApplication;
45
import org.springframework.boot.autoconfigure.SpringBootApplication;
56

67
@SpringBootApplication
78
public class SpringBootJavaRandomUserApplication {
89

910
public static void main(String[] args) {
11+
Dotenv.configure()
12+
.ignoreIfMissing()
13+
.load()
14+
.entries()
15+
.forEach(entry -> System.setProperty(entry.getKey(), entry.getValue()));
16+
1017
SpringApplication.run(SpringBootJavaRandomUserApplication.class, args);
1118
}
1219

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
11
spring.application.name=spring_boot_java_random_user
2+
23
# Swagger UI custom path
34
springdoc.swagger-ui.path=/api
5+
6+
# Database configuration
7+
spring.datasource.url=jdbc:postgresql://localhost:${POSTGRES_PORT}/${POSTGRES_DB}
8+
spring.datasource.username=${POSTGRES_USER}
9+
spring.datasource.password=${POSTGRES_PASSWORD}
10+
spring.datasource.driver-class-name=org.postgresql.Driver
11+
12+
13+
# Spring Data JDBC - Initialize database
14+
spring.sql.init.mode=always
15+
spring.sql.init.schema-locations=classpath:schema.sql
16+
spring.sql.init.data-locations=
17+
spring.sql.init.platform=postgresql
18+
spring.sql.init.continue-on-error=true

src/main/resources/schema.sql

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
DROP TABLE IF EXISTS "user";
2+
3+
CREATE TABLE IF NOT EXISTS "user"
4+
(
5+
id SERIAL PRIMARY KEY,
6+
gender VARCHAR(20),
7+
firstname VARCHAR(100),
8+
lastname VARCHAR(100),
9+
civility VARCHAR(20),
10+
email VARCHAR(255),
11+
phone VARCHAR(50),
12+
picture VARCHAR(500),
13+
nationality VARCHAR(10)
14+
);

src/test/java/com/xpeho/spring_boot_java_random_user/SpringBootJavaRandomUserApplicationTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
import org.junit.jupiter.api.Test;
44
import org.springframework.boot.test.context.SpringBootTest;
5-
import org.springframework.context.annotation.Import;
5+
import org.springframework.test.context.ActiveProfiles;
66

77
@SpringBootTest
8+
@ActiveProfiles("test")
89
class SpringBootJavaRandomUserApplicationTests {
910

1011
@Test
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
POSTGRES_USER=your_postgres_user
2+
POSTGRES_PASSWORD=your_postgres_password
3+
POSTGRES_DB=your_postgres_db
4+
POSTGRES_PORT=5433
5+
6+

0 commit comments

Comments
 (0)