Docker 安装与配置指南
本文介绍如何在 Ubuntu 系统上安装 Docker,解决权限问题,配置 Docker Compose,代理端口转发,容器内部代理问题等并进行相关的优化设置。参考官方文档:Docker 官方安装指南
注意:本教程的部分命令需ubuntu系统可科学上网
一、安装 Docker
1. 卸载旧版本
在安装新版 Docker 之前,建议先卸载旧版本以避免潜在的冲突。执行以下命令卸载旧版本的 Docker:
sudo apt-get remove docker docker-engine docker.io containerd runc
- 1
2. 更新包索引并安装必要的依赖
更新包索引并安装一些必要的依赖包:
sudo apt-get update
sudo apt-get install -y ca-certificates curl
- 1
- 2
3. 配置 Docker 仓库
创建 apt
密钥存储目录
确保密钥存储目录存在,并设置合适的权限:
sudo install -m 0755 -d /etc/apt/keyrings
- 1
移除旧的 Docker 配置
删除之前所有与 Docker 相关的配置文件,以确保仓库配置的干净整洁:
sudo rm -rf /etc/apt/sources.list.d/docker.list
sudo rm -rf /etc/apt/keyrings/docker.asc
- 1
- 2
添加 Docker 的官方 GPG 密钥
从阿里云镜像源添加 Docker 的官方 GPG 密钥:
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
- 1
设置 Docker 仓库
将 Docker 仓库添加到 apt
源列表中:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
- 1
- 2
- 3
- 4
4. 安装 Docker 引擎
更新包索引并安装最新版本的 Docker 引擎及相关组件:
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
- 1
- 2
二、配置 Docker 权限与 Docker Compose
1. 解决 Docker 权限问题
为了避免每次使用 sudo
来运行 Docker 命令,可以将当前用户添加到 docker
用户组:
创建 Docker 用户组
如果 docker
组尚未存在,则创建该组:
sudo groupadd docker
- 1
将当前用户添加到 Docker 组
执行以下命令将当前用户添加到 docker
组中:
sudo usermod -aG docker $USER
- 1
激活组更改
重新加载组更改,使其立即生效:
newgrp docker
- 1
验证权限
运行一个测试镜像以验证配置是否成功:
docker run hello-world
# 如果镜像拉取失败则需要配置代理,请见下文
- 1
- 2
2. 安装 Docker Compose
注意:新版 Docker 已内置 docker compose
(注意中间有空格)命令,无需单独安装 docker-compose
。推荐使用内置命令:
docker compose version
- 1
如果仍然需要安装独立的 docker-compose
,可以执行以下命令:
docker-compose 独立安装指南
# 要下载并安装Docker Compose独立版,请运行:
sudo curl -SL https://github.com/docker/compose/releases/download/v2.32.4/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
# 如果下载失败,使用镜像网站下载,或者本地下载后上传至服务器的 /usr/local/bin/ 目录中, 然后将文件重命名为docker-compose
# 如果linux服务有代理,curl 可以使用 -x 参数挂上代理,如:
sudo curl -x 127.0.0.1:7890 -SL https://github.com/docker/compose/releases/download/v2.32.4/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
# 为目标路径中的独立二进制文件应用可执行权限。
sudo chmod +x /usr/local/bin/docker-compose
# 在安装后 docker-compose 创建一个到 /usr/bin 软链接,以便环境变量可以直接访问 docker-compose 这个命令。例如:
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
# 验证
docker-compose version
which docker-compose
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
3. 启动 Docker 服务
确保 Docker 服务已经启动,并设置为开机自启:
启动 Docker 服务
可以使用以下任意一种方式启动 Docker 服务:
sudo service docker start
- 1
或
sudo systemctl start docker
- 1
设置开机自启
sudo systemctl enable docker
- 1
检查 Docker 服务状态
sudo systemctl status docker
- 1
4. 完整的权限检查和修复
确保 Docker 套接字的权限正确,并验证用户组配置:
检查 Docker Socket 权限
ls -l /var/run/docker.sock
- 1
修改 Socket 权限(如有必要)
如果权限不正确,可以调整为所有用户可读写:
sudo chmod 666 /var/run/docker.sock
- 1
检查用户组
查看当前用户所属的组,确认是否包含 docker
:
groups $USER
- 1
重启 Docker 服务
应用权限更改:
sudo systemctl restart docker
- 1
5. WSL 特定设置
如果你在 Windows Subsystem for Linux 2(WSL2)中使用 Docker,可能需要额外的配置:
设置 iptables
在 WSL2 中设置 iptables 为 legacy 模式:
sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
- 1
重启 Docker 服务
sudo systemctl restart docker
- 1
6. 配置代理(如需要)
一般来说,宿主的代理地址为 127.0.0.1.7890, 正常情况下宿主机的ip:7890 是不能代理的,这对于docker容器内部访问代理很不友好,因此可以使用端口转发的方式,将宿主机的某个端口映射到127.0.0.1.7890端口上,这样使用http://host.docker.internal:映射端口
就能访问宿主机的代理了,和宿主机本身访问127.0.0.1.7890是一致的。端口映射的命令为:
sudo apt-get install socat
# 假设我们映射的宿主ip的端口为7891
socat TCP-LISTEN:7891,fork TCP:127.0.0.1:7890
# 映射完成后,docker 通过http://host.docker.internal:7891就可以使用代理了
## 验证方法
curl -x http://host.docker.internal:7891 www.google.com # http://host.docker.internal:7891 就是使用代理
- 1
- 2
- 3
- 4
- 5
- 6
- 7
有些时候宿主机无法解析 host.docker.internal 时,可以使用以下的方法动态的获得宿主机的ip地址:
- macOS 和 Windows:
在 macOS 和 Windows 上,Docker Desktop 会自动设置 host.docker.internal 为宿主机的 IP 地址,容器可以直接使用这个主机名与宿主机通讯。 - Linux:
在 Linux 系统上,Docker 并不会自动创建 host.docker.internal 的解析。为了让容器能够通过 host.docker.internal 访问宿主机,你需要手动添加这个主机名和对应的宿主机 IP 地址。具体可以见下文第三个方法
# 参看网卡信息
ifconfig
## 其中 eth0: 就是宿主机的ip,docker0 是docker的网关信息
# 1. 第一种方式:
HOST_IP=$(hostname -I | awk '{print $1}')
即:
curl -x http://$(hostname -I | awk '{print $1}'):7891 www.google.com
# 2,第二种方式
HOST_IP=$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)
即:
curl -x http://$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1):7891 www.google.com
3. 第三种方式:
# macOS 和 Windows:
## 在 macOS 和 Windows 上,Docker Desktop 会自动设置 host.docker.internal 为宿主机的 IP 地址,容器可以直接使用这个主机名与宿主机通讯。
## Linux:
## 在 Linux 系统上,Docker 并不会自动创建 host.docker.internal 的解析。为了让容器能够通过 host.docker.internal 访问宿主机,你需要手动添加这个主机名和对应的宿主机 IP 地址。
# 使用 host-gateway实现这个过程,通过在 docker run 命令中添加 --add-host=host.docker.internal:host-gateway:
docker run -d --add-host=host.docker.internal:host-gateway your_image
# 这里的 host-gateway 将自动解析为 Docker 守护进程所运行的主机的 IP 地址,意味着容器对 host.docker.internal 的访问将被成功解析到宿主机的 IP。这使得在 Linux 上的使用体验与 macOS 和 Windows 变得一致。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
拉取镜像Docker Daemon 代理配置
-
方法一:/etc/systemd/system/docker.service.d/http-proxy.conf
当执行 docker pull 拉取镜像,一般是从 DockerHub 等仓库拉取,此时容易遇到网络问题。
这一拉取过程实际上是 Docker daemon 在执行,而它是由 systemd 启动管理的,并不直接使用我们 shell 中配置的代理环境变量。为了让其走代理,需要编写其 systemd 配置。
影响范围:仅影响 Docker Daemon 的网络请求(如拉取镜像、推送镜像等)。不影响 Docker 客户端(docker 命令)或容器内部的网络请求。
# 创建 Docker 服务配置目录 sudo mkdir -p /etc/systemd/system/docker.service.d # 创建 HTTP 代理配置文件 sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf
- 1
- 2
- 3
- 4
添加以下内容:
[Service] Environment="HTTP_PROXY=http://127.0.0.1:7890" 或 "http://host.docker.internal:7891" 均可 Environment="HTTPS_PROXY=http://127.0.0.1:7890" 或 "http://host.docker.internal:7891" 均可
- 1
- 2
- 3
保存配置后,需要重启 Docker daemon。注意:这会重启所有容器
sudo systemctl daemon-reload sudo systemctl restart docker
- 1
- 2
-
方法二:/etc/docker/daemon.json
影响范围:优先级比/etc/systemd/system/docker.service.d低,设置会影响 Docker 的整体行为,不会直接影响容器内部的代理设置,格式是 JSON
sudo mkdir -p /etc/docker sudo nano /etc/docker/daemon.json
- 1
- 2
添加以下内容
{ "proxies": { "http-proxy": "http://host.docker.internal:7891", // 如果上文http://host.docker.internal:7891 不能使用,请使用 ip addr 或 ifconfig 使用 宿主机网卡ip:7891 代替 "https-proxy": "http://host.docker.internal:7891", "no-proxy": "localhost,127.0.0.1" } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
生效方式:
# 修改后需要重启 Docker 服务: sudo systemctl restart docker
- 1
- 2
建议上述两个配置目录和文件都配置一下
使用示例,参考: 若干种设置Docker的网络代理方法
# 1. 创建环境变量文件 .env: HTTP_PROXY=http://host.docker.internal:7891 HTTPS_PROXY=http://host.docker.internal:7891 NO_PROXY=localhost,127.0.0.1,192.168.49.2 # 在 docker-compose.yml 中使用: services: myapp: env_file: - .env # 或在运行容器时: docker run --env-file .env image_name # 对于 Minikube: export HTTP_PROXY=http://host.docker.internal:7891 export HTTPS_PROXY=http://host.docker.internal:7891 export NO_PROXY=localhost,127.0.0.1,192.168.49.2 minikube start --container-runtime=containerd
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
查看代理设置
```bash
docker info
```
```bash
sudo systemctl show --property=Environment docker
```
**注意**:如果 Docker 无法通过设置的代理连接到 Docker Hub,请检查代理配置是否正确,并确保代理服务器正常运行。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
docker 容器内部代理
容器内的应用或许需要访问外部网络甚至外网,我们也希望其流量通过代理。这需要在容器内配置环境变量。
可以在 Dockerfile 或者 docker run 的时候设定环境变量。host.docker.internal
是docker的特殊变量,它可以动态的获取宿主机的ip地址,由于上文我们已经讲宿主机ip:7891 映射本地环回 127.0.0.1:7890,所以http://host.docker.internal:7891就可以做docker容器的代理地址。
内容示例:
若干种设置Docker的网络代理方法
# 这里只能使用 http://host.docker.internal:7891 这种方式代理,因为如果输入127.0.0.1 是容器访问自己的环回地址
docker run -e HTTP_PROXY=http://host.docker.internal:7891 \
-e HTTPS_PROXY=http://host.docker.internal:7891 \
-e NO_PROXY=localhost,127.0.0.1 \
your-container-image
指定 httpProxy 属性值,相当于在容器内同时设定 http_proxy 和 HTTP_PROXY 两个环境变量。
保存配置后,无需重启任何服务。在保存配置之后启动的 docker 容器,都会自动配置对应环境变量(之前的容器不会改变)。然而,应用是否读取该环境变量并使用代理设置,取决于应用的实现。这并不是一个标准。
⚠️ 注意:此处环境变量会在容器内被读取,所以地址 127.0.0.1 指的是容器自身,而非宿主机。
⚠️ 注意:如果容器是以 root 模式启动的(使用 sudo),上面所述的 ~/.docker/config.json 其实指的是 /root/.docker/config.json。
⚠️ 注意:curl 等工具并不支持 socks 代理,只支持 http。所以建议统一配置 http 代理。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
有些时候宿主机无法解析 host.docker.internal 时,可以使用以下的方法动态的获得宿主机的ip地址:
# 参看网卡信息
ifconfig
## 其中 eth0: 就是宿主机的ip,docker0 是docker的网关信息
# 1. 第一种方式:
HOST_IP=$(hostname -I | awk '{print $1}')
即:
curl -x http://$(hostname -I | awk '{print $1}'):7891 www.google.com
# 2,第二种方式
HOST_IP=$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)
即:
curl -x http://$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1):7891 www.google.com
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
7. 验证 Docker 安装
运行以下命令验证 Docker 和 Docker Compose 是否正确安装:
docker run hello-world
docker compose version
- 1
- 2
三、Docker 日常维护
清理 Docker 缓存
定期清理不再使用的 Docker 镜像、容器、网络和缓存,以释放系统资源:
docker system prune -af
- 1
注意:此命令将删除所有未使用的容器、网络、镜像和构建缓存,请谨慎使用。
评论记录:
回复评论: