Docker 问题与修复
GPU 参数报错 安装 NVIDIA Container Toolkit 验证 Docker GPU 是否可用 --- docker-compose 与 docker compose 添加 Docke…
GPU 参数报错
1docker: Error response from daemon: could not select device driver "" with capabilities: [gpu]
安装 NVIDIA Container Toolkit
验证 Docker GPU 是否可用
1docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi
docker-compose 与 docker compose
添加 Docker 官方源(更完整)
1# 移除旧的 Docker
2sudo apt-get remove docker.io docker-doc docker-compose podman-docker containerd runc
3
4# 添加 Docker 官方 GPG 密钥
5sudo apt-get update
6sudo apt-get install ca-certificates curl
7sudo install -m 0755 -d /etc/apt/keyrings
8sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
9sudo chmod a+r /etc/apt/keyrings/docker.asc
10
11# 添加 Docker 官方源
12echo \
13 "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
14 $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
15 sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
16
17# 安装 Docker 和 Compose 插件
18sudo apt-get update
19sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
BuildKit 挂载 amd 架构缓存
ARM Mac 构建 amd64 镜像时,本地 ARM 的 pip 缓存无法直接使用(架构不同)。使用 Docker BuildKit 的缓存挂载,它会自动处理跨平台并缓存对应架构的 wheel。
1# 安装依赖(使用 BuildKit 缓存挂载,自动处理跨平台)
2RUN --mount=type=cache,target=/root/.cache/pip \
3 pip install \
4 --trusted-host mirrors.aliyun.com \
5 -i http://mirrors.aliyun.com/pypi/simple \
6 -r requirements.txt && \
7 rm -rf /tmp/* /var/tmp/*
BuildKit 会:
自动下载 amd64 架构的 wheel 文件
将下载的文件缓存到 BuildKit 的缓存中
下次构建时直接使用缓存的 amd64 wheel 文件
1第一次构建:
2├─ pip 下载包到 /root/.cache/pip
3├─ BuildKit 检测到缓存挂载
4├─ 将缓存保存到 BuildKit 的缓存存储中
5└─ 构建完成
6
7第二次构建(requirements.txt 未变):
8├─ BuildKit 恢复缓存到 /root/.cache/pip
9├─ pip 发现缓存中已有包
10├─ 直接从缓存读取(无需下载)
11└─ 构建速度大幅提升
buildx 不指定 –driver
1# 不指定 driver
2docker buildx create --name mybuilder --use
3
4# 默认使用: docker-container
5docker buildx inspect mybuilder
6# Driver: docker-container
Docker 命令行开启网络代理
方法 1:通过 systemd 的 drop-in 环境变量设置
假设你用的是 systemd 管理 Docker 服务(常见于 Ubuntu、CentOS 等):
- 创建 drop-in 配置目录(如果尚不存在):
1sudo mkdir -p /etc/systemd/system/docker.service.d
- 在该目录下新建一个文件,比如
http-proxy.conf,内容类似:
1[Service]
2Environment="HTTP_PROXY=http://你的代理地址:端口"
3Environment="HTTPS_PROXY=http://你的代理地址:端口"
4Environment="NO_PROXY=localhost,127.0.0.1,.你的内部域名"
注意:如果有用户名/密码,要写作 http://user:pass@proxyhost:port(必要时要进行 URL 编码)。
- 重载 systemd 并重启 Docker 服务:
1sudo systemctl daemon-reload
2sudo systemctl restart docker
- 检查是否生效:
1sudo systemctl show --property=Environment docker
2# 或者
3docker info | grep -i proxy
这样,当你运行 docker pull 时,daemon 就会从它自己的环境中读取这些代理变量,从而使用代理
方法 2:通过 Docker 的 **daemon.json** 配置代理(当版本支持时)
在某些 Docker 版本,可以在 /etc/docker/daemon.json 中添加代理配置:
1{
2 "proxies": {
3 "default": {
4 "http-proxy": "http://你的代理地址:端口",
5 "https-proxy": "http://你的代理地址:端口",
6 "no-proxy": "localhost,127.0.0.1,.你的内部域"
7 }
8 }
9}
修改后需要重启 Docker 服务。注意:有些 Docker 版本或环境(如 Docker Desktop)可能忽略这个设置。
Desktop Windows 集成进 WSL
第一步:确认 Docker Desktop 状态
在 Windows 中:
- 启动 Docker Desktop
- 等待右下角状态为 Running
第二步:开启 WSL Integration
在 Docker Desktop → Settings 中:
- General
- 勾选:
Use the WSL 2 based engine
- 勾选:
- Resources → WSL Integration
- 勾选:
Enable integration with my default WSL distro - 或者单独勾选:
Ubuntu
- 勾选:
- 点击 Apply & Restart
第三步:重启 WSL(非常关键)
在 PowerShell(管理员) 中执行:
1wsl --shutdown
然后重新打开 Ubuntu 终端。
第四步:验证 Docker CLI 是否已注入
在 Ubuntu 中执行:
1which docker
2docker version
正常结果应类似:
/usr/bin/docker- Client 和 Server 信息均能显示
以超管权限进入容器
可以安装软件
1# -u 0 是使用 root 身份进入,不用 root 无法使用 apt 进行安装包
2docker exec -u 0 -it elasticsearch bash
3apt update
4apt install vim
匿名卷和具名卷区别
| 类型 | 命令方式 | 左侧定义 | 由谁管理 | 是否可跨容器复用 | 管理命令支持 | 常见用途 |
|---|---|---|---|---|---|---|
| 匿名卷(Anonymous Volume) | -v /path/in/container | 无,Docker自动生成 | Docker | ❌ 一般不复用 | ✅(docker volume) | 临时数据,生命周期随容器 |
| 具名卷(Named Volume) | -v volume_name:/path/in/container | 卷名(自己定义) | Docker | ✅ 可复用 | ✅(docker volume) | 数据持久化,多容器共享 |
| 绑定挂载(Bind Mount) | -v /host/path:/path/in/container | 主机目录路径 | 用户自己 | ✅ 可复用 | ❌(非 docker volume 管理) | 直接访问宿主机文件,如导入导出 |
1. 创建匿名卷
1docker run -v /app/data my_image
- Docker 自动创建一个匿名卷,并挂载到容器内的 /app/data。
- 使用 docker volume ls 可以看到名称类似于 e3f6e1c7a0a6c3a4c6… 的卷。
2. 创建具名卷
1docker run -v mydata:/app/data my_image
- 明确指定卷名 mydata,方便日后管理与复用。
- 可使用多个容器挂载同一个具名卷,实现数据共享。
3. 创建绑定挂载(挂载卷)
1docker run -v /home/user/data:/app/data my_image
- /home/user/data 是主机上的真实目录。
- 容器内部的 /app/data 映射到主机这个目录。
- 不受 docker volume 管理。
- 容器内操作数据 = 实时操作主机上的文件。
重复镜像加载策略
The image redis:6-alpine already exists, renaming the old one with ID 当你尝试加载一个 Docker 镜像时,如果这个镜像的标签(如 redis:6-alpine)已经在本地存在,Docker 会处理冲突:
它会移除旧镜像的标签(“重命名”旧镜像,将其名称清空)。
然后加载新的镜像,并将它分配给同样的标签 redis:6-alpine。
这个过程确保你的标签总是指向最新加载的镜像。旧的镜像在 Docker 中仍然存在,但没有标签来引用它。如果不需要,可以手动删除旧的镜像。
开启代理
Docker Desktop 中设置 Resources - Proxies - Manual proxy configuration 勾选,并填写 HTTP 和 HTTPS 地址
删除不同标签同镜像
1docker rmi registry.cn-shanghai.aliyuncs.com/zailiang/milvus:v2.4.5
容器挂载方式
方式 1:挂载本地目录
1-v $(pwd)/elasticsearch/data:/usr/share/elasticsearch/data
2-v $(pwd)/elasticsearch/plugins:/usr/share/elasticsearch/plugins
这种方式是将主机上的指定目录挂载到容器中。这里 $(pwd)/elasticsearch/data 和 $(pwd)/elasticsearch/plugins 是主机上的实际目录:
优点:可以直接在主机上查看和编辑这些目录中的数据,任何对文件的更改都会立即在容器中生效。
缺点:需要确保主机目录结构的正确性。如果目录不存在,Docker 不会自动创建,可能会导致启动失败。另外,主机系统的文件权限、文件系统类型等因素可能会影响容器的正常运行。
方式 2:使用 Docker 卷
1-v es-data:/usr/share/elasticsearch/data
2-v es-plugins:/usr/share/elasticsearch/plugins
这种方式是将 Docker 卷挂载到容器中,es-data 和 es-plugins 是 Docker 卷名:
优点:Docker 卷的管理和存储由 Docker 负责,文件安全性和性能通常较好。Docker 卷会跨容器保留数据,适合数据持久化,且不依赖主机文件系统。
缺点:Docker 卷的实际存储路径(如 /var/lib/docker/volumes)在 macOS 和 Windows 主机上通常不可直接访问,因此无法在主机上直接查看和编辑卷内数据。
使用建议
开发调试时:建议使用本地目录挂载方式,方便直接在主机上查看和编辑数据或配置。
生产环境:建议使用Docker 卷方式,以便更好地管理和保护数据,同时避免因主机文件系统问题导致容器运行异常。
容器网络连接解析规则
1docker run -d \
2 --name haha \
3 --net elastic \
4 -p 9200:9200 -p 9300:9300 \
5 elasticsearch:8.8.1
若 elasticsearch 容器运行命名为 haha,则在其同网络的其他容器,例如 logstash 中配置与 elasticsearch 的连接 URL 就为:http://haha:9200
容器目录挂载机制
如果你在 Docker 中使用挂载命令将宿主机的目录 $HOME/logs 挂载到容器中的 /home/zailiang/logs,但容器内的 /home/zailiang/logs 目录不存在,Docker 会如何处理这个情况取决于你指定的挂载方式:
- 创建目录:
- 如果宿主机的目录
$HOME/logs存在且包含文件,Docker 将会把这个目录的内容挂载到容器内的/home/zailiang/logs。 - 如果容器内的
/home/zailiang/logs目录不存在,Docker 会在挂载时 自动创建这个目录。因此,容器启动时会创建/home/zailiang/logs,并将宿主机的内容映射到该目录中。
- 如果宿主机的目录
- 如果宿主机的目录不存在:
- 如果你指定的宿主机目录
$HOME/logs不存在,Docker 将会启动容器,但容器内的/home/zailiang/logs将是一个 空目录。此时,任何尝试访问/home/zailiang/logs的操作都将得到一个空目录的视图。
- 如果你指定的宿主机目录
–link 与 –network(–net) 的区别
由于 –link 的静态性和缺乏灵活性,在如今以微服务和容器编排为核心的架构中已经不再适用。Docker 自定义网络功能更为灵活、安全和可靠,因此 –link 不再推荐使用。
pull 报错:connection refused
1PS C:\Users\Zailiang> docker pull milvusdb/milvus:v2.5.11
2Error response from daemon: failed to resolve reference "docker.io/milvusdb/milvus:v2.5.11": failed to do request: Head "https://registry-1.docker.io/v2/milvusdb/milvus/manifests/v2.5.11": proxyconnect tcp: dial tcp 127.0.0.1:7897: connect: connection refused
什么都不需要配置!!!Resource - Proxies 信息也不需要填
开启 Docker 前先关闭网络代理,启动完 Docker 方可打开网络代理,此时就正常了。
无权限使用 docker 命令
1permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Head "http://%2Fvar%2Frun%2Fdocker.sock/_ping": dial unix /var/run/docker.sock: connect: permission denied
这个错误是因为当前用户没有权限访问 Docker 守护进程(Docker Daemon)。Docker 默认需要 root 或 docker 用户组权限才能操作。以下是解决方法:
方法 1:使用 **sudo**(临时解决)
1sudo docker images
方法 2:将当前用户加入 **docker** 用户组(推荐)
1# 1. 检查 docker 用户组是否存在
2sudo groupadd docker # 如果不存在则创建
3# 2. 将当前用户加入 docker 组
4sudo usermod -aG docker $USER
5# 3. 重启终端
6# 4. 验证权限
7docker images
# syntax=docker/dockerfile:1 特性
- BuildKit 已经是默认构建引擎
- 即使不写
# syntax=...,也会自动使用 BuildKit - 大部分新特性已经默认可用
如果你:
- 使用 Docker 20.10+
- 只用基础指令 (FROM, RUN, COPY, CMD 等)
- 不需要
--mount或 heredoc 等高级特性
→ 可以不写,性能提升已经自动获得
如果你:
- 需要明确使用高级特性
- 想确保团队环境一致
- 追求最佳实践
→ 建议写上,作为明确的声明