Step 7
Step 7 — Deploy
1 views
Table of contents
If your code only runs on your laptop, it doesn't exist. Wrap it as a Docker image so it runs the same anywhere.
Dockerfile
FROM gradle:8.10-jdk21 AS builder
WORKDIR /app
COPY . .
RUN gradle bootJar --no-daemon
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
COPY --from=builder /app/build/libs/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
bootJar is Spring's fat jar. Multi-stage shrinks the final image to ~1/3.
📌 Spring Boot 4 note:
java -Djarmode=tools ... extract --layersfor the four-layer split can have compatibility issues. If the standard directories are empty and content lands in<artifact>-<version>/, the JarLauncher classpath breaks. For now use a singleCOPY *.jar app.jar+ENTRYPOINT ["java", "-jar", "app.jar"], then verify again on a newer Boot version.
docker-compose with DB
services:
postgres:
image: postgres:17-alpine
environment:
POSTGRES_DB: mydb
POSTGRES_USER: user
POSTGRES_PASSWORD: secret
volumes: [pg-data:/var/lib/postgresql/data]
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user"]
interval: 5s
app:
build: .
depends_on: { postgres: { condition: service_healthy } }
environment:
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/mydb
SPRING_DATASOURCE_USERNAME: user
SPRING_DATASOURCE_PASSWORD: secret
ports: ["8080:8080"]
volumes:
pg-data:
docker compose up -d — DB and app together.
Pre-deploy checklist
- ✅
application-prod.ymlseparated - ✅
actuator/healthexposed - ✅
DockerfileHEALTHCHECK - ✅ Caddy / Nginx for HTTPS
- ✅ Automated DB backups (cron or admin UI)
Caddy = HTTPS in one line
api.example.com {
reverse_proxy app:8080
}
Caddy fetches Let's Encrypt certs automatically.
Try it
Add the Dockerfile + docker-compose.yml to your project, run docker compose up -d --build, and visit http://localhost:8080/api/posts.
Going deeper
Next
Course complete. Try devops-cloud (cloud deployment) or python-data-pipeline (data flows).