How to get pipenv running in docker?

Considering your problem, as I know it the easiest way is to update to the latest version of pipenv. It is still in development, so problems are fixed very soon.

We are using pipenv with docker in production. And we really like it. There are several things to keep in mind:

  1. You need to use --system flag, so it will install all packages into the system python, and not into the virtualenv. Since docker containers do not need to have virtualenvs
  2. You need to use --deploy flag, so your build will fail if your Pipfile.lock is out of date
  3. You need to use --ignore-pipfile, so it won't mess with our setup

Check the official docs to be sure that this information is up-to-date.

All in all:

pipenv install --system --deploy --ignore-pipfile

There's also one more thing. If you are using the same Dockerfile for both development and production it would be very nice to also use --dev flag for the development environment only.

Also, check out our django project template to see the full example: wemake-django-template


The pipenv documentation no longer officially recommends using the --system flag in docker instances. Instead, they suggest using virtual environments, as "it is for deployment onto a full-fledged OS". This is with the caveat:

...most containers are deployed without virtualenvs as I believe you both note, I believe the purpose is to stay slim and reduce attack surface area by installing as little as possible

As stated in https://github.com/pypa/pipenv/pull/2762.

Instead, the solution would be to run (as stated in a different answer here):

RUN pipenv install --deploy --ignore-pipfile

And then prefix all calls to python with pipenv run, e.g. CMD ["pipenv", "run", "python", "hello.py"]

Ps. I would have wanted to put this as a comment to the accepted answer, but I don't have the reputation.


The direct answer to this question is to not use shell, but rather run:

CMD ["pipenv", "run", "python", "my/app.py"]

If you need more flexibility, you could also pipenv run sh init.sh, which would create a shell initialized with all the pipenv environment variables.

I actually prefer the approach C. Sweet mentions. If you can get away with prebuilding your virtual environment and simply copying it over (setting PIPENV_VENV_IN_PROJECT then using a nested FROM followed by COPY --from=builder-image), you don't need python nor pipenv nor pipenv dependencies in your final container. This greatly reduces the size of the final image.

Dockerfile:

WORKDIR /etc/service/
CMD ["sh", "/etc/service/init.sh"]

init.sh:

source /etc/service/my/.venv/bin/activate
python my/app.py

Tags:

Docker

Pipenv