本文介绍了如何将PyCharm连接到位于Docker容器内的python解释器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



,但是。



我应该准备专门的Docker图像与暴露的ssh端口?

解决方案

更新:PyCharm 2017.1有一个解决此问题的解决方案,请参阅博客条目:博客.jetbrains.com / pycharm / 2017/03 / docker-compose-getting-flask-up-and-running /



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



首先,我需要扩展目标容器,名为 jqworker 。我将使用supervisior来做大量的管理事情。

  FROM jqworker 

#获取主管来控制多个进程,sshd允许连接。
#和supervisor-stdout允许我们将输出发送到主docker输出。
RUN apt-get update&& apt-get install -y主管openssh-server python-pip \
&& pip安装主管 - 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

#修复SSH,可能应该在实际部署的情况下解决这个问题。
RUN echo'root:soup4nuts'| chpasswd
运行sed -i的/ PermitRootLogin无密码/ PermitRootLogin是/'/ etc / ssh / sshd_config

#SSH登录修复。否则用户在登录后被启动
运行sed's @ session\s * required\s * pam_loginuid.so @ session可选pam_loginuid.so@g'-i /etc/pam.d/sshd
ENV NOTVISIBLE在用户配置文件
RUN echo导出VISIBLE = now>>> / etc / profile

#在22上暴露SSH,但是会映射到其他地址。
EXPOSE 22

#用supervisiord替换旧entrypoint,启动sshd和worker.py
ENTRYPOINT [/ usr / bin / supervisord]

主管让我从一个命令运行多个任务,在这种情况下是原始命令和SSHD。是的,每个人都说,码头中的SSHD是邪恶的,集装箱应该是这样的,而且这个和blah blah,但编程是关于解决问题,不符合忽略上下文的任意规则。我们需要SSH来调试代码,而不是将其部署到现场,这是我们扩展现有容器而不是将其添加到部署结构中的一个原因。我在本地运行它,以便我可以在上下文中调试代码。



这是supervisord.conf文件,请注意,我正在使用supervisor-stdout包将输出引导到主管,而不是记录数据,因为我喜欢看到它在一个地方:

  [supervisord] 
nodaemon = true

