Docker: Install python packages offline - python

What I am trying to do?
Install all dependencies mentioned in requirements.txt using downloaded wheel files i.e. offline installation of packages in Docker
What I have done?
By following this thread I managed to download all my wheels into a wheelhouse folder using mkdir wheelhouse && pip download -r requirements.txt -d wheelhouse and I created a compressed tarball wheelhouse.tar.gz containing all my downloaded .whl files along with a requirements.txt
When I try to install the wheels locally (outside Docker) using pip install -r wheelhouse/requirements.txt --no-index --find-links wheelhouse, it works!
But when I run the same in Docker, it doesn't with the following error:
Processing ./wheelhouse/beautifulsoup4-4.8.2-py3-none-any.whl
ERROR: Could not find a version that satisfies the requirement blis==0.4.1 (from -r ./wheelhouse/requirements.txt (line 2)) (from versions: none)
ERROR: No matching distribution found for blis==0.4.1 (from -r ./wheelhouse/requirements.txt (line 2))
While actually, the wheel for blis 0.4.1 is present in my wheelhouse directory.
Can anyone please help me identify why it doesn't run on Docker and runs on local?
Dockerfile
FROM python:3
COPY . /app
WORKDIR /app
RUN tar -zxf ./wheelhouse.tar.gz
RUN pip install -r ./wheelhouse/requirements.txt --no-index --find-links ./wheelhouse
Screenshot of wheelhouse directory:

Related

Error with requirements file when creating docker image

Note, I'm brand new to docker.
I'm trying to create a docker image of my flask app but when I run sudo docker image build -t flask_docker . it keeps throwing version errors at the step of installing the requirements.txt file.
Here is my docker file
FROM python:3.8-alpine
COPY requirements.txt /app/requirements.txt
WORKDIR /app
RUN pip3 install -r requirements.txt
COPY . /app
ENTRYPOINT ["python3"]
CMD ["app.py"]
And here is the error.
ERROR: Could not find a version that satisfies the requirement Brlapi==0.8.2 (from versions: none)
ERROR: No matching distribution found for Brlapi==0.8.2
WARNING: You are using pip version 22.0.4; however, version 22.2.2 is available.
You should consider upgrading via the '/usr/local/bin/python -m pip install --upgrade pip' command.
What is the proper way to fix this error? Should I just manually go through and find which packages don't install properly and just remove them?
I would recommend using a Virtual environment to install packages, but for your situation try reinstalling Brlapi with
pip install --upgrade --force-reinstall Brlapi
and then pip freeze to get your requirements.txt

Downloading requirements.txt from GitHub

I trying to download requirements.txt from my repo in GitHub
I use pip install -e git+https://github.com/GabrielCoutz/Problema-Chiado#egg=requirements.txt and this is returning:
ERROR: File "setup.py" not found for legacy project requirements.txt from git+https://github.com/GabrielCoutz/Problema-Chiado#egg=requirements.txt.
How i can create setup.py and what i have to put in?
pip install -r https://raw.githubusercontent.com/GabrielCoutz/Problema-Chiado/main/requirements.txt
-e is for local installs for developing, for example. Check this:
What is the use case for `pip install -e`?

Docker pip dependencies installation error

