Installation with pip in Docker fails to find module

Question:

I have the following in my setup.py

    entry_points={
        'console_scripts': [
            'my-app=main:run',
        ],

and my file structure is

▶ tree -L 2
.
├── Dockerfile
├── README.md
├── redis.conf
├── setup.cfg
├── setup.py
├── src
│   ├── main.py
│   ├── settings.py
│   ├── bfile.py
│   └── afile.py

and in my main.py

def run():
    actual_run()

Locally, in a virtualenv when performing

pip install -e . && my-app

it runs smoothly.

However in an image created with the following Dockerfile

FROM python:3.9-slim-buster

WORKDIR /app

COPY . .
RUN pip3 install .

CMD [ "my-app"]

I get

Traceback (most recent call last):
  File "/usr/local/bin/my-app", line 5, in <module>
    from main import run
ModuleNotFoundError: No module named 'main'

What I noticed, is that in my image, in /usr/local/lib/python3.9/site-packages/ there only the a file named my-app-0.0.1.dist-info and not a dir with the source files.

Why is that?

Asked By: pkaramol

||

Answers:

You didn’t give a minimal workable setup.py, but next could works, FYI:

Dockerfile:

FROM python:3.9-slim-buster

WORKDIR /app

COPY . .
RUN pip3 install .

CMD [ "my-app"]

setup.py:

from setuptools import setup, find_packages

setup(
    name="my-app",
    version="0.0.1",

    packages=['main'],
    package_dir={'main':'src'},
    entry_points={
        'console_scripts': [
            'my-app=main.main:run',
        ],
    }
)

src/main.py:

def run():
    print("hello world")

Execution:

# docker build -t abc:1 .
# docker run --rm abc:1
hello world

Explain:

In above, src folder will map to main module, and packages=['main'] specify the python package name which will be installed into site-packages.

In final image, the package will be located as next:

root@7b5ce63d8226:/usr/local/lib/python3.9/site-packages/main# ls
__pycache__  main.py

So, you need to use main.main:run to call your function.

Answered By: atline
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.