当前位置: 首页 > article >正文

docker构建镜像环境搭建深度学习开发环境

我想经常需要装环境的同学应该很烦,可能因为你的不小心,导致系统崩溃等等问题,或者环境需要装另一个版本的cuda,但是目前换可能不是很方便。这些我都遇到过,那么docker可以满足你的一切需求,你可以安装不同的环境,打包然后上传,下次就算是系统崩溃,也可以快速部署环境,不用浪费太多的时间,毕竟时间是最宝贵的。我在网上找了很多相关博客还是不会,然后结合大语言模型,和自己的实际操作,写了这篇文章,主要的目的是记录。那么接下来开始吧。

1. 编写Dockerfile

首先你需要创建一个名字为Dockerfile的文件,然后编写你需要安装的环境。我新装的ubuntu24.4,但是cuda官方只有cuda 12.6可以用,这样在测试一些东西的时候,环境又不匹配,那么利用docker可以安装不同版本的cuda。为了实现这一目的,写了如下的Dockerfile文件

# 使用官方 Ubuntu 22.04 镜像作为基础镜像
FROM ubuntu:22.04

# 安装基本依赖
RUN apt-get update && \
    apt-get install -y \
    wget \
    bzip2 \
    gcc-12 \
    g++-12 \
    make \
    curl \
    gnupg \
    lsb-release \
    cmake \ 
    neofetch \
    net-tools \
    vim \
    openssh-server \ 
    software-properties-common \
    && apt-get clean

# 将本地下载的 Anaconda 安装脚本复制到容器
COPY Anaconda3-2024.06-1-Linux-x86_64.sh /tmp/

# 安装 Anaconda
RUN bash /tmp/Anaconda3-2024.06-1-Linux-x86_64.sh -b -p /opt/anaconda && \
    rm /tmp/Anaconda3-2024.06-1-Linux-x86_64.sh

# 将本地下载的 CUDA 文件复制到容器
COPY cuda-ubuntu2204.pin /etc/apt/preferences.d/cuda-repository-pin-600
COPY cuda-repo-ubuntu2204-12-4-local_12.4.0-550.54.14-1_amd64.deb /tmp/
COPY cudnn-linux-x86_64-8.9.7.29_cuda12-archive.tar.xz /tmp/

# 安装 CUDA
RUN dpkg -i /tmp/cuda-repo-ubuntu2204-12-4-local_12.4.0-550.54.14-1_amd64.deb && \
    cp /var/cuda-repo-ubuntu2204-12-4-local/cuda-*-keyring.gpg /usr/share/keyrings/ && \
    apt-get update && \
    apt-get -y install cuda-toolkit-12-4 && \
    rm /tmp/cuda-repo-ubuntu2204-12-4-local_12.4.0-550.54.14-1_amd64.deb

