A personal endeavor to learn and demonstrate various DevOps concepts: Docker, Kubernetes, Helm, and Terraform β all wrapped around a Spring Boot application.
- Spring Boot Application: A simple RESTful API built with Spring Boot, showcasing basic CRUD operations and exposing monitoring endpoints.
- Docker: Containerization of the Spring Boot application for consistent environments.
- Kubernetes: Deployment and management of the application on a Kubernetes cluster using various manifest types (Deployments, Services, etc.).
- Helm: Packaging and deploying the application to Kubernetes using Helm charts for easier management and versioning.
- Terraform: Infrastructure as Code (IaC) for provisioning and managing the necessary cloud resources (current state focuses on local configurations, but the structure is in place for cloud integration).
- CI/CD: (Implied/Expandable) The project structure allows for the integration of CI/CD pipelines to automate builds, tests, and deployments.
Deployment artefacts live under infra/ and reference documentation lives under docs/. Top-level files (Deploy.sh, Makefile, pom.xml) stay where they are because they're entry points.
DockerPoc-1/
βββ src/ Spring Boot Java source
βββ infra/
β βββ docker/ Dockerfile, Dockerfile.maven-build, nginx/, docker-compose.yml
β βββ kubernetes/ K8s manifests (App/, Ingress/, Storage/, β¦)
β βββ helm/dockerpoc-app/ Helm chart β directory matches Chart.yaml `name:`
β βββ terraform/ Terraform .tf files and state
β βββ flux/ FluxCD manifests and docs
βββ docs/ Standalone Markdown docs (helm-terraform, remote-debugging, β¦)
βββ .github/workflows/ CI: build-and-push.yml, helm-release.yml
βββ Deploy.sh Build + deploy helper script
βββ Makefile Convenience targets (see below)
βββ pom.xml Maven build
βββ README.md
Ensure the following are installed before you begin:
- JDK 17
- Maven
- Docker
kubectl- Helm
- Terraform
- A running Kubernetes cluster (Minikube, Docker Desktop with Kubernetes enabled, or a cloud-based cluster)
git clone https://github.com/your-username/DockerPoc-1.git
cd DockerPoc-1mvn clean packageThis will create an executable JAR file in the target directory.
Common workflows wrapped as Make targets. All commands assume you run them from the repo root.
| Target | What it does |
|---|---|
make build |
Runs ./Deploy.sh --build-only β Maven build, Docker build & push, patches K8s manifest and Helm chart values.yaml tag. No deploy. |
make deploy |
Recreates the local k3d cluster, then runs ./Deploy.sh --build (full pipeline including kubectl apply + port-forward). |
make run |
Runs ./Deploy.sh β skips build, just applies the current K8s manifests and port-forwards. |
make delete |
kubectl delete -f infra/kubernetes/App/Deployment.yaml --ignore-not-found. |
make helm-install |
helm install dockerpoc ./infra/helm/dockerpoc-app. |
make helm-delete |
helm delete dockerpoc (ignores absent release). |
make helm-redeploy |
helm delete + helm install + port-forward in one shot. |
make helm-package |
helm lint + helm package β dist/dockerpoc-app-<version>.tgz (dist/ is gitignored). |
make port-forward |
kubectl port-forward svc/ingress-nginx-controller 8005:80 -n ingress-nginx. |
Deploy.sh accepts an optional flag:
./Deploy.sh # Steps 4-6 only: kubectl apply + port-forward (no build)
./Deploy.sh --build # Steps 1-3b then 4-6: full build + push + patch + deploy
./Deploy.sh --build-only # Steps 1-3b only: build + push + patch β no kubectlStep 3 patches the image tag in infra/kubernetes/App/Deployment.yaml; Step 3b patches tag: in infra/helm/dockerpoc-app/values.yaml. After make build you can make helm-install and the chart will pull the freshly-built image.
-
Build the Docker Image:
docker build -f infra/docker/Dockerfile -t dockerpoc-1 .The build context stays at the repo root so the Dockerfile's
COPY target/dockerpoc-1.jarandCOPY infra/docker/nginx/paths resolve correctly. -
Run the Docker Container:
docker run -p 8005:8005 \ -e SPRING_PROFILES_ACTIVE=dev \ dockerpoc-1
The app listens on port 8005 inside the container (
server.portinapplication.yml). Thedevprofile uses CONSOLE-only logging and the in-memory H2 datasource; switch toprodfor the Aiven Postgres datasource and rolling file logs.
Kubernetes manifests are located in the infra/kubernetes directory.
-
Apply the Manifests:
kubectl apply -f infra/kubernetes/
This command applies all the Kubernetes configuration files in the
infra/kubernetesdirectory to your connected Kubernetes cluster. -
Verify the Deployment:
kubectl get pods kubectl get services
Check the status of your pods and services to ensure the application is running correctly.
The Helm chart for this project is located in the infra/helm/dockerpoc-app directory.
-
Add the Helm Repository (if hosted): If you have hosted your Helm chart in a repository, you can add it using:
helm repo add my-repo https://your-helm-repo-url helm repo update
-
Install the Helm Chart:
make helm-install # or: helm install dockerpoc ./infra/helm/dockerpoc-appThe chart is installed under release name
dockerpoc. After amake buildrun the chart's image tag has already been patched, so it pulls the freshly-pushed image. -
Package the chart for distribution:
make helm-package
This lints the chart and writes
dist/dockerpoc-app-<version>.tgz. Thedist/directory is gitignored. -
Uninstall the Helm Chart:
make helm-delete # or: helm uninstall dockerpoc
Terraform files are located in the infra/terraform directory. While the current configuration might be minimal, the intention is to use Terraform for provisioning infrastructure.
-
Initialize Terraform:
cd infra/terraform terraform init -
Review the Plan:
terraform plan
This command shows you the changes Terraform will make to your infrastructure.
-
Apply the Configuration:
terraform apply
This command applies the Terraform configuration to provision the resources.
Logging is driven by src/main/resources/logback-spring.xml (Spring Bootβaware naming so <springProfile> blocks activate). Behaviour by profile:
| Profile | Appenders attached to root + com.learning.docker |
|---|---|
dev |
CONSOLE only (coloured pattern, no file written) |
prod |
CONSOLE + rolling FILE β logs/dockerpoc.log, daily rollover, 100 MB/file, 30-day retention, 1 GB cap |
other (default, test, β¦) |
No custom root logger; Spring Boot's default config applies |
Set the profile via:
java -Dspring.profiles.active=prod -Ddb.password=<password> -jar target/dockerpoc-1.jar
# or, in container env vars: SPRING_PROFILES_ACTIVE=prodThe Dockerfile bakes -Dspring.profiles.active=prod into JAVA_OPTS, so images built via make build default to prod logging + Postgres.
Once the application is deployed, you can typically access it through a Service (Kubernetes) or by port-forwarding to a pod. Refer to the specific deployment method's documentation for details.
- API Endpoints: The Spring Boot application exposes various REST endpoints.
- Actuator Endpoints: Monitoring information is available via Spring Boot Actuator (e.g.,
/actuator/health,/actuator/metrics). - Swagger UI: API documentation is available through Swagger UI (commonly
/swagger-ui.html, depending on your configuration).
Deeper operator guides live under docs/:
- docs/build-and-deploy.md β pipeline internals (Deploy.sh stages, image tag synchronisation, Make targets, Helm flows, profile-aware logging, troubleshooting).
- docs/push-chart-to-local-chartmuseum.md β 5-minute local-dev setup for pushing this chart to a basic-auth-protected ChartMuseum on your Mac (used to exercise KubeVela's HTTPS chart-fetch auth path).
- docs/helm-terraform.md β reference for combining Helm with Terraform-managed infrastructure.
- docs/remote-debugging.md β JDWP remote debugging walkthrough into a pod from IntelliJ.
This project is designed as a learning tool. Feel free to explore the code and configurations to understand how the different technologies are integrated. Experiment with different deployment strategies, modify the application, and observe the impact on the deployment process.
As this is a personal learning project, contributions are not actively sought, but you are welcome to fork the repository and use it for your own learning purposes.
This project is licensed under the MIT License.
Thanks to the open-source communities of Spring Boot, Docker, Kubernetes, Helm, and Terraform for providing these incredible tools.