|
|
今天我们要完成一个非常实用的任务:在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+ ||
| 内存 | 至少 4GB | - |
| 磁盘空间 | 至少 5GB 可用空间 ||
检查命令
- # 检查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版本(更小,更快)
复制代码
命令解析:
:创建并运行容器
:detached模式,后台运行
:给容器指定一个友好的名称
:端口映射,格式为:镜像名称和标签,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
复制代码
✅ 检查点:打开浏览器访问,应该看到 "Welcome to nginx!" 页面
━━━━━━━━━━━━━━━━━━━━
步骤2:自定义Nginx网页内容
目标:部署自己的HTML页面到Nginx
创建自定义HTML文件:- # 进入nginx目录
- cd ~/docker-practice/day05/nginx
- # 创建自定义HTML页面
- cat > index.html << 'EOF'
- <!DOCTYPE html>
- <html lang="zh-CN">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>我的Docker Nginx</title>
- <style>
- body {
- font-family: Arial, sans-serif;
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- display: flex;
- justify-content: center;
- align-items: center;
- height: 100vh;
- margin: 0;
- }
- .container {
- text-align: center;
- background: white;
- padding: 50px;
- border-radius: 20px;
- box-shadow: 0 10px 40px rgba(0,0,0,0.2);
- }
- h1 { color: #333; margin-bottom: 20px; }
- .emoji { font-size: 80px; }
- .info { color: #666; margin-top: 20px; }
- </style>
- </head>
- <body>
- <div class="container">
- <div class="emoji">🚀</div>
- <h1>Docker Nginx 运行成功!</h1>
- <p class="info">这是我的第一个Docker化的网页</p>
- <p class="info">服务器:Nginx in Docker</p>
- </div>
- </body>
- </html>
- 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)
复制代码
关键参数说明:
:数据卷挂载(volume)
:当前目录的绝对路径
:只读挂载,容器内无法修改文件
✅ 检查点:刷新浏览器,应该看到你的自定义页面!
实时修改测试:- # 修改HTML文件
- echo '<h1>页面已更新!</h1>' >> 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 该用户的密码
复制代码
环境变量说明:
| 环境变量 | 作用 | 示例值 |
|----------|------|--------|
|| root密码(必填) ||
|| 初始数据库名 ||
|| 创建新用户 ||
|| 新用户密码 ||
查看启动日志:- # 查看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
复制代码
配置说明:
| 配置项 | 说明 | 推荐值 |
|--------|------|--------|
|| RDB快照触发条件 ||
|| 是否启用AOF ||
|| AOF同步频率 ||
|| 最大内存限制 ||
|| 内存淘汰策略 ||
使用自定义配置运行:- # 停止旧容器
- 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
提示:
使用镜像
配置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
设置复制用户权限
验证数据同步延迟
资源:
MySQL官方文档 - 复制配置
Docker Hub - MySQL镜像说明
💡 提示:完成这些实践后,在评论区分享你的成果和遇到的问题!
━━━━━━━━━━━━━━━━━━━━
🐛 故障排查
问题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 <PID>
- # Windows
- netstat -ano | findstr :3306
- taskkill /PID <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
复制代码
常见错误:
❌ 使用(有空格)
✅ 使用(无空格)
━━━━━━━━━━━━━━━━━━━━
问题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)
配置文件语法错误
端口冲突
内存不足
━━━━━━━━━━━━━━━━━━━━
更多问题?
如果遇到其他问题:
查看 Docker官方文档
搜索 Stack Overflow
查看镜像的 Docker Hub页面
在评论区留言描述问题
加入学习群讨论(文末二维码)
━━━━━━━━━━━━━━━━━━━━
📚 知识点回顾
今天我们通过实践学习了:
核心命令
| 命令 | 作用 | 示例 |
|------|------|------|
|| 后台运行容器 ||
|| 端口映射 |- docker run -p 8080:80 nginx
复制代码 |
|| 设置环境变量 |- docker run -e MYSQL_ROOT_PASSWORD=pw mysql
复制代码 |
|| 挂载数据卷 |- docker run -v data:/var/lib/mysql mysql
复制代码 |
|| 进入容器 |- docker exec -it mysql bash
复制代码 |
|| 查看日志 ||
|| 创建数据卷 |- docker volume create data
复制代码 |
关键概念
端口映射:,实现外部访问
环境变量:,配置容器运行参数
数据卷:,实现数据持久化
健康检查:定期检查服务是否正常运行
网络隔离:容器间通过网络互联
最佳实践
✅ 使用alpine镜像减小体积
✅ 使用命名卷而非绑定挂载
✅ 为容器设置有意义的名称
✅ 配置健康检查确保服务可用
✅ 敏感信息使用环境变量或secrets
✅ 生产环境配置资源限制
✅ 使用docker-compose管理多容器
三大服务对比
| 服务 | 用途 | 默认端口 | 数据目录 | 配置要点 |
|------|------|----------|----------|----------|
| Nginx | Web服务器 | 80 || 配置文件、静态文件挂载 |
| MySQL | 关系数据库 | 3306 || 必须设置ROOT_PASSWORD |
| Redis | 缓存/NoSQL | 6379 || 持久化配置、内存限制 |
下一步学习
完成今天的实践后,建议:
把三个服务都运行起来并验证
尝试至少一个进阶实践
熟悉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
我们下期见!💪
━━━━━━━━━━━━━━━━━━━━
如果觉得这篇文章对你有帮助,别忘了点赞、在看、转发三连支持一下!你的支持是我持续创作的动力!❤️ |
|