Flask
Docker
Deployment
Server Issues
App Development

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:

python
1from flask import Flask
2
3app = Flask(__name__)
4
5@app.route("/")
6def home():
7    return "hello from flask"
8
9if __name__ == "__main__":
10    app.run(host="0.0.0.0", port=5000)

A matching Dockerfile can be:

dockerfile
1FROM python:3.12-slim
2
3WORKDIR /app
4COPY requirements.txt .
5RUN pip install --no-cache-dir -r requirements.txt
6
7COPY app.py .
8EXPOSE 5000
9
10CMD ["python", "app.py"]

And then run:

bash
docker build -t flask-demo .
docker run -p 5000:5000 flask-demo

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.1 means "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:

  1. is the container running
  2. is Flask listening on 0.0.0.0:5000
  3. did you publish the port with -p
  4. are you connecting to the correct host port

Useful commands:

bash
docker ps
docker logs <container-id>
docker exec -it <container-id> sh

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.1 inside the container.
  • Forgetting docker run -p hostPort:containerPort.
  • Assuming EXPOSE alone publishes the port. It does not.
  • Debugging Docker networking first when the Flask process is not even listening correctly inside the container.
  • Assuming localhost always 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 on 127.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.

Course illustration
Course illustration

All Rights Reserved.