Eduardo Morales
Eduardo Morales

Reputation: 843

Installed pip packages are not available when deploying the container

Inside my Dockerfile I have:

FROM python:3.7
RUN apt update
RUN apt install -y git

RUN groupadd -g 1001 myuser
RUN useradd -u 1001 -g 1001 -ms /bin/bash myuser
USER 1001:1001
USER myuser
WORKDIR /home/myuser

COPY --chown=myuser:myuser requirements.txt ./

ENV PYTHONPATH="/home/myuser/.local/lib/python3.7/site-packages:.:$PYTHONPATH"
RUN python3.7 -m pip install -r requirements.txt
COPY --chown=myuser:myuser  . .

ENV PATH="/home/myuser/.local/bin/:$PATH"

ENV HOME=/home/myuser
ENV PYTHONHASHSEED=1
EXPOSE 8001
CMD [ "python3.7", "app.py" ]

During the build, pip list displays all the libraries correctly:

basicauth       0.4.1
pip             21.1.1
python-dateutil 2.8.1
pytz            2019.1
PyYAML          5.1.1
requests        2.22.0
setuptools      56.0.0
six             1.16.0
urllib3         1.25.11
wheel           0.36.2

But once OpenShift deploys the container, I only get the following libraries installed:

WARNING: The directory '/home/myuser/.cache/pip' or its parent directory is not owned or is not writable by the current user. The cache has been disabled. Check the permissions and owner of that directory. If executing pip with sudo, you should use sudo's -H flag.
Package    Version
---------- -------
pip        21.1.1
setuptools 56.0.0
wheel      0.36.2

The CMD command runs as expected, but none of the packages are installed...

Traceback (most recent call last :
File "app.py", line 16, in ‹module>
import requests
ModuleNotFoundError: No module named 'requests'

Upvotes: 0

Views: 1025

Answers (1)

coderanger
coderanger

Reputation: 54249

A revised Dockerfile more in line with standard practices:

FROM python:3.7

RUN apt update && \ 
    apt install -y --no-install-recommends git && \
    rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY requirements.txt .
RUN python3.7 -m pip install -r requirements.txt
COPY . .

ENV PYTHONHASHSEED=1
USER nobody
CMD [ "python3.7", "app.py" ]

I combined the initial RUN layers for a smaller image, and cleaned up the apt lists before exiting the layer. Packages are installed globally as root, and then only after that it changes to runtime user. In this case unless you very specifically need a homedir, I would stick with nobody/65534 as the standard way to express "low privs runtime user".

Remember that OpenShift overrides the container-level USER info https://www.openshift.com/blog/a-guide-to-openshift-and-uids

Upvotes: 2

Related Questions