Как запустить pipenv в докере?

Я устанавливаю pipenv в моем докере:

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

Я получаю ошибку:

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'

Если я бегу

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

вместо этого я получаю еще одну ошибку:

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

Но когда я вместо этого делаю следующее:

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

Это работает...

Итак, два вопроса: во-первых: почему pipenv shell давая мне эту ошибку и второе: почему я должен сделать pipenv install до pipenv install --system заставить его работать?

Я хотел бы использовать pipenv для создания виртуальных сред с разными версиями Python и разными версиями зависимостей.

7 ответов

Решение

Учитывая вашу проблему, насколько я знаю, проще всего обновить ее до последней версии pipenv, Он все еще находится в разработке, поэтому проблемы решаются очень скоро.

Мы используем pipenv с docker в производстве. И нам это очень нравится. Есть несколько вещей, которые нужно иметь в виду:

  1. Вам нужно использовать --system флаг, поэтому он будет устанавливать все пакеты в системный Python, а не в virtualenv, поскольку docker контейнеры не должны иметь virtualenvs
  2. Вам нужно использовать --deploy флаг, так что ваша сборка не удастся, если ваш Pipfile.lock устарел
  3. Вам нужно использовать --ignore-pipfileтак что это не испортит нашу настройку

Проверьте официальные документы, чтобы убедиться, что эта информация актуальна.

В общем:

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

Есть еще одна вещь. Если вы используете тот же Dockerfile как для разработки, так и для производства было бы очень хорошо использовать --dev флаг только для среды разработки.

Кроме того, проверьте наш django шаблон проекта, чтобы увидеть полный пример: wemake-django-template

Документация pipenv больше официально не рекомендует использовать --system флаг в экземплярах докера. Вместо этого они предлагают использовать виртуальные среды, поскольку "они предназначены для развертывания на полноценной ОС". Это с оговоркой:

... большинство контейнеров развернуто без virtualenvs, как я полагаю, вы оба заметили, я считаю, что цель состоит в том, чтобы оставаться стройными и уменьшить площадь поверхности атаки, устанавливая как можно меньше

Как указано в https://github.com/pypa/pipenv/pull/2762.

Вместо этого решение будет запускаться (как указано в другом ответе здесь):

RUN pipenv install --deploy --ignore-pipfile

И затем префикс всех вызовов Python с pipenv runнапример, CMD ["pipenv", "run", "python", "hello.py"]

Ps. Я хотел бы поместить это как комментарий к принятому ответу, но у меня нет репутации.

Прямой ответ на этот вопрос не использовать shell, скорее run:

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

Если вам нужно больше гибкости, вы также можете pipenv run sh init.sh, которая создаст оболочку, инициализированную со всеми pipenv переменные среды

Я на самом деле предпочитаю подход C. Сладкие упоминания. Если вы можете избежать предварительной сборки виртуальной среды и просто скопировать ее (настройка PIPENV_VENV_IN_PROJECT затем с помощью вложенного FROM с последующим COPY --from=builder-image), вам не нужно python ни pipenv ни pipenv зависимости в вашем конечном контейнере. Это значительно уменьшает размер конечного изображения.

Dockerfile:

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

init.sh:

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

Лучшим вариантом для меня оказался следующий вариант:

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

Поскольку при этом не устанавливаются зависимости в pipenv'a virtualenv, не нужно беспокоиться о pipenv в команде docker-compose.

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

Следующая ссылка мне помогла, включает стихи, pip-tools Ссылка PS Я не автор

Каждая директива порождает новую оболочку, поэтому бесполезно пытаться изменить ее с помощьюpipenv shellкоманда: любая следующая инструкция не выиграет от этого.

ВсеRUNдиректива, предназначенная для использования среды pipenv, должна иметь префиксpipenv run.

Это также относится кCMDдиректива, а также любая команда, запускаемая с контейнером после сборки образа, но вы можете взломатьENTRYPOINTсохранять префиксы для команд!

      FROM python
RUN pip install pipenv
WORKDIR /app/
COPY Pipfile* /app
RUN mkdir /app/.venv
RUN pipenv install --deploy
RUN pipenv run something
ENTRYPOINT ["python", "-m", "pipenv", "run"]
CMD ["something"]

Лучше всего не использовать pipenv напрямую, поскольку вам обычно не нужен virtualenv в вашем контейнере.

Существует инструмент под названием micropipenv, который вы можете использовать в своем контейнере вместо pipenv.

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

варианты использования micropipenv

Почему я должен использовать micropipenv вместо Pipenv или Poetry?

  • Я хотел бы иметь инструмент, который «управляет ими всеми» - один легкий инструмент для поддержки всех файловых менеджеров блокировки зависимостей Python (pip-tools, Poetry, Pipenv) и позволяющий пользователям решать, что они хотят использовать при развертывании приложений Python в контейнерных средах. (например, Kubernetes, OpenShift, ...).

  • Я хотел бы иметь быстрый и минималистичный инструмент для установки программных пакетов в CI.

  • Я хотел бы иметь как можно меньше контейнерных приложений Python с минимальным количеством поставляемого программного обеспечения, необходимого для создания и запуска приложения Python в производственной среде.

  • Я хотел бы преобразовать файлы, созданные Pipenv / Poetry, в выходной файл, совместимый с pip-tools.

  • Я не хочу устанавливать Pipenv / Poetry, но я хотел бы запустить проект, который использует Pipenv / Poetry для управления зависимостями (например, в ограниченных средах).

  • Моя установка Pipenv не работает и Pipenv upstream did not issue any new Pipenv release <https://github.com/pypa/pipenv/issues/4058>_.

  • Я хотел бы развернуть свое приложение в производственной среде, и мои зависимости приложения управляются Pipenv / Poetry (зависимости уже разрешены), но я не хочу запускать Pipenv / Poetry в производственной среде (например, процесс сборки OpenShift s2i).

Пытаться

source `pipenv --venv`/bin/activate
Другие вопросы по тегам