[英]Docker volume bind breaks python script CLI entry_point
好的,所以我有一个相当基本的 python click
CLI 应用程序,当它在容器中使用绑定卷运行时(文件上的实时开发)似乎打破了我在setup.py
的entry_point
运行以下任一命令
$ docker run -it -v $(pwd):/opt/app gdax
$ docker run -it --mount src=$(pwd),target=/opt/app,type=bind gdax
我得到以下
Traceback (most recent call last):
File "/usr/local/bin/gdax", line 6, in <module>
from pkg_resources import load_entry_point
File "/usr/local/lib/python3.6/site-packages/pkg_resources/__init__.py", line 3144, in <module>
@_call_aside
File "/usr/local/lib/python3.6/site-packages/pkg_resources/__init__.py", line 3128, in _call_aside
f(*args, **kwargs)
File "/usr/local/lib/python3.6/site-packages/pkg_resources/__init__.py", line 3157, in _initialize_master_working_set
working_set = WorkingSet._build_master()
File "/usr/local/lib/python3.6/site-packages/pkg_resources/__init__.py", line 666, in _build_master
ws.require(__requires__)
File "/usr/local/lib/python3.6/site-packages/pkg_resources/__init__.py", line 984, in require
needed = self.resolve(parse_requirements(requirements))
File "/usr/local/lib/python3.6/site-packages/pkg_resources/__init__.py", line 870, in resolve
raise DistributionNotFound(req, requirers)
pkg_resources.DistributionNotFound: The 'gdax-cli' distribution was not found and is required by the application
FROM python:3.6
RUN mkdir /opt/app
COPY . /opt/app
WORKDIR /opt/app
RUN pip install --editable .
CMD ["gdax", "--help"]
from setuptools import setup
setup(
name='gdax-cli',
version='0.1',
py_modules=['app'],
install_requires=[
'click==6.7',
'gdax==1.0.6'
],
entry_points='''
[console_scripts]
gdax=app:cli
''',
)
#!/usr/local/bin/python
# EASY-INSTALL-ENTRY-SCRIPT: 'gdax-cli','console_scripts','gdax'
__requires__ = 'gdax-cli'
import re
import sys
from pkg_resources import load_entry_point
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(
load_entry_point('gdax-cli', 'console_scripts', 'gdax')()
)
如果我不绑定卷,我可以很好地执行脚本,但我无法在主机上编辑文件。 我相当有信心这与绑定如何“覆盖”文件有关,并且会破坏/usr/local/bin/gdax
加载由setuptools
放置在那里的文件的能力。 有没有办法绕过这个(在容器中调用python app.py
之外)?
对于任何有兴趣在开发过程中通过entry_points
docker-compose run
调用 Python entry_points
控制台脚本的人。 一次将.egg-info
文件夹从正在运行的容器复制到挂载的主机目录对我.egg-info
。
将.egg-info
目录从正在运行的容器复制到主机。 预先关闭挂载,这样.egg-info
目录就不会被覆盖。
sudo docker cp <container id>:/path/to/package/in/container/package.egg-info /path/to/mounted/package/on/host/package.egg-info
重新启用挂载,所需的.egg-info
文件夹现在存在,因此安装的 entry_points 应该可以工作,您可以运行如下命令:
sudo docker-compose run <service name> <entry_point console script name> [OPT] [ARG]
为此,需要在映像中以开发模式安装 Python 包,例如RUN pip install -e /path/to/package/
,否则.egg-info
文件将不会出现在符号链接的源代码中目录,我猜。
当然,替代方案,如@Adam 提到的,总是直接调用CLI
脚本,如:
sudo docker-compose run <service name> python /path/to/package/cli.py [OPT] [ARG]
在当前目录中将 pip 安装为可编辑时,需要存在<package>.egg-info
目录,python 才能找到已安装的包。
可以将目录“列入白名单”,以免被docker-compose.yml
挂载点覆盖,如下所示:
services:
myapp:
image: mafrosis/myapp:dev
build:
context: .
volumes:
- ./:/app
- /app/.git
- /app/myapp.egg-info
在这个例子中,当容器启动时.git
和myapp.egg-info
目录都会出现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.