Docker教程(喂饭级!)
如果你有跨平台开发的需求,或者对每次在新机器上部署项目感到头疼,那么 Docker 是你的理想选择!Docker 通过容器化技术将应用程序与其运行环境隔离,实现快速部署和跨平台支持,极大地简化了开发和部署流程。本文详细介绍了 Docker 的核心组件、工作原理和基本操作流程,并结合算法模型部署的实际应用,以 CUDA 环境部署为例,深入讲解了如何利用 Docker 进行模型部署和调试,帮助你轻松应对复杂的开发与部署挑战。
1. Docker 简介
Docker 是一个用于开发、运输和运行应用程序的开源平台。它将应用程序与环境进行隔离,实现项目的快速部署上线,减少项目在环境部署上所花费的成本。
2. Docker 架构与工作流程
2.1 Docker 架构
Docker 的架构基于客户端-服务器模式,主要由 Docker 客户端和 Docker 守护进程两大核心组件构成。Docker 客户端是用户与系统交互的命令行界面(CLI),用户通过 CLI 发送命令(如构建镜像、启动容器等),这些命令会被传递到 Docker 守护进程(通常为 dockerd)。守护进程作为 Docker 的核心组件,负责管理容器的生命周期、构建镜像、分发镜像等任务,并以后台进程的形式持续运行,监听并处理来自客户端的请求。这种架构使得 Docker 能够高效地构建、管理和运行容器化应用,为用户提供了灵活且强大的开发与部署体验。

