skip to Main Content

I am learning docker and try to dockerize a simple fastapi app.
Here is my docker file

FROM python:3.8-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt -U --no-cache-dir

COPY fast.py .

CMD [ "uvicorn","fast:app","--host","127.0.0.1","--port","8000" ]

Every thing work well when i build and run. I can see packages getting installed.
I can also see uvicorn running
Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
but when i click on url. It say Unable to connect in browser.

I think there is an issue with my dockerfile, but i am unable to figure it out
Edit:
docker build command
docker build -t fastapi .
and docker run command
docker run fastapi
I am not using docker compose.
Here is result of docker ps -a
enter image description here

Full code structure
-Dockerfile
-fast.py
-requirements.txt

Here is code of fast.py

from typing import Union
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
    return {"Hello": "World"}

What I have tried. I added EXPOSE 8000 in Dockerfile and also tried docker run -p 8000:8000 fastapi But nothing work

3

Answers


  1. You did not exposed the port on your dockerfile,

    FROM python:3.8-slim
    WORKDIR /app
    COPY requirements.txt .
    RUN pip install -r requirements.txt -U --no-cache-dir
    
    COPY fast.py .
    
    EXPOSE 8000
    
    CMD [ "uvicorn","fast:app","--host","127.0.0.1","--port","8000" ]
    

    Make sure to remove the container and build the image again.

    Also, make sure you expose the port on your host in your docker run command.

    docker run -p 8000:8000 fastapi
    

    The left 8000 will be the host (your computer) and the right one will be the destination (the container itself)

    Login or Signup to reply.
  2. According to the picture posted it seems like you didn’t expose the ports.

    The ports are exposed from your docker to your pc, in this instance, when you iniate the container not in the Dockerfile

    Try the following

    docker run -p 8000:8000 fastapi
    

    EDIT

    You also should try changing the way you start the fast api app in the container

    From

    CMD [ "uvicorn","fast:app","--host","127.0.0.1","--port","8000" ]
    

    To

    CMD [ "uvicorn","fast:app","--host","0.0.0.0","--port","8000" ]
    

    In the first version you have passed the loopback interface.

    But you can’t do that. The loopback interface inside a container means "only this container", just like on the host means "only this host". If a service is binding to 127.0.0.1 then there is no way — from your host or from another container — to reach that service.

    Caveat This holds true, assuming you dont change the network settings of the container e.g. –network host

    TL;DR

    Change the host from looback interface and when you run your container expose the port 8000

    Login or Signup to reply.
  3. When you run your container, you need to specify the port you want to "publish" your app.

    docker run -p "8000:8000" fastapi
    

    The upper command instructs docker to map the host port 8000 to container port 8000.

    You can find more info in this link.

    You may find easier to use docker-compose.yml

    version: "3.8"
    services:
      fastapi:
        build: . #you can use any directory but it is recommended to be putted together with Dockerfile in the root of your project.
        ports:
          - "8000:8000" # left the (local)host port, right the Dockerfile "EXPOSE" (in this case also uvicorn ... -p xxxx) port. 
    
    

    Please read the comments as I use them in order to help you better understand the parts of docker-compose file.

    In oreder to run your app you can use:

    docker compose up -d
    

    Or

    docker-compose up -d
    

    If you are questioning yourself which version of the upper command you need to use, it depends on what kind of docker compose have you installed in your machine.

    I personally recommend the plugin version (first option), as it feels more docker native.

    EDIT: As @tolis-gerodimos suggested you need to change the listening IP from "127.0.0.1" (localhost) to "0.0.0.0" (any). This is a wide used practice in all languages/frameworks/tools as it reduces the complexity during the deployment.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search