Home > OS >  Docker containers crashed: /bin/sh: 1: [uvicorn,: not found
Docker containers crashed: /bin/sh: 1: [uvicorn,: not found

Time:12-10

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.

CodePudding user response:

Note: You don't need to do docker build -t fastapi . manually. Docker-compose will do it for you (because you set build: .) But! You must run up 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 and CMD

Here is three forms for CMD:

  • CMD ["executable","param1","param2"] (exec form, preferred)
  • CMD ["param1","param2"] (sets additional default parameters for ENTRYPOINT in exec form)
  • CMD command param1 param2 (shell form)

According error, looks like Docker interpreting CMD as a shell form or additional parameters for default ENTRYPOINT

Actually still not sure why it happens, but changing CMD to

CMD uvicorn app.main:app --host 0.0.0.0 --port 8000

or

ENTRYPOINT ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

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 why CMD is interpreted as parameters instead of command.

PS In addition here is note from docker docs:

Note
The exec form is parsed as a JSON array, which means that you must use double-quotes (“) around words not single-quotes (‘).

So exec form syntax must meet the conditions of JSON syntax.

CodePudding user response:

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

docker-compose down

and then

docker-compose up -t

I think that command was not taking the changes into consideration.

then i ran:

docker-compose up --build

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:

docker build .
docker-compose up -t

and it worked fine again.

So basically instead of using creating new image it was using the old one which was not created correctly:

docker-compose up --build

In short you should use docker-compose up --build whenever you make changes in your dockerfile or docker-compose.yml instead of docker-compose up -t

It might be confusing but I am also very new to Docker.

Thanks for the help everyone!

  • Related