news 2026/10/15 15:55:37

LAMP一键安装脚本实战:Ubuntu、CentOS、Kylin下PHP7与MariaDB部署

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LAMP一键安装脚本实战:Ubuntu、CentOS、Kylin下PHP7与MariaDB部署

简介:面向需要在 Ubuntu 24、Kylin V10、CentOS 7 等系统上快速部署 Web 运行环境的运维人员与开发者,压缩包将 Apache、PHP 7.4 与 MariaDB 的安装过程封装为一键脚本,解决手动整理脚本、源码编译和大量后续配置带来的耗时问题。包内共 7 个文件,体积仅 108KB,其中 1 个 sh 脚本承担自动化安装主流程,4 个 rpm 包用于补齐并切换可用的 YUM 源依赖,2 个 ini 文件分别对应 PHP 7.4 与 PHP 默认配置,便于安装后按需调整参数。资源已针对 CentOS 停止维护后无法正常安装的问题,在脚本内重新配置了可用源,降低了环境搭建门槛,已有 559 人学习下载。适合希望省去重复踩坑、快速获得可运行 Web 环境的入门与进阶用户,按脚本执行即可完成核心组件部署。

1. 三套系统一个脚本:为什么要做 LAMP 一键安装

我最近半年把同一套 Apache + PHP 7 + MariaDB 环境,在 Ubuntu 24、Kylin V10、CentOS 7 三类服务器上反复装过很多遍。表面看都是“装 LAMP”,实际上完全是三套玩法:Ubuntu 24 默认只有 PHP 8.3,老业务代码直接报函数不存在;CentOS 7 停了维护,官方 yum 源都变成了 404;Kylin V10 自带 PHP 7.x,但网上教程大多按 CentOS 的写法抄,装完一堆对不上的包。这个「apache php7 mariadb 一键安装资源」要解决的,就是写一套能自动识别系统的脚本,把切源、装包、改 Apache 配置、拉起服务一次做完,让新手不用再对着三篇教程来回试,也让批量交付环境的运维省下手动点四十多分钟的重复劳动。适合被 PHP 7 旧业务绑住、又得面对新系统底座的开发者,以及需要在多平台快速复现环境的测试同学。

2. 一键安装的底层逻辑:先懂 LAMP 版本搭配,再谈自动化

一键安装脚本看着是“一把梭”,真正写起来七成时间花在版本搭配上。脚本里每一次 apt-get 或 yum install 的背后,都是一组经过取舍的包名和源地址。先搞清三个系统默认给了什么、缺什么,再动手写脚本,后面才不会到处打补丁。

2.1 三个系统的默认包差异:一张表看清坑在哪

系统包管理默认 Apache默认 PHP默认 MariaDB主要问题
Ubuntu 24aptapache2 2.4.xPHP 8.310.11PHP 版本过新,旧应用不兼容
CentOS 7yumhttpd 2.4.6PHP 5.45.5全线落后且仓库已归档,必须换源
Kylin V10yum/dnfhttpd 2.4.xPHP 7.x10.3/10.5小版本随 SP 变化,需装后核验

先说 Ubuntu 24。它的 24.04 仓库里默认 PHP 是 8.3,MariaDB 是 10.11,Apache 也是新版本,对一个要跑 PHP 7.4 老项目的场景来说,唯一要解决的变量就是 PHP。CentOS 7 则完全相反,默认 PHP 5.4、MariaDB 5.5,老到没法直接跑现代应用,而且官方仓库整体下线,yum 不换源连 makecache 都会失败。Kylin V10 介于两者之间,仓库里有 PHP 7.x 和 MariaDB 10.x,多数场景不用碰第三方源,但不同 SP 版本提供的具体小版本不一样,所以脚本里要做一次“装完看版本”的兜底检查。

之所以选 MariaDB 而不是 MySQL 8,是因为 MariaDB 10.x 默认保持 mysql_native_password 认证插件,PHP 7.4 自带的 mysqli 驱动可以直接连;MySQL 8 默认的认证方式换过一轮,老版本 PHP 驱动经常报认证握手失败。这个兼容性差异,就是“为什么标题写的是 MariaDB 而不是 MySQL”的直接原因。

