Reputation: 2698
I want to create a Docker image for a package that provides a CLI tool. My image works if I install the package from our pypi server but it doesn't work if I install it from source. Installing from source is required to enable the developer to test his code in a container before publishing a new release.
# Building is done using
# docker build . --build-arg PIPCONTENT="`cat ~/.pip/pip.conf | base64 `" -t tmw:latest
#
FROM python:3.6-slim as base
RUN mkdir /app
WORKDIR /app
# this is our first build stage, it will not persist in the final image
FROM base as intermediate
RUN apt-get update && apt-get install -y \
build-essential \
&& rm -rf /var/lib/apt/lists/*
## contains credentials
ARG PIPCONTENT
RUN mkdir -p /root/.pip/ && echo ${PIPCONTENT} | base64 -d > /root/.pip/pip.conf
COPY requirements.txt /app/
RUN pip install -r requirements.txt
COPY setup.py MANIFEST.in tagger_model_workbench /app/
# doesn't create /usr/local/lib/python3.6/site-packages/tagger_model_workbench
#RUN python setup.py sdist
#RUN pip install dist/*.tar.gz
# TeamCity: python setup.py sdist && twine upload --verbose -r pypicloud dist/*
# does create /usr/local/lib/python3.6/site-packages/tagger_model_workbench
RUN pip install tagger-model-workbench
# build final image
#FROM base
#COPY --from=intermediate /usr/local /usr/local
EXPOSE 8050
ENTRYPOINT ["tagger-model-workbench", "0.0.0.0", "8050"]
Here is the setup.py:
import os
from setuptools import setup, find_packages
def get_install_requires():
with open(os.path.join(os.path.dirname(__file__), "requirements.txt")) as f:
return [line for line in map(str.strip, f) if line and not line.startswith('-') and not line.startswith("git+")]
setup(
name='tagger_model_workbench',
version='0.2.4',
packages=find_packages(include=("tagger_model_workbench", "tagger_model_workbench.*",)),
url='',
license='',
author='',
author_email='',
description='',
install_requires=get_install_requires(),
entry_points={
'console_scripts': ['tagger-model-workbench=tagger_model_workbench.app.main:main'],
}
)
Running the container with the python setup.py sdist && pip install dist/*.tar.gz
option causes this error message:
tmw_1 | Traceback (most recent call last):
tmw_1 | File "/usr/local/bin/tagger-model-workbench", line 6, in <module>
tmw_1 | from tagger_model_workbench.app.main import main
tmw_1 | ModuleNotFoundError: No module named 'tagger_model_workbench'
Installation using pip install
properly installs the package from our internal pypi whereas building and installing using built artifact doesn't.
Build commands are identical. Can anyone explain what's happening?
Upvotes: 0
Views: 332
Reputation: 1479
It seems like tagger_model_workbench
is the folder with the source code of the module. If you copy it in the way you described above it will only copy the content of your folder, but not the folder. Depending on your setup.py
this can lead to an module without any python files if you referencing the folder in your packages
list in the setup.py
instead of listing the content of the folder. If the module have no python files in it you will get the described error message.
If my assumption that tagger_model_workbench
is a folder is right you can simple fix it. Just make sure you are adding the complete folder to the docker image. Simply adapt the line where you copy the setup.py
in the following way:
COPY setup.py MANIFEST.in /app/
COPY tagger_model_workbench /app/tagger_model_workbench
Upvotes: 1