Docker笔记
主要是解决配环境烦的问题
1、Docker安装
1.1 准备工作
检查机器上有没有 Docker
docker --version || true
清理冲突包
sudo apt remove -y $(dpkg --get-selections \
docker.io docker-compose docker-compose-v2 docker-doc podman-docker containerd runc \
| cut -f1) || true
更新 apt 索引
sudo apt update
更新完检查,输出0代表成功
echo $?
安装两个基础工具,ca-certificates:让系统能正确验证 HTTPS 网站的证书(否则 curl 拉 https 可能失败);curl:后面要用它下载 Docker 的 GPG key
sudo apt install -y ca-certificates curl
安装完后检查
curl --version
dpkg -l | grep ca-certificates
创建一个专门放 key 的目录(Docker 官方推荐的路径)
sudo install -m 0755 -d /etc/apt/keyrings
创建完后检查
ls -ld /etc/apt/keyrings
下载 Docker 软件源的 GPG 公钥到本机,从 Docker 官网下载 GPG key,保存为 /etc/apt/keyrings/docker.asc
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
运行后检查
ls -l /etc/apt/keyrings/docker.asc
head -n 2 /etc/apt/keyrings/docker.asc
让所有用户都能读取这个 key 文件(apt 需要),给 key 文件加“所有人可读”。否则 apt 可能读不到 key。
sudo chmod a+r /etc/apt/keyrings/docker.asc
做完检查,权限里应该有 r(比如 -rw-r--r--):
ls -l /etc/apt/keyrings/docker.asc
写入 Docker 的 apt 源配置文件(重点),是在创建/覆盖这个文件:/etc/apt/sources.list.d/docker.sources
里面写的是:
Docker 的源地址 URIs: ...
你的 Ubuntu 版本代号(例如 jammy / noble)
用哪个 key 文件来信任这个源 Signed-By: ...
sudo tee /etc/apt/sources.list.d/docker.sources >/dev/null <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF
做完检查,要确认 Suites: 后面确实是你的代号,比如 jammy/noble。如果看到 Suites: 是空的,说明变量没取到
cat /etc/apt/sources.list.d/docker.sources

再次更新 apt 索引(这一步会验证你的 Docker 源是否生效),应该能看到类似包含 download.docker.com 的行(Hit/Get 都行)
sudo apt update

最后一行也是正常的,N开头,只是Notice,不是报错
1.2 安装 Docker
安装 Docker(官方版)
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
验证 Docker 是否安装成功
docker --version
docker compose version
sudo docker run --rm hello-world
1.3 免 sudo 使用 docker
确保 docker 组存在,创建一个名为 docker 的用户组(可能已存在,所以加 || true 不报错)
sudo groupadd docker 2>/dev/null || true
把当前用户加入 docker 组,把你这个用户加进 docker 组(-aG 是追加,不会把你原来的组覆盖掉)
sudo usermod -aG docker $USER
让组权限立刻生效
newgrp docker
试试看有没有设置成功
getent group docker
docker ps
docker run --rm hello-world
成功了

2、Docker使用
2.1、让容器用上 GPU
主机有 GPU 驱动不等于容器能用 GPU,必须安装并配置 NVIDIA Container Toolkit。
先检查有没有装 Toolkit,没输出就代表需要安装
dpkg -l | grep -i nvidia-container-toolkit || true
安装教程:
先做一件很关键的小事:备份 Docker 配置。因为 nvidia-ctk 会修改 /etc/docker/daemon.json。之前还配了 registry-mirrors,先备份最稳.
sudo mkdir -p /etc/docker
sudo cp -a /etc/docker/daemon.json /etc/docker/daemon.json.bak 2>/dev/null || true
添加 NVIDIA Container Toolkit 的 apt 源(官方方式)
sudo apt-get update
sudo apt-get install -y --no-install-recommends curl gnupg2
# 1.1 导入 GPG key(放到系统 keyrings)
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \
| sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
# 1.2 添加仓库 list(会写到 /etc/apt/sources.list.d/)
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \
| sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' \
| sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list >/dev/null
sudo apt-get update
安装 nvidia-container-toolkit
sudo apt-get install -y nvidia-container-toolkit
安装完立刻确认一下(你应该能看到一行已安装包)
dpkg -l | grep -i nvidia-container-toolkit
让 Docker 用上 NVIDIA runtime(关键步骤).这一步做了什么:nvidia-ctk 会改 /etc/docker/daemon.json,把 NVIDIA runtime 配进去,然后你重启 Docker 生效。
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
检查你的 mirror 有没有被覆盖掉(很重要),看一下 /etc/docker/daemon.json 里是否还保留了你之前的 "registry-mirrors"
cat /etc/docker/daemon.json
应该还在

最终验收:容器里跑 nvidia-smi(过了才算 GPU 打通)
docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi
下载老半天,终于成功!

2.2、放进 Docker 容器里跑代码
先切换到项目目录,例如
cd /data/jaxon/MonkeyOCR_Docker_V1
进入容器模式,新建一个叫monkeyocr_docker_v1的容器,如果没有pytorch/pytorch:latest会自动pull的
docker run -it --gpus all \
--name monkeyocr_docker_v1 \
-v "$PWD":/app \
-w /app \
--shm-size=16g \
pytorch/pytorch:latest bash

这个界面说明就进入到容器里面了,可以试试这两个命令能不能用
ls
nvidia-smi

这时候说明没什么问题,下一步就是在容器里配环境了
退出容器
exit
查看所有容器(包括已停止的)
docker ps -a