2.2 为什么 PHP 7 必须走第三方源,而不是用默认源

PHP 7.4 是整个 PHP 7 系列最后一个版本,官方在 2022 年底停止安全维护。Ubuntu 24 发布时仓库里只有 PHP 8.3,apt 直接装根本拿不到 7.4,常规做法是添加社区维护的 PHP PPA(源路径形如 ppa:ondrej/php),它会提供 php7.4、libapache2-mod-php7.4 等一整套包,并且可以和系统默认的 PHP 8.3 共存。要注意 PPA 里 7.4 和 8.x 的包属于同一套依赖体系,装的时候不要把系统自带的 php8.3 也混装进来,否则 Apache 加载哪个模块完全看排序,很容易翻车。

CentOS 7 这边,官方源里连 PHP 7 的影子都没有,过去常用的 SCL 集合也只维护到 PHP 7.2/7.3,想要 7.4 只能走社区维护的 PHP 仓库。这类仓库提供的是 php74-php 前缀的包,例如 php74-php、php74-php-mysqlnd,PHP 进程以 php-fpm 形态运行,和 CentOS 6 时代直接装 mod_php 的思路完全不同。Kylin V10 是少数不用折腾第三方源的情况,原生仓库就有 PHP 7.x,但小版本跟着 SP 走,安装后必须用 php -v 核验一次,防止某个 SP 只提供 7.2 而业务要求 7.4。

另外,PHP 装完必须带上 mysqlnd 相关扩展。很多自装环境页面报 “Call to undefined function mysqli_connect()”,就是只装了 PHP 核心包、没装 php7.4-mysql 或 php-mysqlnd。所以脚本里把这类扩展包直接写死在 PHP_PKGS 变量中,这一步省不掉。

2.3 mod_php 与 php-fpm 的选择:一键脚本里怎么取舍

同一套 PHP,挂到 Apache 上有两种形态:编译成 Apache 模块(mod_php)随 httpd 进程运行,或者独立成 php-fpm 服务、由 Apache 把 PHP 请求转发过去。Ubuntu 24 和 Kylin V10 我倾向 mod_php,因为包管理器直接提供模块包,装完 a2enmod 就生效,配置量最小,符合一键脚本“少出岔子”的目标。CentOS 7 的 PHP 7.4 社区包默认给 php-fpm 形态,所以 CentOS 分支要走转发通信的方式,配置文件多一处,换来的是 PHP 进程独立、出问题不会拖垮 Apache。

mod_php 有个经典限制:它要求 Apache 处于 prefork MPM 模式,而 Ubuntu 的 apache2 默认启用 event MPM,两者冲突时 Apache 会拒绝启动或干脆不解析 PHP。一键脚本里必须显式做一次 MPM 切换(a2dismod mpm_event、a2enmod mpm_prefork),这个动作不做,装完访问 .php 文件大概率是空白页。php-fpm 形态没有这个限制,event MPM 下也能正常工作,所以 CentOS 分支的流程反而更省事。

如果你的业务明确要求 Apache 保持 event MPM,或者要求 PHP 进程与 Web 进程隔离,那就别用 mod_php,三个系统统一走 php-fpm 路线。只是这样一来 Ubuntu 分支要多写一段 httpd 转发配置,一键脚本的复杂度也会上一个台阶,我会优先照顾“能一次跑通”而不是“架构最优雅”。

3. 脚本主框架:从系统检测到拉起服务的完整流程

一键脚本的骨架就四步:识别系统、映射包名、执行安装、启动服务,剩下的全是细节。这章给出一套可以直接抄的主框架,把最容易出错的判断逻辑单独拆开讲。

3.1 系统检测与变量映射:让一套脚本认识三个系统

