How to get pipenv running in docker?

DockerPipenv

Docker Problem Overview


Im installing pipenv in my docker:

RUN pip install pipenv
RUN cd /my/app/path/ && pipenv install
RUN cd /my/app/path/ && pipenv shell

Im getting the error:

Traceback (most recent call last):
  File "/usr/local/bin/pipenv", line 11, in <module>
	sys.exit(cli())
  File "/usr/local/lib/python2.7/dist-packages/pipenv/vendor/click/core.py", line 722, in __call__
	return self.main(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/pipenv/vendor/click/core.py", line 697, in main
	rv = self.invoke(ctx)
  File "/usr/local/lib/python2.7/dist-packages/pipenv/vendor/click/core.py", line 1066, in invoke
	return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python2.7/dist-packages/pipenv/vendor/click/core.py", line 895, in invoke
	return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python2.7/dist-packages/pipenv/vendor/click/core.py", line 535, in invoke
	return callback(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/pipenv/cli.py", line 2057, in shell
	do_shell(three=three, python=python, fancy=fancy, shell_args=shell_args)
  File "/usr/local/lib/python2.7/dist-packages/pipenv/cli.py", line 1952, in do_shell
	shell = os.path.abspath(PIPENV_SHELL)
  File "/usr/lib/python2.7/posixpath.py", line 360, in abspath
	if not isabs(path):
  File "/usr/lib/python2.7/posixpath.py", line 54, in isabs
	return s.startswith('/')
AttributeError: 'NoneType' object has no attribute 'startswith'

If I run

RUN cd /my/app/path/ && pipenv install --system 

instead, im getting another error:

build	30-Sep-2017 16:50:45	Step 5/9 : RUN cd /my/app/path &&     pipenv install --system
build	30-Sep-2017 16:50:45	 ---> Running in cffd31633074
build	30-Sep-2017 16:50:46	[91mPipfile.lock not found, creating…
build	30-Sep-2017 16:50:46	[0m[91mLocking [dev-packages] dependencies…
build	30-Sep-2017 16:50:46	[0m[91mLocking [packages] dependencies…
build	30-Sep-2017 16:50:49	[0m[91mCRITICAL:pip.utils:Error [Errno 2] No such file or directory while executing command python setup.py egg_info
build	30-Sep-2017 16:50:49	[0m[91mTraceback (most recent call last):
build	30-Sep-2017 16:50:49	  File "/usr/local/bin/pipenv", line 11, in <module>
build	30-Sep-2017 16:50:49	    sys.exit(cli())
build	30-Sep-2017 16:50:49	  File "/usr/local/lib/python2.7/dist-packages/pipenv/vendor/click/core.py", line 722, in __call__
build	30-Sep-2017 16:50:49	[0m[91m    return self.main(*args, **kwargs)
build	30-Sep-2017 16:50:49	  File "/usr/local/lib/python2.7/dist-packages/pipenv/vendor/click/core.py", line 697, in main
build	30-Sep-2017 16:50:49	[0m[91m    rv = self.invoke(ctx)
build	30-Sep-2017 16:50:49	  File "/usr/local/lib/python2.7/dist-packages/pipenv/vendor/click/core.py", line 1066, in invoke
build	30-Sep-2017 16:50:49	[0m[91m    return _process_result(sub_ctx.command.invoke(sub_ctx))
build	30-Sep-2017 16:50:49	  File "/usr/local/lib/python2.7/dist-packages/pipenv/vendor/click/core.py", line 895, in invoke
build	30-Sep-2017 16:50:49	[0m[91m    return ctx.invoke(self.callback, **ctx.params)
build	30-Sep-2017 16:50:49	  File "/usr/local/lib/python2.7/dist-packages/pipenv/vendor/click/core.py", line 535, in invoke
build	30-Sep-2017 16:50:49	    return callback(*args, **kwargs)
build	30-Sep-2017 16:50:49	  File "/usr/local/lib/python2.7/dist-packages/pipenv/cli.py", line 1782, in install
build	30-Sep-2017 16:50:49	[0m[91m    do_init(dev=dev, allow_global=system, ignore_pipfile=ignore_pipfile, system=system, skip_lock=skip_lock, verbose=verbose, concurrent=concurrent, deploy=deploy)
build	30-Sep-2017 16:50:49	  File "/usr/local/lib/python2.7/dist-packages/pipenv/cli.py", line 1290, in do_init
build	30-Sep-2017 16:50:49	[0m[91m    do_lock(system=system)
build	30-Sep-2017 16:50:49	  File "/usr/local/lib/python2.7/dist-packages/pipenv/cli.py", line 1080, in do_lock
build	30-Sep-2017 16:50:49	[0m[91m    pre=pre
build	30-Sep-2017 16:50:49	  File "/usr/local/lib/python2.7/dist-packages/pipenv/utils.py", line 421, in resolve_deps
build	30-Sep-2017 16:50:49	[0m[91m    resolved_tree.update(resolver.resolve())
build	30-Sep-2017 16:50:49	  File "/usr/local/lib/python2.7/dist-packages/pipenv/patched/piptools/resolver.py", line 101, in resolve
build	30-Sep-2017 16:50:49	[0m[91m    has_changed, best_matches = self._resolve_one_round()
build	30-Sep-2017 16:50:49	  File "/usr/local/lib/python2.7/dist-packages/pipenv/patched/piptools/resolver.py", line 199, in _resolve_one_round
build	30-Sep-2017 16:50:49	[0m[91m    for dep in self._iter_dependencies(best_match):
build	30-Sep-2017 16:50:49	  File "/usr/local/lib/python2.7/dist-packages/pipenv/patched/piptools/resolver.py", line 293, in _iter_dependencies
build	30-Sep-2017 16:50:49	    dependencies = self.repository.get_dependencies(ireq)
build	30-Sep-2017 16:50:49	  File "/usr/local/lib/python2.7/dist-packages/pipenv/patched/piptools/repositories/pypi.py", line 171, in get_dependencies
build	30-Sep-2017 16:50:49	    result = reqset._prepare_file(self.finder, ireq)
build	30-Sep-2017 16:50:49	  File "/usr/local/lib/python2.7/dist-packages/pipenv/patched/pip/req/req_set.py", line 639, in _prepare_file
build	30-Sep-2017 16:50:49	[0m[91m    abstract_dist.prep_for_dist()
build	30-Sep-2017 16:50:49	  File "/usr/local/lib/python2.7/dist-packages/pipenv/patched/pip/req/req_set.py", line 134, in prep_for_dist
build	30-Sep-2017 16:50:49	[0m[91m    self.req_to_install.run_egg_info()
build	30-Sep-2017 16:50:49	  File "/usr/local/lib/python2.7/dist-packages/pipenv/patched/pip/req/req_install.py", line 438, in run_egg_info
build	30-Sep-2017 16:50:49	[0m[91m    command_desc='python setup.py egg_info')
build	30-Sep-2017 16:50:49	  File "/usr/local/lib/python2.7/dist-packages/pipenv/patched/pip/utils/__init__.py", line 667, in call_subprocess
build	30-Sep-2017 16:50:49	[0m[91m    cwd=cwd, env=env)
build	30-Sep-2017 16:50:49	  File "/usr/lib/python2.7/subprocess.py", line 711, in __init__
build	30-Sep-2017 16:50:49	[0m[91m    errread, errwrite)
build	30-Sep-2017 16:50:49	  File "/usr/lib/python2.7/subprocess.py", line 1343, in _execute_child
build	30-Sep-2017 16:50:49	[0m[91m    raise child_exception
build	30-Sep-2017 16:50:49	OSError: [Errno 2] No such file or directory
error	30-Sep-2017 16:50:49	The command '/bin/sh -c cd /opt/supercrunch/function-service/lib &&     pipenv install --system' returned a non-zero code: 1
build	30-Sep-2017 16:50:49	[0mSending build context to Docker daemon 40.96 kB

But when I instead do the following:

RUN pip install pipenv
RUN cd /my/app/path && pipenv install
RUN cd /my/app/path && pipenv install --system

It is working...

So two question: First: Why is pipenv shell giving me this error and Second: Why do I have to do pipenv install before pipenv install --system to get it working?

I would like to use pipenv to create virtual environments with different python versions and differne dependency versions.

Docker Solutions


Solution 1 - 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

Solution 2 - Docker

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.

Solution 3 - Docker

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

Solution 4 - Docker

Following alternative turned out to be the best for me:

    RUN  pip install pipenv  \
    && pipenv lock --keep-outdated --requirements > requirements.txt \
    && pip install -r requirements.txt

Since this does not install the dependencies in pipenv'a virtualenv, no need to worry about pipenv in docker-compose command.

command: >
    - sh 
    - -c 
    - |
      python myscript.py
      python myapp.py

Following reference helped me, includes poetry,pip-tools Reference P.S. I am not the author

Solution 5 - Docker

The best thing is not to use pipenv directly, as you usually don't need a virtualenv in your container.

There is a tool called micropipenv that you can use in your container instead of pipenv.

https://github.com/thoth-station/micropipenv

micropipenv use cases

Why should I use micropipenv instead of Pipenv or Poetry?

  • I would like to have a tool that "rules them all" - one lightweight tool to support all Python dependency lock file managers (pip-tools, Poetry, Pipenv) and lets users decide what they want to use when deploying Python applications in containerized environments (e.g. Kubernetes, OpenShift, ...).

  • I would like to have a fast and minimalistic tool to install software packages in CI.

  • I would like to have containerized Python applications as small as possible with minimum software shipped and required to build and run the Python application in production.

  • I would like to convert files produced by Pipenv/Poetry to a pip-tools compatible output.

  • I don't want to install Pipenv/Poetry, but I would like to run a project that uses Pipenv/Poetry for dependency management (e.g. restricted environments).

  • My Pipenv installation is broken and Pipenv upstream did not issue any new Pipenv release <https://github.com/pypa/pipenv/issues/4058>_.

  • I would like to deploy my application into a production environment and my application dependencies are managed by Pipenv/Poetry (dependencies are already resolved), but I don't want to run Pipenv/Poetry in production (e.g. OpenShift's s2i build process).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMulgardView Question on Stackoverflow
Solution 1 - DockersobolevnView Answer on Stackoverflow
Solution 2 - DockerKaliorView Answer on Stackoverflow
Solution 3 - DockerJames TaylorView Answer on Stackoverflow
Solution 4 - DockermuonView Answer on Stackoverflow
Solution 5 - DockerVad1moView Answer on Stackoverflow