繁体   English   中英

如何将PyCharm连接到位于Docker容器内的python解释器?

[英]How to connect PyCharm to a python interpreter located inside a Docker container?

我从Docker开始,但是我不知道如何配置PyCharm以使用位于容器中的python解释器。

使用Vagrant设置起来很容易 ,但是显然还没有使用Docker的正式方法

我应该准备带有暴露的ssh端口的特殊Docker映像吗? 如何更轻松地做到这一点?

更新 :PyCharm 2017.1有解决此问题的方法,请参阅此博客条目

这是我解决问题的方法。 我的情况是,我被分配对使用docker-compose创建四个容器的Web应用程序的特定区域进行干预。 Docker-compose是一种元docker,可通过一个命令管理多个docker容器。 我不想破坏他们现有的设置,因为很多事情都取决于它。 但是由于我正在处理其中一张图像的一个特定部分,所以我决定使用ssh扩展其中一个容器,以便可以从PyCharm进行调试。 此外,我希望该应用程序在启动时能够正常运行,并且只有通过强制退出并从PyCharm连接到该应用程序,我才能拥有一个可调试的组件。 这是我在Mac上使用boot2docker(在VirtualBox上)正确设置docker的操作。

首先,我需要扩展目标容器jqworker 我将使用"supervisior"来繁重地管理事物。

FROM jqworker

# Get supervisor to control multiple processes, sshd to allow connections.
# And supervisor-stdout allows us to send the output to the main docker output.
RUN apt-get update && apt-get install -y supervisor openssh-server python-pip \
  && pip install supervisor-stdout \
  && mkdir -p /var/run/sshd  \
  && mkdir -p /var/log/supervisor \
  && mkdir -p /etc/supervisor/conf.d

COPY ./supervisord.conf /etc/supervisor/conf.d/supervisord.conf

# Fix up SSH, probably should rip this out in real deploy situations.
RUN echo 'root:soup4nuts' | chpasswd
RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config

# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile

# Expose SSH on 22, but this gets mapped to some other address.
EXPOSE 22

# Replace old entrypoint with supervisiord, starts both sshd and worker.py
ENTRYPOINT ["/usr/bin/supervisord"]

主管使我可以从一个命令(在本例中为原始命令和SSHD)运行多个任务。 是的,每个人都说docker中的SSHD是邪恶的,容器应该做到这一点等等,但是编程是解决问题,而不是遵循忽略上下文的任意命令。 我们需要SSH来调试代码,而不是将其部署到现场,这是我们扩展现有容器而不是将其添加到部署结构中的原因之一。 我在本地运行它,以便可以在上下文中调试代码。

这是supervisord.conf文件,请注意,我正在使用supervisor-stdout包将输出定向到supervisor,而不是记录数据,因为我希望在一处看到所有数据:

[supervisord]
nodaemon=true

[program:sshd]
command=/usr/sbin/sshd -D

[program:worker]
command=python /opt/applications/myproject/worker.py -A args
directory=/opt/applications/myproject
stdout_events_enabled=true
stderr_events_enabled=true

[eventlistener:stdout]
command = supervisor_stdout
buffer_size = 100
events = PROCESS_LOG
result_handler = supervisor_stdout:event_handler

我有一个包含以上两个文件的构建目录,并且从那里的一个终端使用以下命令构建Dockerfile

docker build -t fgkrqworker .

这添加了它,以便我可以从dockerdocker-compose调用它。 不要跳过结尾的点!

由于该应用程序使用docker-compose来运行一组容器,因此现有的WORKER容器将替换为可解决我的问题的容器。 但是首先,我想证明在docker-compose.yml另一部分中,我定义了从容器到本地硬盘驱动器的映射,这是要映射的许多卷之一:

volumes: &VOLUMES
  ? /Users/me/source/myproject:/opt/applications/myproject

然后是我的容器的实际定义,它引用了上面的VOLUMES

jqworker: &WORKER
  image: fgkrqworker
  privileged: true
  stdin_open: true
  detach: true
  tty: true
  volumes:
    <<: *VOLUMES
  ports:
    - "7722:22"

