Docker 快速通关

一、Docker 大致介绍

Docker 可以帮助我们完成应用的 运行(run)构建(build)分享(share)

它的核心目标很简单:

  • 把应用和环境打包起来
  • 让应用在不同机器上尽量保持一致
  • 方便部署、迁移和分发

二、Docker 的几个核心概念

1. Docker Host

首先,我们需要一台 VPS,在这台 VPS 上安装 Docker。

这台装了 Docker 环境的 VPS,通常叫做:

text 复制代码
Docker Host

也就是 Docker 主机。

2. Docker Daemon

Docker Daemon 是 Docker 的守护进程。

它会一直运行,负责接收命令并处理容器、镜像等操作。

3. Docker CLI

Docker CLI 是命令行工具,也就是我们平时输入的 docker 命令。

比如:

bash 复制代码
docker pull redis

这个命令就是由 Docker CLI 发给 Docker Daemon 去执行。

4. Registry

Registry 可以理解成镜像仓库,也就是 Docker 的应用市场。

里面有很多常见镜像,比如:

  • MySQL
  • Nginx
  • Redis

这些镜像可以直接下载使用。

5. Image 和 Container

  • Image(镜像):可以理解成应用模板
  • Container(容器):镜像运行起来后的实例

镜像是静态的,容器是运行中的。


三、Docker 的基本工作流程

1. 拉取镜像

bash 复制代码
docker pull redis

这个命令的意思是:

  • Docker Daemon 接收到命令
  • 去 Registry 找 redis 镜像
  • 下载到本地

2. 运行容器

bash 复制代码
docker run redis

这个命令的意思是:

  • 先看本地有没有 redis 镜像
  • 如果没有,就去 Registry 下载
  • 然后用这个镜像启动一个 Redis 容器

3. 多个容器

同一个镜像可以启动多个容器。

比如你可以同时启动多个 Redis 容器,每个容器都是独立隔离的。


四、Docker 能做什么

Docker 最常见的用途就是这三件事:

1. Run:运行应用

把镜像变成正在运行的容器。

2. Build:构建镜像

bash 复制代码
docker build xxx

这个命令可以用来制作自己的镜像。

3. Share:分享镜像

bash 复制代码
docker push xxx

这个命令可以把自己做好的镜像推送到 Registry,方便别人下载和使用。


五、简单理解 Docker 的关系

可以这样记:

  • Docker Host:安装了 Docker 的机器
  • Docker Daemon:后台守护进程,负责干活
  • Docker CLI:我们输入命令的地方
  • Registry:镜像仓库,存放镜像
  • Image:镜像,应用模板
  • Container:容器,镜像运行后的实例

六、Docker 的安装

在 VPS 中可以直接执行官方安装脚本:

bash 复制代码
curl -fsSL https://get.docker.com | bash

官方文档:

text 复制代码
https://docs.docker.com/engine/install/ubuntu/

七、Docker 无法连接时的配置

如果 Docker 无法连接,可以创建这个文件:

bash 复制代码
/etc/docker/daemon.json

在里面可以配置:

  • Docker 数据目录
  • Registry 镜像加速
  • 本地代理

示例配置

json 复制代码
{
  "data-root": "/data/docker",
  "registry-mirrors": [
    "https://docker.1ms.run"
  ],
  "proxies": {
    "http-proxy": "http://127.0.0.1:7890",
    "https-proxy": "http://127.0.0.1:7890",
    "no-proxy": "localhost,127.0.0.1"
  }
}

1. data-root

data-root 是 Docker 的数据根目录。

镜像、容器、卷等持久化数据默认都放在这里。

Linux 默认值是:

text 复制代码
/var/lib/docker

如果你想把 Docker 数据放到别的盘,可以修改这个值,比如:

json 复制代码
"data-root": "/data/docker"

2. registry-mirrors

这个配置是镜像加速地址。

常见用途是加速拉取镜像。

如果已经配置了可用的国内镜像,很多情况下就不需要再额外配代理了。

3. proxies

这个配置是代理。

适合本机无法直接访问外网镜像仓库的情况。


八、代理和镜像的简单理解

一般来说:

  • 国外机器通常只需要配置 data-root
  • 国内机器通常会配置 data-root + 代理
  • 也可以直接配置国内镜像加速

一个常见场景