2.2 Docker 架构的工作流程
- 构建镜像:使用
Dockerfile 创建镜像。 - 推送镜像到注册表:将镜像上传到 Docker Hub 或私有注册表中。
- 拉取镜像:通过
docker pull 从注册表中拉取镜像。 - 运行容器:使用镜像创建并启动容器。
- 管理容器:使用 Docker 客户端命令管理正在运行的容器(例如查看日志、停止容器、查看资源使用情况等)。
- 网络与存储:容器之间通过 Docker 网络连接,数据通过 Docker 卷或绑定挂载进行持久化。
3. Docker 的主要特点
-
容器化技术:
- 隔离性:Docker 使用容器技术,将应用程序及其依赖打包到一个独立的环境中运行,与其他容器和宿主机隔离。
- 轻量级:与虚拟机相比,Docker 容器不需要完整的操作系统,共享宿主机的内核,因此启动速度快,资源占用少。
-
镜像管理:
- 镜像构建:通过 Dockerfile 定义应用程序的运行环境和依赖,然后构建为镜像。
- 镜像分发:镜像可以存储在本地或远程仓库(如 Docker Hub),方便分发和共享。
-
容器管理:
- 容器生命周期管理:可以创建、启动、停止、删除容器。
- 容器编排:支持使用 Docker Compose 等工具管理多个容器的部署和运行。
-
跨平台支持:
- Docker 支持多种操作系统,包括 Linux、Windows 和 macOS,能够确保应用程序在不同环境中的一致性。
4. Docker 的工作原理
- Docker 守护进程(Docker Daemon) :守护进程是 Docker 的核心组件,负责管理镜像、容器、网络和存储卷等资源。
- Docker 客户端(Docker CLI) :用户通过命令行工具与守护进程交互,执行各种操作,如拉取镜像、运行容器等。
- Docker 镜像:镜像是只读模板,包含运行容器所需的文件系统和依赖。镜像由多层组成,每一层代表一次构建操作。
- Docker 容器:容器是镜像的运行实例,具有独立的文件系统、网络接口和资源限制。容器通过联合文件系统(Union File System)在镜像的基础上添加可读写层。
- Docker 仓库:用于存储和分发镜像。Docker Hub 是官方的公共仓库,用户也可以搭建私有仓库。
5. Docker 容器与镜像之间的关系
5.1 定义
- 镜像(Image) :Docker 镜像是一个只读模板,它包含了运行一个容器所需的文件系统、操作系统、应用程序及其依赖项。镜像是静态的,不可修改,是容器运行的基础。
- 容器(Container) :容器是从镜像创建的运行实例。它是镜像的动态运行状态,可以启动、停止、删除等。容器在镜像的基础上添加了可读写层,用于存储运行时产生的临时数据。
5.2 关系
- 镜像是容器的模板:容器是基于镜像创建的。镜像定义了容器的初始状态,包括文件系统、操作系统环境、预安装的软件和配置等。
- 容器是镜像的运行实例:容器是镜像的动态运行版本。当启动一个容器时,Docker 会在镜像的基础上添加一个可读写层,用于存储容器运行时产生的临时数据。
- 镜像的不可变性与容器的可变性:镜像是不可变的,一旦创建,其内容不会改变。而容器是可变的,用户可以在容器中安装软件、修改配置等。
- 容器的创建依赖于镜像:没有镜像,容器无法被创建。用户可以通过拉取公共镜像仓库中的镜像,或者使用 Dockerfile 构建自定义镜像来创建容器。
- 容器的销毁不影响镜像:删除容器后,镜像仍然存在。用户可以基于同一个镜像创建多个容器,每个容器都是独立的运行实例。
5.3 总结
镜像是容器的静态模板,定义了容器的初始状态;容器是镜像的动态运行实例,具有独立的生命周期。镜像为容器提供了运行环境和基础结构,而容器则在镜像的基础上实现了应用程序的运行和管理。
6. Docker 基本操作流程
6.1 创建容器
通过上面,我们知道,容器时基于镜像创建的,因此,根据本地有没有镜像,创建容器的方式可以有这样三种,若本地有可用镜像,则可通过镜像直接创建容器;若本地没有可用镜像,则需先拉取镜像,在通过相应操作创建容器;若需要基于某个镜像自定义镜像并创建容器,则需先拉取基础镜像,然后定义Dockerfile文件,基于基础镜像创建自定义镜像,并通过相应操作创建容器。具体操作过程如下:
6.1.1 直接创建容器
通过 docker run 直接创建一个容器。
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
- OPTIONS:可选参数,用于配置容器的各种属性,比如指定容器名称、端口映射、卷挂载等。
- IMAGE:指定用于创建容器的镜像名称或镜像 ID。
- COMMAND 和 ARG:可选,用于在容器启动时运行的命令及其参数。
示例:
-
从官方镜像创建一个简单的容器:
docker run -d nginx -
指定容器名称:
docker run --name my-container -d nginx -
端口映射:
docker run -p 8080:80 -d nginx -
挂载卷:
docker run -v /host/path:/container/path -d nginx -
设置环境变量:
docker run -e VAR_NAME=value -d my-image
6.1.2 通过镜像创建容器
6.1.2.1 拉取镜像
docker pull [镜像名称]:[标签]
示例:
docker pull nginx:latest
6.1.2.2 使用镜像创建容器
docker run [选项] [镜像名称]:[标签]
以下是一些常用的命令选项:
-
-d:后台运行容器。如果不加-d,容器会在前台运行,直到退出。 -
--name:为容器指定一个名称,方便后续管理。 -
-p:端口映射,将容器内部的端口映射到宿主机的端口。- 格式:
宿主机端口:容器内部端口。
- 格式:
-
-v:挂载卷,将宿主机的目录或文件挂载到容器内部。- 格式:
宿主机路径:容器内部路径。
- 格式:
-
--rm:容器退出时自动删除容器,避免占用空间。 -
-e:设置环境变量。 -
--network:指定容器使用的网络。
示例:
docker run -d --name my-nginx -p 8080:80 nginx:latest
-
-d:后台运行。 -
--name my-nginx:容器名称为my-nginx。 -
-p 8080:80:将容器内部的 80 端口映射到宿主机的 8080 端口。 -
nginx:latest:使用nginx 镜像的latest 版本。
6.1.3 通过 Dockerfile 构建自定义镜像并创建容器
-
拉取基础镜像:
docker pull python:3.9-slim -
编写 Dockerfile:
FROM python:3.9-slim WORKDIR /app COPY . /app RUN pip install -r requirements.txt CMD ["python", "app.py"] -
构建自定义镜像:
docker build -t my-custom-python-app:v1 . -
基于自定义镜像创建容器:
docker run -d --name my-python-container my-custom-python-app:v1
6.2 容器基本操作
6.2.1 启动容器
docker start [容器名称或ID]
示例:
docker start my-container
6.2.2 进入容器
docker exec -it [容器名称或ID] /bin/bash
常见命令选型说明:
-
-it:这两个参数组合起来表示以交互模式进入容器。-
-i:表示交互式,保持 STDIN 打开。 -
-t:分配一个伪终端。
-
-
[容器名称或ID] :指定要进入的容器的名称或 ID。 -
/bin/bash:指定在容器内部启动的命令,通常是/bin/bash 或/bin/sh,用于进入 shell。
示例:
docker exec -it my-container /bin/bash
6.2.3 退出容器
docker stop [容器名称或ID]
示例:
docker stop my-container
7. 模型部署与 Docker
7.1 基于 Dockerfile 构建环境
基于Dockerfile创建虚拟开发环境的基本流程如下:
# 拉取依赖镜像
docker pull nvidia/cuda:12.3.2-cudnn9-devel-ubuntu22.04
# 基于 Dockerfile 文件构建新镜像
docker build -t cuda-cudnn:12.3.2 .
# 基于镜像生成对应容器
docker run --name cuda-12.3.2 -it --gpus all cuda-cudnn:12.3.2
# 检查容器是否生成
docker ps -a
# 启动容器
docker start cuda-12.3.2
# 进入容器
docker exec -it cuda-12.3.2 /bin/bash
# 停止容器
docker stop cuda-12.3.2
7.2 基于 Dockerfile 构建环境,并通过挂载方式实现本地开发容器环境项目
我们创建容器的目的是,在容器中进行项目的开发和测试,因此,在上述容器创建过程的基础上,还需通过挂载的方式,将本地项目映射到容器中去,这样,就可以实现在宿主机(主机中开发),在容器中编译和测试了。具体流程如下:
先在本地创建项目,项目中除了项目代码外,还需包括Dockerfile文件
cuda_test/
├── Dockerfile
├── print_index.cu
└── CMakeLists.txt

