I am quite new to programming and have an error trying to lauch fastapi
project with Docker
and Poetry
.
Here is my project structure:
.
├── backend
│ ├── Dockerfile
│ ├── poetry.lock
│ ├── pyproject.toml
│ ├── src
│ │ ├── domain
│ │ │ └── __init__.py
│ │ ├── infrastructure
│ │ │ └── __init__.py
│ │ ├── __init__.py
│ │ └── presentation
│ │ ├── __init__.py
│ │ └── main.py
│ └── tests
│ └── __init__.py
├── docker-compose.yaml
└── README.md
Here is Docker file:
FROM python:3.11-slim
WORKDIR /backend
COPY . /backend
RUN pip install --upgrade pip && pip install poetry
RUN poetry install
EXPOSE 8000
and docker-compose.yaml:
services:
# PostgreSQL
db:
image: postgres
restart: always
env_file:
- backend/.env
ports:
- '5432:5432'
healthcheck:
test: [ "CMD-SHELL", "sh -c 'pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}'" ]
interval: 10s
timeout: 3s
retries: 3
# BackEnd
backend:
build:
context: backend
command: bash -c 'uvicorn src.presentation.main:app --host 0.0.0.0 --port 8000 --reload'
ports:
- '8000:8000'
volumes:
- .:/backend
restart: always
depends_on:
db:
condition: service_healthy
My pyproject.toml
:
[tool.poetry]
name = "startup"
version = "0.1.0"
description = ""
authors = ["RRoxxxsii <mishabur38@gmail.com>"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.11"
fastapi = {extras = ["all"], version = "^0.109.0"}
pytest="^7.4.4"
pytest-asyncio = "^0.23.3"
pre-commit = "^3.6.0"
sqlalchemy = "^2.0.25"
alembic = "^1.13.1"
uvicorn = "^0.25.0"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
When I start the project with docker compose up
I get the error:
bash: line 1: uvicorn: command not found
And I do not understand why, as I have uvicorn
inside poetry.lock and pyproject.toml
ok so I tried to reproduce the above,
I think there are a few things here to point out,
Poetry related
startup/
under your backend/
directorybackend/
directory, in this case the root dir of the project "startup"Docker related
.
mapped to container dir /backend
, and on top of that you have COPY . /backend
, I suspect this does a funny overwrite operation, although, I'm not 100% sure what happens there but someone more familiar with the docker mounting system would clarify it better than me.However, I got around it by changing the workdir name to something other than /backend
like /service
in the below reproducible example
docker-compose.yml
services:
# BackEnd
backend:
build:
context: backend
command: bash -c 'poetry run uvicorn startup.main:app --host 0.0.0.0 --port 8000 --reload'
ports:
- '8000:8000'
volumes:
- .:/backend
Dockerfile
FROM python:3.11-slim
WORKDIR /service
COPY . /service
RUN pip install --upgrade pip && pip install poetry
RUN poetry install
EXPOSE 8000
directory structure
.
├── backend
│ ├── Dockerfile
│ ├── pyproject.toml
│ ├── README.md
│ └── startup
│ ├── __init__.py
│ └── main.py
└── docker-compose.yaml