Deploying a minimal flask app in docker - server connection issues
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
The most common reason a minimal Flask app works inside Docker but cannot be reached from the host is network binding. Inside a container, binding Flask to 127.0.0.1 only exposes it inside that container, so Docker port publishing will not help unless the app listens on 0.0.0.0.
Build the Minimal App Correctly
Start with a tiny Flask app that explicitly listens on all container interfaces:
A matching Dockerfile can be:
And then run:
Now the app should be reachable at http://localhost:5000.
Why 127.0.0.1 Breaks It
This is the core networking mistake:
- '
127.0.0.1means "listen only on loopback"' - inside Docker, that loopback belongs to the container itself
- the host cannot reach a service that only listens on the container's loopback
Binding to 0.0.0.0 tells Flask to listen on all interfaces inside the container, which allows Docker's published port to forward traffic correctly.
That is why changing only the Docker -p option is not enough if the Flask process itself is still bound to the wrong address.
Check the Whole Path
If the app is still unreachable, debug in order:
- is the container running
- is Flask listening on
0.0.0.0:5000 - did you publish the port with
-p - are you connecting to the correct host port
Useful commands:
Inside the container, you can test the app locally. If it works there but not from the host, the problem is usually port publishing or firewall policy. If it does not work inside the container either, the application process itself is the problem.
Another subtle source of confusion is Docker Desktop, remote Docker daemons, or cloud VMs. In those setups, localhost in your browser may not refer to the machine actually running the container, even when the container itself is configured correctly.
Do Not Confuse Development and Production
For a minimal demo, Flask's built-in server is fine. For a production container, you would normally use a WSGI server such as Gunicorn instead of relying on Flask's development server.
That does not change the core connection lesson, though. Whether you run Flask directly or behind Gunicorn, the service still must listen on the correct interface and port inside the container.
So even after upgrading the server stack, keep the same debugging order: prove the process is listening inside the container first, then prove the container port is published outward.
Common Pitfalls
- Binding Flask to
127.0.0.1inside the container. - Forgetting
docker run -p hostPort:containerPort. - Assuming
EXPOSEalone publishes the port. It does not. - Debugging Docker networking first when the Flask process is not even listening correctly inside the container.
- Assuming
localhostalways points at the same machine even when Docker is running remotely.
Summary
- The usual Docker connection issue for minimal Flask apps is incorrect host binding inside the container.
- Flask must listen on
0.0.0.0, not only on127.0.0.1. - Docker must publish the correct port with
-p. - Test both inside the container and from the host to isolate the failure.
- For real deployments, use a production WSGI server, but the networking principle stays the same.