#!/bin/bash # LAMP 一键安装脚本:检测 -> 切源 -> 装包 -> 配置 -> 起服务 # 用法: bash lamp_onekey.sh,建议 root 执行 set -euo pipefail LOG=/var/log/lamp_install.log detect_os() { # Ubuntu 24 / Kylin V10 / CentOS 7 都有 /etc/os-release,优先读它 if [ -f /etc/os-release ]; then . /etc/os-release SYS_ID="${ID}" SYS_VER="${VERSION_ID}" else # 兜底:少数精简 CentOS 7 镜像缺 os-release SYS_ID="centos" SYS_VER="7" fi echo "检测到系统: ${SYS_ID} ${SYS_VER}" >> "$LOG" } map_packages() { case "${SYS_ID}" in ubuntu) PKG="apt" APACHE_SVC="apache2" PHP_PKGS="libapache2-mod-php7.4 php7.4 php7.4-mysql" DB_PKG="mariadb-server" DB_SVC="mariadb" ;; centos) PKG="yum" APACHE_SVC="httpd" PHP_PKGS="php74-php php74-php-mysqlnd php74-php-fpm" DB_PKG="mariadb-server" DB_SVC="mariadb" ;; kylin) PKG="yum" APACHE_SVC="httpd" PHP_PKGS="php php-mysqlnd" DB_PKG="mariadb-server" DB_SVC="mariadb" ;; *) echo "暂不支持的系统: ${SYS_ID}" >> "$LOG" exit 1 ;; esac }

这段的要点在 map_packages 的变量设计上。APACHE_SVC 和 DB_SVC 两个服务名变量是很容易被忽视的:Ubuntu 上 Apache 服务叫 apache2,CentOS 上叫 httpd,Systemd 单元名完全不同,后面所有 systemctl 调用都依赖这两个变量。PHP_PKGS 是三个系统差异最大的地方,Ubuntu 走 mod_php 模块包,CentOS 走 FPM 系列包,Kylin 直接用原生 php 包。开头的set -euo pipefail是防止脚本“带病继续”,任何一个命令失败直接退出,日志能定位卡在哪一步;代价是脚本不具备幂等性,失败了要清理残留包再重跑,这个处理放在第五章讲。

3.2 安装主流程:切源、装包、改配置

lamp_install() { case "${PKG}" in apt) export DEBIAN_FRONTEND=noninteractive apt-get install -y software-properties-common add-apt-repository -y ppa:ondrej/php # 社区 PHP 源,提供 7.4 apt-get update apt-get install -y apache2 $PHP_PKGS $DB_PKG ;; yum) modify_yum_source # 见 4.2/4.3,负责把源切成可用状态 yum install -y epel-release httpd $PHP_PKGS $DB_PKG ;; esac } lamp_config() { case "${SYS_ID}" in ubuntu) a2dismod mpm_event # mod_php 必须配 prefork a2enmod mpm_prefork php7.4 ;; centos) write_fpm_bridge_conf # 生成 httpd 到 php-fpm 的转发配置 ;; kylin) : # 原生 mod_php,默认配置即可 ;; esac } detect_os map_packages lamp_install lamp_config systemctl enable --now "$APACHE_SVC" "$DB_SVC" 2>>"$LOG" || true

DEBIAN_FRONTEND=noninteractive是把 apt 的交互式提问压掉的关键参数,比如 MariaDB 装包时偶尔弹出的配置对话框,没有这个环境变量,脚本会卡死在等待输入。CentOS 分支里的modify_yum_source和write_fpm_bridge_conf是函数占位,具体实现放在第四章按系统展开。最后的systemctl enable --now同时完成开机自启和立即启动,注意|| true的容错:新装环境里 httpd 因为缺少配置启动失败并不少见,脚本在这里直接退出的话,用户反而看不到后面的完整诊断信息。

3.3 服务自启与状态确认:让脚本收尾干净

check_all() { echo "===== 服务状态 =====" >> "$LOG" systemctl is-active "$APACHE_SVC" >> "$LOG" || true systemctl is-active "$DB_SVC" >> "$LOG" || true echo "===== 端口监听 =====" >> "$LOG" ss -lntup | grep -E ':80|:3306' >> "$LOG" || true } lamp_install check_all

