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
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
You did not exposed the port on your dockerfile,
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.
The left 8000 will be the host (your computer) and the right one will be the destination (the container itself)
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
EDIT
You also should try changing the way you start the fast api app in the container
From
To
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 yourcontainer
expose
the port 8000When you run your container, you need to specify the port you want to "publish" your app.
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
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:
Or
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.