这会将SSH端口映射到VM中可用的已知端口,回想一下我正在使用VirtualBox上的boot2docker ,但是需要映射到PyCharm可以使用的位置。 在VirtualBox中,打开boot2docker VM,然后选择Adapter 1 有时,“附加到:”组合会取消选择自身,因此请注意这一点。 就我而言,它应该选择NAT

单击“端口转发”,然后将内部端口映射到localhost上的端口,我选择使用相同的端口号。 应该是这样的:

  • 名称: ssh_mapped ;
  • 协议: TCP
  • 主机IP: 127.0.0.1 ;
  • 主机端口: 7722
  • 访客IP :;
  • 访客端口: 7722

注意:注意不要更改boot2docker ssh设置,否则最终将无法正确启动VM。

因此,这时我们有了一个扩展我的目标容器的容器。 它在端口22上运行ssh并将其映射到7722因为其他容器可能要使用22 ,并且在VirtualBox环境中可见。 VirtualBox将77227722映射到本地主机,您可以使用以下方法将ssh放入容器:

ssh root@localhost -p 7722

然后将提示输入密码“ soup4nuts”,您应该能够找到特定于您的容器的东西,以验证它是正确的容器,并且一切正常。 如果将其部署到本地计算机以外的任何地方,我都不会打乱root,因此请注意。 这仅用于本地调试,在实况站点上进行此操作应三思而后行

如果您使用了PyCharm的远程调试功能,那么到现在为止,您可能可以弄清其余内容。 但是这是我的设置方法:

首先,回想一下我有docker-compose.yml映射了项目目录:

? /Users/me/source/myproject:/opt/applications/myproject 

在我的容器中, /opt/applications/myproject实际上是本地硬盘上的/Users/me/source/myproject 因此,这是我项目的基础。 我的PyCharm将此目录视为项目根目录,我希望PyCharm在此处编写.pycharm_helpers ,以便在会话之间持久存在。 我在Mac方面管理源代码,但PyCharm认为这是其他地方的unixy框。 是的,直到JetBrains纳入Docker解决方案之前,这都是一个难题。

首先,转到Project X / Project Structure并创建本地映射的内容根,在我的情况下,这意味着/Users/me/source/myproject

稍后,返回并将.pycharm_helpers添加到排除的集合中,我们不希望它最终出现在源代码控制中或混淆PyCharm。

转到“构建,执行,部署”选项卡,选择“部署”并创建SFTP类型的新部署。 主机是localhost,端口7722 ,根路径是/opt/applications/myproject ,用户名是root ,密码是soup4nuts ,我检查了保存密码的选项。 我将Deployment命名为“ dockercompose”,以便以后可以选择它。

在“部署映射”选项卡上,我将本地路径设置为/Users/me/source/myproject并将部署和Web路径设置为单个“ /”,但是由于我的代码不对应于URL,因此我不使用它来调试,它是“ Web路径”设置中的占位符。 我不知道你怎么设置你的。

在Project X / Project Interpreter选项卡上,创建一个新的Remote Python Interpreter。 您可以选择Deployment Configuration并选择我们在上面创建的dockercompose配置。 主机URL应该以ssh://root@localhost:7722填写,Python解释器路径可能是/usr/bin/python 我们需要将PyCharm Helpers路径设置为默认值,因为默认值将无法在重做的容器中保留下来。 实际上,我去了项目本地目录,并在根目录中创建了一个.pycharm_helpers目录,然后在此处将路径设置为/opt/applications/myproject/.pycharm_helpers ,然后单击“确定”按钮,它将文件“ up”复制到该目录中。 。 我不知道它是否会自动创建它。

不要忘记.pycharm_helpers目录可能应该在项目根目录选项卡中排除。

此时,您可以转到“构建,执行,部署”选项卡,然后在“控制台/ Python控制台”下,选择我们在上面创建的远程解释器,并将工作目录设置为/opt/applications/myproject然后可以在容器,如果您喜欢。

现在,您需要创建一个运行配置,以便可以远程调试python代码。 进行新的Python配置,并将脚本设置为用于启动容器中python代码的脚本。 从主管的设置来看,我的是:

/opt/applications/myproject/worker.py -A args

所以我将脚本设置为/opt/applications/myproject/worker.py并将参数设置为-A args