A:国内 VPS
  • 安装 Docker
  • 需要拉外网镜像
B:国外 VPS
  • 安装 Tinyproxy
  • 作为 HTTP 正向代理
A 机器的 Docker daemon
  • daemon.json 里把代理指向 B

这样 A 就能通过 B 去拉镜像。


九、在国外 VPS 上安装 Tinyproxy

在国外 VPS 上可以这样安装:

bash 复制代码
sudo apt update
sudo apt install -y tinyproxy

安装完成后,Tinyproxy 可以作为 HTTP 正向代理使用。


十、国外服务器 B:Tinyproxy 完整配置

/etc/tinyproxy/tinyproxy.conf

conf 复制代码
User nobody
Group nogroup

Port 8888
Timeout 600
Listen 0.0.0.0
Allow 1.2.3.4
BasicAuth dockerproxy StrongPass123
Syslog On
LogLevel Info

# 不写 ConnectPort 表示允许 CONNECT 到所有目标端口
# 如果以后想收紧,只允许标准 HTTPS,可以取消下面这一行注释
# ConnectPort 443

配置说明

  • User nobody / Group nogroup:Tinyproxy 的运行身份,按机器实际存在的用户组来写
  • Port 8888:代理监听端口
  • Timeout 600:连接空闲超时
  • Listen 0.0.0.0:监听全部网卡
  • Allow 1.2.3.4:只允许国内 A 机公网 IP 访问
  • BasicAuth dockerproxy StrongPass123:代理认证
  • Syslog On:日志输出到 syslog
  • LogLevel Info:日志级别
  • ConnectPort 443:如果启用,只允许 CONNECT 到 443 端口

十一、Docker daemon 的代理配置示例

json 复制代码
{
  "data-root": "/data/docker",
  "registry-mirrors": [
    "https://your-mirror.example.com"
  ],
  "proxies": {
    "http-proxy": "http://dockerproxy:StrongPass123@203.0.113.10:8888",
    "https-proxy": "http://dockerproxy:StrongPass123@203.0.113.10:8888",
    "no-proxy": "localhost,127.0.0.1,.local"
  }
}

说明

  • 如果已经配置了可用的国内镜像,很多情况下就不需要再额外配代理了
  • 如果还是需要访问外网镜像仓库,就可以继续保留代理配置
  • no-proxy 里写本机地址和局域网域名,避免这些地址走代理

十二、国内服务器通过 systemd 给 Docker 配代理

国内服务器还可以通过 systemd 单独给 Docker 服务配代理。

配置文件

bash 复制代码
/etc/systemd/system/docker.service.d/http-proxy.conf

内容

ini 复制代码
[Service]
Environment="HTTP_PROXY=http://dockerproxy:StrongPass123@203.0.113.10:8888"
Environment="HTTPS_PROXY=http://dockerproxy:StrongPass123@203.0.113.10:8888"
Environment="NO_PROXY=localhost,127.0.0.1,.local"

说明

这样 Docker 服务启动之后,就默认使用这个代理。

修改完以后,执行:

bash 复制代码
sudo systemctl daemon-reload
sudo systemctl restart docker

额外说明

  • 修改了 /etc/docker/daemon.json 后,只需要执行:
bash 复制代码
sudo systemctl restart docker
  • 修改了 /etc/systemd/system/docker.service.d/http-proxy.conf 后,需要先执行:
bash 复制代码
sudo systemctl daemon-reload
sudo systemctl restart docker

十三、Docker 常用命令

Docker 的基础环境和运行原理了解之后,就可以开始学常用命令了。

下面这些是最常用的一批命令。

搜索镜像。

bash 复制代码
docker search redis

2. docker pull

从镜像仓库拉取镜像。

bash 复制代码
docker pull redis
docker pull 的完整写法

docker pull 的本质是:

text 复制代码
镜像名:标签

比如:

bash 复制代码
docker pull nginx

实际上等价于:

bash 复制代码
docker pull nginx:latest

因为不写标签时,默认就是 latest

如果你拉取了 nginx,再用:

bash 复制代码
docker images

就能看到本地已经有这个镜像了。

下载指定版本镜像

如果你想下载指定版本,就直接在镜像名后面加标签,比如:

bash 复制代码
docker pull nginx:1.26.0

