第 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 | 网络模式 |
动手练习
docker run -d -p 8080:80 --name web nginx,浏览器访问localhost:8080看到 nginx 欢迎页docker exec -it web bash进容器改/usr/share/nginx/html/index.html,注意改了容器内重启会丢(下一章 Dockerfile 解决)- 用
-v /tmp/web:/usr/share/nginx/html:ro挂载,改宿主机文件生效 - 启一个 MySQL 容器,用命名卷,验证容器删了数据还在
下一章:第 4 章:Dockerfile 与镜像 →