[程序: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  

添加它,以便我可以从 docker docker-compose 。不要跳过尾点!



由于应用程序使用 docker-compose 运行一组容器,所以现有的 WORKER 容器将被替换为解决我的问题的容器。但是首先我想显示在另一部分我的 docker-compose.yml 中我定义了从容器到本地硬盘驱动器的映射,这是一个卷被映射:

 卷:& VOLUMES 
? / users / me / source / myproject:/ opt / applications / myproject

然后我的实际定义容器,其引用上述 VOLUMES

  jqworker:& WORKER 
image:fgkrqworker
特权:true
stdin_open:true
detach:true
tty:true
卷:
<< * VOLUMES
ports:
- 7722:22

SSH端口到虚拟机中可用的已知端口,请记住,我正在使用在$ VirtualBox上的 boot2docker ,但需要映射到PyCharm可以获取的位置。在VirtualBox中,打开 boot2docker VM,然后选择 Adapter 1 。有时候,附属于组合会自动选择,因此请注意。在我的情况下,应该选择 NAT



点击端口转发,将内部端口映射到端口在本地主机上,我选择使用相同的端口号。它应该是,名称: ssh_mapped ;协议: TCP ;主机IP: 127.0.0.1 ;主机端口: 7722 ;访客IP:嘉宾港: 7722 。注意:小心不要更改boot2docker`ssh'设置,否则最终无法正确启动VM。



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

  ssh root @ localhost -p 7722 

然后会提示输入密码soup4nuts,您应该可以找到特定于您的容器的东西验证它是正确的,一切都正常。如果我在任何地方部署我的本地机器,我不会弄乱root,所以要警告。 这只是为了在本地进行调试,你应该在现场网站上考虑两次或三次这样做。



在这一点上,如果您使用PyCharm的远程调试功能,您可以将其余部分看出来。但是这是我如何设置:



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

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

在我的容器中<$ c在我的本地硬盘上,$ c> / opt / applications / myproject 实际上是 / Users / me / source / myproject 所以,这是我项目的根源。我的PyCharm将此目录视为项目根目录,我希望PyCharm在此处写入 .pycharm_helpers ,以便它们在会话之间保持不变。我正在管理Mac上的源代码,但PyCharm认为它是其他地方的一个非混合的框。是的,直到JetBrains结合了Docker解决方案,这是一个垃圾。



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



稍后再回来,将 .pycharm_helpers 添加到排除的设置,我们不希望最终在源代码控制或混淆PyCharm。



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



在部署映射选项卡上,将本地路径设置为 / Users / me / source / myproject 和部署和Web路径到一个'/',但由于我的代码不对应于一个URL,我不使用这个来调试,它是Web路径设置中的占位符。我不知道你如何设置你的。



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



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



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



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

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

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



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



现在我想进入我的容器并停止了worker.py脚本,所以我可以启动一个调试版本。当然,如果你喜欢,你可以忽略默认运行该脚本,并且仅使用容器进行调试。



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

  $> docker exec -i -t supervisorctl stop worker 

由于我的进程名为worker。请注意,您可以通过用开始替换 stop 命令来重新启动。



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



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


I'm starting with Docker, but I don't know how to configure PyCharm to use a python interpreter located in a container.

It was easy to setup with Vagrant, but there's apparently no official way to do it with Docker yet.

Should I prepare special Docker image with exposed ssh port? How to do that more easily?

解决方案

UPDATE: PyCharm 2017.1 has a solution for this problem, see the blog entry at: blog.jetbrains.com/pycharm/2017/03/docker-compose-getting-flask-up-and-running/

Here is how I solved the problem. My circumstances are that I was assigned to do an intervention on a specific area of a web app that used docker-compose to create a set of four containers. Docker-compose is a kind of meta docker that manages multiple docker containers from one command. I did not want to mangle their existing setup since so many things depend on it. But since I was working on one specific part in one of the images I decided that I would extend one of the containers with ssh so that I could debug from PyCharm. Further, I wanted the app to run as normal when started and only by forcing it to quit and then connecting to it from PyCharm would I have a debuggable component. Here is what I did on my mac that uses boot2docker (on VirtualBox) to setup docker correctly.

First, I need to extend the target container, called jqworker. I am going to use "supervisior" to do the heavy lifting of managing things.

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"]

Supervisor lets me run multiple tasks from one command, in this case the original command and SSHD. Yes, everyone says that SSHD in docker is evil and containers should this and that and blah blah, but programming is about solving problems, not conforming to arbitrary dicta that ignore context. We need SSH to debug code and are not deploying this to the field, which is one reason we are extending the existing container instead of adding this in to the deployment structure. I am running it locally so that I can debug the code in context.

Here is the supervisord.conf file, note that I am using the supervisor-stdout package to direct output to supervisor instead of logging the data as I prefer to see it all in one place:

[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

I have a build directory containing the above two files, and from a terminal in there I build the Dockerfile with:

docker build -t fgkrqworker .

This adds it so that I can call it from docker or docker-compose. Don't skip the trailing dot!

Since the app uses docker-compose to run a set of containers, the existing WORKER container will be replaced with one that solves my problems. But first I want to show that in another part of my docker-compose.yml I define a mapping from the containers to my local hard drive, this is one of a number of volumes being mapped:

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

Then the actual definition for my container, which references the above VOLUMES:

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

This maps the SSH port to a known port that is available in the VM, recall I am using boot2docker which rides on VirtualBox, but the needs to be mapped out to where PyCharm can get at it. In VirtualBox, open the boot2docker VM and choose Adapter 1. Sometimes the "Attached to:" combo unselects itself, so watch for that. In my case it should have NAT selected.

Click "Port Forwarding" and map the inner port to the a port on localhost, I choose to use the same port number. It should be something like, Name: ssh_mapped; Protocol: TCP; Host IP:127.0.0.1; Host Port:7722; Guest IP:; Guest Port: 7722. Note: be careful not to change the boot2docker `ssh' setting or you will eventually be unable to start the VM correctly.

So, at this point we have a container that extends my target container. It runs ssh on port 22 and maps it to 7722 since other containers might want to use 22, and is visible in the VirtualBox environment. VirtualBox maps 7722 to 7722 to the localhost and you can ssh into the container with:

ssh root@localhost -p 7722

Which will then prompt for the password, 'soup4nuts' and you should be able to locate something specific to your container to verify that it is the right one and that everything works OK. I would not mess with root if I were deploying this anywhere but my local machine, so be warned. This is only for debugging locally and you should think twice or thrice about doing this on a live site.

At this point you can probably figure the rest of it out if you have used PyCharm's remote debugging. But here is how I set it up:

First, recall that I have docker-compose.yml mapping the project directory:

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

In my container /opt/applications/myproject is actually /Users/me/source/myproject on my local hard drive. So, this is the root of my project. My PyCharm sees this directory as the project root and I want PyCharm to write the .pycharm_helpers here so that it persists between sessions. I am managing source code on the mac side of things, but PyCharm thinks it is a unixy box elsewhere. Yes, it is a bit of kludge until JetBrains incorporates a Docker solution.

First, go to the Project X/Project Structure and create a Content Root of the local mapping, in my case that means /Users/me/source/myproject

Later, come back and add .pycharm_helpers to the excluded set, we don't want this to end up in source control or confuse PyCharm.

Go to the Build, Execution, Deployment tab, pick Deployment and create a new Deployment of SFTP type. The host is localhost, the port 7722, the root path is /opt/applications/myproject and the username is root and password is soup4nuts and I checked the option to save the password. I named my Deployment 'dockercompose' so that I would be able to pick it out later.

On the Deployment Mappings tab I set the local path to /Users/me/source/myproject and deployment and web path to a single '/' but since my code doesn't correspond to a URL and I don't use this to debug, it is a placeholder in the Web Path setting. I don't know how you might set yours.

On the Project X/Project Interpreter tab, create a new Remote Python Interpreter. You can pick the Deployment Configuration and choose the 'dockercompose' configuration we created above. The host URL should fill in as 'ssh://root@localhost:7722' and the Python Interpreter Path will likely be /usr/bin/python. We need to set the PyCharm Helpers Path as the default will not survive the container being redone. I actually went to my project local directory and created a .pycharm_helpers directory in the root, then set the path here as /opt/applications/myproject/.pycharm_helpers and when I hit the OK button it copied the files "up" to the directory. I don't know if it will create it automatically or not.

Don't forget that the .pycharm_helpers directory should probably be excluded on the project roots tab.

At this point you can go to the Build, Execution, Deployment tab, and under Console/Python Console, pick the remote interpreter we created above and set the working directory to /opt/applications/myproject and you can run your Python Console in the container if you like.

Now you need to create a Run Configuration so that you can remotely debug your python code. Make a new Python configuration and set the script to the one that used to start the python code in the container. Mine, from the supervisor setup, above is:

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

So I set the script to /opt/applications/myproject/worker.py and the parameters to -A args.

Choose the remote interpreter we created above, and the working directory as needed, for me it is /opt/applications/myproject and for me that does the job.

Now I want to enter my container and stop the worker.py script so I can start up a debug version. Of course, if you like you can ignore running the script by default and only use the container for debugging.

I could open a ssh session to stop the script, but docker provides a useful command that will do the work for me by passing it into the environment.

$> docker exec -i -t supervisorctl stop worker

As my process is named 'worker'. Note that you can restart by replacing the stop command with start.

Now, in PyCharm start a debug session with the Run Configuration created above. It should connect and start things up and give you console output in the window. Since we killed the one that Supervision originally started it is no longer connected.

This was a seat of the pants operation, so there may be errors and incorrect assumptions I didn't notice. Particularly, the PyCharm setup required a few iterations, so the order may be incorrect, try going through it again if it fails. This is a lot of stuff and easy to skip something critical.

这篇关于如何将PyCharm连接到位于Docker容器内的python解释器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 09:56
查看更多