docker+tensorflow+pycharm完美配置

本文实现目标

通过 Pycharm 运行和调试 docker 中 Tensorflow-GPU 的代码

为什么写这篇文章

原因1

因为网上其他的配置方法对我来说并不是很完美

网上大部分的教程都是使用 SFTP 来进行部署, 但是对于本地运行调试来说并不是很好, 一是需要上传文件到 docker , 二是如果数据集很大, 那么会有两份很占空间

原因2

很多奇奇怪怪的问题别人的教程中都没有提及

Pycharm设置

先谈一谈 Pycharm 中的 Tools->Deployment 和 Settings->Project Interpreter

Deployment

Deployment 的功能即将 Pycharm 当前项目的文件自动上传到需要部署的目录

在这其中有几种不同的方式, 介绍如下

SFTP

将 Pycharm 当前项目的文件上传到你设置的远程服务器目录里

Local or mounted folder

将 Pycharm 当前项目的文件上传到你设置的本地目录里

In place

当前目录即需要部署的目录

三种方法总结

如果是调试本地 docker 中代码, 那么用 In place 加下文要讲的 Path Mappings 更好

如果是调试远程 docker 中代码, 那么只能使用 SFTP

对于 Local, 相当与比 In place 少了一个限制, 详见下文 Project Interpreter 中几个例子的比较

Project Interpreter

设置远程解释器很简单, 复杂的是需要设置目录映射 ( Path Mappings )

通过三个例子来讲解

SFTP例子

一般使用 SFTP 在设置 Deployment 会自动设置 Path Mappings

假设写代码的目录是/A, 要运行的文件是/A/1.py, 远程目录为/B

写一个映射/A->/B, 那么运行时会把/A的部分替换为/B, 然后命令就变成了ssh://root@remote_ip:22/usr/bin/python3 -u /B/1.py

此时实际运行的代码是/B/1.py

In place+docker

注意: 在这种情况下, 代码所在位置必须为共享目录的子目录

假设写代码的目录是/A/B, 要运行的文件是/A/B/1.py, docker容器的映射是/A:/C, 则需要添加Path Mappings, 添加一个/A->/C, 此时实际运行的代码是/A/B/1.py

local+docker

相比 In place , 解除了代码目录必须为共享目录的子目录的限制

假设写代码的目录是/A, 需要本地部署的目录是/B, 容器的映射是/B:/C, 则需要添加/A->/C, 此时实际运行的代码是/B/1.py

总结

始终记住以下三件事即可

  1. Deployment 只是将代码换了个地方

  2. docker 的目录是共享的(同一个目录)

  3. Path Mappings 只是将写代码的目录的前面相应部分进行替换, 需要确保替换了以后在docker中是可以找到这个目录的

整体过程

建议先看一遍后再运行命令

配置docker

创建容器

sudo docker run -p 10000:22 --privileged=true --gpus all -it --name=tf -v /home/zx:/home/zx tensorflow/tensorflow:latest /bin/bash

参数解释:

-p 10000:22 如果你只是在本地开发, 那么可以不用端口映射(可以直接访问容器的 ip ), 如果需要远程连接, 那么这就是必须的了

--privileged=true 取决于你需要多大的权限, 使用该参数,container 内的 root 拥有真正的 root 权限, 可以看到很多 host 上的设备,并且可以执行 mount , 同时解锁一些命令(例如 systemctl )

-v /home/zx:/home/zx host 与 docker 目录映射, 如果你的 Deployment 选择了 In place , 那么至少需要有一个映射

配置ssh

小提示: apt 可以通过设置代理加速下载, 例如apt -o Acquire::http::proxy="http://172.17.0.1:8888/" update

apt update

apt install nano

apt install openssh-server

/etc/ssh/sshd_config最后添加

PermitRootLogin yes

如果需要通过公钥登录, 那么再添加下面这一行

PubkeyAuthentication yes

如果使用密码登录, 记得使用passwd设置密码

注意: ssh 是无法开机启动的, 即每次启动 docker 需要手动启动 ssh 服务

service ssh start

配置SFTP

这一步是必须的, 因为 Pycharm 会上传一些文件到你的 docker 容器中

默认 SFTP 是不行的, 会报错(Received message too long 458961211 Ensure the remote shell produces no output for non-interactive sessions.)

/etc/ssh/sshd_config找到Subsystem sftp /usr/lib/openssh/sftp-server这一行并注释, 然后在下面添加一行Subsystem sftp internal-sftp

配置Debug

本节主要介绍如何在 host 调试 docker 中的代码

在 Pycharm 的 Run/Debug Configurations 中创建一个 Python Debug Server , 设置本机的 ip 和监听端口, 这个 ip 取决与你是在哪个网络中进行调试(比如 docker 调试那就填 172.17.0.1)

然后上面有很多提示, 总的来说就两个意思

  1. 在远程服务器或docker中安装相应的库

  2. 在需要调试的文件中加入命令以连接 Debug Server

如何Debug

先运行 Python Debug Server 进行监听, 然后再运行需要调试的文件, 当运行至pydevd_pycharm.settrace时就会停住, 然后就和本地 Debug 没区别了