Docker 命令详解 - 从零开始学习

Docker 命令详解 - 从零开始学习

_

📖 Docker 基础概念

什么是Docker?

  • 镜像(Image): 类似于"程序安装包",包含了运行应用所需的所有文件

  • 容器(Container): 类似于"正在运行的程序",是镜像的运行实例

  • Docker守护进程: 后台运行的Docker服务,负责管理镜像和容器

类比理解

镜像 = 游戏安装包(.exe文件)
容器 = 正在运行的游戏程序
Docker = 游戏平台(如Steam)

🔧 脚本中使用的Docker命令详解

1. 环境检查命令

command -v docker

# 作用:检查docker命令是否存在
# 类似于:which docker
# 返回:如果找到返回路径,否则返回空

if ! command -v docker &> /dev/null; then
    echo "Docker未安装"
fi

docker info

# 作用:显示Docker系统信息
# 检查:Docker服务是否正在运行
# 输出:Docker版本、容器数量、镜像数量等信息

docker info
# 如果Docker服务未启动,会报错:Cannot connect to the Docker daemon

2. 容器管理命令

docker ps

# 作用:列出容器
docker ps        # 只显示正在运行的容器
docker ps -a     # 显示所有容器(包括已停止的)

# 输出格式:
# CONTAINER ID | IMAGE | COMMAND | CREATED | STATUS | PORTS | NAMES

docker stop

# 作用:优雅停止容器
docker stop container_name

# 工作原理:
# 1. 发送SIGTERM信号给容器内的主进程
# 2. 等待10秒让程序自己关闭
# 3. 如果还没关闭,发送SIGKILL强制终止

docker rm

# 作用:删除容器
docker rm container_name

# 注意:
# - 只能删除已停止的容器
# - 删除后容器的所有数据都会丢失(除非使用了数据卷)

docker run

# 作用:从镜像创建并启动新容器
# 这是最复杂但最重要的命令

docker run [选项] 镜像名 [命令]

# 常用选项解释:
-d                    # 后台运行(detached)
--name my-app         # 给容器命名
-p 8080:80           # 端口映射:主机端口:容器端口
-e KEY=value         # 设置环境变量
--restart unless-stopped  # 重启策略
-v /host:/container  # 挂载目录(数据持久化)

脚本中的完整运行命令:

docker run -d \
    --name "stack-game-app" \        # 容器名称
    --restart unless-stopped \       # 重启策略
    -p "9527:9527" \                 # 端口映射
    -e NODE_ENV=production \         # 环境变量1
    -e PORT="9527" \                 # 环境变量2
    "stack-game:latest"              # 镜像名称

3. 镜像管理命令

docker build

# 作用:从Dockerfile构建镜像
docker build -t 镜像名:标签 构建上下文路径

# 参数解释:
-t stack-game:latest    # 打标签,格式:名称:版本
.                      # 构建上下文为当前目录

# 工作流程:
# 1. Docker客户端将当前目录所有文件打包发送给Docker守护进程
# 2. Docker守护进程读取Dockerfile文件
# 3. 按照Dockerfile的指令逐步构建镜像
# 4. 每个指令都会创建一个新的镜像层

docker images

# 作用:列出本地镜像
docker images

# 输出格式:
# REPOSITORY | TAG | IMAGE ID | CREATED | SIZE

docker rmi

# 作用:删除镜像
docker rmi 镜像名:标签

# 注意:
# - 不能删除正在被容器使用的镜像
# - 需要先停止并删除使用该镜像的容器

4. 日志和调试命令

docker logs

# 作用:查看容器日志
docker logs container_name           # 查看所有日志
docker logs container_name -f        # 实时跟踪日志(类似tail -f)
docker logs container_name --tail 20 # 只看最后20行

# 日志来源:
# - 容器内应用写入 stdout 和 stderr 的内容
# - 包括console.log、print、echo等输出

docker exec

# 作用:在运行的容器内执行命令
docker exec -it container_name sh    # 进入容器的shell
docker exec container_name ls /app   # 在容器内执行ls命令

# 参数解释:
-i    # 交互模式,保持STDIN开放
-t    # 分配伪终端,让命令行更友好

🚀 脚本执行流程图

开始
  ↓
检查Docker是否安装 ──→ 未安装 ──→ 退出并提示安装
  ↓ 已安装
