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.
FROM python:3.6
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
ENTRYPOINT ["/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
USER app
WORKDIR /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
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.
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.
Running Docker containers as root is not a good idea. Check out Graham Dumpleton's blog for more details on this.
We are going to create a new user that lives in /app
and change the WORKDIR
accordingly.
Finally, it's time to install the Pipfile. If this is a Dockerfile for a
development environment, you want to add the --dev
flag.
This is where you add your own code. No help here, you have to write this yourself.
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:
docker-compose.yml
version: '2'
services:
app:
build: .
Next, create a minimal Pipfile with requests
as its only dependency:
Pipfile
[packages]
requests = "*"
Time to build the image, run:
docker-compose build
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.