这表示下载 nginx1.26.0 版本。

3. docker images

查看本地有哪些镜像。

bash 复制代码
docker images

4. docker ps

查看正在运行的容器。

bash 复制代码
docker ps

docker ps 是查看正在运行中的容器

5. docker ps -a

查看所有容器,包括已经停止的。

bash 复制代码
docker ps -a

docker ps -a 是查看正在运行 + 已停止 的所有容器。

6. docker run

运行一个容器。

bash 复制代码
docker run redis

7. docker stop

停止一个正在运行的容器。

bash 复制代码
docker stop 容器ID

8. docker start

启动一个已经停止的容器。

bash 复制代码
docker start 容器ID

已停止的容器,可以通过 docker start 再次运行。

9. docker restart

重启容器。

bash 复制代码
docker restart 容器ID

已经运行的容器,可以通过 docker restart 重新运行。

10. docker rm

删除容器。

bash 复制代码
docker rm 容器ID

删除容器时,容器必须已经停止。

你也可以使用:

bash 复制代码
docker rm -f 容器ID

这个方式可以强制删除正在运行中的容器。

11. docker rmi

删除镜像。

bash 复制代码
docker rmi 镜像ID

12. docker logs

查看容器日志。

bash 复制代码
docker logs 容器ID

13. docker exec

进入正在运行的容器执行命令。

bash 复制代码
docker exec -it 容器ID bash

14. docker inspect

查看容器或镜像的详细信息。

bash 复制代码
docker inspect 容器ID

15. docker build

构建镜像。

bash 复制代码
docker build -t myapp:1.0 .

16. docker push

推送镜像到仓库。

bash 复制代码
docker push myapp:1.0

17. docker stats

查看容器资源使用情况。

bash 复制代码
docker stats

十四、镜像和容器命令补充说明

前面这一节已经把最常用的镜像和容器命令列出来了,这里做一个简单归类:

镜像相关

  • docker search
  • docker pull
  • docker images
  • docker rmi
  • docker build
  • docker commit
  • docker save
  • docker load
  • docker login
  • docker tag
  • docker push

容器相关

  • docker run
  • docker ps
  • docker ps -a
  • docker stop
  • docker start
  • docker restart
  • docker rm
  • docker logs
  • docker exec
  • docker inspect
  • docker stats

一些常见组合

bash 复制代码
docker ps -aq
docker rm -f $(docker ps -aq)
bash 复制代码
docker commit -m "修改了Nginx首页" mynginx myNginx:v1.0
bash 复制代码
docker save -o nginx.tar nginx:1.26.0
bash 复制代码
docker load -i nginx.tar

十五、保存镜像的几个命令

十五、保存镜像的几个命令

1. docker commit

把正在运行的容器保存成一个新的镜像。

bash 复制代码
docker commit -m "修改了Nginx首页" mynginx myNginx:v1.0

这个命令的意思是:

  • -m:提交说明
  • mynginx:容器名
  • myNginx:v1.0:新的镜像名和版本

执行完 docker commit -m "修改了Nginx首页" mynginx myNginx:v1.0 之后,再执行:

bash 复制代码
docker images

就可以看到你自己的镜像了。

2. docker save

把镜像保存成一个文件。

bash 复制代码
docker save -o nginx.tar nginx:1.26.0

docker save -o 后面写导出的 .tar 文件名,再写镜像名和版本,就可以把镜像导出成 xxx.tar

这个 xxx.tar 可以用 scp 传输给其他机子。

3. docker load

把保存好的镜像文件重新加载回来。

bash 复制代码
docker load -i nginx.tar

执行完 docker load -i xxx.tar 后,再执行:

bash 复制代码
docker images

就可以看到有这个镜像了。


十六、Docker 镜像分享社区

Docker 镜像分享到社区时,通常会用到这三个命令:

1. docker login

登录镜像仓库。

默认登录的是 Docker Hub。

如果是个人 Harbor,也可以登录你的 Harbor 仓库地址。

2. docker tag

给本地镜像打标签,改成仓库地址格式。

3. docker push

把镜像推送到仓库。

个人 Harbor 的完整流程

假设你的 Harbor 地址是 harbor.example.com,完整流程一般是这样:

bash 复制代码
docker login harbor.example.com

然后给镜像打标签:

