冷蟊初退 孤灯野澜 志起鸡鸣 墓不悲秋 技术交流 软件开发 商业合作 加Q:411239339

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

浏览:222次阅读
没有评论

共计 5663 个字符,预计需要花费 15 分钟才能阅读完成。

文章目录
  • Docker Nginx 运行成功!
  • 页面已更新!
  • 第二部分:运行 MySQL 数据库
  • 第三部分:运行 Redis 缓存服务
  • 💻 完整代码
  • 🚀 进阶实践
  • 🐛 故障排查
  • 📚 知识点回顾
  • 💬 作业时间
  • 📖 系列文章
  • 🎁 福利资源
  • 今天我们要完成一个非常实用的任务: 在 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+ docker --version
    内存 至少 4GB
    磁盘空间 至少 5GB 可用空间 df -h

    检查命令

    # 检查 Docker 是否安装
    docker --version
    
    # 检查 Docker 是否运行
    docker ps
    
    # 检查可用磁盘空间
    docker system df

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

    准备工作目录

    # 创建工作目录
    mkdir -p ~/docker-practice/day05/{nginx,mysql,redis}
    cd ~/docker-practice/day05
    
    # 验证目录结构
    tree -L 2

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


    📖 操作步骤

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

    步骤 1:启动基础 Nginx 容器

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

    操作命令

    # 运行 Nginx 容器
    docker run -d \
      --name my-nginx \
      -p 8080:80 \
      nginx:alpine
    
    # 命令说明:# -d              后台运行
    # --name my-nginx 容器命名为 my-nginx
    # -p 8080:80      将容器的 80 端口映射到主机的 8080 端口
    # nginx:alpine    使用 nginx 的 alpine 版本(更小,更快)

    命令解析

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

    预期输出

    Unable to find image 'nginx:alpine' locally
    alpine: Pulling from library/nginx
    ...
    Status: Downloaded newer image for nginx:alpine
    a1b2c3d4e5f6...(容器 ID)

    验证结果

    # 查看运行中的容器
    docker ps
    
    # 输出应该类似:# CONTAINER ID   IMAGE          STATUS         PORTS                  NAMES
    # a1b2c3d4e5f6   nginx:alpine   Up 10 seconds  0.0.0.0:8080->80/tcp   my-nginx

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


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

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

    创建自定义 HTML 文件

    # 进入 nginx 目录
    cd ~/docker-practice/day05/nginx
    
    # 创建自定义 HTML 页面
    cat > index.html << 'EOF'
    
    
    
        
        
         我的 Docker Nginx
        
    
    
        
    🚀

    Docker Nginx 运行成功!

    这是我的第一个 Docker 化的网页

    服务器:Nginx in Docker

    EOF

    停止并删除旧容器

    # 停止容器
    docker stop my-nginx
    
    # 删除容器
    docker rm my-nginx

    挂载自定义页面运行

    # 使用数据卷挂载自定义页面
    docker run -d \
      --name my-nginx \
      -p 8080:80 \
      -v $(pwd)/index.html:/usr/share/nginx/html/index.html:ro \
      nginx:alpine
    
    # 命令解析:# -v 宿主机路径: 容器路径: 权限
    # $(pwd)/index.html  当前目录的 index.html 文件
    # /usr/share/nginx/html/index.html  Nginx 的默认页面路径
    # :ro  只读权限(read-only)

    关键参数说明

    • -v:数据卷挂载(volume)
    • $(pwd):当前目录的绝对路径
    • :ro:只读挂载,容器内无法修改文件

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

    实时修改测试

    # 修改 HTML 文件
    echo '

    页面已更新!

    ' >> index.html # 刷新浏览器,立即看到变化(无需重启容器)

    步骤 3:配置 Nginx 反向代理

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

    创建 Nginx 配置文件

    # 创建配置文件
    cat > nginx.conf << 'EOF'
    server {
        listen 80;
        server_name localhost;
    
        # 网站根目录
        location / {
            root /usr/share/nginx/html;
            index index.html;
        }
    
        # API 代理示例
        location /api/ {
            proxy_pass http://host.docker.internal:3000/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    
        # 健康检查
        location /health {
            access_log off;
            return 200 "healthy\n";
            add_header Content-Type text/plain;
        }
    }
    EOF

    使用自定义配置运行

    # 先停止旧容器
    docker stop my-nginx && docker rm my-nginx
    
    # 使用自定义配置运行
    docker run -d \
      --name my-nginx \
      -p 8080:80 \
      -v $(pwd)/nginx.conf:/etc/nginx/conf.d/default.conf:ro \
      -v $(pwd)/index.html:/usr/share/nginx/html/index.html:ro \
      nginx:alpine

    测试健康检查

    # 访问健康检查端点
    curl http://localhost:8080/health
    
    # 预期输出:# healthy

    检查点 :访问 http://localhost:8080/health 应返回 "healthy"


    第二部分:运行 MySQL 数据库

    步骤 4:启动 MySQL 容器

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

    操作命令

    # 切换到 MySQL 目录
    cd ~/docker-practice/day05/mysql
    
    # 运行 MySQL 容器
    docker run -d \
      --name my-mysql \
      -p 3306:3306 \
      -e MYSQL_ROOT_PASSWORD=my-secret-pw \
      -e MYSQL_DATABASE=testdb \
      -e MYSQL_USER=testuser \
      -e MYSQL_PASSWORD=testpass \
      mysql:8.0
    
    # 命令解析:# -e  设置环境变量
    # MYSQL_ROOT_PASSWORD  root 用户密码(必须设置)# MYSQL_DATABASE       自动创建的数据库名
    # MYSQL_USER          自动创建的用户名
    # MYSQL_PASSWORD      该用户的密码 
    环境变量说明 环境变量 作用 示例值
    MYSQL_ROOT_PASSWORD root 密码(必填) my-secret-pw
    MYSQL_DATABASE 初始数据库名 testdb
    MYSQL_USER 创建新用户 testuser
    MYSQL_PASSWORD 新用户密码 testpass

    查看启动日志

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

    预期输出

    2024-01-15 10:30:21+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.35-1.el8 started.
    ...
    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 容器

    # 进入容器并连接 MySQL
    docker exec -it my-mysql mysql -u testuser -p
    
    # 输入密码:testpass

    执行 SQL 操作

    -- 查看当前数据库
    SHOW DATABASES;
    
    -- 使用 testdb 数据库
    USE testdb;
    
    -- 创建测试表
    CREATE TABLE users (
        id INT AUTO_INCREMENT PRIMARY KEY,
        name VARCHAR(50) NOT NULL,
        email VARCHAR(100),
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    );
    
    -- 插入测试数据
    INSERT INTO users (name, email) VALUES 
        ('张三', 'zhangsan@example.com'),
        ('李四', 'lisi@example.com'),
        ('王五', 'wangwu@example.com');
    
    -- 查询数据
    SELECT * FROM users;
    
    -- 退出 MySQL
    EXIT;

    预期输出

    +----+--------+------------------------+---------------------+
    | id | name   | email                  | created_at          |
    +----+--------+------------------------+---------------------+
    |  1 | 张三   | zhangsan@example.com   | 2024-01-15 10:35:21 |
    |  2 | 李四   | lisi@example.com       | 2024-01-15 10:35:21 |
    |  3 | 王五   | wangwu@example.com     | 2024-01-15 10:35:21 |
    +----+--------+------------------------+---------------------+

    步骤 6:MySQL 数据持久化

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

    停止并删除现有容器

    docker stop my-mysql
    docker rm my-mysql

    创建数据卷并运行

    # 创建命名数据卷
    docker volume create mysql-data
    
    # 使用数据卷运行 MySQL
    docker run -d \
      --name my-mysql \
      -p 3306:3306 \
      -e MYSQL_ROOT_PASSWORD=my-secret-pw \
      -e MYSQL_DATABASE=testdb \
      -e MYSQL_USER=testuser \
      -e MYSQL_PASSWORD=testpass \
      -v mysql-data:/var/lib/mysql \
      mysql:8.0
    
    # 命令解析:# -v mysql-data:/var/lib/mysql
    # 将命名卷 mysql-data 挂载到容器的 /var/lib/mysql(MySQL 数据目录)

    验证数据持久化

    # 等待 MySQL 启动
    sleep 20
    
    # 重新插入数据
    docker exec -i my-mysql mysql -u testuser -ptestpass testdb << EOF
    CREATE TABLE IF NOT EXISTS users (
        id INT AUTO_INCREMENT PRIMARY KEY,
        name VARCHAR(50)
    );
    INSERT INTO users (name) VALUES ('持久化测试');
    SELECT * FROM users;
    EOF
    
    # 停止并删除容器
    docker stop my-mysql
    docker rm my-mysql
    
    # 重新启动容器(使用相同的数据卷)docker run -d \
      --name my-mysql \
      -p 3306:3306 \
      -e MYSQL_ROOT_PASSWORD=my-secret-pw \
      -v mysql-data:/var/lib/mysql \
      mysql:8.0
    
    # 等待启动
    sleep 20
    
    # 验证数据是否还在
    docker exec my-mysql mysql -u root -pmy-secret-pw testdb -e "SELECT * FROM users;"

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

    查看数据卷信息

    # 查看所有数据卷
    docker volume ls
    
    # 查看数据卷详细信息
    docker volume inspect mysql-data

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

    步骤 7:启动 Redis 容器

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

    操作命令

    # 切换到 Redis 目录
    cd ~/docker-practice/day05/redis
    
    # 运行 Redis 容器
    docker run -d \
      --name my-redis \
      -p 6379:6379 \
      redis:alpine \
      redis-server --appendonly yes
    
    # 命令解析:# redis:alpine         使用 alpine 版本的 Redis
    # redis-server         Redis 服务器命令
    # --appendonly yes     开启 AOF 持久化 

    验证 Redis 启动

    # 查看容器状态
    docker ps | grep redis
    
    # 查看 Redis 日志
    docker logs my-redis

    预期输出

    1:C 15 Jan 2024 10:40:15.123 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
    1:C 15 Jan 2024 10:40:15.123 # Redis version=7.2.3, bits=64, commit=00000000, modified=0
    ...
    1:M 15 Jan 2024 10:40:15.125 * Ready to accept connections tcp

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


    步骤 8:连接并操作 Redis

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

    进入 Redis 容器

    # 进入容器并启动 redis-cli
    docker exec -it my-redis redis-cli

    执行 Redis 命令

    # 测试连接
    PING
    # 输出:PONG
    
    # 设置字符串
    SET name "Docker Redis"
    # 输出:OK
    
    # 获取字符串
    GET name
    # 输出:"Docker Redis"
    
    # 设置带过期时间的键(10 秒)SETEX temp 10 "临时数据"
    GET temp
    # 等待 10 秒后再执行
    GET temp
    # 输出:(nil)
    
    # 列表操作
    LPUSH tasks "任务 1" "任务 2" "任务 3"
    LRANGE tasks 0 -1
    # 输出:# 1) "任务 3"
    # 2) "任务 2"
    # 3) "任务 1"
    
    # 哈希操作
    HSET user:1001 name "张三" age "25" city "北京"
    HGETALL user:1001
    # 输出:# 1) "name"
    # 2) "张三"
    # 3) "age"
    # 4) "25"
    # 5) "city"
    # 6) "北京"
    
    # 集合操作
    SADD tags "docker" "redis" "cache"
    SMEMBERS tags
    
    # 查看所有键
    KEYS *
    
    # 退出 redis-cli
    EXIT

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

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

    创建 Redis 配置文件

    # 创建自定义 Redis 配置
    cat > redis.conf << 'EOF'
    # 网络配置
    bind 0.0.0.0
    protected-mode yes
    port 6379
    
    # 持久化配置
    # RDB 持久化
    save 900 1      # 900 秒内至少 1 个 key 变化则保存
    save 300 10     # 300 秒内至少 10 个 key 变化则保存
    save 60 10000   # 60 秒内至少 10000 个 key 变化则保存
    dbfilename dump.rdb
    dir /data
    
    # AOF 持久化
    appendonly yes
    appendfilename "appendonly.aof"
    appendfsync everysec
    
    # 内存管理
    maxmemory 256mb
    maxmemory-policy allkeys-lru
    
    # 日志
    loglevel notice
    EOF
    配置说明 配置项 说明 推荐值
    save RDB 快照触发条件 900 1
    appendonly 是否启用 AOF yes
    appendfsync AOF 同步频率 everysec
    maxmemory 最大内存限制 256mb
    maxmemory-policy 内存淘汰策略 allkeys-lru

    使用自定义配置运行

    # 停止旧容器
    docker stop my-redis
    docker rm my-redis
    
    # 创建数据卷
    docker volume create redis-data
    
    # 使用配置文件和数据卷运行
    docker run -d \
      --name my-redis \
      -p 6379:6379 \
      -v $(pwd)/redis.conf:/usr/local/etc/redis/redis.conf:ro \
      -v redis-data:/data \
      redis:alpine \
      redis-server /usr/local/etc/redis/redis.conf

    验证持久化

    # 写入测试数据
    docker exec -it my-redis redis-cli SET persist-test "数据持久化测试"
    
    # 重启容器
    docker restart my-redis
    
    # 等待启动
    sleep 3
    
    # 验证数据是否还在
    docker exec my-redis redis-cli GET persist-test
    # 输出:"数据持久化测试"

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


    💻 完整代码

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

    目录结构

    day05/
    ├── nginx/
    │   ├── index.html
    │   └── nginx.conf
    ├── mysql/
    │   └── init.sql
    ├── redis/
    │   └── redis.conf
    ├── docker-compose.yml
    └── start-all.sh

    docker-compose.yml

    version: '3.8'
    
    services:
      # Nginx Web 服务器
      nginx:
        image: nginx:alpine
        container_name: my-nginx
        ports:
          - "8080:80"
        volumes:
          - ./nginx/index.html:/usr/share/nginx/html/index.html:ro
          - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
        restart: unless-stopped
        networks:
          - app-network
    
      # MySQL 数据库
      mysql:
        image: mysql:8.0
        container_name: my-mysql
        ports:
          - "3306:3306"
        environment:
          MYSQL_ROOT_PASSWORD: my-secret-pw
          MYSQL_DATABASE: testdb
          MYSQL_USER: testuser
          MYSQL_PASSWORD: testpass
        volumes:
          - mysql-data:/var/lib/mysql
          - ./mysql/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
        restart: unless-stopped
        networks:
          - app-network
        healthcheck:
          test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
          interval: 10s
          timeout: 5s
          retries: 5
    
      # Redis 缓存
      redis:
        image: redis:alpine
        container_name: my-redis
        ports:
          - "6379:6379"
        volumes:
          - redis-data:/data
          - ./redis/redis.conf:/usr/local/etc/redis/redis.conf:ro
        command: redis-server /usr/local/etc/redis/redis.conf
        restart: unless-stopped
        networks:
          - app-network
        healthcheck:
          test: ["CMD", "redis-cli", "ping"]
          interval: 10s
          timeout: 3s
          retries: 5
    
    # 数据卷定义
    volumes:
      mysql-data:
        driver: local
      redis-data:
        driver: local
    
    # 网络定义
    networks:
      app-network:
        driver: bridge

    mysql/init.sql

    -- MySQL 初始化脚本
    USE testdb;
    
    CREATE TABLE IF NOT EXISTS users (
        id INT AUTO_INCREMENT PRIMARY KEY,
        name VARCHAR(50) NOT NULL,
        email VARCHAR(100) UNIQUE,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    
    CREATE TABLE IF NOT EXISTS products (
        id INT AUTO_INCREMENT PRIMARY KEY,
        name VARCHAR(100) NOT NULL,
        price DECIMAL(10, 2) NOT NULL,
        stock INT DEFAULT 0,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    
    -- 插入示例数据
    INSERT INTO users (name, email) VALUES 
        ('张三', 'zhangsan@example.com'),
        ('李四', 'lisi@example.com'),
        ('王五', 'wangwu@example.com');
    
    INSERT INTO products (name, price, stock) VALUES 
        ('商品 A', 99.99, 100),
        ('商品 B', 199.99, 50),
        ('商品 C', 299.99, 30);

    start-all.sh

    #!/bin/bash
    # 一键启动脚本
    
    echo "🚀 启动所有服务..."
    
    # 创建目录
    mkdir -p nginx mysql redis
    
    # 检查配置文件
    if [! -f "docker-compose.yml"]; then
        echo "❌ 未找到 docker-compose.yml 文件"
        exit 1
    fi
    
    # 启动服务
    docker-compose up -d
    
    # 等待服务启动
    echo "⏳ 等待服务启动..."
    sleep 10
    
    # 检查服务状态
    echo ""echo"📊 服务状态检查:"
    docker-compose ps
    
    # 健康检查
    echo ""echo"🏥 健康检查:"
    
    # 检查 Nginx
    if curl -s http://localhost:8080/health > /dev/null 2>&1; then
        echo "✅ Nginx: 运行正常"
    else
        echo "⚠️  Nginx: 可能未就绪"
    fi
    
    # 检查 MySQL
    if docker exec my-mysql mysqladmin ping -h localhost --silent > /dev/null 2>&1; then
        echo "✅ MySQL: 运行正常"
    else
        echo "⚠️  MySQL: 可能未就绪"
    fi
    
    # 检查 Redis
    if docker exec my-redis redis-cli ping | grep -q PONG; then
        echo "✅ Redis: 运行正常"
    else
        echo "⚠️  Redis: 可能未就绪"
    fi
    
    echo ""echo"🎉 所有服务已启动!"echo""
    echo "📝 访问地址:"
    echo "Nginx:  http://localhost:8080"
    echo "MySQL:  localhost:3306 (user: testuser, pass: testpass)"
    echo "Redis:  localhost:6379"
    echo ""echo"📖 查看日志: docker-compose logs -f [服务名]"echo"🛑 停止服务: docker-compose down"

    使用方法

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

    🚀 进阶实践

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

    实践 1:搭建 WordPress 博客

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

    提示

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

    参考思路

    services:
      wordpress:
        image: wordpress:php7.4-fpm
        environment:
          WORDPRESS_DB_HOST: mysql
          WORDPRESS_DB_NAME: wordpress
          WORDPRESS_DB_USER: wp_user
          WORDPRESS_DB_PASSWORD: wp_pass

    实践 2:Redis 主从复制

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

    建议

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

    检查清单

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

    实践 3:MySQL 主从复制

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

    挑战

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

    资源

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


    🐛 故障排查

    问题 1:端口被占用

    症状

    Error: Bind for 0.0.0.0:3306 failed: port is already allocated

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

    解决方案

    方法 1 :更换端口

    ports:
      - "3307:3306"  # 使用 3307 端口 

    方法 2 :停止本机 MySQL 服务

    # macOS
    brew services stop mysql
    
    # Linux
    sudo systemctl stop mysql
    
    # Windows
    net stop mysql

    方法 3 :查找并关闭占用进程

    # macOS/Linux
    lsof -i :3306
    kill -9 
    
    # Windows
    netstat -ano | findstr :3306
    taskkill /PID  /F

    问题 2:MySQL 连接被拒绝

    症状

    ERROR 2003 (HY000): Can't connect to MySQL server on'localhost' (111)

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

    排查步骤

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

    常见错误

    • ❌ 使用 -p my-secret-pw(有空格)
    • ✅ 使用 -pmy-secret-pw(无空格)

    问题 3:数据卷权限问题

    症状

    mkdir: cannot create directory '/var/lib/mysql': Permission denied

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

    解决方案

    方法 1 :使用命名卷(推荐)

    docker volume create mysql-data
    docker run -v mysql-data:/var/lib/mysql mysql:8.0

    方法 2 :修改主机目录权限

    # 创建目录
    mkdir -p ~/mysql-data
    
    # 修改权限
    chmod 777 ~/mysql-data
    
    # 使用绝对路径挂载
    docker run -v ~/mysql-data:/var/lib/mysql mysql:8.0

    问题 4:Redis 持久化失败

    症状

    Can't open the append-only file: Permission denied

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

    解决方案

    # 方法 1:使用命名卷
    docker volume create redis-data
    docker run -v redis-data:/data redis:alpine
    
    # 方法 2:修改目录权限
    chmod 777 ~/redis-data

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

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

    排查步骤

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

    常见原因

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

    更多问题?

    如果遇到其他问题:

    1. 查看 Docker 官方文档
    2. 搜索 Stack Overflow
    3. 查看镜像的 Docker Hub 页面
    4. 在评论区留言描述问题
    5. 加入学习群讨论(文末二维码)

    📚 知识点回顾

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

    核心命令

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

    关键概念

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

    最佳实践

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

    三大服务对比

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

    下一步学习

    完成今天的实践后,建议:

    1. 把三个服务都运行起来并验证
    2. 尝试至少一个进阶实践
    3. 熟悉 docker-compose 的使用
    4. 学习下一篇:Day 6 - 构建自己的 Docker 镜像

    💬 作业时间

    今日挑战

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

    讨论话题

    • 你在配置 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+ 小伙伴一起学习实践!

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

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


    下期预告 🎬
    Day 6 - 构建你的第一个 Docker 镜像:从 Dockerfile 到发布

    • 编写 Dockerfile
    • 构建自定义镜像
    • 优化镜像大小
    • 发布到 Docker Hub

    我们下期见!💪


    如果觉得这篇文章对你有帮助,别忘了点赞、在看、转发三连支持一下!你的支持是我持续创作的动力!❤️

    正文完
    创作不易,扫码加点动力
    post-qrcode
     0
    果较瘦
    版权声明:本站原创文章,由 果较瘦 于2026-03-29发表,共计5663字。
    转载说明:除特殊说明外本站文章皆由果较瘦原创发布,转载请注明出处。