Skip to content
第 3 章 运维 ⏱ 10 分钟阅读

第 3 章:Docker 入门 ​

学习目标 ​

  • 理解容器和镜像的区别
  • 学会 docker run / ps / logs 等基础命令
  • 掌握镜像拉取、启动、进入容器
  • 避开网络和卷挂载的常见坑

一、镜像 vs 容器 ​

  • 镜像(Image):只读模板(类似 .iso 安装包)
  • 容器(Container):镜像的运行实例(类似已启动的 VM)

一个镜像可以起无数个容器,容器之间互不影响。

二、安装 Docker ​

bash
# Ubuntu
curl -fsSL https://get.docker.com | bash

# CentOS
dnf install docker -y

# macOS / Windows
# 装 Docker Desktop(图形界面)

# 启动并自启
systemctl start docker
systemctl enable docker

# 验证
docker version              # 客户端 + 服务端版本
docker run hello-world      # 跑一个测试容器

⚠️ 坑 1:docker 命令默认要 root。想让普通用户用,把用户加进 docker 组:usermod -aG docker $USER,重新登录生效。 ⚠️ 坑 2:Docker Desktop for Windows 走 WSL2,文件存放路径在 Linux 子系统里(\\wsl$\...),共享性能比原生 Linux 差。

三、核心命令 ​

bash
# 镜像
docker search nginx                   # 搜镜像
docker pull nginx:1.25                # 拉镜像(默认 latest)
docker images                         # 看本地镜像
docker rmi nginx:1.25                 # 删镜像

# 容器
docker run -d --name web -p 8080:80 nginx:1.25     # 后台跑
docker ps                             # 运行中的
docker ps -a                          # 所有(含已停)
docker stop web                       # 优雅停
docker start web                      # 启动已存在的
docker restart web                    # 重启
docker rm web                         # 删容器(必须先停)
docker rm -f web                      # 强制删(运行中也行)
docker logs web                       # 看日志
docker logs -f web                    # 实时跟踪
docker logs --tail 100 web            # 最后 100 行
docker exec -it web bash              # 进容器(-it 分配终端)
docker inspect web                    # 查详情(JSON)
docker stats                          # 所有容器实时资源占用

⚠️ 坑 3:docker rm 不能删运行中的容器,要么先 stop 要么加 -f。批量清:docker rm -f $(docker ps -aq)。 ⚠️ 坑 4:docker logs 看不到 stdout?容器主进程必须前台运行(详见 Dockerfile 章)。如果跑了 nohup xxx &,日志永远在文件里看不到。

四、端口映射详解 ​

bash
docker run -d -p 8080:80 nginx:1.25
#            ↑↑   ↑↑  ↑
#            宿主机 容器镜像
#            8080→容器 80

# 多端口
docker run -d -p 8080:80 -p 8443:443 nginx

# 指定网卡
docker run -d -p 127.0.0.1:8080:80 nginx    # 仅本机可访问
docker run -d -p 8080:80 nginx              # 默认 0.0.0.0,所有人可访问

# 随机端口
docker run -d -P nginx                      # 把容器 EXPOSE 端口随机映射

⚠️ 坑 5:宿主机端口已被占用 → bind: address already in use。先查谁占着:ss -tlnp | grep 8080。

五、卷挂载(数据持久化) ​

容器删了,内部数据就没了。重要数据必须挂卷:

bash
# 命名卷(Docker 管)
docker run -d -v mydata:/data nginx

# 绑定挂载(宿主机目录)
docker run -d -v /opt/web:/usr/share/nginx/html:ro nginx
#                                    ↑ ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
#                                       只读(ro)/读写(rw,默认)

# 临时文件系统(性能好,重启丢)
docker run -d --tmpfs /tmp nginx

# 查看卷
docker volume ls
docker volume inspect mydata

⚠️ 坑 6:docker run -v mydata:/data,容器里 /data 改完,容器删了再起,数据还在(命名卷持久)。忘记挂载等于自删库。

六、网络模式 ​

bash
# 默认 bridge(每个容器独立 IP,能访问外网)
docker run -d nginx

# host(直接用宿主机网络,无隔离)
docker run -d --network host nginx

# none(无网络,完全隔离)
docker run -d --network none alpine

# 容器间互联(推荐)
docker network create mynet
docker run -d --network mynet --name db   mysql
docker run -d --network mynet --name app   myapp
# 此时 app 容器可以通过 db 这个主机名直接访问 MySQL
docker network connect mynet existing_container   # 后加进网络

⚠️ 坑 7:同网桥里的容器才可以用名字互访。跨网桥只能通过 IP,DNS 解析不到。

七、镜像推送(发布到仓库) ​

bash
# 登录(Docker Hub)
docker login -u username

# 打 tag(必须是 用户名/仓库名 格式)
docker tag myapp:1.0 username/myapp:1.0

# 推送
docker push username/myapp:1.0

# 拉别人的
docker pull username/myapp:1.0

私有仓库(公司内网):

bash
docker run -d -p 5000:5000 --restart always -v /opt/registry:/var/lib/registry registry:2
docker tag myapp:1.0 192.168.1.10:5000/myapp:1.0
docker push 192.168.1.10:5000/myapp:1.0

⚠️ 坑 8:私有仓库 HTTP 推送被拒?Docker 默认禁 HTTP。改 /etc/docker/daemon.json 加 "insecure-registries": ["192.168.1.10:5000"],再 systemctl restart docker。

八、本章小结 ​

命令作用
docker run跑容器
docker ps / logs / exec查 / 看 / 进
docker pull / push拉 / 推镜像
-p端口映射
-v数据卷挂载
--network网络模式

动手练习 ​

  1. docker run -d -p 8080:80 --name web nginx,浏览器访问 localhost:8080 看到 nginx 欢迎页
  2. docker exec -it web bash 进容器改 /usr/share/nginx/html/index.html,注意改了容器内重启会丢(下一章 Dockerfile 解决)
  3. 用 -v /tmp/web:/usr/share/nginx/html:ro 挂载,改宿主机文件生效
  4. 启一个 MySQL 容器,用命名卷,验证容器删了数据还在

下一章:第 4 章:Dockerfile 与镜像 →

本站基于 VitePress 构建 · 由 StackHub 团队维护