docker容器中图形化界面开发环境配置
背景:在docker中使用图形化界面,例如opencv中的imshow或pyqt5开发
跑dockerhub的pyqt5¶
发现WSL(Windows Subsystem for Linux)支持GUI(图形界面)的Linux应用了
windows端安装vcXsrv https://sourceforge.net/projects/vcxsrv/
然后打开Xlaunch对启动vsXsrv进行设置, additional parameter要添加-ac
之后打开wsl, pull一个docker镜像,例如
指令如下
docker pull fadawar/docker-pyqt5
export DISPLAY=10.180.73.62:0.0 #这里要换成自己windows端的ipv4地址,0.0表示显示编号和屏幕编号
docker run --rm -it -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=$DISPLAY -u qtuser jozo/pyqt5 python3 /tmp/hello.py
参数解读
-v
本地目录:容器目录 或 -v 容器目录. 将本机的当前目录,挂载到镜像中的目录-e
向容器内部传递环境变量-u
用户user
自己构建镜像¶
方法一:由容器构建镜像¶
在容器内中配置环境¶
以下是在容器中下载qt5并且构建为images的方法
首先进入一个基本容器
安装相关的包
apt-get update #更新包索引
apt install pyqt5* qttools5-dev-tools qt5-default python3-pyqt5 #下载qttool
pip3 install pyqt5
更改环境便变量
export DISPLAY=10.180.73.62:0.0
创建下面的python脚本为检查环境是否配置好
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget
import sys
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('win')
self.setGeometry(100, 100, 1000, 500)
self.button = QPushButton('click me!!', self)
self.button.clicked.connect(self.on_button_clicked)
self.layout = QVBoxLayout()
self.layout.addWidget(self.button)
self.widget = QWidget()
self.widget.setLayout(self.layout)
self.setCentralWidget(self.widget)
def on_button_clicked(self):
print("按钮被点击了!")
self.button.setText("already click")
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MainWindow()
ex.show()
sys.exit(app.exec_())
运行该脚本会弹出vcXsrv的窗口界面,即证明环境安装完成
在终端输入
designer
同样会弹出qt designer的界面
提交为镜像¶
wsl终端中输入
docker ps
可查看到当前运行的容器, 找到我们刚刚配置好环境的容器的ID,例如(CONTAINER ID为c3f279d17e0a)
docker commit c3f279d17e0a
此时查看镜像会发现多了一个名为<none>
的镜像, 我们找到它的镜像id, 例如(IMAGE ID
为0c17f0798823), 并给它标号为my_image
docker tag 0c17f0798823 my_image
之后我们继续查看images就会发现之前的<none>
已经成了我们预设的my_image, TAG默认为latest, REPOSITORY后面加:可以指定tag
以上的两条命令可以通过一条命令实现
docker commit c3f279d17e0a my_image:1.0
执行之后的tag为1.0而不是latest
大功告成,之前的容器可以停止并且删除了
docker stop c3f279d17e0a
docker rm c3f279d17e0a
由于没有规定cmd或者entrypoint, 所以在run时要添加--entrypoint /bin/bash
docker run --name my_app -it --rm --entrypoint /bin/bash -e DISPLAY=10.180.73.62:0.0 my_image
方法二¶
将上述的过程编写为Dockerfile
FROM pytorch/pytorch:2.0.0-cuda11.7-cudnn8-devel
ENV DEBIAN_FRONTEND=noninteractive
# 还没有遇到这个问题
# # This fix: libGL error: No matching fbConfigs or visuals found
# ENV LIBGL_ALWAYS_INDIRECT=1
# Install Python 3, PyQt5
RUN apt-get update && apt install -y pyqt5* qttools5-dev-tools qt5-default python3-pyqt5 git vim&& pip3 install pyqt5
CMD /bin/bash
运行镜像
docker run --name my_app -it --rm --entrypoint /bin/bash -e DISPLAY=10.180.73.62:0.0 my_image
之后在vscode中调试可以通过写一个.devcontainer.json
方便配置
vscode中的.devcontainer编写¶
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/docker-existing-dockerfile
{
"name": "app_container",
"image": "my_image",
"runArgs": ["--rm", "--gpus", "all", "-e", "DISPLAY=10.180.73.62:0.0", "--entrypoint","/bin/bash"]
}
ssh连接远程docker¶
ssh-keygen -t rsa -C "PesionKey"
生成本地公钥和私钥,默认存在.ssh/中, -C指定注释,否则默认为本地主机的名字
之后可以指定是否设置passphares, 可以理解之后登录远程机子就仅需输入passphares, 可以为空
ssh-copy-id user@userip
将本地的公钥复制到远程user@userip的主机上, 之后会要求你输入远程机子密码
ssh user@userip
之后就可以通过刚刚设置的passphares登录主机了