使用Docker将PyQt深度学习项目打包成镜像

前言

由于项目原因,需要学习将深度学习项目打包成docker镜像,所以本文将使用一个封装了yolo的PyQt项目为例,展示如何将此项目打包成docker镜像。

安装docker

通过官方源安装:

复制代码
curl -fsSL https://get.docker.com -o get-docker.sh

sudo sh get-docker.sh

如果上面的方法失败就采用下面的指令:

复制代码
sudo apt install -y docker.io

安装好后,将当前用户添加到 docker 组(避免每次使用 sudo)

复制代码
sudo usermod -aG docker $USER

然后重新登录或刷新组权限

复制代码
newgrp docker

docker的基本命令

查看docker版本

复制代码
docker --version

例如我这里是

Docker version 28.4.0, build d8eb465

查看所有的docker镜像,这里只有我先前已经创建好的镜像

复制代码
docker images

将该路径建立为docker镜像

复制代码
docker build -t xxx .

运行docker镜像

复制代码
docker run xxx

查看运行中的镜像

复制代码
docker ps -a

Dockerfile

Dockerfile文件是指导docker进行打包的文档,主要有以下部分:

FROM:制定运行环境

WORKDIR:制定工作目录

COPY:拷贝指令

RUN:预运行指令

CMD:CMD运行指令

下面给出我的项目的Dockerfile仅供参考:

python 复制代码
FROM ubuntu:20.04

ENV DEBIAN_FRONTEND=noninteractive
ENV PYTHONUNBUFFERED=1
ENV QT_DEBUG_PLUGINS=0
ENV USE_FLASH_ATTN=0
ENV PYTHONPATH=/app
ENV XDG_RUNTIME_DIR=/tmp/runtime-root
ENV LANG=zh_CN.UTF-8
ENV DISPLAY=:0

