I am new to Docker and trying to Dockerize my FastAPI application.
First I created a Dockerfile:
FROM python:3.9.9
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
Then ran the following command:
docker build -t fastapi .
The command ran successfully.
After that I created the following docker-compose.yml:
version: "3"
services:
api:
build: .
ports:
- 8000:8000
env_file:
./.env
Then ran the following command:
docker-compose up -d
Ran successfully:
Network fastapi_default Created 0.7s
- Container fastapi_api_1 Started
Then to check if its running properly I ran the following command:
docker ps -a
And it showed that Container exited few seconds after it was created.
Then I ran this command:
docker logs fastapi_api_1
And it says:
/bin/sh: 1: [uvicorn,: not found
Not sure what is the reason. Tried some solutions that I found online but nothing worked out. I do have uvicorn in my requirements.txt file.
Help will be appriciated. Please let me know if additional information is required.
4
Answers
So, basically there was something wrong with the docker. I had created mulitple images. I removed all of them and ran the same commands again and it worked. I don't know the exact reason but its working now.
What I think was happening is that instead of deleting the old images and creating new one. I was just doing
and then
I think that command was not taking the changes into consideration.
then i ran:
and I think that created a new image and it worked.
Then I noticed that there were atleast 10 images created. I deleted all of them and ran the same commands:
and it worked fine again.
So basically instead of using creating new image it was using the old one which was not created correctly:
In short you should use
docker-compose up --build
whenever you make changes in your dockerfile or docker-compose.yml instead ofdocker-compose up -t
It might be confusing but I am also very new to Docker.
Thanks for the help everyone!
Note: You don’t need to do
docker build -t fastapi .
manually. Docker-compose will do it for you (because you setbuild: .
) But! You must runup
command with--build
parameter (docker-compose up --build
) to force rebuild image even if it exists.And about your problem:
Here is a very good article (and one more) about
RUN
,ENTRYPOINT
andCMD
Here is three forms for
CMD
:According error, looks like Docker interpreting
CMD
as a shell form or additional parameters for defaultENTRYPOINT
Actually still not sure why it happens, but changing
CMD
toor
should solve your problem
Also it will be better to use full path to
uvicorn
executable (/usr/bin/uvicorn
or where it installed by default?). It is just my opinion but, that is may be a reason whyCMD
is interpreted as parameters instead of command.PS In addition here is note from docker docs:
So
exec form
syntax must meet the conditions of JSON syntax.I’ve had the same issue with a Dockerfile in my docker-compose environment containing
So I don’t need an extra
command:
line in my docker-compose.ymlIt turned out that if you install uvicorn in your requirements.txt, as I like to do for testing purposes
then it gets installed locally, and
RUN pip install uvicorn==0.20.0
is skipped, which means,there is no
/usr/bin/uvicorn
‘executable’ available, just somewhere in site-packages andCMD
will fail.So, if you use uvicorn in your requirements.txt, and in Dockerfile as well, you can maybe
force the reinstallation
in the Dockerfile,
or set the PATH to find it somewhere in the guts of python,
or – what I find is a better solution to keep the image size small –
is to remove uvicorn from requirements.txt…
Check your
CMD
in Dockerfile. Please give asThe docs says you can use like this in CMD rather than
CMD ["uvicorn", ....]
https://docker-fastapi-projects.readthedocs.io/en/latest/uvicorn.html
Hope this works for you.