找回密码
 立即注册

QQ登录

只需一步,快速开始

peUfSYR.png
查看: 33|回复: 0

Day 05 Docker容器实战:运行Nginx/MySQL/Redis完全指南

[复制链接]

876

主题

13

回帖

2808

积分

管理员

积分
2808
发表于 2026-3-29 16:16:39 | 显示全部楼层 |阅读模式
今天我们要完成一个非常实用的任务:在Docker中运行三个最常用的服务——Nginx、MySQL和Redis

你将学会
  • ✅ 运行Nginx Web服务器并访问自定义页面
  • ✅ 部署MySQL数据库并实现数据持久化
  • ✅ 启动Redis缓存服务并进行基本操作
  • ✅ 掌握端口映射、环境变量、数据卷等核心技能

    难度等级:⭐⭐☆☆☆(初学者友好)

    所需时间:约 30-40 分钟

    前置要求
  • 已安装Docker(参考Day 2)
  • 了解基本的容器操作(参考Day 3-4)
  • 熟悉命令行基本操作

    准备好了吗?让我们开始今天的实战之旅!

    ━━━━━━━━━━━━━━━━━━━━

    🛠️ 环境准备

    在开始之前,请确保你的环境满足以下要求:

    系统要求

    | 项目 | 要求 | 检查方法 |
    |------|------|----------|
    | 操作系统 | macOS 10.15+ / Windows 10+ / Linux | - |
    | Docker版本 | 20.10+ |
    1. docker --version
    复制代码
    |
    | 内存 | 至少 4GB | - |
    | 磁盘空间 | 至少 5GB 可用空间 |
    1. df -h
    复制代码
    |

    检查命令
    1. # 检查Docker是否安装
    2. docker --version
    3. # 检查Docker是否运行
    4. docker ps
    5. # 检查可用磁盘空间
    6. docker system df
    复制代码

    如果以上命令报错,请先阅读 [Day 2 - Docker安装指南]。

    准备工作目录
    1. # 创建工作目录
    2. mkdir -p ~/docker-practice/day05/{nginx,mysql,redis}
    3. cd ~/docker-practice/day05
    4. # 验证目录结构
    5. tree -L 2
    复制代码

    ✅ 环境准备完成,开始正式操作!

    ━━━━━━━━━━━━━━━━━━━━

    📖 操作步骤

    第一部分:运行 Nginx Web 服务器

    步骤1:启动基础Nginx容器

    目标:快速启动一个Nginx容器并访问默认页面

    操作命令
    1. # 运行Nginx容器
    2. docker run -d \
    3.   --name my-nginx \
    4.   -p 8080:80 \
    5.   nginx:alpine
    6. # 命令说明:
    7. # -d              后台运行
    8. # --name my-nginx 容器命名为 my-nginx
    9. # -p 8080:80      将容器的80端口映射到主机的8080端口
    10. # nginx:alpine    使用nginx的alpine版本(更小,更快)
    复制代码

    命令解析
    1. docker run
    复制代码
    :创建并运行容器
    1. -d
    复制代码
    :detached模式,后台运行
    1. --name my-nginx
    复制代码
    :给容器指定一个友好的名称
    1. -p 8080:80
    复制代码
    :端口映射,格式为
    1. 主机端口:容器端口
    复制代码
    1. nginx:alpine
    复制代码
    :镜像名称和标签,alpine版本仅5MB

    预期输出
    1. Unable to find image 'nginx:alpine' locally
    2. alpine: Pulling from library/nginx
    3. ...
    4. Status: Downloaded newer image for nginx:alpine
    5. a1b2c3d4e5f6...(容器ID)
    复制代码

    验证结果
    1. # 查看运行中的容器
    2. docker ps
    3. # 输出应该类似:
    4. # CONTAINER ID   IMAGE          STATUS         PORTS                  NAMES
    5. # a1b2c3d4e5f6   nginx:alpine   Up 10 seconds  0.0.0.0:8080->80/tcp   my-nginx
    复制代码

    检查点:打开浏览器访问
    1. http://localhost:8080
    复制代码
    ,应该看到 "Welcome to nginx!" 页面

    ━━━━━━━━━━━━━━━━━━━━

    步骤2:自定义Nginx网页内容

    目标:部署自己的HTML页面到Nginx

    创建自定义HTML文件
    1. # 进入nginx目录
    2. cd ~/docker-practice/day05/nginx
    3. # 创建自定义HTML页面
    4. cat > index.html << 'EOF'
    5. <!DOCTYPE html>
    6. <html lang="zh-CN">
    7. <head>
    8.     <meta charset="UTF-8">
    9.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
    10.     <title>我的Docker Nginx</title>
    11.     <style>
    12.         body {
    13.             font-family: Arial, sans-serif;
    14.             background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    15.             display: flex;
    16.             justify-content: center;
    17.             align-items: center;
    18.             height: 100vh;
    19.             margin: 0;
    20.         }
    21.         .container {
    22.             text-align: center;
    23.             background: white;
    24.             padding: 50px;
    25.             border-radius: 20px;
    26.             box-shadow: 0 10px 40px rgba(0,0,0,0.2);
    27.         }
    28.         h1 { color: #333; margin-bottom: 20px; }
    29.         .emoji { font-size: 80px; }
    30.         .info { color: #666; margin-top: 20px; }
    31.     </style>
    32. </head>
    33. <body>
    34.     <div class="container">
    35.         <div class="emoji">🚀</div>
    36.         <h1>Docker Nginx 运行成功!</h1>
    37.         <p class="info">这是我的第一个Docker化的网页</p>
    38.         <p class="info">服务器:Nginx in Docker</p>
    39.     </div>
    40. </body>
    41. </html>
    42. EOF
    复制代码

    停止并删除旧容器
    1. # 停止容器
    2. docker stop my-nginx
    3. # 删除容器
    4. docker rm my-nginx
    复制代码

    挂载自定义页面运行
    1. # 使用数据卷挂载自定义页面
    2. docker run -d \
    3.   --name my-nginx \
    4.   -p 8080:80 \
    5.   -v $(pwd)/index.html:/usr/share/nginx/html/index.html:ro \
    6.   nginx:alpine
    7. # 命令解析:
    8. # -v 宿主机路径:容器路径:权限
    9. # $(pwd)/index.html  当前目录的index.html文件
    10. # /usr/share/nginx/html/index.html  Nginx的默认页面路径
    11. # :ro  只读权限(read-only)
    复制代码

    关键参数说明
    1. -v
    复制代码
    :数据卷挂载(volume)
    1. $(pwd)
    复制代码
    :当前目录的绝对路径
    1. :ro
    复制代码
    :只读挂载,容器内无法修改文件

    检查点:刷新浏览器
    1. http://localhost:8080
    复制代码
    ,应该看到你的自定义页面!

    实时修改测试
    1. # 修改HTML文件
    2. echo '<h1>页面已更新!</h1>' >> index.html
    3. # 刷新浏览器,立即看到变化(无需重启容器)
    复制代码

    ━━━━━━━━━━━━━━━━━━━━

    步骤3:配置Nginx反向代理

    目标:创建Nginx配置文件实现反向代理

    创建Nginx配置文件
    1. # 创建配置文件
    2. cat > nginx.conf << 'EOF'
    3. server {
    4.     listen 80;
    5.     server_name localhost;
    6.    
    7.     # 网站根目录
    8.     location / {
    9.         root /usr/share/nginx/html;
    10.         index index.html;
    11.     }
    12.    
    13.     # API代理示例
    14.     location /api/ {
    15.         proxy_pass http://host.docker.internal:3000/;
    16.         proxy_set_header Host $host;
    17.         proxy_set_header X-Real-IP $remote_addr;
    18.     }
    19.    
    20.     # 健康检查
    21.     location /health {
    22.         access_log off;
    23.         return 200 "healthy\n";
    24.         add_header Content-Type text/plain;
    25.     }
    26. }
    27. EOF
    复制代码

    使用自定义配置运行
    1. # 先停止旧容器
    2. docker stop my-nginx && docker rm my-nginx
    3. # 使用自定义配置运行
    4. docker run -d \
    5.   --name my-nginx \
    6.   -p 8080:80 \
    7.   -v $(pwd)/nginx.conf:/etc/nginx/conf.d/default.conf:ro \
    8.   -v $(pwd)/index.html:/usr/share/nginx/html/index.html:ro \
    9.   nginx:alpine
    复制代码

    测试健康检查
    1. # 访问健康检查端点
    2. curl http://localhost:8080/health
    3. # 预期输出:
    4. # healthy
    复制代码

    检查点:访问
    1. http://localhost:8080/health
    复制代码
    应返回 "healthy"

    ━━━━━━━━━━━━━━━━━━━━

    第二部分:运行 MySQL 数据库

    步骤4:启动MySQL容器

    目标:运行MySQL数据库并设置密码

    操作命令
    1. # 切换到MySQL目录
    2. cd ~/docker-practice/day05/mysql
    3. # 运行MySQL容器
    4. docker run -d \
    5.   --name my-mysql \
    6.   -p 3306:3306 \
    7.   -e MYSQL_ROOT_PASSWORD=my-secret-pw \
    8.   -e MYSQL_DATABASE=testdb \
    9.   -e MYSQL_USER=testuser \
    10.   -e MYSQL_PASSWORD=testpass \
    11.   mysql:8.0
    12. # 命令解析:
    13. # -e  设置环境变量
    14. # MYSQL_ROOT_PASSWORD  root用户密码(必须设置)
    15. # MYSQL_DATABASE       自动创建的数据库名
    16. # MYSQL_USER          自动创建的用户名
    17. # MYSQL_PASSWORD      该用户的密码
    复制代码

    环境变量说明
    | 环境变量 | 作用 | 示例值 |
    |----------|------|--------|
    |
    1. MYSQL_ROOT_PASSWORD
    复制代码
    | root密码(必填) |
    1. my-secret-pw
    复制代码
    |
    |
    1. MYSQL_DATABASE
    复制代码
    | 初始数据库名 |
    1. testdb
    复制代码
    |
    |
    1. MYSQL_USER
    复制代码
    | 创建新用户 |
    1. testuser
    复制代码
    |
    |
    1. MYSQL_PASSWORD
    复制代码
    | 新用户密码 |
    1. testpass
    复制代码
    |

    查看启动日志
    1. # 查看MySQL启动日志
    2. docker logs my-mysql
    3. # 等待看到这行表示启动成功:
    4. # [Server] /usr/sbin/mysqld: ready for connections.
    复制代码

    预期输出
    1. 2024-01-15 10:30:21+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.35-1.el8 started.
    2. ...
    3. 2024-01-15 10:30:35+00:00 [Note] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.35'
    复制代码

    检查点:看到 "ready for connections" 表示MySQL启动成功!

    ━━━━━━━━━━━━━━━━━━━━

    步骤5:连接并操作MySQL

    目标:进入MySQL容器执行SQL命令

    进入MySQL容器
    1. # 进入容器并连接MySQL
    2. docker exec -it my-mysql mysql -u testuser -p
    3. # 输入密码:testpass
    复制代码

    执行SQL操作
    1. -- 查看当前数据库
    2. SHOW DATABASES;
    3. -- 使用testdb数据库
    4. USE testdb;
    5. -- 创建测试表
    6. CREATE TABLE users (
    7.     id INT AUTO_INCREMENT PRIMARY KEY,
    8.     name VARCHAR(50) NOT NULL,
    9.     email VARCHAR(100),
    10.     created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    11. );
    12. -- 插入测试数据
    13. INSERT INTO users (name, email) VALUES
    14.     ('张三', 'zhangsan@example.com'),
    15.     ('李四', 'lisi@example.com'),
    16.     ('王五', 'wangwu@example.com');
    17. -- 查询数据
    18. SELECT * FROM users;
    19. -- 退出MySQL
    20. EXIT;
    复制代码

    预期输出
    1. +----+--------+------------------------+---------------------+
    2. | id | name   | email                  | created_at          |
    3. +----+--------+------------------------+---------------------+
    4. |  1 | 张三   | zhangsan@example.com   | 2024-01-15 10:35:21 |
    5. |  2 | 李四   | lisi@example.com       | 2024-01-15 10:35:21 |
    6. |  3 | 王五   | wangwu@example.com     | 2024-01-15 10:35:21 |
    7. +----+--------+------------------------+---------------------+
    复制代码

    ━━━━━━━━━━━━━━━━━━━━

    步骤6:MySQL数据持久化

    目标:使用数据卷实现数据持久化,防止容器删除后数据丢失

    停止并删除现有容器
    1. docker stop my-mysql
    2. docker rm my-mysql
    复制代码

    创建数据卷并运行
    1. # 创建命名数据卷
    2. docker volume create mysql-data
    3. # 使用数据卷运行MySQL
    4. docker run -d \
    5.   --name my-mysql \
    6.   -p 3306:3306 \
    7.   -e MYSQL_ROOT_PASSWORD=my-secret-pw \
    8.   -e MYSQL_DATABASE=testdb \
    9.   -e MYSQL_USER=testuser \
    10.   -e MYSQL_PASSWORD=testpass \
    11.   -v mysql-data:/var/lib/mysql \
    12.   mysql:8.0
    13. # 命令解析:
    14. # -v mysql-data:/var/lib/mysql
    15. # 将命名卷 mysql-data 挂载到容器的 /var/lib/mysql(MySQL数据目录)
    复制代码

    验证数据持久化
    1. # 等待MySQL启动
    2. sleep 20
    3. # 重新插入数据
    4. docker exec -i my-mysql mysql -u testuser -ptestpass testdb << EOF
    5. CREATE TABLE IF NOT EXISTS users (
    6.     id INT AUTO_INCREMENT PRIMARY KEY,
    7.     name VARCHAR(50)
    8. );
    9. INSERT INTO users (name) VALUES ('持久化测试');
    10. SELECT * FROM users;
    11. EOF
    12. # 停止并删除容器
    13. docker stop my-mysql
    14. docker rm my-mysql
    15. # 重新启动容器(使用相同的数据卷)
    16. docker run -d \
    17.   --name my-mysql \
    18.   -p 3306:3306 \
    19.   -e MYSQL_ROOT_PASSWORD=my-secret-pw \
    20.   -v mysql-data:/var/lib/mysql \
    21.   mysql:8.0
    22. # 等待启动
    23. sleep 20
    24. # 验证数据是否还在
    25. docker exec my-mysql mysql -u root -pmy-secret-pw testdb -e "SELECT * FROM users;"
    复制代码

    检查点:如果能看到之前插入的数据,说明数据持久化成功!

    查看数据卷信息
    1. # 查看所有数据卷
    2. docker volume ls
    3. # 查看数据卷详细信息
    4. docker volume inspect mysql-data
    复制代码

    ━━━━━━━━━━━━━━━━━━━━

    第三部分:运行 Redis 缓存服务

    步骤7:启动Redis容器

    目标:运行Redis服务并进行基本操作

    操作命令
    1. # 切换到Redis目录
    2. cd ~/docker-practice/day05/redis
    3. # 运行Redis容器
    4. docker run -d \
    5.   --name my-redis \
    6.   -p 6379:6379 \
    7.   redis:alpine \
    8.   redis-server --appendonly yes
    9. # 命令解析:
    10. # redis:alpine         使用alpine版本的Redis
    11. # redis-server         Redis服务器命令
    12. # --appendonly yes     开启AOF持久化
    复制代码

    验证Redis启动
    1. # 查看容器状态
    2. docker ps | grep redis
    3. # 查看Redis日志
    4. docker logs my-redis
    复制代码

    预期输出
    1. 1:C 15 Jan 2024 10:40:15.123 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
    2. 1:C 15 Jan 2024 10:40:15.123 # Redis version=7.2.3, bits=64, commit=00000000, modified=0
    3. ...
    4. 1:M 15 Jan 2024 10:40:15.125 * Ready to accept connections tcp
    复制代码

    检查点:看到 "Ready to accept connections" 表示Redis启动成功!

    ━━━━━━━━━━━━━━━━━━━━

    步骤8:连接并操作Redis

    目标:使用redis-cli进行缓存操作

    进入Redis容器
    1. # 进入容器并启动redis-cli
    2. docker exec -it my-redis redis-cli
    复制代码

    执行Redis命令
    1. # 测试连接
    2. PING
    3. # 输出:PONG
    4. # 设置字符串
    5. SET name "Docker Redis"
    6. # 输出:OK
    7. # 获取字符串
    8. GET name
    9. # 输出:"Docker Redis"
    10. # 设置带过期时间的键(10秒)
    11. SETEX temp 10 "临时数据"
    12. GET temp
    13. # 等待10秒后再执行
    14. GET temp
    15. # 输出:(nil)
    16. # 列表操作
    17. LPUSH tasks "任务1" "任务2" "任务3"
    18. LRANGE tasks 0 -1
    19. # 输出:
    20. # 1) "任务3"
    21. # 2) "任务2"
    22. # 3) "任务1"
    23. # 哈希操作
    24. HSET user:1001 name "张三" age "25" city "北京"
    25. HGETALL user:1001
    26. # 输出:
    27. # 1) "name"
    28. # 2) "张三"
    29. # 3) "age"
    30. # 4) "25"
    31. # 5) "city"
    32. # 6) "北京"
    33. # 集合操作
    34. SADD tags "docker" "redis" "cache"
    35. SMEMBERS tags
    36. # 查看所有键
    37. KEYS *
    38. # 退出redis-cli
    39. EXIT
    复制代码

    ━━━━━━━━━━━━━━━━━━━━

    步骤9:Redis数据持久化配置

    目标:配置Redis持久化,确保数据安全

    创建Redis配置文件
    1. # 创建自定义Redis配置
    2. cat > redis.conf << 'EOF'
    3. # 网络配置
    4. bind 0.0.0.0
    5. protected-mode yes
    6. port 6379
    7. # 持久化配置
    8. # RDB持久化
    9. save 900 1      # 900秒内至少1个key变化则保存
    10. save 300 10     # 300秒内至少10个key变化则保存
    11. save 60 10000   # 60秒内至少10000个key变化则保存
    12. dbfilename dump.rdb
    13. dir /data
    14. # AOF持久化
    15. appendonly yes
    16. appendfilename "appendonly.aof"
    17. appendfsync everysec
    18. # 内存管理
    19. maxmemory 256mb
    20. maxmemory-policy allkeys-lru
    21. # 日志
    22. loglevel notice
    23. EOF
    复制代码

    配置说明
    | 配置项 | 说明 | 推荐值 |
    |--------|------|--------|
    |
    1. save
    复制代码
    | RDB快照触发条件 |
    1. 900 1
    复制代码
    |
    |
    1. appendonly
    复制代码
    | 是否启用AOF |
    1. yes
    复制代码
    |
    |
    1. appendfsync
    复制代码
    | AOF同步频率 |
    1. everysec
    复制代码
    |
    |
    1. maxmemory
    复制代码
    | 最大内存限制 |
    1. 256mb
    复制代码
    |
    |
    1. maxmemory-policy
    复制代码
    | 内存淘汰策略 |
    1. allkeys-lru
    复制代码
    |

    使用自定义配置运行
    1. # 停止旧容器
    2. docker stop my-redis
    3. docker rm my-redis
    4. # 创建数据卷
    5. docker volume create redis-data
    6. # 使用配置文件和数据卷运行
    7. docker run -d \
    8.   --name my-redis \
    9.   -p 6379:6379 \
    10.   -v $(pwd)/redis.conf:/usr/local/etc/redis/redis.conf:ro \
    11.   -v redis-data:/data \
    12.   redis:alpine \
    13.   redis-server /usr/local/etc/redis/redis.conf
    复制代码

    验证持久化
    1. # 写入测试数据
    2. docker exec -it my-redis redis-cli SET persist-test "数据持久化测试"
    3. # 重启容器
    4. docker restart my-redis
    5. # 等待启动
    6. sleep 3
    7. # 验证数据是否还在
    8. docker exec my-redis redis-cli GET persist-test
    9. # 输出:"数据持久化测试"
    复制代码

    检查点:重启后数据依然存在,说明持久化配置成功!

    ━━━━━━━━━━━━━━━━━━━━

    💻 完整代码

    为了方便你快速上手,这里提供完整的代码和配置文件。

    目录结构
    1. day05/
    2. ├── nginx/
    3. │   ├── index.html
    4. │   └── nginx.conf
    5. ├── mysql/
    6. │   └── init.sql
    7. ├── redis/
    8. │   └── redis.conf
    9. ├── docker-compose.yml
    10. └── start-all.sh
    复制代码

    docker-compose.yml
    1. version: '3.8'
    2. services:
    3.   # Nginx Web服务器
    4.   nginx:
    5.     image: nginx:alpine
    6.     container_name: my-nginx
    7.     ports:
    8.       - "8080:80"
    9.     volumes:
    10.       - ./nginx/index.html:/usr/share/nginx/html/index.html:ro
    11.       - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
    12.     restart: unless-stopped
    13.     networks:
    14.       - app-network
    15.   # MySQL数据库
    16.   mysql:
    17.     image: mysql:8.0
    18.     container_name: my-mysql
    19.     ports:
    20.       - "3306:3306"
    21.     environment:
    22.       MYSQL_ROOT_PASSWORD: my-secret-pw
    23.       MYSQL_DATABASE: testdb
    24.       MYSQL_USER: testuser
    25.       MYSQL_PASSWORD: testpass
    26.     volumes:
    27.       - mysql-data:/var/lib/mysql
    28.       - ./mysql/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
    29.     restart: unless-stopped
    30.     networks:
    31.       - app-network
    32.     healthcheck:
    33.       test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
    34.       interval: 10s
    35.       timeout: 5s
    36.       retries: 5
    37.   # Redis缓存
    38.   redis:
    39.     image: redis:alpine
    40.     container_name: my-redis
    41.     ports:
    42.       - "6379:6379"
    43.     volumes:
    44.       - redis-data:/data
    45.       - ./redis/redis.conf:/usr/local/etc/redis/redis.conf:ro
    46.     command: redis-server /usr/local/etc/redis/redis.conf
    47.     restart: unless-stopped
    48.     networks:
    49.       - app-network
    50.     healthcheck:
    51.       test: ["CMD", "redis-cli", "ping"]
    52.       interval: 10s
    53.       timeout: 3s
    54.       retries: 5
    55. # 数据卷定义
    56. volumes:
    57.   mysql-data:
    58.     driver: local
    59.   redis-data:
    60.     driver: local
    61. # 网络定义
    62. networks:
    63.   app-network:
    64.     driver: bridge
    复制代码

    mysql/init.sql
    1. -- MySQL初始化脚本
    2. USE testdb;
    3. CREATE TABLE IF NOT EXISTS users (
    4.     id INT AUTO_INCREMENT PRIMARY KEY,
    5.     name VARCHAR(50) NOT NULL,
    6.     email VARCHAR(100) UNIQUE,
    7.     created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    8.     updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
    9. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    10. CREATE TABLE IF NOT EXISTS products (
    11.     id INT AUTO_INCREMENT PRIMARY KEY,
    12.     name VARCHAR(100) NOT NULL,
    13.     price DECIMAL(10, 2) NOT NULL,
    14.     stock INT DEFAULT 0,
    15.     created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    16. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    17. -- 插入示例数据
    18. INSERT INTO users (name, email) VALUES
    19.     ('张三', 'zhangsan@example.com'),
    20.     ('李四', 'lisi@example.com'),
    21.     ('王五', 'wangwu@example.com');
    22. INSERT INTO products (name, price, stock) VALUES
    23.     ('商品A', 99.99, 100),
    24.     ('商品B', 199.99, 50),
    25.     ('商品C', 299.99, 30);
    复制代码

    start-all.sh
    1. #!/bin/bash
    2. # 一键启动脚本
    3. echo "🚀 启动所有服务..."
    4. # 创建目录
    5. mkdir -p nginx mysql redis
    6. # 检查配置文件
    7. if [ ! -f "docker-compose.yml" ]; then
    8.     echo "❌ 未找到 docker-compose.yml 文件"
    9.     exit 1
    10. fi
    11. # 启动服务
    12. docker-compose up -d
    13. # 等待服务启动
    14. echo "⏳ 等待服务启动..."
    15. sleep 10
    16. # 检查服务状态
    17. echo ""
    18. echo "📊 服务状态检查:"
    19. docker-compose ps
    20. # 健康检查
    21. echo ""
    22. echo "🏥 健康检查:"
    23. # 检查Nginx
    24. if curl -s http://localhost:8080/health > /dev/null 2>&1; then
    25.     echo "✅ Nginx: 运行正常"
    26. else
    27.     echo "⚠️  Nginx: 可能未就绪"
    28. fi
    29. # 检查MySQL
    30. if docker exec my-mysql mysqladmin ping -h localhost --silent > /dev/null 2>&1; then
    31.     echo "✅ MySQL: 运行正常"
    32. else
    33.     echo "⚠️  MySQL: 可能未就绪"
    34. fi
    35. # 检查Redis
    36. if docker exec my-redis redis-cli ping | grep -q PONG; then
    37.     echo "✅ Redis: 运行正常"
    38. else
    39.     echo "⚠️  Redis: 可能未就绪"
    40. fi
    41. echo ""
    42. echo "🎉 所有服务已启动!"
    43. echo ""
    44. echo "📝 访问地址:"
    45. echo "   Nginx:  http://localhost:8080"
    46. echo "   MySQL:  localhost:3306 (user: testuser, pass: testpass)"
    47. echo "   Redis:  localhost:6379"
    48. echo ""
    49. echo "📖 查看日志: docker-compose logs -f [服务名]"
    50. echo "🛑 停止服务: docker-compose down"
    复制代码

    使用方法
    1. # 1. 克隆或下载所有文件到 day05 目录
    2. # 2. 赋予执行权限
    3. chmod +x start-all.sh
    4. # 3. 一键启动所有服务
    5. ./start-all.sh
    6. # 4. 查看服务状态
    7. docker-compose ps
    8. # 5. 查看特定服务日志
    9. docker-compose logs -f nginx
    10. # 6. 停止所有服务
    11. docker-compose down
    12. # 7. 停止并删除数据卷(慎用)
    13. docker-compose down -v
    复制代码

    ━━━━━━━━━━━━━━━━━━━━

    🚀 进阶实践

    掌握了基础操作后,试试这些进阶玩法:

    实践1:搭建WordPress博客

    目标:使用Nginx + MySQL组合部署WordPress

    提示
  • 使用
    1. wordpress:php7.4-fpm
    复制代码
    镜像
  • 配置Nginx作为反向代理
  • MySQL存储WordPress数据
  • 使用Docker网络连接服务

    参考思路
    1. services:
    2.   wordpress:
    3.     image: wordpress:php7.4-fpm
    4.     environment:
    5.       WORDPRESS_DB_HOST: mysql
    6.       WORDPRESS_DB_NAME: wordpress
    7.       WORDPRESS_DB_USER: wp_user
    8.       WORDPRESS_DB_PASSWORD: wp_pass
    复制代码

    ━━━━━━━━━━━━━━━━━━━━

    实践2:Redis主从复制

    目标:配置Redis主从架构实现数据复制

    建议
  • 启动1个主节点(master)
  • 启动2个从节点(slave)
  • 配置从节点连接主节点
  • 验证数据同步

    检查清单
  • [ ] 主节点写入数据
  • [ ] 从节点能读取到相同数据
  • [ ] 主节点宕机后从节点数据完整

    ━━━━━━━━━━━━━━━━━━━━

    实践3:MySQL主从复制

    目标:配置MySQL主从复制实现读写分离

    挑战
  • 配置主库的binlog
  • 配置从库的relay log
  • 设置复制用户权限
  • 验证数据同步延迟

    资源
  • MySQL官方文档 - 复制配置
  • Docker Hub - MySQL镜像说明

    💡 提示:完成这些实践后,在评论区分享你的成果和遇到的问题!

    ━━━━━━━━━━━━━━━━━━━━

    🐛 故障排查

    问题1:端口被占用

    症状
    1. Error: Bind for 0.0.0.0:3306 failed: port is already allocated
    复制代码

    原因:本机已有MySQL或其他程序占用3306端口

    解决方案

    方法1:更换端口
    1. ports:
    2.   - "3307:3306"  # 使用3307端口
    复制代码

    方法2:停止本机MySQL服务
    1. # macOS
    2. brew services stop mysql
    3. # Linux
    4. sudo systemctl stop mysql
    5. # Windows
    6. net stop mysql
    复制代码

    方法3:查找并关闭占用进程
    1. # macOS/Linux
    2. lsof -i :3306
    3. kill -9 <PID>
    4. # Windows
    5. netstat -ano | findstr :3306
    6. taskkill /PID <PID> /F
    复制代码

    ━━━━━━━━━━━━━━━━━━━━

    问题2:MySQL连接被拒绝

    症状
    1. ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (111)
    复制代码

    原因:MySQL还未完全启动或密码错误

    排查步骤
    1. # 1. 检查容器是否运行
    2. docker ps | grep mysql
    3. # 2. 查看MySQL启动日志
    4. docker logs my-mysql
    5. # 3. 等待"ready for connections"出现
    6. docker logs -f my-mysql | grep "ready for connections"
    7. # 4. 使用正确的密码连接
    8. docker exec -it my-mysql mysql -u root -pmy-secret-pw
    复制代码

    常见错误
  • ❌ 使用
    1. -p my-secret-pw
    复制代码
    (有空格)
  • ✅ 使用
    1. -pmy-secret-pw
    复制代码
    (无空格)

    ━━━━━━━━━━━━━━━━━━━━

    问题3:数据卷权限问题

    症状
    1. mkdir: cannot create directory '/var/lib/mysql': Permission denied
    复制代码

    原因:容器内用户权限不足

    解决方案

    方法1:使用命名卷(推荐)
    1. docker volume create mysql-data
    2. docker run -v mysql-data:/var/lib/mysql mysql:8.0
    复制代码

    方法2:修改主机目录权限
    1. # 创建目录
    2. mkdir -p ~/mysql-data
    3. # 修改权限
    4. chmod 777 ~/mysql-data
    5. # 使用绝对路径挂载
    6. docker run -v ~/mysql-data:/var/lib/mysql mysql:8.0
    复制代码

    ━━━━━━━━━━━━━━━━━━━━

    问题4:Redis持久化失败

    症状
    1. Can't open the append-only file: Permission denied
    复制代码

    原因:Redis无权限写入AOF文件

    解决方案
    1. # 方法1:使用命名卷
    2. docker volume create redis-data
    3. docker run -v redis-data:/data redis:alpine
    4. # 方法2:修改目录权限
    5. chmod 777 ~/redis-data
    复制代码

    ━━━━━━━━━━━━━━━━━━━━

    问题5:容器启动后立即退出

    症状:容器状态显示 "Exited (1) 5 seconds ago"

    排查步骤
    1. # 1. 查看容器日志(最重要)
    2. docker logs <容器名>
    3. # 2. 查看最近的事件
    4. docker events --since 1h
    5. # 3. 使用inspect查看详情
    6. docker inspect <容器名>
    7. # 4. 尝试交互式启动
    8. docker run -it --rm <镜像名> sh
    复制代码

    常见原因
  • 环境变量配置错误(如MySQL缺少ROOT_PASSWORD)
  • 配置文件语法错误
  • 端口冲突
  • 内存不足

    ━━━━━━━━━━━━━━━━━━━━

    更多问题?

    如果遇到其他问题:
  • 查看 Docker官方文档
  • 搜索 Stack Overflow
  • 查看镜像的 Docker Hub页面
  • 在评论区留言描述问题
  • 加入学习群讨论(文末二维码)

    ━━━━━━━━━━━━━━━━━━━━

    📚 知识点回顾

    今天我们通过实践学习了:

    核心命令

    | 命令 | 作用 | 示例 |
    |------|------|------|
    |
    1. docker run -d
    复制代码
    | 后台运行容器 |
    1. docker run -d nginx
    复制代码
    |
    |
    1. docker run -p
    复制代码
    | 端口映射 |
    1. docker run -p 8080:80 nginx
    复制代码
    |
    |
    1. docker run -e
    复制代码
    | 设置环境变量 |
    1. docker run -e MYSQL_ROOT_PASSWORD=pw mysql
    复制代码
    |
    |
    1. docker run -v
    复制代码
    | 挂载数据卷 |
    1. docker run -v data:/var/lib/mysql mysql
    复制代码
    |
    |
    1. docker exec -it
    复制代码
    | 进入容器 |
    1. docker exec -it mysql bash
    复制代码
    |
    |
    1. docker logs
    复制代码
    | 查看日志 |
    1. docker logs -f mysql
    复制代码
    |
    |
    1. docker volume create
    复制代码
    | 创建数据卷 |
    1. docker volume create data
    复制代码
    |

    关键概念

  • 端口映射
    1. -p 主机端口:容器端口
    复制代码
    ,实现外部访问
  • 环境变量
    1. -e KEY=VALUE
    复制代码
    ,配置容器运行参数
  • 数据卷
    1. -v 卷名:容器路径
    复制代码
    ,实现数据持久化
  • 健康检查:定期检查服务是否正常运行
  • 网络隔离:容器间通过网络互联

    最佳实践

  • ✅ 使用alpine镜像减小体积
  • ✅ 使用命名卷而非绑定挂载
  • ✅ 为容器设置有意义的名称
  • ✅ 配置健康检查确保服务可用
  • ✅ 敏感信息使用环境变量或secrets
  • ✅ 生产环境配置资源限制
  • ✅ 使用docker-compose管理多容器

    三大服务对比

    | 服务 | 用途 | 默认端口 | 数据目录 | 配置要点 |
    |------|------|----------|----------|----------|
    | Nginx | Web服务器 | 80 |
    1. /usr/share/nginx/html
    复制代码
    | 配置文件、静态文件挂载 |
    | MySQL | 关系数据库 | 3306 |
    1. /var/lib/mysql
    复制代码
    | 必须设置ROOT_PASSWORD |
    | Redis | 缓存/NoSQL | 6379 |
    1. /data
    复制代码
    | 持久化配置、内存限制 |

    下一步学习

    完成今天的实践后,建议:
  • 把三个服务都运行起来并验证
  • 尝试至少一个进阶实践
  • 熟悉docker-compose的使用
  • 学习下一篇:Day 6 - 构建自己的Docker镜像

    ━━━━━━━━━━━━━━━━━━━━

    💬 作业时间

    今日挑战
  • ✅ 成功运行Nginx、MySQL、Redis三个服务
  • ✅ 使用docker-compose一键启动所有服务
  • ✅ 实现至少一个进阶实践(WordPress或主从复制)
  • ✅ 截图分享你的运行结果

    讨论话题
  • 你在配置MySQL或Redis时遇到了什么问题?
  • 你觉得数据持久化最容易出错的地方是什么?
  • 你会在实际项目中如何使用这三个服务?

    在评论区分享你的:
  • ✅ 三个服务的运行截图
  • 💡 遇到的问题和解决方案
  • 🎯 进阶实践的成果展示
  • 🤔 你的疑问和思考

    ━━━━━━━━━━━━━━━━━━━━

    📖 系列文章

  • Day 1:Docker简介与核心概念
  • Day 2:Docker安装与环境配置
  • Day 3:你的第一个Docker容器
  • Day 4:Docker镜像管理完全指南
  • Day 5:Docker容器实战(本文)⭐
  • Day 6:构建自己的Docker镜像
  • Day 7:Docker Compose入门

    查看完整目录

    ━━━━━━━━━━━━━━━━━━━━

    🎁 福利资源

    代码仓库 📦  
    本文所有示例代码和配置文件:  
    https://github.com/your-repo/docker-30days/tree/main/day05

    学习资料包 📚  
    包含:
  • 三大服务完整配置模板
  • 常见问题解决方案文档
  • Docker Compose最佳实践
  • 性能优化建议

    获取方式:关注公众号,回复「Day5

    ━━━━━━━━━━━━━━━━━━━━

    加入学习群 👥  
    扫描下方二维码,加入Docker学习交流群,和1000+小伙伴一起学习实践!



    关注公众号 🔔  
    回复「Docker」获取完整30天学习路线图

    ━━━━━━━━━━━━━━━━━━━━

    下期预告 🎬  
    Day 6 - 构建你的第一个Docker镜像:从Dockerfile到发布
  • 编写Dockerfile
  • 构建自定义镜像
  • 优化镜像大小
  • 发布到Docker Hub

    我们下期见!💪

    ━━━━━━━━━━━━━━━━━━━━

    如果觉得这篇文章对你有帮助,别忘了点赞、在看、转发三连支持一下!你的支持是我持续创作的动力!❤️
  • 您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    扫码关注微信公众号

    Archiver|手机版|小黑屋|风叶林

    GMT+8, 2026-5-8 23:04 , Processed in 0.181560 second(s), 20 queries .

    Powered by 风叶林

    © 2001-2026 Discuz! Team.

    快速回复 返回顶部 返回列表