进入容器,比如monkeyocr_docker_v1
docker start -ai monkeyocr_docker_v1
2.3、(选看示例)在容器中配置MonkeyOCR环境
项目链接
https://github.com/Yuliang-Liu/MonkeyOCR
https://github.com/Yuliang-Liu/MonkeyOCR/blob/main/docs/install_cuda_pp.md#install-with-cuda-support
这里选LMDeploy作为Backend
这里先试试不用conda环境,直接用默认的python环境
先安装PaddleX
export CUDA_VERSION=126 # for CUDA 12.6
pip install paddlepaddle-gpu==3.0.0 -i https://www.paddlepaddle.org.cn/packages/stable/cu126/
pip install "paddlex[base]"
安装LMDeploy
# github上建议的
pip install torch==2.6.0 torchvision==0.21.0 torchaudio==2.6.0 --index-url https://download.pytorch.org/whl/cu126
pip install -e .
# CUDA 12.6
pip install lmdeploy==0.9.2
运行测试(这里得确保有个装有pdf文件的pdf_example文件夹),而且环境配置要改为对应刚刚安装的后端
MKL_THREADING_LAYER=GNU CUDA_VISIBLE_DEVICES=0 python parse.py pdf_example -o output_test -g 200
跑起来了

2.4、Docker镜像导出
先确认你的容器不是临时的(必须能 commit)

进入容器,把 /app 里的全套项目复制到容器内部目录。因为现在的 /app 大概率是 -v "$PWD":/app 挂载进来的。挂载目录内容不会被 docker commit 打进镜像。所以必须复制到容器内部一个“非挂载路径”,比如 /opt/monkeyocr
切换到项目目录
cd /data/jaxon/MonkeyOCR_Docker_V1
进入容器
docker start -ai monkeyocr_docker_v1
创建目录
mkdir -p /opt/monkeyocr
把包括隐藏文件的所有内容复制过去,这样以后即使没有宿主机挂载,这份代码/权重也在镜像里
cp -a /app/. /opt/monkeyocr/
退出容器
exit
执行 commit,打包容器,镜像名为monkeyocr_bundle:1.0,并且希望进去默认就在 /opt/monkeyocr
docker commit \
--change 'WORKDIR /opt/monkeyocr' \
monkeyocr_docker_v1 \
monkeyocr_bundle:1.0
然后等待就行,要挺久

完成后试试能不能用
docker run -it --rm --gpus all --shm-size=16g monkeyocr_bundle:1.0 bash

可以进去
查看镜像列表
docker images

导出镜像给别人,导出为 tar,例如导出的就是monkeyocr_bundle:1.0
docker save monkeyocr_bundle:1.0 | gzip > monkeyocr_bundle_1.0.tar.gz

2.5、Docker镜像导入使用
其他人拿到monkeyocr_bundle_1.0.tar.gz这个镜像压缩包后
导入镜像
gzip -dc monkeyocr_bundle_1.0.tar.gz | docker load
3、遇到的坑合集
3.1、装完后验证 Docker 是否安装成功时 docker: Error response
sudo docker run --rm hello-world
有一个报错

是在从 Docker Hub 拉镜像时,访问 registry-1.docker.io:443 被 connection reset by peer(网络连接被对端/中间设备重置)。这通常不是你 Docker 装坏了,而是 网络/代理/防火墙/运营商链路 问题。
再次验证下到底是不是“访问 Docker Hub 被网络拦/不通”
curl -I https://registry-1.docker.io/v2/

这个现象非常明确:不是 Docker 装坏了,而是你这台机器到 Docker Hub(registry-1.docker.io:443)的网络链路被重置了。
3.1.1 解决方案 1:给 Docker 配置镜像加速(registry mirror)
Docker 官方支持在 /etc/docker/daemon.json 配 registry-mirrors。
国内常用的一种是 DaoCloud 的 docker.m.daocloud.io(用于 docker.io 镜像加速)。
写入 mirror 配置
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json >/dev/null <<'EOF'
{
"registry-mirrors": ["https://docker.m.daocloud.io"]
}
EOF
重启 Docker
sudo systemctl restart docker
验证 mirror 生效
sudo docker info | sed -n '/Registry Mirrors/,+5p'
再拉 hello-world试试
sudo docker pull hello-world
sudo docker run --rm hello-world
还是不行

再试试mirror 本身是否能访问
curl -I https://docker.m.daocloud.io/v2/
可以访问

但Docker Hub CDN 访问不了,超时
curl -I https://production.cloudflare.docker.com/

再换一个会“兜住 layer 下载”的镜像加速地址。现在用的是 DaoCloud(docker.m.daocloud.io)。可以把 mirror 换成/加上其他可用的 DockerHub 加速源,比如 dockerproxy.net、docker.1panel.live 等(这些在近期可用列表里被整理过)。其中 docker.1panel.live 还注明“限制只能中国地区”。
sudo tee /etc/docker/daemon.json >/dev/null <<'EOF'
{
"registry-mirrors": [
"https://dockerproxy.net",
"https://docker.1panel.live",
"https://docker.m.daocloud.io"
]
}
EOF
重启 Docker
sudo systemctl restart docker
然后重试
curl -I https://production.cloudflare.docker.com/
sudo docker pull hello-world
sudo docker run --rm hello-world
奇妙的是,第一行命令连接超时了,后面2行都正常!

本文来自博客园,作者:JaxonYe,转载请注明原文链接:https://www.cnblogs.com/yechangxin/articles/19457782
侵权必究
浙公网安备 33010602011771号