Deploying and the production checklist
Everything so far has prepared for this: getting Dakiya onto the internet, running reliably, over HTTPS. This lesson ties the deployment module together — where to run a Spring Boot app, the deploy process, and a launch checklist that pulls in every production concern the course has raised. It is the last mile that turns a project into a running service.
Where to run a Spring Boot app
A Spring Boot jar (or container image) runs anywhere that runs the JVM (or Docker). The realistic options, by operational weight:
- A platform-as-a-service (Railway, Render, Fly.io, Heroku-style, or a cloud's app platform) — you push the jar or image and the platform runs it, provides HTTPS, and offers a managed PostgreSQL. Least operational work, fastest to launch — the sensible default for a small team, so you spend time on the app, not on servers.
- A container platform (Kubernetes, ECS, Cloud Run) — for scale and orchestration; more power, more complexity. Right when you have many services or need fine-grained scaling.
- A plain VM/server — you install Java (or Docker), run the jar behind a reverse proxy (Nginx), and manage HTTPS, updates and monitoring yourself. Most control, most ongoing work.
The cost-and-effort-conscious default for a service like Dakiya is a platform-as-a-service with a small managed PostgreSQL — HTTPS and backups handled, no server to babysit — moving to a container platform only when scale demands it.
HTTPS is mandatory
Every production API must be served over HTTPS — it encrypts traffic so credentials, JWTs and data cannot be read in transit, and it is required for secure cookies and any token-based auth to be safe. Today it is free and usually automatic:
- On a platform-as-a-service, HTTPS is typically provisioned and renewed for you when you add a domain — you do nothing.
- On your own server, use Let's Encrypt (via Certbot or the reverse proxy) for free, auto-renewing certificates, terminating TLS at the proxy in front of the app.
When the app runs behind a TLS-terminating proxy, set server.forward-headers-strategy=framework (or the
platform's equivalent) so Spring sees the original https scheme and client IP. HTTPS is not optional for a
real API, and there is no longer any excuse to skip it.
The deploy process
However you host, a deploy runs a repeatable sequence — automated (a CI/CD pipeline), not hand-typed:
- Build —
./mvnw package(orbuild-image) produces the jar/image; run the tests as part of the build so a failing test blocks the deploy. - Migrate — Flyway runs pending migrations against the production database (on startup, or as a separate step). Plan destructive migrations carefully.
- Deploy — push the image/jar and start it, with production configuration and secrets fed as
environment variables (
SPRING_PROFILES_ACTIVE=prod,DATABASE_URL, secrets). - Health-check — the platform waits for
/actuator/healthto report UP (readiness) before sending traffic; a failed startup does not receive requests. - Roll forward/back — because you deploy one built artifact, rolling back is redeploying the previous image — fast and reliable.
Automating this makes deploys boring and repeatable, which is exactly what you want; a deploy you run by remembering commands is one you eventually get wrong.
The launch checklist
Before declaring Dakiya live, confirm — this is the whole course's production concerns in one list:
- Profile —
SPRING_PROFILES_ACTIVE=prod; production settings loaded. - Database — real PostgreSQL (not H2),
ddl-auto=validate, Flyway managing the schema, and tested backups (a courier's data is irreplaceable). - Secrets — DB password, JWT secret, keys from environment/secrets manager; none committed.
- HTTPS — enabled (platform or Let's Encrypt), forward-headers configured; secure cookies if session-based.
- Security — object-level authorisation enforced, entities not exposed (DTOs), no stack traces to
clients (
include-stack-trace=never); the security module's checklist clear. - Observability —
/actuator/healthwired to the platform's health check; metrics exposed (secured); logs to stdout, INFO level, error tracking configured. - Performance — no known N+1 on hot paths; pagination on list endpoints; indexes on filtered columns.
- Tests green — the suite (unit, slice, integration) passes in the build.
- Verify the live service — actually call the deployed API over HTTPS (create a parcel, fetch it,
hit
/actuator/health) rather than assuming the deploy worked.
That last item is the habit that catches surprises: a deploy succeeding is not the same as the service working — call the live endpoints and confirm. Work down the checklist and going live becomes a verified, unremarkable step, which is what a good deployment should be. Every item traces to a lesson in this course; running the checklist is applying the whole course at once.
Check your work
Where to run it. Platform-as-a-service (least ops, sensible default — HTTPS + managed Postgres handled), container platform (scale/orchestration), or a plain VM (most control/ops). Default: PaaS + small managed PostgreSQL.
HTTPS. Mandatory (encrypts credentials/tokens/data; required for secure auth); free and usually
automatic (platform-provisioned or Let's Encrypt); set forward-headers-strategy behind a TLS-terminating
proxy.
Deploy process. Build+test → migrate (Flyway) → deploy with env-var config/secrets → health-check
(/actuator/health readiness before traffic) → roll back by redeploying the previous artifact. Automated,
not hand-typed.
Launch checklist. Prod profile; real Postgres + validate + Flyway + tested backups; secrets
externalised; HTTPS + forward headers; security (object-level auth, DTOs, no stack traces); observability
(health check wired, metrics, logs); performance (no N+1, pagination, indexes); tests green; and verify the
live service, not assume.
Practice
- Run the packaged jar with production-style env vars (
SPRING_PROFILES_ACTIVE=prod, aDATABASE_URL) and confirm it starts against a real (or containerised) Postgres. - Deploy Dakiya to a platform-as-a-service (or describe the exact steps): push the image, add a domain, confirm HTTPS is provisioned.
- Configure
forward-headers-strategyand confirm Spring seeshttpsbehind a proxy. - Write a deploy pipeline that runs build → tests → migrate → deploy → health-check in order.
- Configure a database backup and restore it to prove it works.
- Run the full launch checklist against a deployed Dakiya, finishing by calling the live API over HTTPS and
/actuator/health— verifying, not assuming, it works.
Official documentation
- Spring Boot — Deploying Spring Boot applications — Deployment options and the built artifact.
- Spring Boot — Running behind a proxy (forward headers) —
forward-headers-strategyfor HTTPS behind a proxy. - Let's Encrypt — Free, automated HTTPS.
Next: the capstone brief — a courier and parcel-tracking API.
Stuck on this lesson?
Being stuck is part of it — but being stuck alone for three days is not. Our internship programme pairs this curriculum with code review and one-to-one help from working developers, and it is free.
About the internship