bash 复制代码
docker tag mynginx:v1.0 harbor.example.com/library/mynginx:v1.0

最后推送:

bash 复制代码
docker push harbor.example.com/library/mynginx:v1.0

如果是 Docker Hub,流程也类似,只是仓库地址会换成 Docker Hub 的命名方式。

docker tag 为什么需要

docker tag 是因为推送的镜像需要满足仓库的命名要求。

也就是说,先把本地镜像改成"仓库地址 + 项目名 + 版本号"的格式,docker push 才知道推到哪里。


十七、Docker 命令速记图

text 复制代码
镜像
- docker search
- docker pull
- docker images
- docker rmi

容器
- docker run
- docker ps
- docker stop
- docker start
- docker restart
- docker stats
- docker logs
- docker exec
- docker rm

分享
- docker commit
- docker save
- docker load
- docker login
- docker tag
- docker push

十八、一个小技巧

docker ps -aq

  • -a:打印所有容器
  • -q:只打印容器 ID

所以:

bash 复制代码
docker ps -aq

表示打印所有容器的 ID,包括运行中的和停止的。

删除所有容器

bash 复制代码
docker rm -f $(docker ps -aq)

这个命令的意思是:

  • docker ps -aq 先拿到所有容器 ID
  • docker rm -f 再强制删除这些容器

所以它可以删除所有运行中的和停止的容器。


十九、Docker 存储:目录挂载和卷映射

Docker 的存储方式,常见有两种:

  • 目录挂载
  • 卷映射

1. 目录挂载

目录挂载可以用 -v 把宿主机目录映射到容器里。

例如:

bash 复制代码
docker run -v ./data:/data nginx

或者使用绝对路径:

bash 复制代码
docker run -v /data/app:/data nginx

目录挂载的意思是:

  • 宿主机上的文件夹
  • 映射到 Docker 容器内

目录挂载适合什么情况

如果这些文件是 容器运行之后生成的,目录挂载就很合适。

比如:

  • 日志文件
  • 上传文件
  • 数据文件
  • 容器运行后才生成的配置文件

目录挂载的问题

如果这些文件是 容器一开始就需要存在的,目录挂载就可能有问题。

因为:

  • 容器里原本有内容
  • 但宿主机挂进去的是空目录
  • 结果把容器里的原始内容覆盖掉了

除非你在宿主机上提前把这些文件准备好,否则目录挂载可能会对容器产生严重影响。

2. 卷映射

卷映射可以解决这个问题。

它适合:

  • 容器需要持久化数据
  • 不想直接依赖宿主机具体路径
  • 想让 Docker 自己管理数据

卷映射的默认位置

卷映射默认会放在 Docker 的数据根目录下面。

如果没有改过配置,默认是在:

text 复制代码
/var/lib/docker/volumes/<volume-name>/_data

如果你在 /etc/docker/daemon.json 里配置了:

json 复制代码
"data-root": "/data/docker"

那么卷映射的数据位置也会跟着变到:

text 复制代码
/data/docker/volumes/<volume-name>/_data

也就是说,data-root 会影响 Docker 整体数据存放位置,卷映射的位置也会一起改变。

目录挂载和卷映射的写法

目录挂载

目录挂载是把宿主机目录映射到容器目录。

写法通常是:

bash 复制代码
docker run -v /app/nghtml:/usr/share/nginx/html nginx

如果使用相对路径,也可以这样写:

bash 复制代码
docker run -v ./data:/data nginx

目录挂载要注意区分:

  • 绝对路径写法/app/nghtml:/usr/share/nginx/html
  • 相对路径写法./data:/data
卷映射

卷映射也是用 -v,但左边通常不是你自己指定的宿主机目录,而是 Docker 管理的卷名。

例如:

bash 复制代码
docker run -v ngconf:/etc/nginx nginx

宿主机变化会不会影响容器

无论是目录挂载还是卷映射,宿主机里的内容变化,都会反映到容器内部。

也就是说:

  • 宿主机改了文件,容器里会看到变化
  • 容器里改了文件,宿主机里也会看到变化

这就是挂载和卷映射的意义:让宿主机和容器共享同一份数据

目录挂载和卷映射的区别

目录挂载
  • 你自己指定宿主机路径
  • 比如 /app/nghtml./data
  • 适合自己明确知道文件放哪的场景