选择我们在上面创建的远程解释器,并根据需要/opt/applications/myproject工作目录,对我来说,它是/opt/applications/myproject ,对我而言,它是工作。

现在,我想输入我的容器并停止worker.py脚本,以便启动调试版本。 当然,如果愿意,可以默认情况下忽略运行脚本,而仅使用容器进行调试。

我可以打开一个ssh会话来停止脚本,但是docker提供了一个有用的命令,该命令可以将其传递到环境中来为我完成工作。

$> docker exec -i -t supervisorctl stop worker

因为我的过程被称为“工人”。 请注意,可以通过将stop命令替换为start来重新start

现在,在PyCharm中,使用上面创建的“运行配置”启动调试会话。 它应该连接并启动设备,并在窗口中提供控制台输出。 由于我们杀死了Supervision最初启动的设备,因此不再连接。

这是裤子操作的一部分,所以可能有错误和错误的假设,我没有注意到。 特别是,PyCharm设置需要几次迭代,因此顺序可能不正确,如果失败,请尝试重新进行排序。 这是很多东西,很容易跳过一些关键的东西。

现在还没有,但是不久以后这应该不再是问题了,因为

从PyCharm 4.1 EAP(四月开始)开始,将在PyCharm中引入Docker支持。

来源: http : //blog.jetbrains.com/pycharm/2015/03/feature-spotlight-python-remote-development-with-pycharm/#comment-187772

为了避免任何SSH开销(这对于Docker来说是很合理的), docker exec绝对是必经之路。
不幸的是,到目前为止我还无法正常工作。 如果有人可以填补空白,那就太好了。 这是我所做的(使用PyCharm 4.0.4和Docker 1.4.1):

  1. 创建一个名为python_myproject.sh的文件, python_myproject.sh包含以下内容:

     #!/bin/bash docker exec -i myproject_container /path/to/containers/python2.7 

    请注意,文件名必须以python开头,否则PyCharm会抱怨。

  2. 在PyCharm的设置中的Project Interpreter ,添加一个新的本地解释器。 为其提供python_myproject.sh文件的路径。


这就是我卡住的地方。 在相当长的加载时间后(很烦的人说“正在设置库文件”),出现一个名为“无效的Python SDK”的窗口,并显示:

无法设置python SDK
在/path/to/python_myproject.sh中。
SDK似乎无效。

~/.PyCharm40/system/log/.idea

2015-02-19 17:33:30,569 [ 166966]   WARN - ution.process.OSProcessHandler - Cannot kill process tree. Trying to destroy process using Java API. Cmdline:
2015-02-19 17:34:30,628 [ 227025]   WARN - ution.process.OSProcessHandler - Cannot kill process tree. Trying to destroy process using Java API. Cmdline:
2015-02-19 17:34:30,653 [ 227050]   INFO - rains.python.sdk.PythonSdkType - 
Timed out

我认为,如果确实需要,在容器中包含SSH并不坏。 是的,自从引入docker docker exec以来,在其他用例中并不是必需的,但是由于Intellij / PyCharm仅支持通过SSH的远程解释器,因此可以。

您可以使用phusion/baseimage作为使用SSH和所需版本的Python(默认情况下PY3随附)构建自己的容器的良好起点。

从理论上讲,最好还是继续使用Vagrant来完成此任务,因为它允许您创建一个既可以在Windows / OS X机器(通过使用boot2docker)又可以在Linux(本机Docker)上运行的工作流程。

实际上,由于要进入SSH服务必须经过双NAT层,因此我无法使其在OS X上运行,而且似乎无法向Vagrant boot2docker框添加额外的接口(Vagrant 1.7.2)。

如果您只需要调试在docker容器内启动的代码,则可以使用pycharm的python调试服务器功能。 对我来说,这比通过SSH访问远程解释器麻烦得多。 该解决方案的缺点是,对于自动完成和所有此类内容,您应该具有容器解释器的本地副本,并将其标记为项目的解释器(适用于自动完成,但是我不确定是否可以从中调试代码第三方库)或使容器的解释器文件对pycharm可见(完全未经测试)。 另请注意,Python调试服务器是Professional Edition的功能

