Pipfiles, pipenv and Docker
Exciting times in Python. With the recent introduction of
Pipfiles and the new pipenv
library it's time to rewrite our Dockerfiles to leverage all the goodness
of modern Python packaging.
ENV PYTHONUNBUFFERED 1
# 1. install pipenv and create an entrypoint
RUN pip install pipenv
RUN echo "#!/bin/bash" >> /entrypoint.sh && \
echo "source /app/.local/share/virtualenvs/app/bin/activate" >> /entrypoint.sh && \
echo 'exec "$@"' >> /entrypoint.sh && \
chmod +x /entrypoint.sh
# 2. install system level dependencies
# <-- system level dependencies here
# 3. don't run as root
RUN groupadd --gid 1001 app
RUN useradd --uid 1001 --gid app --home /app app
RUN mkdir /app && \
chown app.app /app
# 4. copy the Pipfile and install it
COPY Pipfile /app/Pipfile
RUN pipenv install
# 5. add your own code
# <--- own code here
COPY . /app/app
1. Install pipenv and create an entrypoint
The first thing we have to do is install pipenv. In order to use it properly, we are going to
create a small entrypoint that activates the virtualenv whenever we enter the container.
2. Install system level dependencies
If you have any system level dependencies, install them here. We are going
to switch to a non-privileged user next, this is your last chance.
3. Don't run as root
Running Docker containers as root is not a good idea. Check out
Graham Dumpleton's blog for more details on
We are going to create a new user that lives in
/app and change the
4. Copy the Pipfile and install it
Finally, it's time to install the Pipfile. If this is a Dockerfile for a
development environment, you want to add the
5. add your own code
This is where you add your own code. No help here, you have to write this yourself.
Try it out
First, create a new
Dockerfile with the contents from above.
Docker Compose makes it extremely simple to build Dockerfiles, so we are going to use it.
If you haven't already, install it and create a
docker-compose.yml that looks like this:
Next, create a minimal Pipfile with
requests as its only dependency:
requests = "*"
Time to build the image, run:
And run the container by running:
docker-compose run app python
This should give you a Python shell with pre installed
requests to play with.