端口检查用 ss 而不是 netstat,因为新版系统里 netstat 往往没装。:80表示 Apache 对外服务,:3306表示 MariaDB 监听,如果 3306 只出现在 127.0.0.1 上,说明 MariaDB 默认只允许本机连接,需要远程访问的场景要额外改 bind-address 和账号授权。这一步的意义在于把“装完是否成功”的判断交给日志而不是肉眼,脚本跑完直接看尾部就知道环境是不是真的可用了。

4. 三个系统的差异化配置:源、PHP 形态与 Apache 参数

主框架搭好后,最容易让人反复折腾的是每个系统的差异化细节。这章把三个分支的完整命令给出,并解释每个参数为什么这么写。

4.1 Ubuntu 24:PHP 7.4 的 PPA 与 Apache MPM 切换

# 1) 可选:把 apt 源换成访问更快的镜像站 # sed -i 's|http://archive.ubuntu.com|https://你的镜像站|g' /etc/apt/sources.list # 2) 添加 PHP 7.4 社区 PPA 并安装 export DEBIAN_FRONTEND=noninteractive apt-get install -y software-properties-common add-apt-repository -y ppa:ondrej/php apt-get update apt-get install -y apache2 libapache2-mod-php7.4 php7.4 php7.4-mysql # 3) 切换 MPM 并挂载 PHP 模块 a2dismod mpm_event a2enmod mpm_prefork a2enmod php7.4 # 4) 重启并核验 systemctl restart apache2 apache2ctl -M | grep php

第三组命令是整个 Ubuntu 分支的核心。libapache2-mod-php7.4 安装后模块本身会注册,但 MPM 如果不从 event 切到 prefork,Apache 启动就会报错或行为异常,所以 a2dismod 和 a2enmod 的顺序不能反。切完模块后,apache2ctl -M输出里出现 php7.4 字样才算真正生效。另外提醒一句:如果是新装系统,先单独跑一次apt-get update确认基础源通得过,再执行 add-apt-repository,否则 PPA 添加成功后 update 阶段报的错会被误判成源的问题,排查起来很绕。

4.2 CentOS 7:归档源与 PHP 7.4 仓库的组合操作

# 1) CentOS 7 官方源已下线,把 baseurl 切到归档地址并固定版本号 sed -e 's|^mirrorlist=|#mirrorlist=|' \ -e 's|^#baseurl=http://mirror.centos.org/centos/$releasever|baseurl=http://vault.centos.org/7.9.2009|' \ /etc/yum.repos.d/CentOS-Base.repo yum clean all && yum makecache # 2) 装 EPEL 与 PHP 7.4 系列包 yum install -y epel-release yum install -y httpd php74-php php74-php-mysqlnd php74-php-fpm mariadb-server # 3) 生成 httpd 到 php-fpm 的转发配置 cat > /etc/httpd/conf.d/php74-fpm.conf <<'EOF' <FilesMatch \.php$> SetHandler "proxy:unix:/var/opt/remi/php74/run/php-fpm/www.sock|fcgi://localhost" </FilesMatch> EOF # 4) 启动服务 systemctl enable --now httpd php74-php-fpm mariadb

第一步 sed 是 CentOS 7 必做的“续命操作”。官方仓库下线后,原来的 mirrorlist 指向的域名全部失效,必须改用归档地址;第二个替换把$releasever换成 7.9.2009 是有意为之,因为归档目录只按具体版本号存放,让 yum 自己去展开$releasever会得到“7”而不是“7.9.2009”,结果就是 404。装完 php74-php-fpm 后,要确认 FPM 的 socket 文件路径与配置里写的一致,Remi 系包默认就是这个路径;如果自定义过 FPM 监听方式,FilesMatch 里的路径必须同步改。这里用 heredoc 写入配置文件,包住内容避免 shell 展开变量,是写脚本时容易漏的细节。

4.3 Kylin V10:优先原生仓库,注意 yum/dnf 并存

# 1) 用原生源安装,不引入第三方仓库 yum install -y httpd php php-mysqlnd mariadb-server # 2) 确认 PHP 实际版本,避免 SP 差异带来的版本不符 php -v | head -1 # 3) 启动并检查 Apache 是否加载了 PHP 模块 systemctl enable --now httpd mariadb httpd -M 2>/dev/null | grep php

