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

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

1. 编写Dockerfile

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

bash 复制代码
# 使用官方 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 我下载到本地然后执行操作,相应的目录树如下所示:

c 复制代码
.
├── 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

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

bash 复制代码
docker build -t deepl_env .

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

2. 启动编写启动脚本

bash 复制代码
#!/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连接内部的深度学习环境,那么我需要通过端口映射来实现,最终直接执行启动脚本,你将会得到如下输出:

bash 复制代码
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连接就好,当然安装过程不止这些,还有很多的小细节,如果有需要可以互相交流联系。如果不对的地方,希望大佬指正。

相关推荐
阿尔帕兹1 小时前
构建 HTTP 服务端与 Docker 镜像:从开发到测试
网络协议·http·docker
ZHOU西口3 小时前
微服务实战系列之玩转Docker(十八)
分布式·docker·云原生·架构·数据安全·etcd·rbac
羊小猪~~3 小时前
神经网络基础--什么是正向传播??什么是方向传播??
人工智能·pytorch·python·深度学习·神经网络·算法·机器学习
软工菜鸡4 小时前
预训练语言模型BERT——PaddleNLP中的预训练模型
大数据·人工智能·深度学习·算法·语言模型·自然语言处理·bert
哔哩哔哩技术5 小时前
B站S赛直播中的关键事件识别与应用
深度学习
deephub5 小时前
Tokenformer:基于参数标记化的高效可扩展Transformer架构
人工智能·python·深度学习·架构·transformer
___Dream5 小时前
【CTFN】基于耦合翻译融合网络的多模态情感分析的层次学习
人工智能·深度学习·机器学习·transformer·人机交互
极客代码5 小时前
【Python TensorFlow】入门到精通
开发语言·人工智能·python·深度学习·tensorflow
景天科技苑6 小时前
【云原生开发】K8S多集群资源管理平台架构设计
云原生·容器·kubernetes·k8s·云原生开发·k8s管理系统
wclass-zhengge6 小时前
K8S篇(基本介绍)
云原生·容器·kubernetes