通过Python调试服务器进行调试应采取的措施:

1)确保将包含项目的目录添加到容器中。 在Dockerfile中可能看起来像这样:

ADD . /path/in/container

2)将pycharm-debug.eggpycharm-debug-py3k.egg于Python3的pycharm-debug-py3k.egg )从主机上安装pycharm的目录复制到容器的目录中,该目录位于容器的PYTHONPATH中。 开发者主机上pycharm-debug.egg的路径可能是:

  • 对于Mac: /Applications/PyCharm.app/Contents/pycharm-debug.egg
  • 对于Linux: /opt/pycharm/pycharm-debug.egg

3)创建运行/调试配置,以在主机上启动Python调试服务器,如docs的 To configure a remote debug server部分中所述。 端口是您选择的任何主机的端口,但是IP是可从容器访问主机的地址。 它可能是:

  • 如果容器通过boot2docker运行,则IP可能是192.168.99.1-带有vbox机器的仅主机网络上的主机地址
  • 如果主机是Linux,则可以通过ifconfig找到IP,对我来说是:
 docker0 Link encap:Ethernet HWaddr 56:84:7a:fe:97:99 inet addr:172.17.42.1 Bcast:0.0.0.0 Mask:255.255.0.0 

另外,不要忘记在开发人员主机上的项目路径与容器上的项目路径之间指定路径映射。

此博客文章也可能对当前步骤有所帮助

4)启动此创建的配置(例如,通过Run一个” Debug按钮)

5)创建python脚本,它将启动您的项目,并添加以下代码进行调试初始化,作为此脚本的第一行。 (确保pycharm-debug.egg在PYTHONPATH中,否则此代码无法import pydevd ):

  import pydevd pydevd.settrace('172.17.42.1', suspend=False, port=8765, stdoutToServer=True, stderrToServer=True) 

6)最后,您可以通过创建的脚本在容器中设置断点并从主机启动应用程序。 例如:

docker-compose run 'container_name' python 'script_name' 'args'

在启动时,您的启动脚本将连接到在主机上运行的Python调试服务器,并在断点处停止。 调试器功能将照常提供。

PyCharm Professional Edition 2017.2特有的步骤(但是它们可以与PyCharm CE一起使用)

我采取了以下几个步骤来使设置生效

步骤1:环境

有关您(或可能正在阅读此书的人)项目结构的一些假设:

bleh
├── README.md
├── api
│   ├── Dockerfile  <---- this is the one we want to debug
│   ├── config.example.ini
│   └── src
│       ├── __init__.py    <---- this is a pycharm project
│       ├── __main__.py    <---- this is a pycharm project
│       └── ...
├── proxy
│   ├── Dockerfile
│   ├── config.example.ini
│   └── src
│       ├── ...
│       └── ...
├── webserver
│   ├── Dockerfile
│   ├── config.example.ini
│   └── src
│       ├── ...
│       └── ...
├── frontend
│   ├── Dockerfile
│   ├── config.example.ini
│   └── src
│       ├── ...
│       └── ...
├── db
│   ├── Dockerfile
│   ├── ...
│   └── migrations
│       ├── ...
│       └── ...
└── docker-compose.yml
  • 注意bleh作为我的项目名称作为示例。
  • 注意我们还将假定该项目的绝对位置为/Users/myfunkyusername/Projects/bleh
  • 注意显然,就命名和位置而言,这都是随机的,请针对您的系统/项目进行调整
  • 注意我们还将假设您希望实时调试api服务,如稍后在docker-compose.yml文件中所示
  • 注意我们还将假设您api的内容是唯一的Dockerfile就是这样

     FROM python ADD config.example.ini /etc/bleh/config.ini RUN chmod +x /usr/bin/bleh COPY ./src /usr/bin/bleh WORKDIR /usr/bin/bleh RUN pip install -r requirements.txt CMD ["sh", "-c", "python -m bleh --cfg=/etc/bleh/config.ini"] 
  • 注意我们假设您唯一docker-compose.yml具有这些内容

     version: '2' services: api: build: context: ./api depends_on: - db expose: - "8080" networks: - default frontend: build: context: ./frontend ports: - "80:7000" networks: - default webserver: build: context: ./webserver depends_on: - frontend networks: - default proxy: build: context: ./proxy ports: - "80:80" - "443:443" depends_on: - webserver - api networks: - default db: build: context: ./db expose: - "3306" networks: - default networks: default: driver: bridge 

