I used to think an MVP was almost finished when the main feature worked.
The API responded.
The UI did what I wanted.
The application started without errors.
On localhost, everything looked fine.
Then I tried to deploy it.
That was when I realized I had been checking whether my application worked, not whether it was actually ready to leave my machine.
Ports behaved differently.
Environment variables mattered.
A service I had casually called through localhost suddenly didn't exist anymore.
Something could deploy successfully and still not be usable.
That experience changed the way I look at the last part of an MVP.
Now, before I consider a Spring Boot project ready to ship, these are the things I check.
- Does the project build from a clean state?
This sounds obvious.
But during development, an IDE can hide a surprising amount of context.
Cached dependencies, local configuration files, already-running services, and files that were never committed can all make a project look healthier than it really is.
Before shipping, I want this to work without relying on my current IDE session.
./gradlew clean build
If the clean build fails, deployment is not my first problem yet.
- Are the tests actually running?
A green build doesn't mean much if the tests I expected were never executed.
I check the test output instead of only looking at:
BUILD SUCCESSFUL
For a small MVP, I may not have a huge test suite.
That's fine.
But I still want to know exactly what was tested and what was not.
- Can the application start without my IDE?
This was one of those things I underestimated.
During development, pressing the Run button in IntelliJ becomes normal.
Production doesn't have an IntelliJ Run button.
So I try starting the built application directly.
java -jar build/libs/app.jar
This often reveals configuration assumptions that were invisible during normal development.
- Is anything hardcoded to localhost?
This one hit me directly.
Locally, code like this feels completely normal:
or:
But localhost always means:
this machine
Once the application moves to another environment, "this machine" is no longer my laptop.
That sounds obvious now.
It wasn't always obvious while I was building.
So before deployment, I search the project for things like:
localhost
127.0.0.1
and ask whether each one still makes sense outside my development machine.
- Is the application port configurable?
Locally, I normally used a fixed Spring Boot port.
Then deployment platforms forced me to think differently.
Instead of assuming:
server.port=8080
I prefer something like:
server.port=${PORT:8080}
Locally, it still runs on 8080.
In an environment like Railway, the platform can provide the actual port.
One small configuration change removed an assumption I didn't even know I had.
- Are secrets outside the repository?
API keys and credentials should not live inside source code.
That includes things like:
API keys
database passwords
access tokens
private credentials
I now treat environment configuration as part of the deployment itself, not something to think about after deployment.
A project that only works because my local .env file happens to exist isn't ready yet.
- Do I know every external dependency the application needs?
A Spring Boot application rarely lives alone.
Mine started depending on things outside the JVM:
a database, external APIs, AI services, storage, and other processes.
Locally, those dependencies were already there.
Production started asking a more useful question:
What does this application need in order to stay alive?
Writing those dependencies down helped more than I expected.
- Can production actually reach those dependencies?
Knowing that a dependency exists isn't enough.
The deployed application also needs to reach it.
For every important dependency, I check things like:
host
port
credentials
network access
timeout
production URL
This is especially important when something worked locally because another service was running on the same machine.
- Do I know what configuration is different in production?
Local and production environments are never completely identical.
The dangerous part is not that they are different.
The dangerous part is forgetting how they are different.
I want to know which values change between environments.
Not every value needs to be documented in a massive configuration system.
But I should at least know what I'm changing.
- Do I know which commit is actually deployed?
This sounds boring until something breaks.
If I deploy several times while fixing an issue, I eventually need to answer:
Which version is running right now?
"I think it's the latest one" is not a great answer.
At minimum, I want the commit SHA or release point associated with the deployment.
That single piece of information makes debugging much less vague.
- Does a health check pass after deployment?
A successful deployment message is useful.
But:
Deployment successful
does not mean:
Application verified
I want the running service to prove that it is alive.
Even a simple health endpoint is better than relying entirely on the deployment platform saying the container started.
- Did I test the actual critical user flow?
This was another mindset change for me.
A server being alive doesn't mean the product works.
If the important flow is:
Upload
→ Analyze
→ Process
→ Return result
then I want to test that exact flow in the deployed environment.
Not only /health.
Not only the home page.
The part the user actually came for.
- Do I know where the logs are?
When something fails locally, I immediately see the console.
When something fails in production, the first question becomes:
Where did the error go?
Before shipping, I now make sure I know how to find the application logs.
It sounds like a tiny operational detail.
But the first production error becomes much less stressful when I already know where to look.
- Do I have a rollback point?
For my early MVPs, I mostly thought about one direction:
build → deploy → done
Now I also think about the reverse direction.
deploy → something breaks → ?
I don't need an enterprise-grade rollback system for every small MVP.
But I do want to know:
what the previous working version was
whether I can redeploy it
whether database or configuration changes prevent rollback
A release without a way back is more fragile than it needs to be.
- What is still NOT VERIFIED?
This might be the most useful question on the list.
Especially when using AI.
I use AI constantly while developing now.
It helps me review code, inspect configuration, find possible deployment problems, and think through things I missed.
But I noticed a dangerous pattern.
I could ask:
Is this application production-ready?
and get a very convincing answer.
The problem is that AI can reason about the information I gave it.
It cannot magically verify a production environment it has never seen.
So I started separating these three things:
VERIFIED
INFERRED
NOT VERIFIED
For example:
Build passed
→ VERIFIED
This environment variable appears to be configured correctly
→ INFERRED
Production database connection works
→ NOT VERIFIED until tested
That distinction became much more valuable than asking for a generic "production readiness score."
Confidence is not evidence
This is probably the biggest thing I learned while turning an MVP into something I could actually deploy.
A project can feel finished.
AI can say the configuration looks good.
The deployment platform can show a green status.
None of those things automatically prove that the release works.
What I want now is evidence.
Did the build run?
Did the application start?
Did the health check pass?
Did the critical flow work?
Which commit was tested?
What still needs verification?
That is a much more useful definition of "ready" for me.
I turned this into a checklist
While working through these problems, I started writing the checks down instead of trying to remember them every time.
I eventually turned the lightweight version into a free GitHub checklist:
👉 Spring Boot Release Checklist — Free on GitHub
It includes the main release blockers and an evidence-based way to review them.
If that is enough for your project, use it.
I also made a more detailed 58-page runbook for developers who want a repeatable workflow with evidence fields, failure actions, AI review prompts, deployment checks, and rollback guidance:
👉 Ship Your Spring Boot MVP — Full 58-Page Runbook
I originally started writing all of this because my application worked perfectly on localhost.
Deployment was what showed me how many assumptions localhost had been hiding.
Top comments (0)