进入到项目目录下,通过docker创建项目环境。
-
拉取镜像:
docker pull nvidia/cuda:12.3.2-cudnn9-devel-ubuntu22.04 -
构建新镜像:
docker build -t cuda-cudnn:12.3.2 . -
生成容器并挂载本地路径:
docker run --name cuda_test -it --gpus all -v /mnt/e/Code/Cuda_test:/workspace cuda-cudnn:12.3.2 /bin/bash

通过上述操作完成了项目环境的创建,然后进入宿主机进行项目开发,完成编码后,启动镜像进行编译。
#启动容器(若容器停止执行)
docker start cuda_test
#进入容器
docker exec -it cuda_test /bin/bash
#进行编译
ls
mkdir build && cd build
cmake ..
make
./you_project

7.3 挂载到容器的项目在容器中进行 Debug
我们在开发的过程中还需要deubg代码,下面是通过vscode配置deocker容器debug的过程。
-
创建可进行 Debug 的容器:
docker run --name cuda_test -it --gpus all --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -v /mnt/e/Code/Cuda_test:/workspace cuda-cudnn:12.3.2 /bin/bash -
在本地项目中创建 VSCode 的
launch.json 文件:{"version": "0.2.0","configurations": [{"name": "Docker_debug","type": "cppdbg","request": "launch","program": "/workspace/you_path", //可执行文件路径"args": [],"stopAtEntry": false,"cwd": "/workspace/you_path", //命令行路径"environment": [],"externalConsole": false,"sourceFileMap": {"/workspace/you_path": "${workspaceFolder}/you_path" //源码在容器中和工作空间的路径对应关系},"pipeTransport": {"pipeProgram": "docker","pipeArgs": ["exec","-i","container_name", //容器名称"/usr/bin/gdb","--interpreter=mi"],"debuggerPath": "/usr/bin/gdb","pipeCwd": "${workspaceFolder}"},"MIMode": "gdb","setupCommands": [{"description": "Enable pretty-printing for gdb","text": "-enable-pretty-printing","ignoreFailures": true}]}] }
配置好launch.json文件后,即可在vscode中进行debug。




8. 参考资料
- Docker部署深度学习模型 - ZeroZeroSeven - 博客园
- 轻松构建:Qt应用与Docker容器完美结合的界面攻略 - 云原生实践
- 从零开始使用vs code连接Linux系统下的docker容器_vscode连接容器的方法-CSDN博客
- 手把手教你在windows上用docker和vscode配置环境 - MiniOB
- (多种方法)VSCode调试docker容器里的程序_vscode docker-CSDN博客
相关文章:
Docker教程(喂饭级!)
如果你有跨平台开发的需求,或者对每次在新机器上部署项目感到头疼,那么 Docker 是你的理想选择!Docker 通过容器化技术将应用程序与其运行环境隔离,实现快速部署和跨平台支持,极大地简化了开发和部署流程。本文详细介绍…...
HTML:自闭合标签简单介绍
1. 什么是自结束标签? 定义:自结束标签(Self-closing Tag)是指 不需要单独结束标签 的 HTML 标签,它们通过自身的语法结构闭合。语法形式: 在 HTML5 中:直接写作 <tag>,例如 …...
【和鲸社区获奖作品】内容平台数据分析报告
1.项目背景与目标 在社交和内容分享领域,某APP凭借笔记、视频等丰富的内容形式,逐渐吸引了大量用户。作为一个旨在提升用户互动和平台流量的分享平台,推荐算法成为其核心功能,通过精准推送内容,努力实现更高的点击率和…...
GitCode 助力 python-office:开启 Python 自动化办公新生态
项目仓库:https://gitcode.com/CoderWanFeng1/python-office 源于需求洞察,打造 Python 办公神器 项目作者程序员晚枫在运营拥有 14w 粉丝的 B 站账号 “Python 自动化办公社区” 时,敏锐察觉到非程序员群体对 Python 学习的强烈需求。在数字…...
超参数、网格搜索
一、超参数 超参数是在模型训练之前设置的,它们决定了训练过程的设置和模型的结构,因此被称为“超参数”。以KNN为例: 二、网格搜索 交叉验证(Cross-Validation)是在机器学习建立模型和验证模型参数时常用的方法&…...
or-tools编译命令自用备注
cmake .. -G "Visual Studio 17 2022" -A Win32 //vs2022 cmake .. -G "Visual Studio 15 2017" -A Win32 //vs2017 -DBUILD_DEPSON //联网下载 -DCMAKE_INSTALL_PREFIXinstall //带安装命令 -DCMAKE_CXX_FLAGS"/u…...
vulnhub靶场【kioptrix-4】靶机
前言 靶机:kioptrix-4,IP地址为192.168.1.75,后期IP地址为192.168.10.8 攻击:kali,IP地址为192.168.1.16,后期IP地址为192.168.10.6 都采用VMware虚拟机,网卡为桥接模式 这里的靶机…...
readline模块详解!!【Node.js】
“书到用时方恨少,事非经过不知难。” —— 陆游 目录 readline 是什么?基本用法:创建 Interface 类:核心流程: Interface 类的关键事件:line:close:pause:…...
软件测试的七大误区
随着软件测试对提高软件质量重要性的不断提高,软件测试也不断受到重视。但是,国内软件测试过程的不规范,重视开发和轻视测试的现象依旧存在。因此,对于软件测试的重要性、测试方法和测试过程等方面都存在很多不恰当的认识…...
【欢迎来到Git世界】Github入门
241227 241227 241227 Hello World 参考:Hello World - GitHub 文档. 1.创建存储库 r e p o s i t o r y repository repository(含README.md) 仓库名需与用户名一致。 选择公共。 选择使用Readme初始化此仓库。 2.何时用分支…...
解决 Ubuntu 24.04 虚拟机内无法ping 通 Hostname 的问题
问题背景 在 VMware 或 VirtualBox 中安装 Ubuntu 24.04 虚拟机时,遇到无法通过主机名(Hostname)进行网络通信的问题。例如,将虚拟机的主机名设置为 001,执行 ping 001 时返回 ping 0.0.0.1 并超时。此问题通常由 主机…...
给小白的oracle优化工具,了解一下
有时懒得分析或语句太长,可以尝试用oracle的dbms_sqldiag包进行sql优化, --How To Use DBMS_SQLDIAG To Diagnose Query Performance Issues (Doc ID 1386802.1) --诊断SQL 性能 SET ECHO ON SET LINESIZE 132 SET PAGESIZE 999 SET LONG 999999 SET SER…...
CT技术变迁史——CT是如何诞生的?
第一代CT(平移-旋转) X线球管为固定阳极,发射X线为直线笔形束,一个探测器,采用直线和旋转扫描相结合,即直线扫描后,旋转1次,再行直线扫描,旋转180完成一层面扫描,扫描时间3~6分钟。矩阵象素256256或320320。仅用于颅脑检查。 第二代CT (平移-旋转) 与第一代无质…...
【PHP脚本语言详解】为什么直接访问PHP文件会显示空白?从错误示例到正确执行!
前言 作为一名开发者,你是否曾经遇到过这样的问题:写了一个PHP脚本,放到服务器根目录后,直接通过file:///路径访问却显示空白页面?而换成http://localhost却能正常显示?这篇文章将带你深入理解PHP脚本语言…...
软件工程---需求工程
软件需求工程师发现、获取、组织、分析、编写和管理需求的系统方法,以使客户和项目组之间达成共识。 需求工程共包含五个步骤: 需求获取:对业务问题分析,与项目干系人沟通,以理解系统的目标、期望和约束,…...
spring注解开发(Spring整合MyBatis——Mapper代理开发模式、(Spring、MyBatis、Jdbc)配置类)(6)
目录 一、纯MyBatis独立开发程序。 (1)数据库与数据表。 (2)实体类。 (3)dao层接口。(Mapper代理模式、无SQL映射文件——注解配置映射关系) (4)MyBatis核心配…...
散户情绪周期模型(情绪影响操作)
目录 一、个股上涨阶段情绪演化二、个股下跌阶段情绪演化三、底部震荡阶段情绪演化四、情绪观察与操作工具箱1. 情绪自测量表(每日收盘后记录)2. 情绪-指标对照表 五、高阶情绪管理技巧1.认知重构训练2.生理指标监控(需配合智能手表ÿ…...
计算机毕业设计SpringBoot+Vue.js网上商城系统(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
自动化测试无法启动(java.net.SocketException)
在运行测试代码,对浏览器进行自动化操作时,遇到了以下问题,添加依赖,编写了测试代码,但是程序无法运行 这个有两种原因(我使用的是谷歌浏览器): 网络问题: 因为需要从GitHub上下载对应包,所以有时候可能会出现网络问题,这个时候可以打开VPN之后,重新对程序进行启动 浏览器版本…...
智能机器人加速进化:AI大模型与传感器的双重buff加成
Deepseek不仅可以在手机里为你解答现在的困惑、占卜未来的可能,也将成为你的贴心生活帮手! 2月21日,追觅科技旗下Dreamehome APP正式接入DeepSeek-R1大模型,2月24日发布的追觅S50系列扫地机器人也成为市面上首批搭载DeepSeek-R1的…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
android RelativeLayout布局
<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...
AxureRP-Pro-Beta-Setup_114413.exe (6.0.0.2887)
Name:3ddown Serial:FiCGEezgdGoYILo8U/2MFyCWj0jZoJc/sziRRj2/ENvtEq7w1RH97k5MWctqVHA 注册用户名:Axure 序列号:8t3Yk/zu4cX601/seX6wBZgYRVj/lkC2PICCdO4sFKCCLx8mcCnccoylVb40lP...
Qwen系列之Qwen3解读:最强开源模型的细节拆解
文章目录 1.1分钟快览2.模型架构2.1.Dense模型2.2.MoE模型 3.预训练阶段3.1.数据3.2.训练3.3.评估 4.后训练阶段S1: 长链思维冷启动S2: 推理强化学习S3: 思考模式融合S4: 通用强化学习 5.全家桶中的小模型训练评估评估数据集评估细节评估效果弱智评估和民间Arena 分析展望 如果…...
未授权访问事件频发,我们应当如何应对?
在当下,数据已成为企业和组织的核心资产,是推动业务发展、决策制定以及创新的关键驱动力。然而,未授权访问这一隐匿的安全威胁,正如同高悬的达摩克利斯之剑,时刻威胁着数据的安全,一旦触发,便可…...
codeforces C. Cool Partition
目录 题目简述: 思路: 总代码: https://codeforces.com/contest/2117/problem/C 题目简述: 给定一个整数数组,现要求你对数组进行分割,但需满足条件:前一个子数组中的值必须在后一个子数组中…...
