feat: Add Docker health checks, unified Docker Compose, and Traefik reverse proxy#15
Conversation
…everse proxy - Update Dockerfile with proper curl-based health check, Node 18, and custom nginx config for SPA routing - Add environment.docker.ts with relative API URL for containerized builds - Add angular.json 'docker' build configuration - Create nginx.conf with SPA fallback routing and /health endpoint - Add Traefik reverse proxy with Docker provider and ping health check - Create docker-compose.yml with three services: - reverse-proxy (Traefik v2.11) on port 80 - api-server (spring-petclinic-rest) on port 9966 - frontend (Angular/nginx) on port 8080 - All services include health checks with proper intervals/retries - Services use depends_on with service_healthy conditions - Custom bridge network (petclinic-network) for inter-service communication
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
| return 200 '{"status":"UP"}'; | ||
| add_header Content-Type application/json; |
There was a problem hiding this comment.
🟡 nginx add_header after return produces duplicate Content-Type header
In the /health location block, add_header Content-Type application/json; is placed after return 200 .... The return directive internally sets Content-Type: text/plain for text responses. The add_header directive does not replace existing headers—it appends a new one. This results in the response containing two Content-Type headers (text/plain and application/json), which is an HTTP protocol violation. Different clients may interpret this inconsistently.
The correct approach is to use default_type application/json; instead, which controls the Content-Type that return uses when generating the response.
| return 200 '{"status":"UP"}'; | |
| add_header Content-Type application/json; | |
| default_type application/json; | |
| return 200 '{"status":"UP"}'; |
Was this helpful? React with 👍 or 👎 to provide feedback.
Summary
Adds production-ready Docker infrastructure for the Spring PetClinic microservices architecture with three services orchestrated via Docker Compose and routed through a Traefik reverse proxy.
Architecture
Changes
Dockerfile— Updated to Node 18 / nginx 1.25 (alpine), replaced brokenservice nginx statushealth check withcurl-based check against/healthendpoint, added customnginx.conffor SPA routing, builds with--configuration=dockerfor relative API URLsnginx.conf— Frontend nginx config with SPAtry_filesfallback, gzip compression, static asset caching, and/healthendpointsrc/environments/environment.docker.ts— Docker-specific Angular environment using relative API URL (/petclinic/api/) so requests route through Traefikangular.json— Newdockerbuild configuration that swaps inenvironment.docker.tstraefik/traefik.yml— Traefik static config with Docker provider, ping health check, and access loggingdocker-compose.yml— Unified compose file with:reverse-proxy(Traefik v2.11) — entry point on port 80, dashboard on 8081api-server(spring-petclinic-rest) — backend REST API on port 9966frontend(Angular/nginx) — SPA on port 8080depends_onwithcondition: service_healthypetclinic-networkbridge networkHow it works
/petclinic/api/*(priority 20) →api-server:9966/(priority 10) →frontend:8080Review & Testing Checklist for Human
docker compose up --buildand verify all three services start healthy (docker compose psshould show all ashealthy)http://localhost— Angular UI should load and display owners/vets data from the APIhttp://localhost:8081— Traefik dashboard should show the configured routers and servicescurl http://localhost/petclinic/api/vetsshould return JSON vet datahttp://localhost/ownersand refresh — page should load (not 404)Notes
springcommunity/spring-petclinic-rest:latestimage is used for the backend; replace with a custom image if you have a private buildenvironment.ts(dev) andenvironment.prod.ts(prod) are unchanged — only Docker builds use the new relative URL environmentLink to Devin session: https://partner-workshops.devinenterprise.com/sessions/17abbf031f6240b3b64ddb22226759d4