Tags: #python #virtualenv #docker #venv
Python 3 has two ways of handling Virtual Environments:
virtualenv
(which venv
module is a subset of)The downside of option 1 is that it only works for the version of the Python 3 interpreter that’s running. For example, if your Python 3 version is 3.6
then you can’t run a virtual environment of packages using Python 3.7
At least with virtualenv
you have the option of specifying the Python interpreter you want to use: virtualenv --python=/opt/python-3.3/bin/python
.
Once the virtual environment is created you’ll need to activate it: source <path/to/venv>/bin/activate
It’s easy to think of activate
as some mysterious magic, a pentacle drawn in blood to keep Python safely trapped. But it’s just software, and fairly simple software at that. The virtualenv documentation will even tell you that activate
is “purely a convenience.”
If you go and read the code for activate
, it does a number of things:
deactivate
function to your shell, and messes around with pydoc
.PYTHONHOME
environment variable, if someone happened to set it.VIRTUAL_ENV
and PATH
.The first four are basically irrelevant to Docker usage, so that just leaves the last item. The most important part is setting PATH: PATH
is a list of directories which are searched for commands to run. activate
simply adds the virtualenv’s bin/
directory to the start of the list.
We can replace activate
by setting the appropriate environment variables: Docker’s ENV
command applies both subsequent RUN
s as well as to the CMD
.
The result is the following Dockerfile:
FROM ubuntu:18.04
RUN apt-get update && apt-get install \
-y --no-install-recommends python3 python3-virtualenv
ENV VIRTUAL_ENV=/opt/venv
RUN python3 -m virtualenv --python=/usr/bin/python3 $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
# Install dependencies:
COPY requirements.txt .
RUN pip install -r requirements.txt
# Run the application:
COPY myapp.py .
CMD ["python", "myapp.py"]