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

tri*_*eta 35 python pycharm docker

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

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

我应该使用暴露的ssh端口准备特殊的Docker镜像吗?如何更容易地做到这一点?

Fra*_* K. 12

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

这是我解决问题的方法.我的情况是,我被指派对使用docker-compose创建一组四个容器的Web应用程序的特定区域进行干预.Docker-compose是一种meta 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"]
Run Code Online (Sandbox Code Playgroud)

Supervisor允许我从一个命令运行多个任务,在这种情况下是原始命令和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
Run Code Online (Sandbox Code Playgroud)

我有一个包含上述两个文件的构建目录,并且从那里的终端我构建了supervisord.conf:

docker build -t fgkrqworker .
Run Code Online (Sandbox Code Playgroud)

这会添加它,以便我可以从supervisor-stdout或调用它Dockerfile.不要跳过尾随点!

由于应用程序用于docker运行一组容器,现有docker-compose容器将替换为解决我的问题的容器.但首先我要表明,在我的另一部分中,我docker-compose定义了从容器到本地硬盘的映射,这是映射的多个卷之一:

volumes: &VOLUMES
  ? /Users/me/source/myproject:/opt/applications/myproject
Run Code Online (Sandbox Code Playgroud)

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

jqworker: &WORKER
  image: fgkrqworker
  privileged: true
  stdin_open: true
  detach: true
  tty: true
  volumes:
    <<: *VOLUMES
  ports:
    - "7722:22"
Run Code Online (Sandbox Code Playgroud)

这将SSH端口映射到VM中可用的已知端口,回想一下我正在使用docker-compose.yml哪个端口乘坐VirtualBox,但需要将其映射到PyCharm可以获取的位置.在VirtualBox中,打开VOLUMESVM并选择boot2docker.有时候"附加到:"组合会自行取消选择,所以要注意这一点.在我的情况下它应该已经boot2docker选择.

单击"端口转发"并将内部端口映射到localhost上的端口,我选择使用相同的端口号.应该是这样的,名字:Adapter 1; 议定书:NAT; 主机IP ssh_mapped:; 主机端口:TCP; 访客IP:; 宾客港:127.0.0.1.注意:注意不要更改boot2docker`ssh'设置,否则最终将无法正确启动VM.

所以,此时我们有一个扩展我的目标容器的容器.它在端口22上运行ssh并将其映射到7722,因为其他容器可能想要使用22,并且在VirtualBox环境中可见.VirtualBox将7722到7722映射到localhost,您可以使用以下命令ssh到容器中:

ssh root@localhost -p 7722
Run Code Online (Sandbox Code Playgroud)

然后会提示输入密码'soup4nuts',你应该能够找到特定于容器的东西,以验证它是否正确,并且一切正常.如果我在除了本地机器之外的任何地方部署它,我不会乱用root,所以要警告.这仅适用于本地调试,您应该在实际站点上三思或三次.

此时,如果您使用了PyCharm的远程调试,您可能会想到剩下的部分.但这是我如何设置它:

首先,回想一下我已经7722映射了项目目录:

? /Users/me/source/myproject:/opt/applications/myproject 
Run Code Online (Sandbox Code Playgroud)

在我的容器7722中实际上是ssh在我的本地硬盘上.所以,这是我项目的根源.我的PyCharm将此目录视为项目根目录,我希望PyCharm在22此处编写,以便它在会话之间保持不变.我在mac方面管理源代码,但是PyCharm认为它在其他地方是一个unixy盒子.是的,在JetBrains采用Docker解决方案之前,这是一个很大的问题.

首先,转到项目X /项目结构并创建本地映射的内容根,在我的情况下意味着 7722

稍后,回过头来添加22到排除的集合中,我们不希望这最终导致源代码控制或混淆PyCharm.

转到构建,执行,部署选项卡,选择部署并创建新的SFTP类型部署.主机是localhost,端口7722,根路径是7722,用户名是7722密码docker-compose.yml,我选中了保存密码的选项.我将我的部署命名为"dockercompose",以便我以后可以选择它.

在部署映射选项卡上,我将本地路径/opt/applications/myproject和部署以及Web路径设置为单个'/',但由于我的代码与URL不对应,我不使用它来调试,它是Web中的占位符路径设置.我不知道你怎么设置你的.

在Project X/Project Interpreter选项卡上,创建一个新的Remote Python Interpreter.您可以选择部署配置并选择我们在上面创建的'dockercompose'配置.主机URL应填写为'ssh:// root @ localhost:7722',Python解释器路径可能是/Users/me/source/myproject.我们需要设置PyCharm Helpers Path,因为默认情况下,容器无法重做.我实际上去了我的项目本地目录并.pycharm_helpers在根目录中创建了一个目录,然后在这里设置路径/Users/me/source/myproject,当我点击OK按钮时,它将文件"up"复制到目录中.我不知道它是否会自动创建它.

不要忘记.pycharm_helpers应该在项目根选项卡上排除目录.

此时,您可以转到构建,执行,部署选项卡,然后在控制台/ Python控制台下,选择我们在上面创建的远程解释器并将工作目录设置为7722,如果愿意,您可以在容器中运行Python控制台.

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

/opt/applications/myproject/worker.py -A args
Run Code Online (Sandbox Code Playgroud)

所以我将脚本设置为/opt/applications/myproject和参数root.

选择我们上面创建的远程解释器,并根据需要选择工作目录,对我而言,这soup4nuts对我来说是完成工作的.

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

我可以打开一个ssh会话来停止脚本,但是docker提供了一个有用的命令,它可以通过将它传递给环境来完成我的工作.

$> docker exec -i -t supervisorctl stop worker
Run Code Online (Sandbox Code Playgroud)

因为我的流程被命名为"工人".请注意,您可以通过替换/Users/me/source/myproject命令来重新启动dockercompose.

现在,在PyCharm中,使用上面创建的运行配置启动调试会话.它应该连接并启动,并在窗口中为您提供控制台输出.因为我们杀了监督最初开始的那个,它已经不再连接了.

这是裤子操作的一个席位,所以可能会有错误和错误的假设,我没有注意到.特别是,PyCharm设置需要几次迭代,因此顺序可能不正确,如果失败则再试一次.这是很多东西,很容易跳过一些关键的东西.


duk*_*ody 0

对于 Docker 1.3,使用以下exec命令构建 Python 解释器的路径:

sudo docker exec container_name /usr/bin/python
Run Code Online (Sandbox Code Playgroud)

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

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

  • 仅供参考:http://forum.jetbrains.com/thread/PyCharm-2224 在这个问题中提到没有得到解答。我还没有找到办法做到这一点。 (2认同)