Kylin V10 存在 yum 和 dnf 两套命令并存的情况,脚本里统一用 yum 兼容性更好。装完立刻php -v核验小版本,是因为 V10 不同 SP 的仓库里 PHP 版本可能停在 7.2 或 7.4,如果业务代码用了 7.4 才有的语法,这一步能提前暴露问题,而不是等到页面报错再回头查。Kylin 分支建议别引入第三方源,麒麟自带的源维护节奏和 CentOS 不同,混用容易碰到依赖冲突。如果原生源里的 PHP 版本确实不满足,我一般直接建议换容器方案,而不是在这个系统上硬编第三方 PHP 源。

5. 五个典型翻车点:从空白页到 SELinux 的排查清单

脚本本身不难,难的是装完之后各种“看着都对就是跑不起来”的玄学现场。这章列五个我实际踩过、且非常典型的坑,每个按现象、原因、解决的顺序来。

5.1 装完访问 .php 文件,页面空白或直接下载

现象:curl 首页返回 HTML 正常,访问 info.php 要么白屏,要么浏览器提示下载文件。原因:Apache 根本没有解析 PHP,模块没加载,或者 MPM 与 mod_php 冲突被 Apache 静默降级。解决:先apache2ctl -M | grep php(CentOS 用 httpd -M)确认模块在不在;再查 MPM,Ubuntu 上执行apache2ctl -M | grep mpm,如果是 event 而你又用的 mod_php,执行 a2dismod mpm_event 和 a2enmod mpm_prefork 后重启。CentOS 走 php-fpm 的话,检查 httpd 的 error_log 里有没有 “Connection refused” 指向 socket 路径,路径对不上就改 FilesMatch。

5.2 mysql -uroot 登录总报 Access denied

现象:mysql -uroot -p输入安装时设的密码或空密码,全部被拒。原因:MariaDB 10.4 之后的 Debian/Ubuntu 系默认给 root 配了 unix_socket 认证,只能在系统 root 用户下执行sudo mysql进入;CentOS 系则常见为安装后 root 密码为空但只允许本地 socket。解决:用sudo mysql进库,显式建业务账号,别折腾 root:

CREATE USER 'webuser'@'localhost' IDENTIFIED BY '强密码'; GRANT ALL PRIVILEGES ON *.* TO 'webuser'@'localhost'; FLUSH PRIVILEGES;

一键脚本的教训是永远不要在脚本里给 root 设空密码,否则安全审计那关过不去。

5.3 CentOS 7 的 yum makecache 报 404 或 Could not resolve host

现象:脚本跑在 yum makecache 时报错,提示无法解析主机或 404。原因:停维后官方域名部分路径失效,且当前网络环境里 DNS 解析不到原 mirrorlist 的地址。解决:按 4.2 的 sed 把源改成归档地址并固定版本号,然后yum clean all && yum makecache验证;如果还报 fastestmirror 插件相关错误,用yum --disablerepo=fastestmirror makecache绕开。这一步做完再跑安装,后续错误会明显变少。

5.4 CentOS 7 上页面 502,SELinux 悄悄拦截

现象:php-fpm 和 httpd 都显示 active,但访问 .php 返回 502,error_log 里有 Permission denied。原因:SELinux 默认策略不允许 httpd 进程连接 php-fpm 的 unix socket,属于策略层面拦截,不是权限位问题。解决:先临时放行验证,再永久生效:

setsebool -P httpd_can_network_connect 1 restorecon -Rv /var/opt/remi/php74/run 2>/dev/null || true

这类问题最耗时的就是“看起来一切正常就是不通”,所以排查顺序一定是先看 error_log 再看 SELinux,而不是反复重启服务。

5.5 本机 curl 正常,外网就是访问不到 80 端口

现象:服务器上 curl localhost 返回正常,外网访问超时或拒绝。原因:firewalld(CentOS/Kylin)或 ufw(Ubuntu)默认不放行 80,少部分云环境还要额外看安全组策略。解决:本机先确认监听,再放行防火墙:

