Search code examples
pythondockerdocker-composefastapiuvicorn

Why can't docker compose find uvicorn module


I am new to docker and was trying to dockerize my fastapi application. I built a Dockerfile shown below

# syntax=docker/dockerfile:1

FROM python:3.8-slim-buster

WORKDIR /app

COPY requirements.txt requirements.txt

RUN apt-get update
RUN apt-get -y install libpq-dev gcc
RUN apt-get -y install libnss3-tools
RUN apt-get -y install curl
RUN curl -LJO https://github.com/FiloSottile/mkcert/releases/download/v1.4.4/mkcert-v1.4.4-linux-amd64
RUN mv mkcert-v1.4.4-linux-amd64 mkcert
RUN chmod +x mkcert
RUN ./mkcert -install
RUN ./mkcert -cert-file cert.pem -key-file key.pem 0.0.0.0 localhost 127.0.0.1 ::1

RUN pip3 install -r requirements.txt

COPY . .

CMD ["python3.8", "-m", "uvicorn", "main:app", "--host=0.0.0.0", "--ssl-keyfile=./key.pem",  "--ssl-certfile=./cert.pem"]

and ran the containers and they all worked. But when I try to combine the containers with docker compose its tells me can't find uvicorn module even when it's in the requirements.txt file . Here is a snippet of my docker compose file containing the server service.

services:

  server:
    container_name: server
    image: python:3.8-slim-buster
    command: ["python3.8", "-m", "uvicorn", "main:app", "--host=0.0.0.0", "--ssl-keyfile=./key.pem",  "--ssl-certfile=./cert.pem"]
    ports:
      - 8000:8000
    working_dir: /app

I have tried using changing the command part of the server service in docker compose to

command: bash "python3.8 -m uvicorn main:app --host=0.0.0.0 --ssl-keyfile=./key.pem  --ssl-certfile=./cert.pem"

didn't work. changed it to

command: sh -c "python3.8 -m uvicorn main:app --host=0.0.0.0 --ssl-keyfile=./key.pem  --ssl-certfile=./cert.pem"

didn't work.

I removed the command totally it still didn't work, keeps showing

server | /usr/local/bin/python3.8: No module named uvicorn
server exited with code 1


Solution

  • The image you use in the docker compose is not the one previously built in the Dockerfile but a basic Python image.
    You could build the image from your Dockerfile

    docker build .  -t fastapi
    

    then modify your docker-compose.yml file with something like this

    services:
      api:
        image: fastapi
        ports:
          - "8000:8000"
    

    then run docker compose

    docker-compose -f docker-compose.yml up