# 安装 cuDNN
RUN tar -xvf /tmp/cudnn-linux-x86_64-8.9.7.29_cuda12-archive.tar.xz -C /tmp && \
    cp -P /tmp/cudnn-linux-x86_64-8.9.7.29_cuda12-archive/include/* /usr/local/cuda/include/ && \
    cp -P /tmp/cudnn-linux-x86_64-8.9.7.29_cuda12-archive/lib/* /usr/local/cuda/lib64/ && \
    chmod a+r /usr/local/cuda/include/cudnn*.h /usr/local/cuda/lib64/libcudnn* && \
    rm -rf /tmp/cudnn-linux-x86_64-8.9.7.29_cuda12-archive


COPY TensorRT-10.4.0.26.Linux.x86_64-gnu.cuda-12.6.tar.gz /tmp/

# 安装 TensorRT
RUN tar -xzvf /tmp/TensorRT-10.4.0.26.Linux.x86_64-gnu.cuda-12.6.tar.gz -C /tmp && \
    mv /tmp/TensorRT-10.4.0.26 /opt/ && \
    rm /tmp/TensorRT-10.4.0.26.Linux.x86_64-gnu.cuda-12.6.tar.gz

# 安装其他依赖
ENV PATH=/usr/local/cuda-12.4/bin:$PATH
ENV LD_LIBRARY_PATH=/usr/local/cuda-12.4/lib64:$LD_LIBRARY_PATH
ENV PATH=/opt/anaconda/bin:$PATH

# 复制 requirements.txt 到容器
COPY requirements.txt /tmp/

# 创建 Conda 环境并安装依赖
RUN conda create -n pytorch python=3.10 --yes && \
    conda run -n pytorch pip install torch torchvision torchaudio -i https://mirrors.bfsu.edu.cn/pypi/web/simple && \
    conda run -n pytorch pip install -r /tmp/requirements.txt -i https://mirrors.bfsu.edu.cn/pypi/web/simple

# 激活环境
SHELL ["conda", "run", "-n", "base", "/bin/bash", "-c"]

# 设置工作目录
WORKDIR /home/only/workspace/deep_learning

# 默认命令
CMD [ "bash" ]

上述的文件不知道是否能看懂,其实你仔细看看,这不就是在Linux环境中经常使用的操作嘛,只是有docker自己特殊的写法而已。由于一些安装包需要拉取国外网站的东西,so 我下载到本地然后执行操作,相应的目录树如下所示:

.
├── Anaconda3-2024.06-1-Linux-x86_64.sh
├── cuda-repo-ubuntu2204-12-4-local_12.4.0-550.54.14-1_amd64.deb
├── cuda-ubuntu2204.pin
├── cudnn-linux-x86_64-8.9.7.29_cuda12-archive.tar.xz
├── Dockerfile
├── requirements.txt
└── TensorRT-10.4.0.26.Linux.x86_64-gnu.cuda-12.6.tar.gz

此时,进入到保存这些文件的文件夹,然后执行如下命令:

docker build -t deepl_env .

因为我需要构建深度学习环境,所以我取得名字是deepl_env,记得最后的那个,重要,重要,重要

2. 启动编写启动脚本

#!/bin/bash
# 这行指定了脚本的解释器为 `bash`,确保脚本使用 Bash shell 运行。

# 容器名称
CONTAINER_NAME="deeplearning-container"
# 定义一个名为 `CONTAINER_NAME` 的变量,用于存储容器的名称 `"deeplearning-container"`。
# 这个名称用于识别和管理 Docker 容器。

# 镜像名称
IMAGE_NAME="deepl_env"
# 定义一个名为 `IMAGE_NAME` 的变量,用于存储 Docker 镜像的名称 `"deepl_env"`。
# 这个镜像将用于创建容器。

# 端口映射
HOST_PORT=10008
CONTAINER_PORT=22
# 定义两个变量:`HOST_PORT` 和 `CONTAINER_PORT`。
# `HOST_PORT` 是主机上的端口号(10008),`CONTAINER_PORT` 是容器内的端口号(22)。
# 这行设置了端口映射,将主机的端口 10008 映射到容器的端口 22,通常用于 SSH 服务。

# 挂载路径
HOST_DIR="/home/only/workspace/deep_learning/"
CONTAINER_DIR="/opt/deep_learning"
# 定义两个变量:`HOST_DIR` 和 `CONTAINER_DIR`。
# `HOST_DIR` 是主机上的目录路径,`CONTAINER_DIR` 是容器内的目录路径。
# `-v ${HOST_DIR}:${CONTAINER_DIR}` 选项将主机目录挂载到容器内,使容器能够访问主机上的文件。

# 检查并删除同名的现有容器
if [ "$(docker ps -a -q -f name=${CONTAINER_NAME})" ]; then
    echo "删除现有容器: ${CONTAINER_NAME}"
    docker rm -f ${CONTAINER_NAME}
fi
# 检查是否已经存在名为 `${CONTAINER_NAME}` 的容器。
# 命令 `docker ps -a -q -f name=${CONTAINER_NAME}` 用于搜索该容器。
# 如果找到,使用 `docker rm -f ${CONTAINER_NAME}` 强制删除它。
# 这确保在启动新容器时不会发生冲突。

# 运行新的容器并保持它持续运行
echo "启动新容器: ${CONTAINER_NAME}"
docker run --gpus all -d -p ${HOST_PORT}:${CONTAINER_PORT} -v ${HOST_DIR}:${CONTAINER_DIR} --name ${CONTAINER_NAME} ${IMAGE_NAME} /usr/sbin/sshd -D
# 启动新的 Docker 容器:
# - `--gpus all`: 允许容器使用所有可用的 GPU。
# - `-d`: 以分离模式运行容器(在后台)。
# - `-p ${HOST_PORT}:${CONTAINER_PORT}`: 将主机端口 10008 映射到容器端口 22。
# - `-v ${HOST_DIR}:${CONTAINER_DIR}`: 将主机目录 `/home/only/workspace/deep_learning/` 挂载到容器目录 `/opt/deep_learning`。
# - `--name ${CONTAINER_NAME}`: 给容器指定一个名称。
# - `${IMAGE_NAME}`: 指定要使用的 Docker 镜像。
# - `/usr/sbin/sshd -D`: 在容器中运行 SSH 服务并保持它在后台运行。

# 检查容器是否启动成功
if [ $? -eq 0 ]; then
    echo "容器启动成功,正在启动 SSH 服务..."
    # 在容器中启动 SSH 服务
    docker exec -it ${CONTAINER_NAME} service ssh start
    echo "SSH 服务已启动,使用以下命令连接到容器:"
    echo "ssh root@localhost -p ${HOST_PORT}"
else
    echo "容器启动失败,请检查日志。"
fi
# 检查容器是否成功启动:
# - `$?`: 上一个命令的退出状态码。`0` 表示成功。
# - 如果容器启动成功,打印 `"容器启动成功,正在启动 SSH 服务..."` 并在容器内启动 SSH 服务,使用 `docker exec -it ${CONTAINER_NAME} service ssh start`。
# - 打印 SSH 连接信息,告知用户如何使用 SSH 连接到容器。
# - 如果容器启动失败,打印 `"容器启动失败,请检查日志。"` 并提示用户检查日志以获取更多详细信息。


我想通过vscode使用ssh连接内部的深度学习环境,那么我需要通过端口映射来实现,最终直接执行启动脚本,你将会得到如下输出:

Removing existing container: deeplearning-container
deeplearning-container
Starting new container: deeplearning-container
ef996282380e664529f8caf9e953a3dee61ded0294007d6d5d2fd3d02ed9a639
Container started successfully, starting SSH service...
 * Starting OpenBSD Secure Shell server sshd                                                                                                                                           [ OK ] 
SSH service started. Use the following command to connect to the container:
ssh root@localhost -p 10008

最后不管是终端还是vscode,通过ssh root@localhost -p 10008连接就好,当然安装过程不止这些,还有很多的小细节,如果有需要可以互相交流联系。如果不对的地方,希望大佬指正。


http://www.kler.cn/news/306725.html

相关文章:

  • 简单说说关于shell中zsh和bash的选择
  • 基于Keil软件实现读写备份寄存器(江协科技HAL库)
  • Edge浏览器设置夜间模式/深色模式
  • OpenCV高阶操作
  • 1.使用 VSCode 过程中的英语积累 - File 菜单(每一次重点积累 5 个单词)
  • 【AI大模型-什么是大模型】
  • 03 战略的本质与实践 - 战略管理实践的启示
  • k8s独立组件ingress,七层转发
  • \section*{References}为什么需要加*
  • DAY20240909 VUE:编程式导航,动态路由,命名路由
  • DeepGaitV2:显式时间建模,CNN和Transformer在步态任务上的影响
  • 设计模式 23 访问者模式
  • Wophp靶场寻找漏洞练习
  • 从OracleCloudWorld和财报看Oracle的转变
  • 苏州科技大学、和数联合获得国家知识产权局颁发的3项发明专利证书
  • 计算机毕业设计 在线新闻聚合平台的设计与实现 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试
  • C++复习day12
  • Android桌面(Launcher)源码分析
  • 【LeetCode每日一题】2024年9月第二周(下)
  • 【C++】学完c语言后的c++基础知识补充!(命名空间、输入和输出、缺省函数、函数重载、引用、内联函数代替宏、nullptr代替NULL)
  • SpringBoot Kafka发送消息与接收消息实例
  • Nignx 增加权限(windows)
  • BrainSegFounder:迈向用于神经影像分割的3D基础模型|文献速递--Transformer架构在医学影像分析中的应用
  • 系统架构设计师 需求分析篇一
  • Oracle临时表
  • 类型转换等 面试真题
  • Vue常见面试题目
  • 横向移动-WMI
  • k8s--pod控制器--1
  • Qt:饿汉单例(附带单例使用和内存管理)