1
0 Comments

60% of Flask deployments on my platform were failing — and it was my fault

60% of Flask deployments on my platform were failing — and it was my fault


I built a container hosting platform. Users connect a GitHub repo, the platform auto-detects the framework, generates a Dockerfile, and deploys. Simple in theory.


Except Flask deploys were failing at a 60% rate. And I couldn't figure out why.


The symptom


Users would push a Flask app. The build would succeed. The container would start. Then the health check would fail, and the deployment would roll back after 15 minutes of waiting. No crash logs. No error messages. Just... silence.


What went wrong


My auto-detection code treated all Python apps the same. It read requirements.txt, saw Python dependencies, and defaulted to port 8000. Every time.


The problem: Flask defaults to port 5000. Gunicorn binds to 5000. But my generated Dockerfile said EXPOSE 8000, and the health check was hitting port 8000. Nobody was listening there.


One line. One wrong port number. 60% failure rate.


It got worse. The same bug existed for frontend frameworks. Angular, React, and Vue apps all got classified as "Node" and assigned port 3000. But those apps build to static files served by nginx on port 80. Same result — health checks hit the wrong port, deployment fails silently.


Why it took weeks to find


Three things made this invisible:


- The build always succeeded (the code compiled fine)

- The container started without errors (gunicorn was running on 5000)

- The health check failure looked like a network issue, not a port issue


I was debugging networking, load balancer configs, security groups. The actual bug was a hardcoded 8000 buried in the framework detection logic.


The fix


I rewrote the detection to actually read what's in the repo:


- requirements.txt has flask? Port 5000.

- requirements.txt has fastapi or uvicorn? Port 8000.

- package.json has angular? That's nginx on port 80, not Node on port 3000.

- Same for React and Vue — static builds, nginx, port 80.


Then I added a fast-fail mechanism. Instead of waiting 15 minutes for a failed deployment to time out, the system now detects sustained unhealthy health checks after 120 seconds and aborts early. Failure time dropped from ~15 minutes to ~3.5 minutes.


The numbers


- Flask failure rate: 60% → near 0%

- Frontend framework failures: similar fix

- Failed deployment wait time: 15 min → 3.5 min

- Root cause: 1 hardcoded port number

- Time to find: ~3 weeks

- Time to fix: 2 days


What I learned


- Auto-detection that works 80% of the time is worse than no auto-detection. The 20% that fails silently destroys trust.

- Health check failures should tell you exactly what went wrong. "Unhealthy" is not a useful error message. I now surface the expected port vs actual port in the error.

- Always test the most popular framework first. Flask is the most common Python framework on my platform. I should have caught this on day one.


If you're building any kind of deployment automation, test the happy path with real repos, not just sample apps you wrote yourself. Your sample app probably has the right port because you wrote the detection logic.


Happy to share more details on the detection architecture or the fast-fail mechanism.

posted toAvatar for product SnapDeploy
SnapDeploy