本文最后更新于41 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com
文档信息
- 部署目标: MySQL 8.0 + Nginx + Redis
- 部署方式: Docker Compose V2
- 服务器IP:
- 域名:(可选)
- 文档版本: 1.0
一、环境要求与检查
1.1 系统要求
- 已安装 Docker Engine 20.10+
- 已安装 Docker Compose V2+
- 至少 4GB 可用内存
- 至少 20GB 可用磁盘空间
- 开放端口: 80, 443, 3306, 6379
1.2 预部署检查
bash
# 1. 检查 Docker 环境
docker --version
docker compose version
# 2. 检查端口占用
ss -tlnp | grep -E ":80|:443|:3306|:6379"
# 3. 检查资源
free -h
df -h /
# 4. 创建项目目录
mkdir -p ~/docker-stack/{mysql,nginx,redis,backup,config}
cd ~/docker-stack
二、MySQL 8.0 部署配置
2.1 MySQL 配置文件
bash
# 创建 MySQL 自定义配置
cat > config/mysql/my.cnf << 'EOF'
[mysqld]
# 基础配置
port = 3306
bind-address = 0.0.0.0
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
default_authentication_plugin = mysql_native_password
# 性能优化
max_connections = 1000
innodb_buffer_pool_size = 1G
innodb_log_file_size = 256M
innodb_flush_log_at_trx_commit = 2
innodb_file_per_table = 1
# 连接设置
wait_timeout = 600
interactive_timeout = 600
max_allowed_packet = 256M
# 日志配置
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
log_error = /var/log/mysql/error.log
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
EOF
2.2 MySQL 初始化脚本
bash
# 创建数据库初始化脚本(可选)
cat > config/mysql/init.sql << 'EOF'
-- 创建应用数据库示例
CREATE DATABASE IF NOT EXISTS app_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 创建应用用户(建议根据实际修改)
CREATE USER IF NOT EXISTS 'app_user'@'%' IDENTIFIED BY 'YourStrongPassword123!';
GRANT ALL PRIVILEGES ON app_db.* TO 'app_user'@'%';
-- 创建只读用户(可选)
CREATE USER IF NOT EXISTS 'readonly_user'@'%' IDENTIFIED BY 'ReadOnlyPass123!';
GRANT SELECT ON app_db.* TO 'readonly_user'@'%';
FLUSH PRIVILEGES;
EOF
2.3 MySQL 环境变量
bash
# 创建 MySQL 环境变量文件
cat > config/mysql/.env.mysql << 'EOF'
# MySQL 8.0 配置
MYSQL_ROOT_PASSWORD=RootSecurePass2025!
MYSQL_DATABASE=app_db
MYSQL_USER=app_user
MYSQL_PASSWORD=AppUserPass2025!
# 性能相关
MYSQL_INNODB_BUFFER_POOL_SIZE=1G
MYSQL_INNODB_LOG_FILE_SIZE=256M
MYSQL_MAX_CONNECTIONS=1000
# 时区
TZ=Asia/Shanghai
EOF
三、Nginx 适配部署配置
3.1 Nginx 主配置文件
bash
# 创建 Nginx 主配置
cat > config/nginx/nginx.conf << 'EOF'
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
# 基础优化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
# 文件上传大小限制
client_max_body_size 100M;
client_body_buffer_size 128k;
# Gzip 压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml text/javascript
application/json application/javascript application/xml+rss
application/xhtml+xml image/svg+xml;
# 上游服务配置(用于反向代理)
upstream backend_servers {
least_conn;
server app:8080 max_fails=3 fail_timeout=30s;
# 可添加更多后端服务器
# server app2:8080 max_fails=3 fail_timeout=30s;
}
# 包含站点配置
include /etc/nginx/conf.d/*.conf;
}
EOF
3.2 默认站点配置(适配 HTTPS)
bash
# 创建默认站点配置
cat > config/nginx/conf.d/default.conf << 'EOF'
# HTTP 重定向到 HTTPS(如果有证书)
server {
listen 80;
listen [::]:80;
server_name lccdream.xyz www.lccdream.xyz;
server_tokens off;
# 重定向到 HTTPS
return 301 https://$server_name$request_uri;
# 如果没有证书,使用下面配置
# root /usr/share/nginx/html;
# index index.html index.htm;
# location / {
# try_files $uri $uri/ =404;
# }
}
# HTTPS 服务器配置(如果有 SSL 证书)
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name lccdream.xyz www.lccdream.xyz;
server_tokens off;
# SSL 证书路径(请替换为实际路径)
ssl_certificate /etc/nginx/ssl/lccdream.xyz.pem;
ssl_certificate_key /etc/nginx/ssl/lccdream.xyz.key;
# SSL 优化配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# 安全头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# 根目录配置
root /usr/share/nginx/html;
index index.html index.htm index.php;
# 静态资源缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 30d;
add_header Cache-Control "public, immutable";
access_log off;
}
# 反向代理到后端应用示例
location /api/ {
proxy_pass http://backend_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# WordPress 配置示例(如果使用)
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_pass app:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
# 禁止访问敏感文件
location ~ /\.(?!well-known).* {
deny all;
access_log off;
log_not_found off;
}
location ~ /\.ht {
deny all;
}
}
# 如果没有证书,使用纯 HTTP 配置
server {
listen 80;
listen [::]:80;
server_name _; # 默认服务器
server_tokens off;
root /usr/share/nginx/html;
index index.html index.htm;
# 安全头(即使 HTTP 也建议添加)
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
location / {
try_files $uri $uri/ =404;
}
# 静态文件缓存
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
# 健康检查端点
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
EOF
3.3 静态页面示例
bash
# 创建默认首页
mkdir -p nginx/html
cat > nginx/html/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 栈部署成功 | lccdream.xyz</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
line-height: 1.6; color: #333; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh; display: flex; align-items: center; justify-content: center;
}
.container {
background: white; border-radius: 20px; padding: 40px;
box-shadow: 0 20px 60px rgba(0,0,0,0.3); max-width: 800px; width: 90%;
}
h1 { color: #4a5568; margin-bottom: 20px; border-bottom: 3px solid #667eea; padding-bottom: 10px; }
.status-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 20px; margin: 30px 0; }
.status-card { background: #f7fafc; padding: 20px; border-radius: 10px; border-left: 4px solid; }
.mysql { border-color: #00758f; }
.nginx { border-color: #269539; }
.redis { border-color: #d82c20; }
.status-card h3 { margin-bottom: 10px; color: #2d3748; }
.checkmark { color: #38a169; font-weight: bold; }
.info { background: #e6fffa; padding: 15px; border-radius: 8px; margin-top: 20px; border-left: 4px solid #38b2ac; }
code { background: #edf2f7; padding: 2px 6px; border-radius: 4px; font-family: 'Courier New', monospace; }
</style>
</head>
<body>
<div class="container">
<h1>🚀 Docker 栈部署成功</h1>
<p>恭喜!MySQL 8.0、Nginx 与 Redis 已通过 Docker Compose 成功部署。</p>
<div class="status-grid">
<div class="status-card mysql">
<h3>MySQL 8.0</h3>
<p><span class="checkmark">✓</span> 状态: <strong>运行中</strong></p>
<p>端口: <code>3306</code></p>
<p>用户: <code>app_user</code></p>
</div>
<div class="status-card nginx">
<h3>Nginx</h3>
<p><span class="checkmark">✓</span> 状态: <strong>运行中</strong></p>
<p>HTTP: <code>80</code></p>
<p>HTTPS: <code>443</code></p>
</div>
<div class="status-card redis">
<h3>Redis</h3>
<p><span class="checkmark">✓</span> 状态: <strong>运行中</strong></p>
<p>端口: <code>6379</code></p>
<p>内存策略: <code>allkeys-lru</code></p>
</div>
</div>
<div class="info">
<h4>📋 部署信息</h4>
<p>服务器: <code>115.190.165.36</code></p>
<p>域名: <code>lccdream.xyz</code></p>
<p>部署时间: <script>document.write(new Date().toLocaleString('zh-CN'));</script></p>
<p>查看服务状态: <code>docker compose ps</code></p>
<p>查看日志: <code>docker compose logs -f</code></p>
</div>
<div style="margin-top: 30px; padding-top: 20px; border-top: 1px solid #e2e8f0; text-align: center; color: #718096; font-size: 0.9em;">
<p>Docker Stack | MySQL 8.0 + Nginx + Redis | 自动生成页面</p>
</div>
</div>
<script>
// 简单的实时时间更新
function updateTime() {
const timeElements = document.querySelectorAll('script');
const lastScript = timeElements[timeElements.length - 1];
lastScript.previousElementSibling.innerHTML =
'部署时间: ' + new Date().toLocaleString('zh-CN');
}
setInterval(updateTime, 60000);
</script>
</body>
</html>
EOF
四、Redis 部署配置
4.1 Redis 配置文件
bash
# 创建 Redis 配置文件
cat > config/redis/redis.conf << 'EOF'
# Redis 配置文件 - Docker 优化版
# 网络绑定
bind 0.0.0.0
port 6379
protected-mode yes
# 通用配置
daemonize no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis/redis.log
# 持久化配置
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data
# 内存管理
maxmemory 512mb
maxmemory-policy allkeys-lru
maxmemory-samples 5
# 性能优化
timeout 0
tcp-keepalive 300
tcp-backlog 511
# 安全配置(建议通过环境变量设置密码)
# requirepass your_strong_password_here
# 客户端限制
maxclients 10000
# 慢查询日志
slowlog-log-slower-than 10000
slowlog-max-len 128
# AOF 配置(可选)
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# 主从复制配置(可选)
# replicaof <masterip> <masterport>
# masterauth <master-password>
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
replica-priority 100
EOF
4.2 Redis 环境变量
bash
# 创建 Redis 环境变量文件
cat > config/redis/.env.redis << 'EOF'
# Redis 配置
REDIS_PASSWORD=RedisSecurePass2025!
REDIS_PORT=6379
REDIS_DATABASES=16
REDIS_MAXMEMORY=512mb
REDIS_MAXMEMORY_POLICY=allkeys-lru
# 持久化配置
REDIS_APPENDONLY=no
REDIS_SAVE_INTERVAL="900 1 300 10 60 10000"
# 时区
TZ=Asia/Shanghai
EOF
五、Docker Compose 集成部署
5.1 主 docker-compose.yml 文件
yaml
# 创建主部署文件
cat > docker-compose.yml << 'EOF'
version: '3.8'
services:
# MySQL 8.0 服务
mysql:
image: mysql:8.0
container_name: mysql-8.0
restart: unless-stopped
environment:
# 从环境变量文件加载
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-RootSecurePass2025!}
MYSQL_DATABASE: ${MYSQL_DATABASE:-app_db}
MYSQL_USER: ${MYSQL_USER:-app_user}
MYSQL_PASSWORD: ${MYSQL_PASSWORD:-AppUserPass2025!}
TZ: Asia/Shanghai
volumes:
- mysql_data:/var/lib/mysql
- ./config/mysql/my.cnf:/etc/mysql/conf.d/my.cnf:ro
- ./config/mysql/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
- ./logs/mysql:/var/log/mysql
ports:
- "3306:3306"
networks:
- backend
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"]
interval: 30s
timeout: 10s
retries: 3
deploy:
resources:
limits:
memory: 2G
cpus: '1.0'
reservations:
memory: 1G
cpus: '0.5'
# Redis 服务
redis:
image: redis:7-alpine
container_name: redis-server
restart: unless-stopped
command: >
redis-server
--requirepass ${REDIS_PASSWORD:-RedisSecurePass2025!}
--maxmemory ${REDIS_MAXMEMORY:-512mb}
--maxmemory-policy ${REDIS_MAXMEMORY_POLICY:-allkeys-lru}
volumes:
- redis_data:/data
- ./config/redis/redis.conf:/usr/local/etc/redis/redis.conf:ro
- ./logs/redis:/var/log/redis
ports:
- "6379:6379"
networks:
- backend
healthcheck:
test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD:-RedisSecurePass2025!}", "ping"]
interval: 30s
timeout: 10s
retries: 3
# Nginx 服务
nginx:
image: nginx:alpine
container_name: nginx-proxy
restart: unless-stopped
volumes:
- ./config/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./config/nginx/conf.d:/etc/nginx/conf.d:ro
- ./nginx/html:/usr/share/nginx/html:ro
# SSL 证书目录(如果有)
# - ./ssl:/etc/nginx/ssl:ro
- ./logs/nginx:/var/log/nginx
ports:
- "80:80"
- "443:443"
networks:
- frontend
- backend
depends_on:
# - mysql: # 通常 Nginx 不直接依赖 MySQL
# - redis: # 通常 Nginx 不直接依赖 Redis
condition: service_started
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
timeout: 5s
retries: 3
# 网络配置
networks:
frontend:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
gateway: 172.20.0.1
backend:
driver: bridge
internal: false # 允许其他服务访问
ipam:
config:
- subnet: 172.21.0.0/16
gateway: 172.21.0.1
# 数据卷配置
volumes:
mysql_data:
driver: local
driver_opts:
type: none
o: bind
device: ./data/mysql
redis_data:
driver: local
driver_opts:
type: none
o: bind
device: ./data/redis
EOF
5.2 环境变量文件
bash
# 创建主环境变量文件
cat > .env << 'EOF'
# 项目配置
COMPOSE_PROJECT_NAME=docker-stack
COMPOSE_PROJECT_DIR=/root/docker-stack
TZ=Asia/Shanghai
# MySQL 配置
MYSQL_ROOT_PASSWORD=RootSecurePass2025!
MYSQL_DATABASE=app_db
MYSQL_USER=app_user
MYSQL_PASSWORD=AppUserPass2025!
# Redis 配置
REDIS_PASSWORD=RedisSecurePass2025!
REDIS_MAXMEMORY=512mb
REDIS_MAXMEMORY_POLICY=allkeys-lru
# Nginx 配置
NGINX_HOST=lccdream.xyz
NGINX_HTTP_PORT=80
NGINX_HTTPS_PORT=443
# 网络配置
FRONTEND_SUBNET=172.20.0.0/16
BACKEND_SUBNET=172.21.0.0/16
EOF
六、部署与验证
6.1 部署脚本
bash
# 创建部署脚本
cat > deploy.sh << 'EOF'
#!/bin/bash
# Docker Stack 部署脚本
set -e # 遇到错误立即退出
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
echo -e "${GREEN}=== Docker Stack 部署开始 ===${NC}"
# 1. 创建目录结构
echo "创建目录结构..."
mkdir -p {data,logs}/{mysql,redis,nginx} backup
# 2. 设置权限
echo "设置目录权限..."
chmod 755 data logs backup
chmod 644 config/**/* 2>/dev/null || true
# 3. 加载环境变量
if [ -f .env ]; then
echo "加载环境变量..."
export $(cat .env | grep -v '^#' | xargs)
else
echo -e "${YELLOW}警告: .env 文件不存在,使用默认值${NC}"
fi
# 4. 拉取镜像
echo "拉取 Docker 镜像..."
docker compose pull
# 5. 启动服务
echo "启动服务..."
docker compose up -d
# 6. 等待服务就绪
echo "等待服务启动..."
sleep 10
# 7. 验证部署
echo -e "\n${GREEN}=== 部署验证 ===${NC}"
# 检查容器状态
echo "容器状态:"
docker compose ps
# MySQL 连接测试
echo -e "\n测试 MySQL 连接..."
if docker compose exec mysql mysql -u root -p${MYSQL_ROOT_PASSWORD} -e "SELECT 1" &>/dev/null; then
echo -e "✅ MySQL 连接正常"
else
echo -e "${RED}❌ MySQL 连接失败${NC}"
fi
# Redis 连接测试
echo -e "\n测试 Redis 连接..."
if docker compose exec redis redis-cli -a ${REDIS_PASSWORD} ping | grep -q PONG; then
echo -e "✅ Redis 连接正常"
else
echo -e "${RED}❌ Redis 连接失败${NC}"
fi
# Nginx 连接测试
echo -e "\n测试 Nginx 连接..."
if curl -s http://localhost/health 2>/dev/null | grep -q healthy; then
echo -e "✅ Nginx 服务正常"
else
echo -e "${YELLOW}⚠️ Nginx 健康检查未配置,尝试基本连接...${NC}"
if curl -s -o /dev/null -w "%{http_code}" http://localhost | grep -q "200\|301\|302"; then
echo -e "✅ Nginx 响应正常"
else
echo -e "${RED}❌ Nginx 连接失败${NC}"
fi
fi
echo -e "\n${GREEN}=== 部署完成 ===${NC}"
echo "MySQL: localhost:3306 (root/${MYSQL_ROOT_PASSWORD})"
echo "Redis: localhost:6379 (密码: ${REDIS_PASSWORD})"
echo "Nginx: http://localhost:80"
echo " http://${NGINX_HOST:-localhost}:80"
echo ""
echo "管理命令:"
echo " docker compose ps # 查看状态"
echo " docker compose logs -f # 查看日志"
echo " docker compose stop # 停止服务"
echo " docker compose restart # 重启服务"
EOF
chmod +x deploy.sh
6.2 管理脚本
bash
# 创建管理脚本
cat > manage.sh << 'EOF'
#!/bin/bash
# Docker Stack 管理脚本
case "$1" in
start)
echo "启动服务..."
docker compose up -d
;;
stop)
echo "停止服务..."
docker compose down
;;
restart)
echo "重启服务..."
docker compose restart
;;
status)
echo "服务状态:"
docker compose ps
echo -e "\n资源使用:"
docker compose top
;;
logs)
echo "查看日志..."
docker compose logs -f
;;
backup)
echo "备份数据..."
BACKUP_DIR="backup/$(date +%Y%m%d_%H%M%S)"
mkdir -p "$BACKUP_DIR"
# 备份 MySQL
docker compose exec mysql mysqldump -u root -p${MYSQL_ROOT_PASSWORD} --all-databases > "$BACKUP_DIR/mysql-all.sql"
# 备份 Redis
docker compose exec redis redis-cli -a ${REDIS_PASSWORD} save
cp data/redis/dump.rdb "$BACKUP_DIR/redis-dump.rdb" 2>/dev/null || true
# 备份配置
cp docker-compose.yml .env "$BACKUP_DIR/"
echo "✅ 备份完成: $BACKUP_DIR"
;;
update)
echo "更新服务..."
docker compose pull
docker compose up -d
;;
*)
echo "用法: $0 {start|stop|restart|status|logs|backup|update}"
echo ""
echo " start 启动所有服务"
echo " stop 停止所有服务"
echo " restart 重启所有服务"
echo " status 查看服务状态"
echo " logs 查看服务日志"
echo " backup 备份数据"
echo " update 更新镜像并重启"
exit 1
;;
esac
EOF
chmod +x manage.sh
6.3 验证部署
bash
# 执行部署
./deploy.sh
# 或者手动部署
docker compose up -d
# 验证服务状态
docker compose ps
# 查看日志
docker compose logs -f
七、访问与测试
7.1 服务访问信息
| 服务 | 内网地址 | 外部端口 | 默认凭据 | 用途 |
|---|---|---|---|---|
| MySQL | mysql:3306 | 3306 | root / RootSecurePass2025! | 数据库 |
| Redis | redis:6379 | 6379 | 密码: RedisSecurePass2025! | 缓存 |
| Nginx | nginx:80 | 80 | – | Web服务器 |
| Nginx HTTPS | nginx:443 | 443 | – | HTTPS访问 |
7.2 连接测试命令
bash
# 1. MySQL 连接测试
mysql -h 115.190.165.36 -P 3306 -u root -p
# 密码: RootSecurePass2025!
# 2. Redis 连接测试
redis-cli -h 115.190.165.36 -p 6379 -a RedisSecurePass2025!
ping # 应返回 PONG
# 3. Nginx 访问测试
curl http://115.190.165.36
# 或访问 http://lccdream.xyz
# 4. 查看服务健康状态
curl http://115.190.165.36/health
7.3 性能监控
bash
# 创建监控脚本
cat > monitor.sh << 'EOF'
#!/bin/bash
echo "=== Docker Stack 监控 ==="
echo "时间: $(date)"
echo ""
echo "1. 容器状态:"
docker compose ps --format "table {{.Name}}\t{{.Status}}\t{{.Ports}}"
echo -e "\n2. 资源使用:"
docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}"
echo -e "\n3. MySQL 状态:"
docker compose exec mysql mysql -u root -p${MYSQL_ROOT_PASSWORD} -e "SHOW STATUS LIKE 'Threads_connected'; SHOW PROCESSLIST;" 2>/dev/null | head -20
echo -e "\n4. Redis 状态:"
docker compose exec redis redis-cli -a ${REDIS_PASSWORD} info memory 2>/dev/null | grep -E "used_memory:|maxmemory:"
echo -e "\n5. 磁盘使用:"
df -h / | tail -1
EOF
chmod +x monitor.sh
八、维护与故障排除
8.1 常见问题解决
问题1: MySQL 启动失败
bash
# 查看错误日志
docker compose logs mysql
# 常见原因: 数据目录权限
sudo chown -R 999:999 data/mysql # MySQL容器用户UID
# 重置MySQL(数据会丢失)
docker compose down -v mysql
docker compose up -d mysql
问题2: Redis 连接被拒绝
bash
# 检查密码是否正确
docker compose exec redis redis-cli -a YourPassword ping
# 检查绑定地址
docker compose exec redis cat /usr/local/etc/redis/redis.conf | grep bind
# 重启Redis
docker compose restart redis
问题3: Nginx 配置错误
bash
# 测试Nginx配置
docker compose exec nginx nginx -t
# 查看错误日志
docker compose logs nginx | grep -i error
# 重新加载配置
docker compose exec nginx nginx -s reload
8.2 数据备份与恢复
bash
# 备份MySQL所有数据库
docker compose exec mysql mysqldump -u root -pRootSecurePass2025! --all-databases > backup/all-databases.sql
# 备份Redis数据
docker compose exec redis redis-cli -a RedisSecurePass2025! save
cp data/redis/dump.rdb backup/redis-backup.rdb
# 恢复MySQL
cat backup/all-databases.sql | docker compose exec -i mysql mysql -u root -pRootSecurePass2025!
# 恢复Redis
cp backup/redis-backup.rdb data/redis/dump.rdb
docker compose restart redis
8.3 安全加固建议
bash
# 1. 修改默认密码
# 编辑 .env 文件,修改所有密码
# 2. 限制访问IP(通过防火墙)
# 仅允许特定IP访问MySQL/Redis
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="YOUR_IP" port port="3306" protocol="tcp" accept'
# 3. 启用SSL(如果有证书)
# 在nginx配置中启用SSL
# 在MySQL配置中启用SSL连接
# 4. 定期更新镜像
docker compose pull
docker compose up -d
附录
A. 端口映射说明
| 容器端口 | 主机端口 | 协议 | 说明 |
|---|---|---|---|
| 3306 | 3306 | TCP | MySQL 数据库 |
| 6379 | 6379 | TCP | Redis 缓存 |
| 80 | 80 | TCP | HTTP 访问 |
| 443 | 443 | TCP | HTTPS 访问 |
B. 数据卷位置
text
~/docker-stack/
├── data/mysql/ # MySQL 数据文件
├── data/redis/ # Redis 数据文件
├── logs/ # 所有日志文件
├── config/ # 配置文件
└── backup/ # 备份文件
C. 常用命令速查
bash
# 服务管理
./manage.sh start # 启动
./manage.sh stop # 停止
./manage.sh status # 状态
./manage.sh logs # 日志
# Docker命令
docker compose exec mysql bash # 进入MySQL容器
docker compose exec redis redis-cli # 进入Redis CLI
docker compose exec nginx sh # 进入Nginx容器
# 数据操作
docker compose exec mysql mysql -u root -p # MySQL命令行
docker compose exec redis redis-cli -a 密码 # Redis命令行
D. 联系信息
- 服务器:
- 域名:
- 部署路径: /root/docker-stack
- 服务状态: MySQL 8.0 + Nginx + Redis
- 文档版本: 1.0
部署完成验证
运行以下命令验证完整部署:
bash
# 进入项目目录
cd ~/docker-stack
# 运行部署脚本
./deploy.sh
# 验证所有服务
docker compose ps | grep -c "Up" # 应该输出 3(三个服务)




