Reputation: 69
I am currently following docker's doc on how to build an image using python
:
My "bug" could therefore be reproduced by following the doc.
I have checked & triple-checked my actions, and everything is exactly as the doc shows.
Also, i have looked at quite a few similar posts here, but none helped me resolve my problem.
For those that do not wish to look at the link, this is what i did:
The commands used :
$ cd /path/to/python-docker
$ pip3 install Flask
$ pip3 freeze > requirements.txt
$ touch app.py
afterward, we create the dockfile (NOTE: this is my dockfile, not the doc's):
FROM python:3.8-slim-buster
WORKDIR /app
COPY requirements.txt requirements.txt
# RUN apt update && apt install -y python3-pip
# RUN pip install --upgrade setuptools
# NOTE: the 2 RUN above are the 2 latest attempts to find a solution by using a RUN line.
RUN pip3 install -r requirements.txt
COPY . .
CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0"]
and then:
$ docker build --tag python-docker .
[+] Building 2.7s (10/10) FINISHED
=> [internal] load build definition from Dockerfile
=> => transferring dockerfile: 203B
=> [internal] load .dockerignore
=> => transferring context: 2B
=> [internal] load metadata for docker.io/library/python:3.8-slim-buster
=> [1/6] FROM docker.io/library/python:3.8-slim-buster
=> [internal] load build context
=> => transferring context: 953B
=> CACHED [2/6] WORKDIR /app
=> [3/6] COPY requirements.txt requirements.txt
=> [4/6] RUN pip3 install -r requirements.txt
=> [5/6] COPY . .
=> [6/6] CMD [ "python3", "-m", "flask", "run", "--host=0.0.0.0"]
=> exporting to image
=> => exporting layers
=> => writing image sha256:8cae92a8fbd6d091ce687b71b31252056944b09760438905b726625831564c4c
=> => naming to docker.io/library/python-docker
The above is the result that is supposed to happen. This is what i get:
$ sudo docker build --tag python-docker .
Sending build context to Docker daemon 16.38kB
Step 1/6 : FROM python:3.8-slim-buster
---> b426ee0e7642
Step 2/6 : WORKDIR /app
---> Using cache
---> 32f83359c4ca
Step 3/6 : COPY requirements.txt requirements.txt
---> Using cache
---> 2d84b2a8013a
Step 4/6 : RUN pip3 install -r requirements.txt
---> Running in de270828b1b5
ERROR: Could not find a version that satisfies the requirement apturl==0.5.2
ERROR: No matching distribution found for apturl==0.5.2
The command '/bin/sh -c pip3 install -r requirements.txt' returned a non-zero code: 1
While i could just delete this line from my requirements.txt
, the fact is that I did not write the file manually, and there is therefore no reason for it to be wrong. Regardless of that, apturl==0.5.2
is not the only one to have a similar error, and i estimate that around 40% of the content of requirements.txt
would produce the same error.
Me & my colleague have been stumped, and seeing that the solutions proposed in the similar posts that we have seen that we have yet to try spoke about manipulating DNS, i decided to create this question, since we aren't comfortable with playing with this in the workplace :D
NOTE: the sudo is simply because docker do not work without.
Thanks TERMINATOR for the edit!
Upvotes: 2
Views: 4816
Reputation: 203
If anyone stumbles upon this issue, try using another Python image. Preferably the one that uses Debian under the hood.
In your Dockerfile consider changing the first line to:
# FROM python:3.8-slim-buster
FROM python:3.8
In my case I was trying to install TensorFlow using the image python:3.9-alpine3.17
and it failed until I changed it to python:3.9
.
Upvotes: 0
Reputation: 69
The solution was found, with the great help of Iain Shelvington in the comments of my Question.
The problem was that $ pip3 install Flask
& $ pip3 freeze > requirements.txt
recorded ALL the packages installed in local, and not necessarily those that where truly needed.
As Iain Shelvington said, the packages in my requirements.txt
are not only pip packages, but also Ubuntu packages.
Two path are then possible:
python3 -m venv foo && . ./foo/bin/activate && pip install Flask && pip freeze > requirements.txt
(Or in multiple lines):
$ python3 -m venv foo
$ . ./foo/bin/activate
$ pip install Flask
$ pip freeze > requirements.txt
and another one that I cover after :)
Yet, when doing the first line of the path:
$ python3 -m venv python-docker
The virtual environment was not created successfully because ensurepip is not
available. On Debian/Ubuntu systems, you need to install the python3-venv
package using the following command.
apt-get install python3-venv
You may need to use sudo with that command. After installing the python3-venv
package, recreate your virtual environment.
I tried without then with a sudo. The attempt with a sudo looked like this:
$ sudo apt-get install python3-venv
E: dpkg was interrupted, you must manually run 'sudo dpkg --configure -a' to correct the problem.
Understandably, since I'm at my workplace I didn't want to change the configs.
Thankfully, Iain Shelvington provided a second path. Indeed, in the Dockfile I have FROM python:3.8-slim-buster
, which allow me to do this:
$ sudo docker run python:3.8-slim-buster bash -c "pip install Flask && pip freeze"
Collecting Flask
Downloading Flask-1.1.2-py2.py3-none-any.whl (94 kB)
Collecting Jinja2>=2.10.1
Downloading Jinja2-2.11.3-py2.py3-none-any.whl (125 kB)
Collecting click>=5.1
Downloading click-7.1.2-py2.py3-none-any.whl (82 kB)
Collecting itsdangerous>=0.24
Downloading itsdangerous-1.1.0-py2.py3-none-any.whl (16 kB)
Collecting Werkzeug>=0.15
Downloading Werkzeug-1.0.1-py2.py3-none-any.whl (298 kB)
Collecting MarkupSafe>=0.23
Downloading MarkupSafe-1.1.1-cp38-cp38-manylinux2010_x86_64.whl (32 kB)
Installing collected packages: MarkupSafe, Werkzeug, Jinja2, itsdangerous, click, Flask
Successfully installed Flask-1.1.2 Jinja2-2.11.3 MarkupSafe-1.1.1 Werkzeug-1.0.1 click-7.1.2 itsdangerous-1.1.0
click==7.1.2
Flask==1.1.2
itsdangerous==1.1.0
Jinja2==2.11.3
MarkupSafe==1.1.1
Werkzeug==1.0.1
Those 6 last lines are then my "real" requirements. By replacing the content of requirements.txt
by those obtained with sudo docker run python:3.8-slim-buster bash -c "pip install Flask && pip freeze"
, I can then proceed and try again to build my image:
$ sudo docker build --tag python-docker .
Sending build context to Docker daemon 15.36kB
Step 1/6 : FROM python:3.8-slim-buster
---> b426ee0e7642
Step 2/6 : WORKDIR /app
---> Using cache
---> 32f83359c4ca
Step 3/6 : COPY requirements.txt requirements.txt
---> b4c880e0fc47
Step 4/6 : RUN pip3 install -r requirements.txt
---> Running in 55b1a05658ba
Collecting click==7.1.2
Downloading click-7.1.2-py2.py3-none-any.whl (82 kB)
Collecting Flask==1.1.2
Downloading Flask-1.1.2-py2.py3-none-any.whl (94 kB)
Collecting itsdangerous==1.1.0
Downloading itsdangerous-1.1.0-py2.py3-none-any.whl (16 kB)
Collecting Jinja2==2.11.3
Downloading Jinja2-2.11.3-py2.py3-none-any.whl (125 kB)
Collecting MarkupSafe==1.1.1
Downloading MarkupSafe-1.1.1-cp38-cp38-manylinux2010_x86_64.whl (32 kB)
Collecting Werkzeug==1.0.1
Downloading Werkzeug-1.0.1-py2.py3-none-any.whl (298 kB)
Installing collected packages: MarkupSafe, Werkzeug, Jinja2, itsdangerous, click, Flask
Successfully installed Flask-1.1.2 Jinja2-2.11.3 MarkupSafe-1.1.1 Werkzeug-1.0.1 click-7.1.2 itsdangerous-1.1.0
Removing intermediate container 55b1a05658ba
---> a7be3cfb1fbb
Step 5/6 : COPY . .
---> acade9a05de9
Step 6/6 : CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0"]
---> Running in b1dfdf99b8aa
Removing intermediate container b1dfdf99b8aa
---> f6198e9d28f4
Successfully built f6198e9d28f4
Successfully tagged python-docker:latest
And finally, SUCCESS!
The two path are built around the same principle: to create or enter an environment that is not influenced by the local packages, so that the pip freeze
may properly work and give us only the requirements necessary to build our image, and not just all the packages installed in the local.
While the first path do that via a virtual environment, the second path make use of the python image that was called earlier in the Dockfile, and launch the pip freeze
directly within the python image, insuring that only the appropriate packages shows with the pip freeze
Obviously, the first path, while ultimately not the correct one for me, isn't a wrong one, just not adapted to MY specific situation.
Upvotes: 2