检查Docker服务是否运行 ──→ 未运行 ──→ 退出并提示启动
  ↓ 正在运行
清理现有容器
  ↓
清理现有镜像(可选)
  ↓
构建新镜像 ──→ 构建失败 ──→ 退出并显示错误
  ↓ 构建成功
启动新容器 ──→ 启动失败 ──→ 退出并显示错误
  ↓ 启动成功
等待应用启动(10秒)
  ↓
健康检查(最多10次)──→ 检查失败 ──→ 退出并显示日志
  ↓ 检查成功
显示成功信息和管理命令
  ↓
结束

🔍 深入理解:为什么这样设计?

1. 为什么要先清理现有容器?

# 问题:如果不清理,会发生什么?
# 1. 端口冲突 - 9527端口已被占用
# 2. 容器名冲突 - stack-game-app 名称已存在
# 3. 资源浪费 - 旧容器继续占用内存

# 解决方案:
docker stop old_container  # 优雅停止
docker rm old_container    # 删除容器

2. 为什么要进行健康检查?

# 容器启动 ≠ 应用可用
# 可能的情况:
# 1. 容器启动了,但应用还在初始化
# 2. 应用启动失败,但容器进程没有退出
# 3. 依赖服务连接失败

# 健康检查确保:
curl http://localhost:9527/health  # 应用真正可用

3. 为什么使用多阶段构建?

# 阶段1:构建环境(体积大,包含开发工具)
FROM node:18-alpine AS builder
RUN npm install  # 安装所有依赖
RUN npm run build  # 构建前端

# 阶段2:生产环境(体积小,只包含运行时)
FROM node:18-alpine AS production
COPY --from=builder /app/dist ./dist  # 只复制构建结果

# 优势:
# - 最终镜像体积更小
# - 不包含开发工具,更安全
# - 构建过程更清晰

🛠️ 实践练习

练习1:基础命令

# 1. 查看Docker版本
docker --version

# 2. 查看系统信息
docker info

# 3. 列出所有容器
docker ps -a

# 4. 列出所有镜像
docker images

练习2:运行一个简单容器

# 1. 运行nginx容器
docker run -d --name my-nginx -p 8080:80 nginx

# 2. 访问应用
curl http://localhost:8080

# 3. 查看日志
docker logs my-nginx

# 4. 进入容器
docker exec -it my-nginx bash

# 5. 停止并删除
docker stop my-nginx
docker rm my-nginx

练习3:理解端口映射

# 启动容器,映射不同端口
docker run -d --name test1 -p 8081:80 nginx  # 主机8081 → 容器80
docker run -d --name test2 -p 8082:80 nginx  # 主机8082 → 容器80

# 验证:
curl http://localhost:8081  # 访问第一个容器
curl http://localhost:8082  # 访问第二个容器

# 清理
docker stop test1 test2
docker rm test1 test2

💡 常见错误和解决方法

1. 端口已被占用

# 错误信息:bind: address already in use
# 原因:端口9527已被其他程序占用

# 解决方法:
# 查找占用端口的程序
netstat -tlnp | grep 9527
# 或者
lsof -i :9527

# 停止占用端口的程序,或使用其他端口
docker run -p 9528:9527 stack-game:latest

2. 镜像构建失败

# 常见原因:
# 1. 网络问题 - 无法下载依赖
# 2. Dockerfile语法错误
# 3. 依赖配置错误

# 调试方法:
# 逐步构建,找到失败的步骤
docker build -t test . --no-cache

3. 容器启动后立即退出

# 查看退出原因
docker logs container_name

# 常见原因:
# 1. 应用配置错误
# 2. 缺少必要文件
# 3. 权限问题

# 调试方法:
# 进入容器手动启动应用
docker run -it --entrypoint sh stack-game:latest

🎓 学习总结

通过这个脚本,学会了:

  1. Docker环境检查 - 确保Docker可用

  2. 容器生命周期管理 - 创建、启动、停止、删除

  3. 镜像构建和管理 - 从代码到可运行镜像

  4. 网络和端口映射 - 让外部访问容器内应用

  5. 日志和调试 - 排查问题的方法

  6. 健康检查 - 确保应用真正可用

checkPermissionModifier 权限修饰器组件 2025-12-30
项目代码制作制品库以及上传 2025-12-30

评论区