步骤2:建立Docker机器

专为bleh项目创建bleh -machine

docker-machine create bleh

步骤3: 连接远程解释器

  • PyCharm / Preferences / Build, Execution, Deployment / Docker单击+
  • 选择Docker machine单选按钮并在下拉bleh突出显示bleh机器
  • 选择Apply
  • 来自PyCharm / Preferences / Project:bleh / Project Interpreter
  • 单击“ Project Interpreter字段最右侧的齿轮图标,然后选择“ Add Remote
  • 选择Docker单选按钮
  • 在“ Server字段中,为该项目选择先前创建的docker计算机
  • 选择保存了您想要的该项目的python解释器的bleh_api (例如bleh_api
  • 无需更改Python interpreter path
  • 点击OK

步骤4: 配置远程调试器

  • Run / Edit Configurations选择+添加配置
  • 选择Python
  • 在“ Script字段中,使用脚本文件在将要运行的docker容器上的位置(在本示例中,该文件为/usr/bin/bleh/__main__.py因为我们提供了目标脚本的绝对位置)
  • 在“ Script parameters字段中,提供CLI参数(如果有)(模拟Dockerfile的最后一个CMD命令,即--cfg=/etc/bleh/config.ini
  • 在“ Python Interpreter字段中,选择以前建立的远程python解释器
  • Working directory字段中,选择Docker容器中Script所在的目录(例如/usr/bin/bleh
  • Path mappings字段中,单击...然后选择本地(例如/Users/myfunkyusername/Projects/bleh/api/src )和远程(例如/usr/bin/bleh
  • Docker container settings字段中,单击...
    • 确保您选择了正确的bleh_api:latest容器(例如bleh_api:latest
    • 添加端口绑定容器/主机,以模拟您在Dockerfile拥有的Dockerfile (例如Dockerfile并使用tcp协议公开到0.0.0.0现在我尚未显示您的应用程序结构是什么,但是假设您是理智的,在您的应用程序中,还指定8080作为您提供数据的端口
    • 添加卷绑定容器/主机/usr/bin/bleh / /Users/myfunkyusername/Projects/bleh/api/src
    • 确保将Network mode感谢Piotr )设置为<name_of_project_directory>_<name_of_network_from_compose_file> (例如bleh_default ,您可以在正确的docker-machine通过bleh_default docker network ls进行确认)

第5步:晒太阳或重击头部

这些步骤使我进入了工作的docker和PyCharm设置。

我不假装在每个步骤中都是正确的。 我会很乐意更新您发现的任何错误/改进。

在Docker 1.3中,使用exec命令来构建Python解释器的路径:

sudo docker exec container_name /usr/bin/python

https://docs.docker.com/reference/commandline/cli/#exechttp://forum.jetbrains.com/thread/PyCharm-2224

您可以在容器内安装SSH,然后公开端口,但这不是期望使用容器的方式,因为这会使它们肿。

我还没有尝试过,但是我会尝试创建一个调用docker exec ...的Bash脚本,就像@Anto的answer一样

然后,安装BashSupport扩展 现在创建一个新的运行配置 ,将您的脚本作为Bash脚本运行。

通过在容器中安装Pycharm并从那里运行它,您可能会有些疯狂。 您必须通过docker run -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=:0.0 pycharm-image来执行此操作,但它应该可以正常工作。 但是请记住,所有Pycharm和您的来源也都在该容器中。 因此,请经常保存,提交和推动。

他们使用PyCharm 5添加了对docker的支持。 您必须在docker-machine中配置您的docker。

如果您还没有使用docker-machine,则可以使用通用机器引擎连接到现有计算机,并通过SSH进入无业游民的VM或本地主机(如果您不在VM中运行事物)。 不幸的是,我没有找到解决ssh到localhost的方法。

我还没有找到一种将卷挂载到它们使用的docker映像中以与我的开发树共享文件的方法,但是这可能是可行的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM