Add Docker configuration and GitHub Actions workflow

This commit is contained in:
Bhavesh Khandelwal 2025-11-18 20:00:06 +05:30
parent 6feeae0f13
commit 879201b99d
5 changed files with 162 additions and 23 deletions

15
.dockerignore Normal file
View file

@ -0,0 +1,15 @@
/target
/build
/.mvn/wrapper/maven-wrapper.jar
/.idea
/.vscode
/.git
/.gitignore
README.md
LICENSE.txt
docker-compose.yml
k8s
node_modules
*.iml
*.log

51
.github/workflows/container-build.yml vendored Normal file
View file

@ -0,0 +1,51 @@
name: Container Build and Publish
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up JDK 25
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '25'
cache: maven
- name: Build and test with Maven
run: ./mvnw -B verify
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: .
push: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
cache-from: type=gha
cache-to: type=gha,mode=max

23
Dockerfile Normal file
View file

@ -0,0 +1,23 @@
FROM eclipse-temurin:25-jdk-alpine AS builder
WORKDIR /workspace
COPY mvnw .
COPY .mvn .mvn
COPY pom.xml .
COPY src src
RUN chmod +x mvnw \
&& ./mvnw -B -DskipTests package
FROM eclipse-temurin:25-jre-alpine
WORKDIR /app
ENV SPRING_PROFILES_ACTIVE=${SPRING_PROFILES_ACTIVE:-mysql}
ENV JAVA_OPTS=""
COPY --from=builder /workspace/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]

View file

@ -1,4 +1,4 @@
# Spring PetClinic Sample Application [![Build Status](https://github.com/spring-projects/spring-petclinic/actions/workflows/maven-build.yml/badge.svg)](https://github.com/spring-projects/spring-petclinic/actions/workflows/maven-build.yml)[![Build Status](https://github.com/spring-projects/spring-petclinic/actions/workflows/gradle-build.yml/badge.svg)](https://github.com/spring-projects/spring-petclinic/actions/workflows/gradle-build.yml)
# Spring PetClinic Sample Application [![Build Status](https://github.com/spring-projects/spring-petclinic/actions/workflows/maven-build.yml/badge.svg)](https://github.com/spring-projects/spring-petclinic/actions/workflows/maven-build.yml)[![Build Status](https://github.com/spring-projects/spring-petclinic/actions/workflows/gradle-build.yml/badge.svg)](https://github.com/spring-projects/spring-petclinic/actions/workflows/gradle-build.yml)[![Container Build Status](https://github.com/spring-projects/spring-petclinic/actions/workflows/container-build.yml/badge.svg)](https://github.com/spring-projects/spring-petclinic/actions/workflows/container-build.yml)
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/spring-projects/spring-petclinic) [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=7517918)
@ -37,14 +37,42 @@ Or you can run it from Maven directly using the Spring Boot Maven plugin. If you
> NOTE: If you prefer to use Gradle, you can build the app using `./gradlew build` and look for the jar file in `build/libs`.
## Building a Container
## Containerized Deployment
There is no `Dockerfile` in this project. You can build a container image (if you have a docker daemon) using the Spring Boot build plugin:
Spring PetClinic now ships with a first-class Dockerfile and Compose stack.
### Build a local image
```bash
./mvnw spring-boot:build-image
docker build -t spring-petclinic .
docker run --rm -p 8080:8080 \
-e SPRING_PROFILES_ACTIVE=mysql \
-e SPRING_DATASOURCE_URL=jdbc:mysql://localhost:3306/petclinic?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC \
-e SPRING_DATASOURCE_USERNAME=petclinic \
-e SPRING_DATASOURCE_PASSWORD=petclinic \
spring-petclinic
```
### Run the full stack with Docker Compose
```bash
docker compose up --build
```
The default profile uses the MySQL service declared in `docker-compose.yml`. To stop the stack run `docker compose down`.
To switch to PostgreSQL, enable the `postgres` profile and override the datasource values:
```bash
SPRING_PROFILES_ACTIVE=postgres \
SPRING_DATASOURCE_URL=jdbc:postgresql://postgres:5432/petclinic \
docker compose --profile postgres up --build
```
## Continuous Integration and Deployment
The repository now includes a `Container Build and Publish` workflow that complements the existing Maven and Gradle pipelines. Every push and pull request triggers unit and integration tests via Maven and builds a container image using Docker Buildx. Successful builds on `main` automatically publish a `ghcr.io/<owner>/spring-petclinic:latest` container image using the repository `GITHUB_TOKEN`.
## In case you find a bug/suggested improvement for Spring Petclinic
Our issue tracker is available [here](https://github.com/spring-projects/spring-petclinic/issues).
@ -72,17 +100,7 @@ docker run -e POSTGRES_USER=petclinic -e POSTGRES_PASSWORD=petclinic -e POSTGRES
Further documentation is provided for [MySQL](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt)
and [PostgreSQL](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/resources/db/postgres/petclinic_db_setup_postgres.txt).
Instead of vanilla `docker` you can also use the provided `docker-compose.yml` file to start the database containers. Each one has a service named after the Spring profile:
```bash
docker compose up mysql
```
or
```bash
docker compose up postgres
```
Instead of vanilla `docker` you can also rely on the provided `docker-compose.yml` file to start both the application and database containers together as shown above.
## Test Applications

View file

@ -1,21 +1,53 @@
services:
app:
build:
context: .
dockerfile: Dockerfile
image: spring-petclinic:latest
ports:
- "8080:8080"
environment:
SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE:-mysql}
SPRING_DATASOURCE_URL: ${SPRING_DATASOURCE_URL:-jdbc:mysql://mysql:3306/petclinic?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC}
SPRING_DATASOURCE_USERNAME: ${SPRING_DATASOURCE_USERNAME:-petclinic}
SPRING_DATASOURCE_PASSWORD: ${SPRING_DATASOURCE_PASSWORD:-petclinic}
depends_on:
mysql:
condition: service_healthy
restart: unless-stopped
mysql:
image: mysql:9.2
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=
- MYSQL_ALLOW_EMPTY_PASSWORD=true
- MYSQL_USER=petclinic
- MYSQL_PASSWORD=petclinic
- MYSQL_DATABASE=petclinic
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-root}
MYSQL_USER: ${SPRING_DATASOURCE_USERNAME:-petclinic}
MYSQL_PASSWORD: ${SPRING_DATASOURCE_PASSWORD:-petclinic}
MYSQL_DATABASE: ${MYSQL_DATABASE:-petclinic}
MYSQL_ALLOW_EMPTY_PASSWORD: "false"
volumes:
- "./conf.d:/etc/mysql/conf.d:ro"
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h localhost -p${MYSQL_ROOT_PASSWORD:-root}"]
interval: 10s
timeout: 5s
retries: 10
start_period: 20s
postgres:
image: postgres:18.0
ports:
- "5432:5432"
environment:
- POSTGRES_PASSWORD=petclinic
- POSTGRES_USER=petclinic
- POSTGRES_DB=petclinic
POSTGRES_PASSWORD: ${SPRING_DATASOURCE_PASSWORD:-petclinic}
POSTGRES_USER: ${SPRING_DATASOURCE_USERNAME:-petclinic}
POSTGRES_DB: ${POSTGRES_DB:-petclinic}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${SPRING_DATASOURCE_USERNAME:-petclinic}"]
interval: 10s
timeout: 5s
retries: 10
start_period: 20s
profiles:
- postgres