How to get pipenv running in docker?

Viewed 58924

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.

5 Answers

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

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

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).

Related