简介:这是一套面向Linux运维初学者与后端开发者的自动化部署资源包,围绕JDK、MySQL、Redis、Nginx四大核心组件的安装与配置展开,帮助读者在Linux服务器上快速搭建高性能Web服务环境,省去逐个手动编译与调试的繁琐过程。压缩包共27个文件,约930.56MB,以sh安装脚本、gz源码包、conf与cnf配置文件、rpm依赖包及tar归档为主,脚本负责环境变量设置、服务启动与安全初始化,源码包与依赖包则覆盖编译安装所需的运行库。资源内含完整的目录模块划分,从JDK环境配置、MySQL安全加固与密码重置,到Redis缓存服务、Nginx反向代理及systemd服务管理均有对应脚本与配置样例,便于读者理解各组件协同部署的流程与排错思路。目前已有298人学习下载,适合希望掌握一键式部署与自动化运维技能的读者参考实践。
1. 一键脚本装四件套:为什么我劝你先别急着curl | bash
在 Linux 上把 JDK、MySQL、Redis、Nginx 这四个东西一次性装好,是很多后端和运维同学入行后第一个想“抄近道”的场景。新机器到手,环境要搭、服务要起、项目要跑,手动一个个apt install或者编译安装,光是 MySQL 的初始化和 Redis 的配置文件就够折腾小半天。于是“一键式安装脚本”成了刚需——下载一个.sh,chmod +x然后执行,十几分钟后四个服务全部systemctl status显示绿色,听起来很美好。
但现实是,这类脚本翻车的概率远比想象中高。我见过太多人拿到脚本直接curl xxx | bash,结果 MySQL 的 root 密码被写死在脚本里、Redis 默认监听0.0.0.0且没设密码、Nginx 的nginx.conf被覆盖导致原有站点全挂。所以这篇不是教你“怎么点一下就跑”,而是把这份 Linux 一键安装 JDK、MySQL、Redis、Nginx 的资源拆开,讲清楚它到底做了什么、每一步的参数怎么改、哪些地方必须手动兜底。适合刚接手新服务器、想快速拉起基础环境的同学,也适合已经用过类似脚本但踩过坑、想搞明白内部逻辑的老手。
2. 拆开脚本看骨架:四个组件到底按什么顺序装
2.1 安装顺序不是随便排的,依赖关系决定先后
一份靠谱的一键脚本,内部执行顺序基本是固定的:先 JDK,再 MySQL,然后 Redis,最后 Nginx。这个顺序不是拍脑袋定的。JDK 是很多中间件运行的基础,虽然 MySQL 和 Redis 本身是 C/C++ 写的、不依赖 JVM,但 Nginx 如果后面要跑 Java 应用的反向代理,或者脚本里带了基于 Java 的监控 agent,JDK 就必须先到位。更关键的是,脚本通常会用java -version来验证环境是否正常,如果 JDK 没装好,后面的步骤可能直接中断。
MySQL 排在 Redis 前面,是因为 MySQL 的安装和初始化耗时最长,而且涉及数据目录权限、my.cnf配置、systemd服务注册,一旦失败需要回滚的东西最多。把它放在前面,出问题能尽早暴露。Redis 相对轻量,编译或包安装都快,放在 MySQL 之后可以快速验证。Nginx 放最后,是因为它经常要配合前面几个服务做代理配置,比如把/api转发到 Java 后端、把静态资源指向某个目录,最后装方便统一改配置。
脚本里一般会有一个install_all()函数,按顺序调用install_jdk、install_mysql、install_redis、install_nginx。每个函数内部会先检查是否已安装,比如if command -v java &>/dev/null; then return; fi,避免重复执行。这个检查逻辑很重要,如果你在已经装了 MySQL 的机器上跑脚本,它应该跳过而不是覆盖。
2.2 版本选择:脚本里写死的版本号能不能改
大部分一键脚本会把版本号写成变量放在文件头部,类似这样:
#!/bin/bash # 版本定义区,改这里就能换版本 JDK_VERSION="17" MYSQL_VERSION="8.0" REDIS_VERSION="7.2" NGINX_VERSION="1.24"这种设计的好处是你不用去翻脚本中间的逻辑,只改变量就行。但要注意,版本号不是随便换的。JDK 从 8 换到 17,MySQL 从 5.7 换到 8.0,安装方式和默认配置差异很大。比如 MySQL 8.0 默认用caching_sha2_password认证插件,而 5.7 是mysql_native_password,如果你的应用驱动比较老,连 8.0 会报认证失败。Redis 7.x 和 6.x 在配置文件指令上也有区别,比如replicaof替代了slaveof。
我一般会先确认脚本支持的版本范围,再决定要不要改。如果脚本里 MySQL 的安装逻辑是基于apt install mysql-server的,那你改成 5.7 可能就找不到包。更稳妥的做法是:保持脚本默认版本,装完后如果需要特定版本,再单独卸载重装。别在一键脚本里硬改版本,那是给自己找麻烦。
2.3 包管理还是源码编译:两条路线的取舍
脚本安装这四个组件,通常有两种路线:包管理器(apt/yum)和源码编译。包管理器的优点是快、依赖自动解决、systemctl服务文件现成。缺点是版本受发行版仓库限制,比如 CentOS 7 默认仓库的 MySQL 还是 5.7,Redis 是 3.2,Nginx 是 1.16。源码编译的优点是版本自由、可以定制编译参数,缺点是慢、依赖要手动装、升级麻烦。
一份成熟的一键脚本往往会混用:JDK 用包管理器装 OpenJDK,MySQL 用官方仓库或二进制包,Redis 用源码编译,Nginx 用官方仓库。比如 Redis 源码编译也就一两分钟,还能顺便指定make MALLOC=libc避免 jemalloc 的兼容问题。Nginx 如果用包管理器,nginx -V能看到编译参数,但想加第三方模块就得重新编译。
判断脚本走哪条路,看它有没有wget下载 tar 包、有没有make && make install。如果全是apt install,那版本基本锁死;如果看到./configure,那就是源码编译,编译前记得确认gcc、make、pcre-devel、zlib-devel、openssl-devel这些依赖已经装好,否则会在./configure阶段报错。
3. 逐组件落地:JDK、MySQL、Redis、Nginx 的安装细节与参数
3.1 JDK:用 OpenJDK 还是 Oracle JDK,环境变量怎么配
脚本里装 JDK 最常见的是apt install openjdk-17-jdk -y或者yum install java-17-openjdk-devel -y。选 OpenJDK 的原因是开源、免费、包管理器直接维护,不用手动下载 tar 包。Oracle JDK 虽然在一些老项目里还有要求,但下载需要登录账号,脚本没法自动化,所以一键脚本基本不会用。
装完之后要验证:
java -version javac -version echo $JAVA_HOME如果JAVA_HOME是空的,说明脚本没配环境变量。手动补上:
# 找到 Java 安装路径 readlink -f $(which java) # 输出类似 /usr/lib/jvm/java-17-openjdk-amd64/bin/java # 那么 JAVA_HOME 就是 /usr/lib/jvm/java-17-openjdk-amd64 echo 'export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64' >> /etc/profile echo 'export PATH=$JAVA_HOME/bin:$PATH' >> /etc/profile source /etc/profile参数说明:readlink -f用来解析软链接的真实路径,因为which java可能指向/usr/bin/java这个软链。/etc/profile是全局环境变量文件,对所有用户生效。如果你只想对当前用户生效,改~/.bashrc。改完必须source或者重新登录才生效,这是新手最容易忘的一步。
提示:如果脚本装的是 JRE 而不是 JDK,
javac会找不到。跑 Java 应用可能没问题,但如果你要编译代码或者用 Maven,必须确认装的是-devel或-jdk包。
3.2 MySQL:初始化、root 密码和安全配置
MySQL 的安装是一键脚本里最容易出问题的环节。以apt为例,apt install mysql-server -y装完后,MySQL 服务通常会自动启动,但 root 用户的认证方式和密码是随机的或者空的。脚本一般会做几件事:启动服务、设置 root 密码、允许远程连接(可选)、创建业务数据库。
一个典型的初始化片段:
# 启动 MySQL systemctl start mysql systemctl enable mysql # 设置 root 密码,假设脚本里定义 MYSQL_ROOT_PASSWORD mysql -uroot <<EOF ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '${MYSQL_ROOT_PASSWORD}'; FLUSH PRIVILEGES; EOF # 如果需要远程访问 mysql -uroot -p${MYSQL_ROOT_PASSWORD} <<EOF CREATE USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '${MYSQL_ROOT_PASSWORD}'; GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION; FLUSH PRIVILEGES; EOF逻辑说明:第一段用mysql -uroot免密进入,是因为刚装完的 MySQL 在 Debian/Ubuntu 上默认用auth_socket插件,本地 root 可以直接进。ALTER USER把认证插件改成mysql_native_password并设密码,这样后续用密码登录。第二段创建root@%允许任意 IP 连接,GRANT ALL给全部权限。生产环境不建议这么干,但一键脚本为了“能用”通常会开。
参数说明:MYSQL_ROOT_PASSWORD是脚本变量,你必须在执行前改掉默认值。mysql_native_password是为了兼容老客户端,MySQL 8.0 默认的caching_sha2_password在有些 Navicat 版本或老驱动上会报Authentication plugin 'caching_sha2_password' cannot be loaded。FLUSH PRIVILEGES让权限变更立即生效,不加的话要重启 MySQL。
配置文件方面,脚本可能会改/etc/mysql/mysql.conf.d/mysqld.cnf,把bind-address从127.0.0.1改成0.0.0.0。改完必须systemctl restart mysql。如果启动失败,看/var/log/mysql/error.log,常见原因是数据目录权限不对或者my.cnf里有语法错误。
3.3 Redis:编译安装、守护进程与密码设置
Redis 用源码编译的脚本,核心步骤是下载、解压、make、make install。以 Redis 7.2 为例:
cd /usr/local/src wget https://download.redis.io/releases/redis-7.2.0.tar.gz tar -zxvf redis-7.2.0.tar.gz cd redis-7.2.0 make MALLOC=libc -j$(nproc) make install PREFIX=/usr/local/redis # 复制配置文件 mkdir -p /usr/local/redis/conf cp redis.conf /usr/local/redis/conf/逻辑说明:MALLOC=libc指定用系统 libc 的内存分配器,避免在某些发行版上 jemalloc 编译失败。-j$(nproc)用所有 CPU 核心并行编译,加快速度。PREFIX=/usr/local/redis把可执行文件装到指定目录,方便管理。复制redis.conf是为了后续改配置,不要直接改源码目录里的文件。
接下来改配置文件,关键参数:
# 编辑 /usr/local/redis/conf/redis.conf daemonize yes # 后台运行 bind 0.0.0.0 # 允许远程连接,按需改 protected-mode no # 关闭保护模式,否则远程连不上 requirepass YourStrongPassword # 设置密码参数说明:daemonize yes让 Redis 以守护进程运行,否则终端一关就退出。bind 0.0.0.0和protected-mode no必须配合使用,只改一个另一个不改,远程还是连不上。requirepass后面跟密码,设了之后客户端连接要AUTH。生产环境这三项要谨慎,尤其是bind 0.0.0.0加弱密码等于把数据库敞开。
启动和验证:
/usr/local/redis/bin/redis-server /usr/local/redis/conf/redis.conf /usr/local/redis/bin/redis-cli -a YourStrongPassword ping # 返回 PONG 说明正常如果要配systemd开机自启,新建/etc/systemd/system/redis.service,ExecStart指向redis-server和配置文件路径,ExecStop用redis-cli shutdown。写完systemctl daemon-reload && systemctl enable redis。
3.4 Nginx:仓库安装、反向代理与静态资源
Nginx 用包管理器装最省事:
apt install nginx -y systemctl start nginx systemctl enable nginx装完默认站点在/var/www/html,配置文件在/etc/nginx/nginx.conf,站点配置在/etc/nginx/sites-available/和/etc/nginx/sites-enabled/。一键脚本通常会覆盖默认配置,加一个反向代理:
server { listen 80; server_name _; location / { root /var/www/html; index index.html; } location /api/ { 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; } }逻辑说明:location /处理静态文件,location /api/把请求转发到本机 8080 端口的 Java 应用。proxy_set_header三行是为了让后端拿到真实客户端 IP 和原始 Host,不加的话后端日志里全是127.0.0.1。
参数说明:proxy_pass http://127.0.0.1:8080/;末尾的斜杠很关键。有斜杠时,/api/user转发成/user;没斜杠时转发成/api/user。这个差异经常导致 404,改配置前先确认后端接口路径。改完nginx -t测试语法,通过后systemctl reload nginx平滑重载,不要用restart,会断连接。
注意:如果脚本覆盖了
/etc/nginx/nginx.conf,你原有的include可能被删掉。执行前先备份cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak,出问题能快速回滚。
4. 避坑与排查:一键脚本最容易翻车的五个地方
4.1 脚本执行到一半报错退出,怎么续跑
现象:apt install或make阶段报错,脚本set -e直接退出,前面装好的组件还在,后面的没装。
原因:脚本用了set -e,任何命令返回非零就终止。常见触发点是网络超时、依赖缺失、磁盘空间不足。
解决:先看报错行,补装依赖或清理磁盘。然后不要重新跑整个脚本,而是手动执行剩余步骤。如果脚本有函数拆分,可以source script.sh后单独调install_redis。更稳妥的做法是跑之前bash -x script.sh 2>&1 | tee install.log,把每一步都记下来,出错时知道断在哪。
4.2 MySQL 启动失败,日志里全是权限错误
现象:systemctl start mysql失败,journalctl -u mysql显示Permission denied或Can't create/write to file。
原因:数据目录/var/lib/mysql的属主不是mysql用户,或者my.cnf里指定的datadir路径不存在。
解决:chown -R mysql:mysql /var/lib/mysql,确认datadir路径存在且有权限。如果是自定义my.cnf,检查[mysqld]段下的datadir、socket、pid-file三个路径是否一致。改完再启动,还失败就看/var/log/mysql/error.log最后 20 行。
4.3 Redis 远程连不上,telnet 端口不通
现象:本机redis-cli能连,远程客户端连不上,telnet ip 6379超时。
原因:bind还是127.0.0.1,或者protected-mode yes且没设密码,或者防火墙没放行 6379。
解决:确认redis.conf里bind 0.0.0.0、protected-mode no、requirepass三项都改了。然后检查防火墙:firewall-cmd --add-port=6379/tcp --permanent && firewall-cmd --reload,或者ufw allow 6379。云服务器还要看安全组规则。三项都对了再redis-cli -h ip -a password ping测试。
4.4 Nginx 502 Bad Gateway,后端明明在跑
现象:访问 Nginx 返回 502,但curl 127.0.0.1:8080后端有响应。
原因:SELinux 阻止了 Nginx 的网络连接,或者proxy_pass的地址写错,或者后端只监听了 IPv6 的::1而 Nginx 转发到127.0.0.1。
解决:先getenforce,如果是Enforcing,临时setenforce 0测试,确认是 SELinux 就setsebool -P httpd_can_network_connect 1。然后检查proxy_pass的 IP 和端口,用ss -tlnp | grep 8080看后端监听地址。如果是 IPv6 问题,把proxy_pass改成http://[::1]:8080/或者让后端监听0.0.0.0。
4.5 脚本里的默认密码太弱,上线前必须改
现象:脚本里MYSQL_ROOT_PASSWORD="123456"、requirepass foobared,装完能跑但心里不踏实。
原因:一键脚本为了演示方便,默认密码往往极简,甚至所有机器一样。
解决:执行前先把脚本里的密码变量改成强密码,至少 16 位、大小写数字符号混合。如果已经装完,MySQL 用ALTER USER改,Redis 改redis.conf后重启,Nginx 本身不涉及密码但如果有 Basic Auth 也要改。改完记得同步更新应用连接串,别改完数据库密码忘了改应用配置,那就从“不安全”变成“不可用”了。
5. 进阶:把一键脚本改造成可重复执行、可验证的部署工具
一键脚本最大的价值不是“省那几步命令”,而是把安装过程标准化。但原始脚本往往只能跑一次,第二次跑就报错。我一般会做三件事把它变成可重复使用的工具。
第一,加幂等判断。每个安装函数开头检查是否已安装,已安装就跳过而不是重装。比如 JDK 检查java -version,MySQL 检查mysql --version和systemctl is-active mysql,Redis 检查redis-cli ping,Nginx 检查nginx -v。这样脚本可以反复执行,适合放进 CI/CD 或者初始化模板。
第二,加验证步骤。装完不是结束,要自动验证四个服务都能正常响应。写一个verify_all()函数:
verify_all() { echo "=== 验证 JDK ===" java -version || { echo "JDK 验证失败"; exit 1; } echo "=== 验证 MySQL ===" mysql -uroot -p"${MYSQL_ROOT_PASSWORD}" -e "SELECT 1;" || { echo "MySQL 验证失败"; exit 1; } echo "=== 验证 Redis ===" redis-cli -a "${REDIS_PASSWORD}" ping | grep -q PONG || { echo "Redis 验证失败"; exit 1; } echo "=== 验证 Nginx ===" curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1 | grep -q "200\|301\|302" || { echo "Nginx 验证失败"; exit 1; } echo "全部组件验证通过" }逻辑说明:每个验证用||接失败处理,任何一项不过就退出并打印是哪一项。MySQL 用SELECT 1验证连接和认证,Redis 用ping验证密码和响应,Nginx 用curl拿 HTTP 状态码,200/301/302 都算正常。这样跑完脚本你立刻知道环境能不能用,不用一个个手动试。
第三,把配置抽成外部文件。密码、端口、数据目录这些不要写死在脚本里,放到config.env,脚本开头source config.env。这样同一份脚本可以用于开发、测试、生产不同环境,只换配置文件就行。config.env里至少包含:
| 变量名 | 说明 | 示例 |
|---|---|---|
| JDK_VERSION | JDK 大版本 | 17 |
| MYSQL_ROOT_PASSWORD | MySQL root 密码 | 强密码 |
| MYSQL_PORT | MySQL 端口 | 3306 |
| REDIS_PASSWORD | Redis 密码 | 强密码 |
| REDIS_PORT | Redis 端口 | 6379 |
| NGINX_PORT | Nginx 监听端口 | 80 |
改完这三处,一键脚本就从“一次性玩具”变成了“可维护的部署工具”。从那以后我每次拿到新机器,都先跑一遍验证函数,确认四个服务全绿再往上部署应用。希望帮到你。
本文还有配套的精品资源,点击获取