ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Ubuntu服务器环境搭建:MySQL、Redis、Nginx与自动化备份全攻略

2026/10/7 3:03:54 拓冰建站 浏览量
Ubuntu服务器环境搭建:MySQL、Redis、Nginx与自动化备份全攻略 去年我给一台 2C4G 的 Ubuntu 服务器做基础环境搭建要把 MySQL、Redis、Nginx 和自动备份一次性搞定。网上教程不少但大多东拼西凑版本混乱参数解释不清照着抄经常出问题。这篇就把我个人实际操作的整套流程写下来从系统初始化到备份恢复演练每个关键步骤都会解释为什么这么做以及我踩过的坑。适合刚接触 Linux 服务器部署、想自己搭一套可靠 Web 环境的朋友参考。整套流程用的是 Ubuntu 24.04 LTS MySQL 8.0 Redis 7.x Nginx 1.24都是当前主流稳定版本配置思路同样适用于其他 Ubuntu 版本。1. 部署前规划版本选择与系统准备1.1 为什么选 Ubuntu Server 24.04 LTSUbuntu 24.04 LTS 是长期支持版本官方维护到 2029 年软件源里的包比较新同时还保留了 apt 安装的便捷性。相比 CentOS 那边已经停止维护的尴尬局面Ubuntu 的社区资料和云镜像都很丰富遇到问题更容易搜到答案。如果你用的是腾讯云、阿里云或 AWS默认镜像里基本都有 Ubuntu 24.04 的选项直接选就行。有些人喜欢用 Docker 部署 MySQL 和 Redis我这次选择直接用 apt 安装原生服务原因有三点一是系统资源占用更小2G 内存的机器跑 Docker 再加几个容器会有点紧二是原生服务用 systemd 管理开机自启和日志查看都很直接三是在做备份的时候直接操作物理文件比操作容器卷更直观不容易出错。如果你的机器内存大于 8G而且喜欢容器化那 Docker 方案也可以但下面讲的配置思路同样适用。1.2 系统初始化与安全加固拿到一台新服务器我习惯先更新系统并创建普通用户避免一直用 root 操作。apt update apt upgrade -y apt install -y curl wget git vim ufw然后创建一个部署用户加入 sudo 组adduser deploy usermod -aG sudo deploy切换到这个用户后续所有操作都用它。接下来配置 SSH 密钥登录编辑/etc/ssh/sshd_config把PasswordAuthentication改成noPermitRootLogin改成no。记得先把自己的公钥加到~/.ssh/authorized_keys里再去重启 sshd不然容易把自己锁在外面。防火墙方面用 ufw 放行必要端口ufw allow OpenSSH ufw allow 80,443/tcp ufw enable这里只放行了 SSH、HTTP、HTTPS。MySQL 的 3306 端口不要对外开放后面我会说明如何安全访问。1.3 软件源与基础依赖安装Ubuntu 默认源在国内速度可能不理想如果服务器在国内建议先换清华或阿里镜像源。修改/etc/apt/sources.list.d/ubuntu.sources把http://archive.ubuntu.com/ubuntu/替换成https://mirrors.tuna.tsinghua.edu.cn/ubuntu/然后apt update。基础依赖包里build-essential一般在编译安装软件时要用虽然我们主要用 apt 安装但以防后续要装 PHP 扩展或其他工具先装上准没错。另外我还会装fail2ban来防止 SSH 暴力破解apt install -y build-essential fail2ban systemctl enable --now fail2banfail2ban 默认配置就能对 SSH 登录失败进行封禁不用做特别调整。2. MySQL 8.0 安装与配置2.1 安装方式对比与选择MySQL 8.0 是当前主流版本性能和安全性都比 5.7 好很多。安装方式主要有两种apt 直接安装Ubuntu 24.04 源里的 MySQL 8.0 版本较新安装简单适合绝大多数场景。MySQL 官方 APT 源安装可以指定小版本获得官方更新适合对版本敏感的生产环境。我这边选择官方 APT 源因为 Ubuntu 源里的 MySQL 有时候打补丁不够及时而官方源能保证第一时间更新。配置官方源的方法wget https://dev.mysql.com/get/mysql-apt-config_0.8.33-1_all.deb dpkg -i mysql-apt-config_0.8.33-1_all.deb安装过程中会弹窗让你选版本选择 MySQL 8.0 即可。然后apt update apt install -y mysql-server安装完成后先看下版本和运行状态mysql --version systemctl status mysql2.2 安装后的安全初始化MySQL 8.0 安装后 root 默认是 auth_socket 认证只能用sudo mysql进控制台。先登录sudo mysql执行以下 SQL 来设置 root 密码并切换为密码认证ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 你的强密码; FLUSH PRIVILEGES; EXIT;注意 MySQL 8.0 默认的 caching_sha2_password 比 mysql_native_password 更安全但是某些老客户端不支持如果你用的是新版客户端建议保留默认认证方式这里用 mysql_native_password 只是兼容旧应用实际部署时根据你的客户端情况选择。然后运行安全脚本mysql_secure_installation这个脚本会引导你移除匿名用户、禁用 root 远程登录、删除 test 库。我建议全部选 Y。其中删除匿名用户和禁止 root 远程登录是必须的因为 MySQL 一旦暴露到公网扫描机器人很容易爆破。创建一个用于业务的数据库和用户CREATE DATABASE appdb DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER appuserlocalhost IDENTIFIED BY 强密码; GRANT ALL PRIVILEGES ON appdb.* TO appuserlocalhost; FLUSH PRIVILEGES;这里强调localhost是因为应用和 MySQL 同机部署不需要远程访问。如果确实需要远程连接我建议通过 SSH 隧道或内网安全组限制来源 IP不要直接对所有 IP 开放 3306。2.3 性能调优与安全配置MySQL 默认配置偏向保守2G 内存的机器需要修改/etc/mysql/mysql.conf.d/mysqld.cnf。我的常用配置[mysqld] port 3306 bind-address 127.0.0.1 max_connections 200 character-set-server utf8mb4 collation-server utf8mb4_unicode_ci innodb_buffer_pool_size 512M innodb_log_file_size 128M slow_query_log 1 slow_query_log_file /var/log/mysql/slow.log long_query_time 2innodb_buffer_pool_size是 InnoDB 缓存池大小一般建议设置为物理内存的 50% 到 70%2G 内存我设置 512M留一部分给 Redis 和 Nginx。slow_query_log开启后超过 2 秒的查询会被记录方便后续排查性能问题。改完配置后重启systemctl restart mysql查看端口监听情况ss -lntp | grep 3306如果看到127.0.0.1:3306而不是0.0.0.0:3306说明端口没对外暴露这就对了。2.4 常见问题排查问题 1安装后mysql命令找不到PATH 问题。Ubuntu 上 MySQL 客户端路径一般是/usr/bin/mysql如果找不到用which mysql看看或者重新安装mysql-client。问题 2应用连接数据库报Authentication plugin caching_sha2_password cannot be loaded老客户端不支持新认证方式。要么升级客户端驱动要么将用户改为 mysql_native_passwordALTER USER appuserlocalhost IDENTIFIED WITH mysql_native_password BY 密码;问题 3内存不够导致 MySQL 崩溃检查/var/log/mysql/error.log如果出现Out of memory需要调小innodb_buffer_pool_size同时检查系统是否有其他进程占用内存。可以临时降低到 256M 看是否稳定。3. Redis 安装与配置3.1 Redis 安装与基础配置Redis 7.x 是目前的主流性能比 6.x 进一步优化。Ubuntu 24.04 源里的 Redis 是 7.0.15 左右直接 apt 安装即可apt install -y redis-server查看版本redis-server --version默认配置在/etc/redis/redis.conf。先做最重要的一项关闭外网访问。Redis 默认监听127.0.0.1这个不要改。如果改成0.0.0.0并且没设密码公网立刻会被扫描到直接写满恶意命令。我的经验是Redis 只允许本机应用访问如果有跨机需求走内网或专用网络并且一定要开启密码。开启密码认证在 redis.conf 中requirepass 你的Redis强密码重启 Redissystemctl restart redis-server验证密码生效redis-cli -a 你的Redis强密码 ping3.2 持久化与内存优化Redis 是内存数据库配置持久化非常重要。我使用 RDB AOF 混合方式。RDB 快照配置save 900 1 save 300 10 save 60 10000表示在 900 秒内有 1 次修改就保存快照300 秒内有 10 次修改保存60 秒内有 10000 次修改保存。AOF 默认是关闭的开启后追加日志appendonly yes appendfilename appendonly.aof appendfsync everysecappendfsync everysec表示每秒同步一次崩溃时最多丢失 1 秒数据性能影响较小。如果追求更高性能可以改成no但安全性略降。内存优化方面设置最大内存上限maxmemory 256mb maxmemory-policy allkeys-lru这里根据机器总内存调整2G 机器给 Redis 分配 256M 比较合理。allkeys-lru表示内存满时优先淘汰最近最少使用的 key。如果业务数据不能随意淘汰需要根据实际场景调整策略。3.3 分布式锁与常见使用场景Redis 在项目里常用作缓存、分布式锁、消息队列等。以分布式锁为例最简单的实现是用SET key value NX EX命令SET lock:order:123 unique_value NX EX 30这样只有当 key 不存在时才能设置成功达到加锁效果EX 30设置 30 秒自动过期防止死锁。释放锁时要用 Lua 脚本原子匹配if redis.call(get,KEYS[1]) ARGV[1] then return redis.call(del,KEYS[1]) else return 0 end这个场景网上说的很多但真正动手部署时一定要考虑时钟跳跃和网络延迟。生产环境建议使用 Redisson 等成熟客户端而不是自己轮子。这一点在部署篇里顺带提到就行。3.4 常见问题排查问题 1redis-cli连不上先确认服务状态systemctl status redis-server如果 status 显示 active (running)检查 redis.conf 中supervised是否设置成 systemd否则 systemd 会检测不到进程。问题 2写入数据报MISCONF Errors writing to the AOF file磁盘满了或者文件权限不对。查看df -h检查剩余空间并对数据目录授权chown -R redis:redis /var/lib/redis问题 3内存被占满导致 OOM检查maxmemory-policy如果业务 key 不可淘汰需要及时扩容或清理过期 key。用redis-cli info memory查看内存使用情况。4. Nginx 安装与站点配置4.1 Nginx 安装与常用模块Nginx 直接 apt 安装apt install -y nginx查看版本nginx -vUbuntu 源里的 Nginx 版本是 1.24稳定且支持 HTTP/2、反向代理、负载均衡等常用功能。装好后默认会启动访问服务器 IP 能看到 Welcome to nginx 页面。Nginx 配置目录结构/etc/nginx/nginx.conf主配置/etc/nginx/sites-available/站点配置存放处/etc/nginx/sites-enabled/启用的站点软链接这种设计便于管理多个站点。我通常把每个站点的配置写在 sites-available 里然后创建软链接到 sites-enabled。4.2 多站点配置与反向代理假设有两个域名example.com和api.example.com分别指向一个静态站和一个后端服务。先创建两个配置文件# /etc/nginx/sites-available/example.com server { listen 80; server_name example.com www.example.com; root /var/www/example; index index.html; location / { try_files $uri $uri/ 404; } }# /etc/nginx/sites-available/api.example.com server { listen 80; server_name api.example.com; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }启用站点并测试ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/ ln -s /etc/nginx/sites-available/api.example.com /etc/nginx/sites-enabled/ nginx -t systemctl reload nginxnginx -t必须执行能检查出语法错误避免 reload 失败导致服务中断。多端口配置也很常见比如同一台服务器用不同端口跑不同服务Nginx 可以实现基于端口的server块server { listen 8080; ... }这在本地虚拟机开发环境里尤其好用配合自定义域名/etc/hosts映射就能模拟线上多站点环境。4.3 SSL 证书配置与注意事项现在 HTTPS 基本是标配。我使用 certbot 自动申请 Lets Encrypt 证书apt install -y certbot python3-certbot-nginx certbot --nginx -d example.com -d www.example.comcertbot 会自动修改 Nginx 配置并重载。证书有效期为 90 天certbot 安装后自带 systemd timer 自动续期。续期服务查看systemctl list-timers | grep certbot若要手动续期certbot renew --dry-run一个巨坑当你替换 SSL 证书后Nginx 没生效。这通常是因为没有 reload。修改证书后必须nginx -t systemctl reload nginx有时候客户端浏览器还在缓存证书建议在测试环境用curl -v https://example.com查看新证书生效情况。4.4 常见问题排查问题 1访问站点出现 502 Bad Gateway后端服务没有启动或者 proxy_pass 指向的端口错误。先确认后端进程ss -lntp | grep 8080再检查 Nginx 错误日志tail -f /var/log/nginx/error.log问题 2HTTP 301 重定向循环通常是 server 块中同时监听了 80 和 443且 server_name 配置不准确certbot 修改后的配置有时候会产生重复 server 块。检查配置文件确保只有一个 server 块承担重定向。问题 3上传文件大小受限Nginx 默认client_max_body_size 1m上传大文件时会报 413。在 server 或 location 中增加client_max_body_size 20m;5. 自动化备份方案设计与实施5.1 备份策略设计备份是部署中最容易被忽略但最重要的一环。我设计的备份策略分三层MySQL 每天全量备份保留 7 天。Redis 每天持久化文件备份保留 7 天。每周将本地备份数据同步到远程对象存储或另一台机器。对于 MySQL使用mysqldump备份。需要注意几点备份时要用专门账号避免 root 权限过大。备份文件要压缩后再存储节省空间。备份前检查磁盘空间避免写满导致服务异常。5.2 编写备份脚本创建/opt/backup/backup.sh#!/bin/bash BACKUP_DIR/data/backup DATE$(date %Y%m%d_%H%M%S) MYSQL_USERbackup MYSQL_PASS你的备份密码 MYSQL_DBappdb REDIS_DB_DIR/var/lib/redis mkdir -p $BACKUP_DIR # MySQL backup mysqldump -u$MYSQL_USER -p$MYSQL_PASS --single-transaction --flush-logs --routines --triggers $MYSQL_DB | gzip $BACKUP_DIR/mysql_$DATE.sql.gz # Redis backup cp $REDIS_DB_DIR/dump.rdb $BACKUP_DIR/redis_dump_$DATE.rdb cp $REDIS_DB_DIR/appendonly.aof $BACKUP_DIR/redis_appendonly_$DATE.aof # Delete old backups find $BACKUP_DIR -type f -name mysql_* -mtime 7 -delete find $BACKUP_DIR -type f -name redis_* -mtime 7 -delete echo Backup completed at $DATE赋予执行权限chmod x /opt/backup/backup.sh创建备份账号CREATE USER backuplocalhost IDENTIFIED BY 备份密码; GRANT SELECT, SHOW VIEW, TRIGGER, PROCESS ON *.* TO backuplocalhost; FLUSH PRIVILEGES;--single-transaction参数用于 InnoDB 表的非阻塞备份备份期间不影响业务写入。5.3 定时任务与远程存储用 crontab 每天凌晨执行备份crontab -e加入0 2 * * * /opt/backup/backup.sh /var/log/backup.log 21这个 log 文件可以用于排查问题。每周同步到远程存储的脚本单独写比如用 rclone 同步到对象存储rclone sync /data/backup remote:bucket/backup --log-file/var/log/rclone.log如果你没有对象存储也可以用rsync同步到另一台备份机。注意一定要异地备份防止服务器磁盘损坏导致数据全丢。5.4 备份恢复演练备份不演练等于没有备份。我每月会做一次恢复演练在一个临时目录恢复数据确认备份文件可用。MySQL 恢复gunzip mysql_20250101_020000.sql.gz | mysql -uappuser -p appdbRedis 恢复先停掉 Redis把备份的 rdb 文件替换到数据目录再启动。注意 AOF 文件存在时 Redis 优先加载 AOF如果要恢复 RDB需要先清空 AOF 或者直接用 AOF 恢复。恢复演练后检查数据条数和关键业务值确认无误后才算成功。6. 实战踩坑与优化心得6.1 最容易忽略的系统参数部署完成后有几个系统参数需要调整。vm.swappiness控制内存交换倾向服务端建议调低sysctl vm.swappiness10写入/etc/sysctl.conf永久生效。否则系统可能频繁使用 swap 导致 Redis 和 MySQL 性能下降。net.core.somaxconn影响 Nginx 高并发连接队列。默认 1024可以调高到 65535。在/etc/sysctl.conf中加net.core.somaxconn 65535ulimit文件描述符上限也要注意Nginx 或应用如果报Too many open files需要提高进程限制。6.2 我踩过的坑和排查过程第一个坑MySQL 安装后使用mysql_secure_installation设置密码结果 root 密码一直不生效。原因是 Ubuntu 的 MySQL 默认 root 使用 auth_socket 认证必须先用sudo mysql进入手动修改 root 用户的认证插件和密码再执行安全脚本。如果直接执行安全脚本它会提示无法用 root 密码登录。第二个坑Redis 配置了requirepass之后重启服务一直失败。查看日志发现是 redis.conf 权限不对Redis 以 redis 用户运行无法读取 root 属主的文件。解决chown redis:redis /etc/redis/redis.conf第三个坑Nginx 配置反向代理后页面 CSS 和图片加载不出来。原因是代理后端时没有传递 Host 头导致站点的静态资源路径解析错误。加上proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr;同时后端应用需要读取真实 IP 时依赖X-Forwarded-For头这个也要一并设置。6.3 性能压测与优化建议部署完成后我用 ApacheBench 简单压测了 Nginx 静态页面和反向代理接口ab -n 1000 -c 100 http://example.com/如果 QPS 不理想优先检查后端应用瓶颈再考虑 Nginx 调优。几个常用的优化点开启 Gzip 压缩减少传输体积。静态资源设置长缓存。调整worker_processes为 CPU 核心数。对于 MySQL开启慢查询日志后定期分析。Redis 则用redis-benchmark工具压测本机性能。备份脚本执行时间也需要关注如果备份时间长可以加上--single-transaction --quick参数或者改用 MySQL 的物理备份工具 Percona XtraBackup不过日常数据量不大mysqldump 完全够用。整套环境搭建好之后我个人的体会是部署本身不复杂难的是把每一项配置的原理搞明白并且养成定期演练备份的习惯。后续你还可以在这个基础上集成监控工具比如 Prometheus Grafana或者用 Netdata 做轻量监控。先把这套基础打牢后面扩容和接业务都能省很多事。最后再分享一个小技巧每次修改任何配置文件一定要在执行restart之前先做语法测试。MySQL 有mysqld --validate-configNginx 有nginx -tRedis 可以用redis-server --test-memory别小看这一步能避免大量不可预期的中断事故。