Как заставить pipenv работать в докере?
Im устанавливаю pipenv в моем docker:
RUN pip install pipenv
RUN cd /my/app/path/ && pipenv install
RUN cd /my/app/path/ && pipenv shell
Im получение ошибки:
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 install --system
чтобы заставить ее работать?
Я хотел бы использовать pipenv для создания виртуальных сред с разными версиями python и разными версиями зависимостей.
Ответы
Ответ 1
Учитывая вашу проблему, насколько я знаю, проще всего обновить ее до последней версии pipenv
. Он все еще находится в разработке, поэтому проблемы решаются очень скоро.
Мы используем pipenv
с docker
в производстве. И нам это очень нравится. Есть несколько вещей, которые нужно иметь в виду:
- Вам нужно использовать флаг
--system
, чтобы он устанавливал все пакеты в системный питон, а не в virtualenv
. Так как docker
контейнеры не должны иметь virtualenv
s - Вам нужно использовать флаг
--deploy
, чтобы ваша сборка не Pipfile.lock
если ваш Pipfile.lock
устарел - Вам нужно использовать
--ignore-pipfile
, чтобы он не --ignore-pipfile
нашей установке
Проверьте официальные документы, чтобы убедиться, что эта информация актуальна.
В общем:
pipenv install --system --deploy --ignore-pipfile
Там также еще одна вещь. Если вы используете один и тот же Dockerfile
как для разработки, так и для производства, было бы очень хорошо использовать флаг --dev
для среды разработки.
Также посмотрите наш шаблон проекта django
чтобы увидеть полный пример: wemake-django-template
Ответ 2
Прямым ответом на этот вопрос является не использование shell
, а скорее run
:
CMD ["pipenv", "run", "python", "my/app.py"]
Если вам нужна большая гибкость, вы также pipenv run sh init.sh
, чтобы создать оболочку, инициализированную всеми переменными окружения pipenv
.
Я действительно предпочитаю подход C. Sweet упоминает. Если вам удастся скомпилировать виртуальную среду и просто скопировать ее (установка 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
Ответ 3
Документация 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. Я хотел бы поместить это как комментарий к принятому ответу, но у меня нет репутации.
Ответ 4
пытаться
source 'pipenv --venv'/bin/activate