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-archiveCOPY 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})" ]; thenecho "删除现有容器: ${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 ]; thenecho "容器启动成功,正在启动 SSH 服务..."# 在容器中启动 SSH 服务docker exec -it ${CONTAINER_NAME} service ssh startecho "SSH 服务已启动,使用以下命令连接到容器:"echo "ssh root@localhost -p ${HOST_PORT}"
elseecho "容器启动失败,请检查日志。"
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.rhkb.cn/news/427336.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

测试开发基础——软件测试中的bug

二、软件测试中的Bug 1. 软件测试的生命周期 软件测试贯穿于软件的整个生命周期 需求分析 测试计划 测试设计与开发 测试执行 测试评估 上线 运行维护 用户角度:软件需求是否合理 技术角度:技术上是否可行,是否还有优化空间 测试角度…

Android 15 正式发布至 AOSP

Google官方宣布,将于近期发布了 Android 15,而在早些时候,Google已经将其源代码推送至 Android 开源项目 (AOSP)。未来几周内,Android 15 将在受支持的 Pixel 设备上正式推出,并将于今年晚些时候在三星、Honor、iQOO、…

[vue2+axios]下载文件+文件下载为乱码

export function downloadKnowledage(parameter) {return axios({url: /knowledage/download,method: GET,params: parameter,responseType: blob}) }添加 responseType: blob’解决以下乱码现象 使用触发a标签下载文件 downloadKnowledage(data).then((res) > {let link …

高效处理NPE!!

相信不少小伙伴已经被java的NPE(Null Pointer Exception)所谓的空指针异常搞的头昏脑涨,有大佬说过“防止 NPE,是程序员的基本修养。”但是修养归修养,也是我们程序员最头疼的问题之一,那么我们今天就要尽可能的利用Java8的新特性 Optional来…

AI绘画与摄影新纪元:ChatGPT+Midjourney+文心一格 共绘梦幻世界

文章目录 一、AI艺术的新时代二、ChatGPT:创意的引擎与灵感的火花三、Midjourney:图像生成的魔法与技术的奇迹四、文心一格:艺术的升华与情感的共鸣五、融合创新:AI绘画与摄影实战的无限可能六、应用场景与实践案例AI艺术的美好未…

11 vue3之插槽全家桶

插槽就是子组件中的提供给父组件使用的一个占位符&#xff0c;用<slot></slot> 表示&#xff0c;父组件可以在这个占位符中填充任何模板代码&#xff0c;如 HTML、组件等&#xff0c;填充的内容会替换子组件的<slot></slot>标签。 匿名插槽 1.在子组…

一个场景是否可以同时选择CPU和GPU渲染

一个场景是否可以同时选择CPU和GPU渲染&#xff0c;主要取决于所使用的渲染软件及其支持的渲染引擎。在大多数情况下&#xff0c;现代渲染软件如3DMax等确实支持同时利用CPU和GPU进行渲染&#xff0c;以提高渲染效率和速度。 渲染软件的支持 以3DMax为例&#xff0c;它允许用…

xxl-job、Quartz、power-job、elastic-job对比选型

一、框架对比 1. Quartz 优点&#xff1a;稳定性和可扩展性好&#xff0c;适用于企业级应用&#xff1b;调度功能丰富&#xff0c;满足多种需求。 缺点&#xff1a;本身不提供原生的分布式支持&#xff0c;需要通过扩展或与其他组件结合来实现分布式任务调度&#xff1b;调度…

使用NotificationChannel实现后台视频上传

1、添加依赖 implementation net.gotev:uploadservice:4.8.0 implementation net.gotev:uploadservice-okhttp:4.8.02、在application中初始化服务&#xff1a; //初始化上传服务private fun initUploadService() {// 文件上传createNotificationChannel()//notificationChan…

算法里面的离散化

一、离散化&#xff08;discretization&#xff09;在算法和数据结构中指的是将连续的输入数据映射到离散的值或者范围&#xff0c;从而使得处理和计算变得更高效。通常用于处理大范围或者无限可能的输入&#xff0c;以便将其转化为有限的、可以有效处理的范围。 离散化的定义…

【深度学习】(3)--损失函数

文章目录 损失函数一、L1Loss损失函数1. 定义2. 优缺点3. 应用 二、NLLLoss损失函数1. 定义与原理2. 优点与注意3. 应用 三、MSELoss损失函数1. 定义与原理2. 优点与注意3. 应用 四、BCELoss损失函数1. 定义与原理2. 优点与注意3. 应用 五、CrossEntropyLoss损失函数1. 定义与原…

9.19总结

这几天学习了网络流 1&#xff0c;EK ek的主要思路是不断通过bfs找到增广路&#xff0c;找到增广路再建立反向边&#xff0c;直到不能再bfs到汇点&#xff0c;为什么可以通过建反向边呢&#xff1f;以上图举例&#xff0c;上图走完第一条增广路建立了一条反向边&#xff0c;当…

Maya动画基础

Maya动画基础教程&#xff08;完整&#xff09;_哔哩哔哩_bilibili 第一集 动画基础设置 altv播放动画 选择撕下副本 右键---播放预览 第二集 k帧记录物体的空间信息 初始位置清零 删除历史记录 s键key帧 自动记录位置信息 删除帧&#xff0c;按住右键选择delete 按shif…

Python if 语句优化技巧

大家好&#xff01;今天我们来聊聊Python中的if语句优化技巧。if语句是Python中最基本的控制结构之一&#xff0c;它用于根据条件执行不同的代码块。虽然if语句本身非常简单&#xff0c;但通过一些小技巧&#xff0c;可以让我们的代码更加高效、简洁。接下来&#xff0c;我们将…

LeetCode 算法笔记-第 04 章 基础算法篇

1.枚举 采用枚举算法解题的一般思路如下&#xff1a; 确定枚举对象、枚举范围和判断条件&#xff0c;并判断条件设立的正确性。一一枚举可能的情况&#xff0c;并验证是否是问题的解。考虑提高枚举算法的效率。 我们可以从下面几个方面考虑提高算法的效率&#xff1a; 抓住…

js中两种异步方式:async+await以及then

第一种方式 第二种方式 完整代码 前端代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>pywebv…

重学SpringBoot3-SpringApplicationRunListener

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-SpringApplicationRunListener 1. 基本作用2. 如何实现2.1. 创建SpringApplicationRunListener2.2. 注册SpringApplicationRunListener2.3. 完整示例 3.…

【机器学习】经典数据集鸢尾花的分类识别

【机器学习】经典数据集鸢尾花的分类识别 1、数据集介绍1.1 数据集详情 2、实验内容2.1 准备数据集2.2 创建颜色映射对象2.3 绘制特征散点图2.4 数据的归一化2.5 数据的标准化 3、实验截图提取萼片长度与萼片宽度分类提取萼片长度与花瓣长度分类提取萼片长度与花瓣宽度分类提取…

【海贼王航海日志:前端技术探索】一篇文章带你走进JavaScript(一)

目录 1 -> 初识JavaScript 1.1 -> JavaScript是什么 1.2 -> 发展历史 1.3 -> JavaScript和HTML和CSS之间的关系 1.4 -> JavaScript运行过程 1.5 -> JavaScript的组成 2 -> 前置知识 2.1 -> JavaScript的书写形式 2.2 -> 注释 2.3 -> 输…

使用OpenCV进行模糊检测(拉普拉斯算子)

参考&#xff1a; 使用OpenCV进行模糊检测&#xff08;拉普拉斯算子&#xff09; 代码&#xff1a; # import the necessary packages from imutils import paths import argparse import cv2 import osdef variance_of_laplacian(image):# compute the Laplacian of the ima…