I'm trying to build a Docker image for a Flask app I wrote, but I'm getting a pip related error when it's installing the build dependencies as you can see from the log below.
I'm using pipenv for dependency management, and I'm able to get the app running locally without any error using pipenv run python3 run.py
It seems it's not able to install bcrypt, but I can't figure out why.
Dockerfile:
FROM alpine:3.8
RUN apk add --no-cache python3-dev && pip3 install --upgrade pip
WORKDIR /app
COPY . /app
RUN pip3 --no-cache-dir install -r requirements.txt
EXPOSE 5000
ENTRYPOINT ["python3"]
CMD ["run.py"]
requirements.txt (generated with pipenv shell; pip freeze > requirements.txt)
bcrypt==3.1.6
blinker==1.4
cffi==1.11.5
Click==7.0
Flask==1.0.2
Flask-Bcrypt==0.7.1
Flask-Login==0.4.1
Flask-Mail==0.9.1
Flask-SQLAlchemy==2.3.2
Flask-WTF==0.14.2
itsdangerous==1.1.0
Jinja2==2.10
MarkupSafe==1.1.0
Pillow==5.4.1
pycparser==2.19
six==1.12.0
SQLAlchemy==1.2.17
Werkzeug==0.14.1
WTForms==2.2.1
Docker build image process log:
$ docker build -t flaskapp:latest .
Sending build context to Docker daemon 2.16MB
Step 1/8 : FROM alpine:3.8
---> 3f53bb00af94
Step 2/8 : RUN apk add --no-cache python3-dev && pip3 install --upgrade pip
---> Using cache
---> 3856c6d59bbe
Step 3/8 : WORKDIR /app
---> Using cache
---> 54ed0e7464e4
Step 4/8 : COPY . /app
---> Using cache
---> 9e045f4ce91c
Step 5/8 : RUN pip3 --no-cache-dir install -r requirements.txt
---> Running in 25909f37b071
Collecting bcrypt==3.1.6 (from -r requirements.txt (line 1))
Downloading https://files.pythonhosted.org/packages/ce/3a/3d540b9f5ee8d92ce757eebacf167b9deedb8e30aedec69a2a072b2399bb/bcrypt-3.1.6.tar.gz (42kB)
Installing build dependencies: started
Installing build dependencies: finished with status 'error'
Complete output from command /usr/bin/python3.6 /usr/lib/python3.6/site-packages/pip install --ignore-installed --no-user --prefix /tmp/pip-build-env-9iojppec/overlay --no-warn-script-location --no-binary :none: --only-binary :none: -i https://pypi.org/simple -- setuptools wheel "cffi>=1.1; python_implementation != 'PyPy'":
Collecting setuptools
Downloading https://files.pythonhosted.org/packages/bf/ae/a23db1762646069742cc21393833577d3fa438eecaa59d11fb04fa57fcd5/setuptools-40.7.1-py2.py3-none-any.whl (574kB)
Collecting wheel
Downloading https://files.pythonhosted.org/packages/ff/47/1dfa4795e24fd6f93d5d58602dd716c3f101cfd5a77cd9acbe519b44a0a9/wheel-0.32.3-py2.py3-none-any.whl
Collecting cffi>=1.1
Downloading https://files.pythonhosted.org/packages/e7/a7/4cd50e57cc6f436f1cc3a7e8fa700ff9b8b4d471620629074913e3735fb2/cffi-1.11.5.tar.gz (438kB)
Complete output from command python setup.py egg_info:
Package libffi was not found in the pkg-config search path.
Perhaps you should add the directory containing `libffi.pc'
to the PKG_CONFIG_PATH environment variable
Package 'libffi', required by 'virtual:world', not found
Package libffi was not found in the pkg-config search path.
Perhaps you should add the directory containing `libffi.pc'
to the PKG_CONFIG_PATH environment variable
Package 'libffi', required by 'virtual:world', not found
Package libffi was not found in the pkg-config search path.
Perhaps you should add the directory containing `libffi.pc'
to the PKG_CONFIG_PATH environment variable
Package 'libffi', required by 'virtual:world', not found
Package libffi was not found in the pkg-config search path.
Perhaps you should add the directory containing `libffi.pc'
to the PKG_CONFIG_PATH environment variable
Package 'libffi', required by 'virtual:world', not found
Package libffi was not found in the pkg-config search path.
Perhaps you should add the directory containing `libffi.pc'
to the PKG_CONFIG_PATH environment variable
Package 'libffi', required by 'virtual:world', not found
No working compiler found, or bogus compiler options passed to
the compiler from Python's standard "distutils" module. See
the error messages above. Likely, the problem is not related
to CFFI but generic to the setup.py of any Python package that
tries to compile C code. (Hints: on OS/X 10.8, for errors about
-mno-fused-madd see http://stackoverflow.com/questions/22313407/
Otherwise, see https://wiki.python.org/moin/CompLangPython or
EDIT:
After changing the RUN command in Dockerfile to:
RUN apk add --no-cache python3-dev openssl-dev libffi-dev gcc musl-dev && pip3 install --upgrade pip
I now get this error (relevant part posted):
...
Collecting SQLAlchemy==1.2.17 (from -r requirements.txt (line 17))
Downloading https://files.pythonhosted.org/packages/c6/52/73d1c92944cd294a5b165097038418abb6a235f5956d43d06f97254f73bf/SQLAlchemy-1.2.17.tar.gz (5.7MB)
Collecting Werkzeug==0.14.1 (from -r requirements.txt (line 18))
Downloading https://files.pythonhosted.org/packages/20/c4/12e3e56473e52375aa29c4764e70d1b8f3efa6682bef8d0aae04fe335243/Werkzeug-0.14.1-py2.py3-none-any.whl (322kB)
Collecting WTForms==2.2.1 (from -r requirements.txt (line 19))
Downloading https://files.pythonhosted.org/packages/9f/c8/dac5dce9908df1d9d48ec0e26e2a250839fa36ea2c602cc4f85ccfeb5c65/WTForms-2.2.1-py2.py3-none-any.whl (166kB)
Exception:
Traceback (most recent call last):
File "/usr/lib/python3.6/site-packages/pip/_internal/cli/base_command.py", line 176, in main
status = self.run(options, args)
File "/usr/lib/python3.6/site-packages/pip/_internal/commands/install.py", line 346, in run
session=session, autobuilding=True
File "/usr/lib/python3.6/site-packages/pip/_internal/wheel.py", line 886, in build
assert have_directory_for_build
AssertionError
The command '/bin/sh -c pip3 --no-cache-dir install -r requirements.txt' returned a non-zero code: 2
EDIT2:
It seems it's an Alpine Linux known issue. More info here: have_directory_for_build AssertionError when installing with --no-cache-dir (19.0.1)
The problem is that cffi requires a compiler and development libraries to be available on install.
A simple way to get around this is by simply installing the required packages as part of the docker build process.
RUN apk add --no-cache python3-dev openssl-dev libffi-dev gcc && pip3 install --upgrade pip
This might not be the best long term solution and something like multi-stage builds might be better long term.
I tried pulling the version of alpine:3.4 and it works, but with 3.7 and 3.9, the install of dependencies in python crashes every time. It should be something of alpine image.
SOLVED:
I had the error installing Fabric2 and one of its dependencies was bcrypt and cryptography, and those threw many errors so, looking for in the Cryptography notes it says you have to add this line in the Dockerfile:
RUN apk-install gcc musl-dev python3-dev libffi-dev openssl-dev make
The worst thing is that it increases the layer size in 231MiB
A good approach to a lower image size is installing those tools, do the installation of the python libraries and uninstalling the tools needed before, all in one RUN clause
The image size shrinks to 83MiB so it's the best idea.
I used the latest version of alpine in this case and it works fine now!
You could use the python docker file with alpine: Python 3.7 Alpine 3.8 Dockerfile
You can look here to get the appropriate image based on the python version you have and it should remove the overhead of having to install any python dependencies which are missing. Then at the top of your dockerfile you can just write:
FROM 3.7.2-alpine3.8
If you don't want to go that root adding in libffi-dev and gcc to the following command should fix your problem. If you look at the dockerfile linked though you can see that there a lot of additional dependencies which may be needed included in the python image.
RUN apk add --no-cache python3-dev libffi-dev gcc && pip3 install --upgrade pip
Hope this helps!
Try to install gcc into your with apt before installing python requirements.

Docker pip3 not installing packages

I have the following Dockerfile and requirements.txt file. The requirements.txt appears to be processed, but I don't see any output "Installing collected packages" statements like I see when I install the packages on my system without Docker. In the docker build I end up with an error where the previous package in requirements.txt should have been installed.
Dockerfile
FROM alpine:3.8
ADD . /code
RUN apk add alpine-sdk python3-dev
WORKDIR /code
RUN sudo apk update
RUN pip3 install --trusted-host pypi.python.org -r requirements.txt
CMD ["python3", "linqcmd"]
requirements.txt
boto3
click
python-levenshtein
python-dateutil
cython
# pip3 install git+https://github.com/izderadicka/pdfparser
-e git://github.com/izderadicka/pdfparser.git#egg=pdfparser
docker-compose up --build output
...
Step 6/7 : RUN pip3 install --trusted-host pypi.python.org -r requirements.txt
---> Running in 515dd716aa7c
Collecting boto3 (from -r requirements.txt (line 4))
Downloading https://files.pythonhosted.org/packages/a8/45/810f786ce144bfd19d9f2f700a8cd4358435559a2b88b2c235f7bb3f29df/boto3-1.8.6-py2.py3-none-any.whl (128kB)
Collecting click (from -r requirements.txt (line 5))
Downloading https://files.pythonhosted.org/packages/34/c1/8806f99713ddb993c5366c362b2f908f18269f8d792aff1abfd700775a77/click-6.7-py2.py3-none-any.whl (71kB)
Collecting python-levenshtein (from -r requirements.txt (line 6))
Downloading https://files.pythonhosted.org/packages/42/a9/d1785c85ebf9b7dfacd08938dd028209c34a0ea3b1bcdb895208bd40a67d/python-Levenshtein-0.12.0.tar.gz (48kB)
Collecting python-dateutil (from -r requirements.txt (line 7))
Downloading https://files.pythonhosted.org/packages/cf/f5/af2b09c957ace60dcfac112b669c45c8c97e32f94aa8b56da4c6d1682825/python_dateutil-2.7.3-py2.py3-none-any.whl (211kB)
Collecting cython (from -r requirements.txt (line 8))
Downloading https://files.pythonhosted.org/packages/21/89/ca320e5b45d381ae0df74c4b5694f1471c1b2453c5eb4bac3449f5970481/Cython-0.28.5.tar.gz (1.9MB)
Obtaining pdfparser from git+git://github.com/izderadicka/pdfparser.git#egg=pdfparser (from -r requirements.txt (line 10))
Cloning git://github.com/izderadicka/pdfparser.git to ./src/pdfparser
Complete output from command python setup.py egg_info:
You need to install cython first - sudo pip install cython
----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /code/src/pdfparser/
You are using pip version 10.0.1, however version 18.0 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
ERROR: Service 'web' failed to build: The command '/bin/sh -c pip3 install --trusted-host pypi.python.org -r requirements.txt' returned a non-zero code: 1
By design, pip doesn't install any packages until after it's collected & built wheels for everything it's going to install; this is done to prevent a failure in the middle of installation from causing only some packages to be installed. Thus, in your case, cython won't be installed before a wheel is built for pdfparser, which apparently needs cython in order to build, and so the installation fails. You need to install cython and pdfparser in two separate steps.

How do I specify to pip that it should only build wheels if they don't exist in the wheelhouse?

So currently we have a build process that works like so:
#copy wheelhouse if it exists
if [[ -d $WHEELHOUSE ]]; then
sudo cp -aTr $WHEELHOUSE $WORKSPACE/wheelhouse
fi
cd $WORKSPACE; pip install --find-links=$WORKSPACE/wheelhouse --use-wheel -r requirements-meta.txt; pip install --find-links=$WORKSPACE/wheelhouse --use-wheel -r requirements.txt; pip install --find-links=$WORKSPACE/wheelhouse --use-wheel -r requirements-dev.txt;
echo "Now building wheels"
pip wheel --wheel-dir=$WORKSPACE/wheelhouse --find-links $WORKSPACE/wheelhouse -r requirements-meta.txt; pip wheel --wheel-dir=$WORKSPACE/wheelhouse --find-links $WORKSPACE/wheelhouse -r requirements-dev.txt; pip wheel --wheel-dir=$WORKSPACE/wheelhouse --find-links $WORKSPACE/wheelhouse -r requirements.txt
This allows us to then copy over the wheelhouse with the rest of the workspace onto our production servers, and use those wheels as the install base for pip on those servers.
For some reason, this always builds wheels for numpy and scipy (as well as pycrypto and a few others, but those are less time-consuming), even if they already exist in $WORKSPACE/wheelhouse.
What we'd like to have happen is for pip wheel to skip building these wheels if they already exist in $WORKSPACE/wheelhouse. Is there something I'm missing on how to do this?

Categories