Skip to content

Commit 261862e

Browse files
MayuriXxCopilotprofotoce59romainVanhee
authored
feat(docker): add docker with postgresql (#17)
* feat(docker): add docker with postgresql * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * feat(docker): format readme file * fix(sonar_docker): add a config to skip docker on sonar (#22) Co-authored-by: Romain Vanhee <romain.vanhee@yrycom.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Romain Vanhée <71013671+profotoce59@users.noreply.github.com> Co-authored-by: Romain Vanhee <romain.vanhee@yrycom.com>
1 parent b74f516 commit 261862e

10 files changed

Lines changed: 257 additions & 96 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

.github/workflows/sonar.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,4 @@ jobs:
4040
mkdir -p src/test/resources
4141
echo ${{ secrets.APPLICATION_TEST_PROPERTIES }} | base64 -d > src/test/resources/application-test.properties
4242
echo "spring.sql.init.mode=never" >> src/test/resources/application-test.properties
43-
mvn clean verify sonar:sonar -Dsonar.qualitygate.wait=true
43+
mvn clean verify sonar:sonar -DskipDocker=true -Dsonar.qualitygate.wait=true

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,7 @@ build/
3232
### VS Code ###
3333
.vscode/
3434

35+
### Environment variables ###
36+
.env
3537
# Test configuration generated in CI
3638
src/test/resources/application-test.properties

README.md

Lines changed: 99 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,74 @@
11
# spring_boot_java_random_user
22

3-
Spring Boot Java project that exposes a REST API consuming the public [Random User](https://randomuser.me/) API.
4-
The interactive API documentation is available via **Swagger UI / OpenAPI**.
3+
Spring Boot REST API that consumes the public [Random User](https://randomuser.me/) API and persists data in a PostgreSQL database.
4+
Interactive API documentation is available via **Swagger UI / OpenAPI**.
55

66
---
77

88
## 🛠️ Tech Stack
99

10-
| Technology | Version |
11-
|----------------------|-----------------|
12-
| Java | 25 |
13-
| Spring Boot | 4.0.3 |
14-
| Spring Web MVC | (managed by Boot) |
15-
| Spring Actuator | (managed by Boot) |
16-
| springdoc-openapi | 3.0.1 |
17-
| PostgreSQL (driver) | (managed by Boot) |
18-
| Testcontainers | (managed by Boot) |
19-
| Maven | Wrapper included |
10+
| Technology | Version |
11+
|---|---|
12+
| Java | 25 |
13+
| Spring Boot | 4.0.3 |
14+
| Spring Web MVC | (managed by Boot) |
15+
| Spring Data JDBC | (managed by Boot) |
16+
| Spring Actuator | (managed by Boot) |
17+
| springdoc-openapi | 3.0.1 |
18+
| PostgreSQL | 15 |
19+
| dotenv-java | 5.2.2 |
20+
| Docker / Docker Compose | - |
21+
| Maven | Wrapper included |
2022

2123
---
2224

2325
## 📋 Prerequisites
2426

25-
- **Java 25** (or compatible version)
27+
- **Java 25+**
2628
- **Maven** (or use the included `./mvnw` wrapper)
27-
- **PostgreSQL** running (if data persistence is enabled)
29+
- **Docker Desktop**
2830

2931
---
3032

3133
## ⚙️ Configuration
3234

33-
The main configuration file is located at:
35+
### 1. Environment variables
3436

35-
```
36-
src/main/resources/application.properties
37+
Copy the template and fill in the values:
38+
39+
```bash
40+
cp .env.template .env
3741
```
3842

39-
### Properties to configure
43+
`.env` content:
44+
45+
```env
46+
POSTGRES_USER={POSTGRES_USER}
47+
POSTGRES_PASSWORD={POSTGRES_PASSWORD}
48+
POSTGRES_DB={POSTGRES_DB}
49+
POSTGRES_PORT={POSTGRES_PORT}
50+
```
4051

41-
```properties
42-
spring.application.name=spring_boot_java_random_user
52+
> ⚠️ The `.env` file is git-ignored. Never commit it.
4353
44-
# Swagger UI — available at /api
45-
springdoc.swagger-ui.path=/api
54+
### 2. Test properties
4655

47-
# PostgreSQL datasource (add these if you use persistence)
48-
spring.datasource.url=jdbc:postgresql://localhost:5432/<database_name>
49-
spring.datasource.username=<username>
50-
spring.datasource.password=<password>
51-
spring.datasource.driver-class-name=org.postgresql.Driver
56+
```bash
57+
cp src/test/resources/application-test.properties.template src/test/resources/application-test.properties
5258
```
5359

54-
> ⚠️ **Common startup error**:
55-
> ```
56-
> Failed to configure a DataSource: 'url' attribute is not specified
57-
> and no embedded datasource could be configured.
58-
> Reason: Failed to determine a suitable driver class
59-
> ```
60-
> This error occurs because the PostgreSQL driver is present in the dependencies but the datasource URL is not configured.
61-
> **Fix**: either add the `spring.datasource.*` properties above, or exclude the DataSource auto-configuration if no database is needed:
62-
> ```properties
63-
> spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
64-
> ```
60+
> ⚠️ This file is also git-ignored.
6561
6662
---
6763

6864
## 🚀 Running the project
6965

66+
### Start the database
67+
68+
```bash
69+
docker-compose up -d
70+
```
71+
7072
### With the Maven Wrapper (recommended)
7173

7274
```bash
@@ -86,17 +88,17 @@ mvn spring-boot:run
8688
java -jar target/spring_boot_java_random_user-0.0.1-SNAPSHOT.jar
8789
```
8890

91+
The application will be available at: http://localhost:8080
92+
8993
---
9094

9195
## 📖 API Documentation (Swagger UI)
9296

93-
Once the project is running, the interactive documentation is available at:
94-
9597
```
9698
http://localhost:8080/api
9799
```
98100

99-
The raw OpenAPI specification (JSON) is available at:
101+
Raw OpenAPI specification (JSON):
100102

101103
```
102104
http://localhost:8080/v3/api-docs
@@ -106,8 +108,6 @@ http://localhost:8080/v3/api-docs
106108

107109
## 🔍 Monitoring (Actuator)
108110

109-
Spring Boot Actuator is enabled. Health endpoints are available at:
110-
111111
```
112112
http://localhost:8080/actuator
113113
http://localhost:8080/actuator/health
@@ -117,25 +117,24 @@ http://localhost:8080/actuator/health
117117

118118
## 🧪 Tests
119119

120-
Run unit and integration tests:
120+
The Maven plugin starts and stops Docker Compose automatically during tests:
121121

122122
```bash
123-
./mvnw test
123+
./mvnw verify
124124
```
125125

126-
Tests use **Testcontainers** to spin up ephemeral Docker containers for external dependencies (e.g. PostgreSQL).
126+
Execution cycle:
127+
1. `pre-integration-test``docker-compose up` (PostgreSQL starts)
128+
2. `integration-test` → tests run
129+
3. `post-integration-test``docker-compose down` (PostgreSQL stops)
127130

128-
> **Prerequisite for tests**: Docker must be installed and running.
131+
> **Prerequisite**: Docker must be installed and running.
129132
130133
---
131134

132135
## 🔎 Code Quality (SonarQube)
133136

134-
A GitHub Actions workflow is configured in:
135-
136-
```bash
137-
.github/workflows/sonar.yaml
138-
```
137+
A GitHub Actions workflow is configured in `.github/workflows/sonar.yaml`.
139138

140139
### Workflow triggers
141140

@@ -147,45 +146,32 @@ A GitHub Actions workflow is configured in:
147146
- Java 25 setup (Temurin)
148147
- Maven build + tests + SonarQube analysis:
149148

150-
```bash
151-
mvn clean verify sonar:sonar
152-
```
153-
154-
The CI command waits for the Quality Gate result:
155-
156149
```bash
157150
./mvnw clean verify sonar:sonar -Dsonar.qualitygate.wait=true
158151
```
159152

160-
Before running tests, the workflow recreates:
161-
162-
```bash
163-
src/test/resources/application-test.properties
164-
```
165-
166-
from a Base64-encoded GitHub secret.
167-
168153
### Required GitHub Secrets
169154

170-
- `SONAR_TOKEN`
171-
- `SONAR_HOST_URL`
172-
- `APPLICATION_TEST_PROPERTIES` (Base64-encoded `application-test.properties` content)
155+
| Secret | Description |
156+
| `APPLICATION_TEST_PROPERTIES` (Base64-encoded `application-test.properties` content)
157+
| `SONAR_TOKEN` | SonarQube authentication token |
158+
| `SONAR_HOST_URL` | SonarQube instance URL |
159+
| `POSTGRES_USER` | PostgreSQL user |
160+
| `POSTGRES_PASSWORD` | PostgreSQL password |
161+
| `POSTGRES_DB` | Database name |
162+
| `POSTGRES_PORT` | PostgreSQL port |
173163

174164
> `GITHUB_TOKEN` is provided automatically by GitHub Actions.
175165
176-
### Generate the JaCoCo coverage report locally
177-
178-
Run:
166+
### JaCoCo coverage report (local)
179167

180168
```bash
181169
./mvnw clean verify
182170
```
183171

184172
Generated reports:
185-
186-
- HTML report: `target/site/jacoco/index.html`
187-
- XML report (used by SonarQube): `target/site/jacoco/jacoco.xml`
188-
173+
- HTML: `target/site/jacoco/index.html`
174+
- XML (used by SonarQube): `target/site/jacoco/jacoco.xml`
189175

190176
---
191177

@@ -195,16 +181,43 @@ Generated reports:
195181
src/
196182
├── main/
197183
│ ├── java/com/xpeho/spring_boot_java_random_user/
198-
│ │ └── SpringBootJavaRandomUserApplication.java # Entry point
184+
│ │ └── SpringBootJavaRandomUserApplication.java Entry point, loads .env
199185
│ └── resources/
200-
│ └── application.properties # Configuration
186+
│ ├── application.properties ← Spring configuration
187+
│ └── schema.sql ← Database schema
201188
└── test/
202-
└── java/com/xpeho/spring_boot_java_random_user/
203-
└── SpringBootJavaRandomUserApplicationTests.java
189+
├── java/com/xpeho/spring_boot_java_random_user/
190+
│ └── SpringBootJavaRandomUserApplicationTests.java
191+
└── resources/
192+
├── application-test.properties ← Test config (git-ignored)
193+
└── application-test.properties.template ← Template to copy
194+
.env ← Environment variables (git-ignored)
195+
.env.template ← Template to copy
196+
docker-compose.yml ← Local PostgreSQL
204197
```
205198

206199
---
207200

201+
## 🗄️ Database
202+
203+
### Schema
204+
205+
The `user` table is created automatically on startup via `schema.sql`:
206+
207+
| Column | Type | Description |
208+
|---|---|---|
209+
| `id` | SERIAL PK | Auto-incremented identifier |
210+
| `gender` | VARCHAR(20) | Gender |
211+
| `firstname` | VARCHAR(100) | First name (`name.first`) |
212+
| `lastname` | VARCHAR(100) | Last name (`name.last`) |
213+
| `civility` | VARCHAR(20) | Title (`name.title`) |
214+
| `email` | VARCHAR(255) | Email address |
215+
| `phone` | VARCHAR(50) | Phone number |
216+
| `picture` | VARCHAR(500) | Medium picture URL |
217+
| `nationality` | VARCHAR(10) | Nationality |
218+
219+
---
220+
208221
## 🌐 External API
209222

210223
This project consumes the public **Random User Generator** API:
@@ -217,12 +230,12 @@ This project consumes the public **Random User Generator** API:
217230
## ✅ Todo
218231

219232
- [x] [Add Sonarqube in the project](https://github.com/XPEHO/spring_boot_java_random_user/issues/2)
220-
- [ ] [Add PostgreSQL database with docker](https://github.com/XPEHO/spring_boot_java_random_user/issues/6)
221-
- [ ] [Add this endpoint get /user/random](https://github.com/XPEHO/spring_boot_java_random_user/issues/5)
222-
- [ ] [Add this endpoint get /user/{id}](https://github.com/XPEHO/spring_boot_java_random_user/issues/8)
223-
- [ ] [Add this endpoint put /user/{id}](https://github.com/XPEHO/spring_boot_java_random_user/issues/9)
224-
- [ ] [Add this endpoint delete /user/{id}](https://github.com/XPEHO/spring_boot_java_random_user/issues/10)
225-
- [ ] [Add this endpoint post /user](https://github.com/XPEHO/spring_boot_java_random_user/issues/11)
233+
- [x] [Add PostgreSQL database with docker](https://github.com/XPEHO/spring_boot_java_random_user/issues/6)
234+
- [ ] [Add this endpoint GET /user/random](https://github.com/XPEHO/spring_boot_java_random_user/issues/5)
235+
- [ ] [Add this endpoint GET /user/{id}](https://github.com/XPEHO/spring_boot_java_random_user/issues/8)
236+
- [ ] [Add this endpoint PUT /user/{id}](https://github.com/XPEHO/spring_boot_java_random_user/issues/9)
237+
- [ ] [Add this endpoint DELETE /user/{id}](https://github.com/XPEHO/spring_boot_java_random_user/issues/10)
238+
- [ ] [Add this endpoint POST /user](https://github.com/XPEHO/spring_boot_java_random_user/issues/11)
226239

227240
---
228241

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:17.9-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+
- "${POSTGRES_PORT}: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+

0 commit comments

Comments
 (0)