0

I have a simple FastAPI project called toyrest that runs a trivial API. The code looks like this.

from fastapi import FastAPI

__version__ = "1.0.0"

app = FastAPI()


@app.get("/")
def root():
    return "hello"

I've built the usual Python package infrastructure around it. I can install the package. If I run uvicorn toyrest:app the server launches on port 8000 and everything works.

Now I'm trying to get this to run in a Docker image. I have the following Dockerfile.

# syntax=docker/dockerfile:1

FROM python:3

# Create a user.
RUN useradd --user-group --system --create-home --no-log-init user
USER user
ENV PATH=/home/user/.local/bin:$PATH

# Install the API.
WORKDIR /home/user
COPY --chown=user:user . ./toyrest
RUN python -m pip install --upgrade pip && \
    pip install -r toyrest/requirements.txt
RUN pip install toyrest/ && \
    rm -rf /home/user/toyrest


CMD ["uvicorn", "toyrest:app"]

I build the Docker image and run it, forwarding port 8000 to the running container.

docker run -p 8000:8000 toyrest:1.0.0
INFO:     Started server process [1]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

When I try to connect to http://127.0.0.1:8000/ I get no response.

Presumably I am doing the port forwarding incorrectly. I've tried various permutations of the port forwarding argument (e.g. -p 8000, -p 127.0.0.1:8000:8000) to no avail.

This is such a basic Docker command that I can't see how I'm getting it wrong, but somehow I am. What am I doing wrong?

W.P. McNeill
  • 16,336
  • 12
  • 75
  • 111
  • 2
    The app is listening on the loopback interface, inside the container. You cannot expose this by publishing a port. You need to bind to the private network interface, preferably using 0.0.0.0. – The Fool Aug 23 '22 at 14:41

1 Answers1

1

try to add this line to yourCMD in ̀dockerfile`:

CMD ["uvicorn", "toyrest:app","--host", "0.0.0.0"]
Mouad Slimane
  • 913
  • 3
  • 12
  • 1
    Please explain what you are doing and why. – The Fool Aug 23 '22 at 14:39
  • Thanks. Adding "--host 0.0.0.0" to the CMD works. Why is it necessary though? – W.P. McNeill Aug 23 '22 at 14:40
  • well I m not very good in docker but as i know the docker container have his own network so the `uvicorn` server inside the docker re listening to the docker nertwork `localhost` so when you try to communicate with the `uvicorn` from outside the container you re not using the same `localhost` runing `uvicorn`on `0.0.0.0` can solve the problem you can check this answer https://stackoverflow.com/a/20778887/18317391 – Mouad Slimane Aug 23 '22 at 14:48