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
.