pythondockerpackagepython-venvpython-poetry

ModuleNotFoundError when running docker and poetry


I am running into an error when trying to run my container where it is saying it can't find a module while trying to import. Specifically:

ModuleNotFoundError: No module named 'sentry_sdk'

The following is my DockerFile which is a multistage build, it seems to install all the packages according to the console output.

###############################################
# Base Image
###############################################
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9 as python-base

ENV PYTHONUNBUFFERED=1 \
    PYTHONDONTWRITEBYTECODE=1 \
    PIP_NO_CACHE_DIR=off \
    PIP_DISABLE_PIP_VERSION_CHECK=on \
    PIP_DEFAULT_TIMEOUT=100 \
    POETRY_VERSION=1.1.13 \
    POETRY_HOME="/opt/poetry" \
    POETRY_VIRTUALENVS_IN_PROJECT=true \
    POETRY_NO_INTERACTION=1 \
    PYSETUP_PATH="/opt/pysetup" \
    VENV_PATH="/opt/pysetup/.venv"

# prepend poetry and venv to path
ENV PATH="$POETRY_HOME/bin:$VENV_PATH/bin:$PATH"

###############################################
# Builder Image
###############################################
FROM python-base as builder-base

# install poetry - respects $POETRY_VERSION & $POETRY_HOME
RUN curl -sSL https://install.python-poetry.org | python3 -

# copy project requirement files here to ensure they will be cached.
WORKDIR $PYSETUP_PATH
COPY pyproject.toml ./

# install runtime deps - uses $POETRY_VIRTUALENVS_IN_PROJECT internally
RUN poetry install --no-dev

###############################################
# Production Image
###############################################
FROM python-base as production
COPY --from=builder-base $PYSETUP_PATH $PYSETUP_PATH
COPY . .
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]

The start of my main file is the following:

from logging import getLogger
from os import environ
from typing import List

from fastapi import FastAPI
from starlette.status import HTTP_200_OK
from sentry_sdk import init as SentryInit
from sentry_sdk.integrations.asgi import SentryAsgiMiddleware
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration

It is failing on the line:

from sentry_sdk import init as SentryInit

This is the first line where the package is not a default install on the container, so this may be related to the venv but I am not sure why or how.

My pyproject.toml looks like this:

[tool.poetry]
authors = ["xxx"]
name = "xxx"
description = "xxx"
version = "xxx"

[tool.poetry.dependencies]
asyncpg = "^0.21.0"
fastapi = "^0.73.0"
pydantic = "^1.9.0"
python = "^3.8.7"
sqlalchemy = "^1.3.22"
databases = "^0.5.5"
sentry-sdk = "^1.5.5"

[tool.poetry.dev-dependencies]
pytest = "^3.4"
httpx = "^0.22.0"

[build-system]
build-backend = "poetry.core.masonry.api"
requires = ["poetry-core>=1.0.0"]

Solution

  • OK I figured it out and now I feel dumb.

    The issue was indeed related to the venv, basically, uvicorn is installed on the base image but not in my pyproject.toml. So poetry didn't install it in the venv. When I started the app in the Dockerfile using CMD it couldn't find uvicorn in the venv so went to the base install and ran from there. When I added uvicorn to the venv it all worked fine.