Home > Enterprise >  How do I run uvicorn in a docker container that exposes the port?
How do I run uvicorn in a docker container that exposes the port?

Time:02-01

I am developing a fastapi inside a docker container in windows/ubuntu (code below). When I test the app outside the container by running python -m uvicorn app:app --reload in the terminal and then navigating to 127.0.0.1:8000/home everything works fine:

{
  Data: "Test"
}

However, when I docker-compose up I can neither run python -m uvicorn app:app --reload in the container (due to the port already being used), nor see anything returned in the browser. I have tried 127.0.0.1:8000/home, host.docker.internal:8000/home and localhost:8000/home and I always receive:

{
   detail: "Not Found"
}

What step am I missing?

Dockerfile:

FROM python:3.8-slim

EXPOSE 8000

ENV PYTHONDONTWRITEBYTECODE=1

ENV PYTHONUNBUFFERED=1

COPY requirements.txt .
RUN python -m pip install -r requirements.txt

WORKDIR /app
COPY . /app

RUN adduser -u nnnn --disabled-password --gecos "" appuser && chown -R appuser /app
USER appuser

CMD ["gunicorn", "--bind", "0.0.0.0:8000", "-k", "uvicorn.workers.UvicornWorker", "app:app"]

Docker-compose:

version: '3.9'

services:
  fastapitest:
    image: fastapitest
    build:
      context: .
      dockerfile: ./Dockerfile
    ports:
      - 8000:8000
    extra_hosts:
      - "host.docker.internal:host-gateway"

app.py:

from fastapi import FastAPI

app = FastAPI()

@app.get("/home") #must be one line above the function fro the route
def home():
    return {"Data": "Test"}

if __name__ == '__main__':
    import uvicorn
    uvicorn.run(app, host="127.0.0.1", port=8000)

CodePudding user response:

The issue here is that when you specify host="127.0.0.1" to uvicorn, that means you can only access that port from that same machine. Now, when you run outside docker, you are on the same machine, so everything works. But since a docker container is (at least to some degree) a different computer, you need to tell it to allow connections from outside the container as well. To do this, switch to host="0.0.0.0", and then you should be able to access your dockerized API on http://localhost:8000.

  • Related