ss -lntup | grep :80 firewall-cmd --permanent --add-service=http && firewall-cmd --reload ufw allow 80/tcp

注意 Kylin 上 firewalld 和 iptables 服务可能同时存在,放行要用实际生效的那一套,避免这边加完那边没生效的乌龙。

6. 装完先别交工:用一组命令做最终验收

脚本跑通不等于环境合格,我习惯在交付前用固定一套命令把三件事验收掉:版本对不对、模块挂没挂、数据库能不能连。

验证点命令(Ubuntu 下)期望结果
PHP 版本php -v输出包含 7.4 的小版本
Apache 加载 PHPapache2ctl -M能看到 php7.4 模块
MariaDB 版本mysql -e "SELECT VERSION();"输出版本号且无报错
服务存活systemctl is-active apache2 mariadb两个都输出 active

验收完,临时放一个探针文件再删掉,是最快的端到端检查:在网站根目录写一个只含<?php phpinfo();的文件,curl 请求返回 200 且输出 PHP 信息,确认后马上删除。这个文件属于高危残留,忘了删等于把服务器信息页暴露在公网,我不止一次见过有人栽在这上面。

验收通过后做三个低成本加固:Apache 配置里把 ServerTokens 设为 Prod,隐藏版本细节;默认站点去掉 Indexes 权限,防止目录列表泄露;然后跑一遍mysql_secure_installation处理匿名用户和测试库。再养成一个习惯——把改过的配置目录(/etc/httpd 或 /etc/apache2、/etc/my.cnf)打包备份。一键脚本的价值是让环境可重建,配置备份则保证重建后行为可复现,这两件事配合起来才是长期不翻车的底气。

这套方案本身不复杂,核心就是把“系统差异”老老实实写进脚本分支,不在安装阶段偷懒。跟着本文把三个分支各跑一遍,你会对生产环境里的版本搭配心里有数,下次再被拉去救火时也能少走弯路,希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/15 15:54:41

国产工控系统落地实战:从IO配置到视觉检测的全栈工程化路径

1. 项目概述&#xff1a;国产工控系统落地不是口号&#xff0c;是每天在产线边缘调试的实操“国产工业控制系统怎么落地&#xff1f;”——这个问题最近在某高校自动化实验室、某汽车零部件厂的车间控制室、某能源集团的调度中心被反复提起。它不像写一篇论文那样可以闭门推演&…

作者头像 李华
网站建设 2026/10/15 15:54:36

这几天都在聊演唱会散场后,我更想推荐《活出自己》

耳机戴上后&#xff0c;复盘时心里乱。添火乐队《活出自己》「独自走在黑夜里&#xff0f;任由意识自由的沉溺」把处境写近。词曲&#xff1a;小熊歌&#xff5c;演唱&#xff1a;添火乐队。第三方听感&#xff0c;非硬广。听感笔记口吻。完整听一遍&#xff0c;第一遍记歌名&a…

作者头像 李华
网站建设 2026/10/15 15:54:27

51单片机智能家居实战:从传感器到继电器,吃透嵌入式底层原理

51单片机做智能家居&#xff0c;乍一听有点“过时”&#xff0c;但真正动手做完一次&#xff0c;你会发现这个方案能教给你的东西&#xff0c;比直接用ESP32调库要多得多。项目做出来是一个很完整的智能家居控制中枢&#xff1a;实时监测温湿度、根据光线自动开灯、根据温度自动…

作者头像 李华
网站建设 2026/10/15 15:53:53

设计素材工程化:构建可验证、可生成、可演进的UI资产体系

简介&#xff1a;本资源是面向UI/UX初学者与界面设计师的「软件人机界面设计素材」实战包&#xff0c;聚焦HCI核心能力培养&#xff0c;解决学习者缺乏系统化设计组件、交互参考与规范支撑的痛点&#xff0c;适用于课程实训、毕业设计及中小项目快速原型搭建。压缩包共445个文件…

作者头像 李华