卷映射
  • Docker 自己管理路径
  • 默认在 Docker 数据目录下的 _data
  • 更适合长期持久化数据

目录挂载的场景示例

比如 Nginx 日志,容器启动后会不断生成新文件,这种场景适合目录挂载:

bash 复制代码
docker run -v /data/nginx/logs:/var/log/nginx nginx
一开始就需要存在的文件

比如某些应用启动时必须读取配置文件,如果容器里本来就有默认配置,而宿主机挂进去的是空目录,就会出问题。这个时候更适合先把宿主机文件准备好,或者改用卷映射。


二十、Docker 网络

Docker 默认会有一个 docker0 网络。

为什么需要自定义 Docker 网络

假设有两个容器:

  • app1
  • app2

宿主机端口映射如下:

  • app1:宿主机 88 端口映射到容器内部 80
  • app2:宿主机 99 端口映射到容器内部 80

如果使用 Docker 默认网络,那么容器内部的 app1 想访问 app2,通常要先访问宿主机地址:

bash 复制代码
curl http://宿主机IP:99

这就很绕,明明两个容器就在同一台机器里,却非要先绕到宿主机端口再访问。

可以把它理解成:

同事就在你旁边,你却先跑到公司门口,再重新进来找他聊天。

很绕,也很不自然。

docker0 是 Docker 的默认网络

docker0 是 Docker 默认网络。

你可以通过下面的命令查看容器的详细信息:

bash 复制代码
docker container inspect xxx

里面会看到容器在 docker0 网络中的 IP 地址,比如:

text 复制代码
172.17.0.2

这个 IP 就是容器在 docker0 网络中的地址。

直接用容器 IP 访问的问题

你可以通过容器 IP 来访问另一个容器,但有一个问题:

  • 容器启动顺序不同,IP 可能变化
  • 容器重启后,IP 也可能变化

所以直接用容器 IP 不够稳定。

容器名和内部 IP 的访问方式

容器名访问比直接写 IP 更好一些。

因为容器名更容易记,也更稳定。

为什么要自定义 Docker 网络

Docker 默认的 docker0 网络,通常不适合直接用容器名互相访问。

如果你想让容器之间直接通过:

  • 容器名
  • 内部 IP

来访问,就需要在运行容器时把它们加入一个自定义网络

这样容器之间就可以直接互相通信,不需要先绕到宿主机端口。

创建和使用自定义网络

先创建一个自定义网络:

bash 复制代码
docker network create mynet

然后把容器加入这个网络:

bash 复制代码
docker run --network mynet --name app1 nginx
docker run --network mynet --name app2 redis

这样 app1 就可以直接通过容器名访问 app2

bash 复制代码
curl http://app2:6379

二十一、最简单的总结

Docker 的安装和基础配置可以先记住这几件事:

  • 安装:curl -fsSL https://get.docker.com | bash
  • 配置文件:/etc/docker/daemon.json
  • data-root:Docker 数据目录
  • registry-mirrors:镜像加速
  • proxies:代理配置
  • Tinyproxy:可以作为国外 VPS 的 HTTP 正向代理出口
  • 也可以通过 systemd 给 Docker 服务单独配置代理

如果你先把这些搞明白,Docker 的入门就算通了。

相关推荐
两点王爷3 小时前
docker 创建和使用存储卷相关内容
java·docker·容器
知秋贺6 小时前
如何在ubuntu24中,使用docker 运行ros2 humble版本
运维·docker·容器
yanwumuxi6 小时前
Windows本地部署Dify(Docker)
人工智能·docker·语言模型
浪潮IT馆7 小时前
WSL2 + Docker Desktop 部署 Dify
运维·docker·容器
芥子沫8 小时前
可独立部署的健身饮食管理推荐:wger,Docker一键安装部署教程
docker·容器·开源·健身
robin59118 小时前
【技术】更改docker网络MTU办法
网络·docker·容器
恼书:-(空寄8 小时前
K8s Ingress 七层网关 + 灰度发布 + HTTPS 实战
容器·kubernetes
不是书本的小明8 小时前
ACK+ESS实现K8s节点自动扩缩容
容器·kubernetes
恼书:-(空寄10 小时前
Docker Swarm + K8s 集群部署完整指南
docker·容器·kubernetes