# 在Ubuntu 20.04中安装Python 3.8和基本环境依赖
RUN apt-get update && apt-get install -y \
    python3 \
    python3-pip \
    python3-pyqt5 \
    python3-pyqt5.qtwebengine \
    language-pack-zh* \
    ttf-wqy-microhei \
    x11-apps \
    && rm -rf /var/lib/apt/lists/*

# 升级pip并设置工作目录
RUN python3 -m pip install -U pip setuptools wheel
WORKDIR /app

# 复制requirements.txt并安装Python依赖
COPY requirements.txt ./
RUN pip install -r requirements.txt

# 复制应用程序代码
COPY . .

# 中文编码设置
RUN locale-gen zh_CN.UTF-8 && \
    update-locale LANG=zh_CN.UTF-8 LANGUAGE=zh_CN.UTF-8 LC_ALL=zh_CN.UTF-8

# 确保settings.json文件存在并设置权限
RUN mkdir -p /app/data && \
    if [ ! -f /app/data/settings.json ]; then \
        echo "{}" > /app/data/settings.json; \
    fi && \
    chmod 666 /app/data/settings.json

# 创建运行时目录
RUN mkdir -p /tmp/runtime-root && chmod 700 /tmp/runtime-root

# 设置入口点
CMD ["python3", "main.py"]

运行本地文件

YOLO_UI/

├── Dockerfile

├── .dockerignore

├── requirements.txt

├── main.py

└── ui/

├── main_window.py

├── init.py

├── assets/

├── tabs/

│ ├── init.py

│ ├── dataset_splitter_tab.py

│ ├── image_quality_yab.py

│ ├── inference_tab.py

│ ├── settings_tab.py

│ ├── testing_tab.py

│ └── training_tab.py

└── utils/

├── init.py

├── console.py

├── error.py

├── file.py

├── infer.py

├── splash_screen.py

├── tester.py

├── theme.py

└── trainer.py

我这里的pyqt的一个项目,直接运行 python main.py文件会报错,根据报错提示,采用下面的指令运行成功。

复制代码
QT_QPA_PLATFORM=wayland python main.py

可以正常的打开了界面了。

docker换源

如果编译这一步走不通,一般都是镜像源的问题:备用源1,备用源2,备用源3。这里提供了三个,我使用第一个就通过了。如果拉取镜像还是网络问题,请切换其他的网络,或者是手机流量均可。

python 复制代码
sudo tee /etc/docker/daemon.json <<-'EOF'
{
    "registry-mirrors": [
     "https://docker.m.daocloud.io",
     "https://docker.imgdb.de",
     "https://docker-0.unsee.tech",
     "https://docker.hlmirror.com",
     "https://docker.1ms.run",
     "https://func.ink",
     "https://lispy.org",
     "https://docker.xiaogenban1993.com"
    ]
}
EOF
python 复制代码
sudo tee /etc/docker/daemon.json <<'EOF'
{
  "registry-mirrors": [
    "https://docker.rainbond.cc",
    "https://docker.registry.cyou/",
    "https://docker-cf.registry.cyou/",
    "https://dockercf.jsdelivr.fyi/",
    "https://docker.jsdelivr.fyi/",
    "https://dockertest.jsdelivr.fyi/",
    "https://mirror.aliyuncs.com/",
    "https://dockerproxy.com/",
    "https://mirror.baidubce.com/",
    "https://docker.m.daocloud.io/",
    "https://docker.nju.edu.cn/",
    "https://docker.mirrors.sjtug.sjtu.edu.cn/",
    "https://docker.mirrors.ustc.edu.cn/",
    "https://mirror.iscas.ac.cn/",
    "https://docker.rainbond.cc/",
    "https://jq794zz5.mirror.aliyuncs.com"
  ]
}
EOF
python 复制代码
sudo tee /etc/docker/daemon.json <<'EOF'
{
  "registry-mirrors": [
    "https://docker.registry.cyou",
    "https://docker-cf.registry.cyou",
    "https://dockercf.jsdelivr.fyi",
    "https://docker.jsdelivr.fyi",
    "https://docker.rainbond.cc",
    "https://dockertest.jsdelivr.fyi",
    "https://mirror.aliyuncs.com",
    "https://dockerproxy.com",
    "https://mirror.baidubce.com",
    "https://docker.m.daocloud.io",
    "https://docker.nju.edu.cn",
    "https://docker.mirrors.sjtug.sjtu.edu.cn",
    "https://docker.mirrors.ustc.edu.cn",
    "https://mirror.iscas.ac.cn",
    "https://docker.rainbond.cc",
    "https://do.nark.eu.org",
    "https://dc.j8.work",
    "https://gst6rzl9.mirror.aliyuncs.com",
    "https://registry.docker-cn.com",
    "http://hub-mirror.c.163.com",
    "http://mirrors.ustc.edu.cn/",
    "https://mirrors.tuna.tsinghua.edu.cn/",
    "http://mirrors.sohu.com/"
  ],
  "insecure-registries": [
    "registry.docker-cn.com",
    "docker.mirrors.ustc.edu.cn"
  ],
  "debug": true,
  "experimental": false
}
EOF

重新加载配置

python 复制代码
systemctl daemon-reload

重启docker

python 复制代码
systemctl restart docker

查看配置是否生效

python 复制代码
docker info

部分信息如下所示:

可以看到我此处的镜像源已经切换成功。

将项目进行打包

接下来打包镜像:

python 复制代码
sudo docker build -t yolo-ui-app .

如果不成功,就换网络试试,切换镜像。

我这里打包成功了!!下面有一些权限问题,参考这篇文章:采用docker部署含有qt界面的Python项目教程_docker pyqt

停止x11访问限制,只允许本地连接,每次开机都要使用此命令

python 复制代码
xhost +local:root

检查DISPLAY变量

python 复制代码
echo $DISPLAY

这里会显示 :0

测试X11是否正常工作

python 复制代码
xeyes

获取X11认证信息

python 复制代码
xauth list $DISPLAY

中间出现了一个错误,问题在我的requirements.txt文件里面:

基础包(使用清华镜像)

-i https://pypi.tuna.tsinghua.edu.cn/simple/

torch>=1.8.0

numpy==1.21.6

PyQt5==5.15.10

PyYAML==6.0.1

opencv-python>=4.5.0

Pillow>=9.0.0

matplotlib>=3.5.0

seaborn>=0.11.0

ultralytics==8.0.145

onnx>=1.12.0

好像是我的Dockfile里面有了,然后这里好像还与版本有关系,但是注释掉就没问题了。

运行容器

python 复制代码
docker run --rm -it \
  --name yolo-ui-app-container \
  -e DISPLAY=$DISPLAY \
  -v /tmp/.X11-unix:/tmp/.X11-unix \
  -v $HOME/.Xauthority:/root/.Xauthority:ro \
  --network host \
  yolo-ui-app

正常显示出来了

总结

目前装的仅是cpu版本,对于gpu版本会发生超时和存储不够的问题,关于这一部分后面再找时间研究一下。

相关推荐
落日漫游3 小时前
InnoDB:MySQL高性能事务引擎详解
运维·sql
龙门吹雪3 小时前
Docker 安装 canal 详细步骤
运维·docker·容器·canal·mysql binlog 日志·增量数据订阅消费
椒盐螺丝钉3 小时前
TypeScript类型兼容性
运维·前端·typescript
老黄编程3 小时前
ubuntu如何查看一个内核模块被什么模块依赖(内核模块信息常用命令)?
linux·运维·ubuntu
Freed&4 小时前
Ansible 生产级自动化指南:Playbook、Handlers、Jinja2 全解析
运维·自动化·ansible
b***25114 小时前
储能电池包的自动化产线探秘|深圳比斯特自动化
运维·自动化
ZeroNews内网穿透4 小时前
新版发布!“零讯”微信小程序版本更新
运维·服务器·网络·python·安全·微信小程序·小程序
工控小楠4 小时前
涡街流量计温度数据的协议桥梁:Modbus RTU 转 Profinet 网关的自动化应用
运维·自动化
<但凡.4 小时前
Linux 修炼:进程控制(一)
linux·运维·服务器·bash