Ubuntu 20.04 手动部署 LAMP+WordPress 完整指南

发布时间:2026/6/21 22:57:46
Ubuntu 20.04 手动部署 LAMP+WordPress 完整指南 1. 项目概述在 Ubuntu 20.04 上亲手搭起一个真正可用的 WordPress 站点你搜“Como instalar o WordPress no Ubuntu 20.04 com uma pilha LAMP”说明你正站在建站的第一道门槛前——不是点几下鼠标用宝塔面板也不是租个现成的 WordPress 托管服务而是想从零开始在一台干净的 Ubuntu 20.04 服务器上亲手把 Apache、MySQL、PHP 这套经典组合也就是 LAMP一砖一瓦垒起来再把 WordPress 安装进去让它跑起来、能访问、能写文章、能换主题。这事儿听着老派但恰恰是理解网站底层逻辑最扎实的路径。我带过几十个刚转行的运维和前端新人几乎所有人第一次自己配通 LAMP WordPress 后看 CMS 的眼神都不一样了原来“后台发布文章”背后是 PHP 调 MySQL 查 wp_posts 表原来“页面打不开”八成是 Apache 的 .htaccess 没生效或 PHP-FPM 没连上原来“上传图片失败”往往卡在 /var/www/html/wp-content 权限没设对。Ubuntu 20.04 是一个长期支持LTS版本内核稳定、软件源成熟Apache 2.4、MySQL 8.0、PHP 7.4 这套组合在它上面经过了数百万站点的实战检验。你不需要追求最新版 PHP 8.x 或 MariaDB 10.6这套“黄金搭档”足够支撑一个日均万级 PV 的企业官网或博客。重点不是炫技而是让每一步操作都有明确意图、每个报错都能精准定位。比如安装 MySQL 时为什么必须手动配置 root 密码策略因为 Ubuntu 20.04 默认启用 validate_password 插件如果跳过这步后续 WordPress 安装向导里填的数据库密码可能被拒绝又比如设置 WordPress 目录权限时为什么不能简单 chmod -R 777因为那等于把网站大门钥匙扔在马路上而真实生产环境里/var/www/html 应该属主 www-data组也是 www-data文件 644、目录 755wp-content 下的 uploads 和 plugins 才需要额外加组写权限。这些细节文档里往往一笔带过但实操中就是成败分水岭。这篇文章不讲“一键脚本”不推“可视化面板”就带你用纯命令行从 apt update 开始到浏览器里看到熟悉的 WordPress 安装向导界面结束。适合所有想真正搞懂建站原理的人——无论是准备面试的应届生、想自己维护公司官网的市场同事还是厌倦了托管服务限制、打算迁站的技术爱好者。你不需要会写代码但得愿意敲几行命令、看懂错误提示、动手改两行配置。2. 整体设计思路与方案选型逻辑2.1 为什么坚持用原生 LAMP而不是 Docker 或 Snap看到网上一堆“Docker 三行部署 WordPress”的教程很多人会疑惑既然有更“现代”的方式为啥还要折腾传统 LAMP我的答案很实在可控性、可读性、可调试性。Docker 镜像就像一个黑盒子当你遇到 Apache 配置不生效、PHP 扩展加载失败、或者 MySQL 连接超时这类问题时你得先搞清楚是容器内 PHP 的 php.ini 有问题还是宿主机网络策略拦截了端口抑或是 docker-compose.yml 里 volumes 挂载路径写错了。而原生 LAMP所有配置文件都在你眼皮底下/etc/apache2/sites-available/000-default.conf、/etc/mysql/mysql.conf.d/mysqld.cnf、/etc/php/7.4/apache2/php.ini出问题直接 vim 打开改完 systemctl restart apache2 就生效。Ubuntu 20.04 的 APT 包管理器对这套栈的支持极其成熟apt install lamp-server^ 这个元包注意末尾的 ^ 符号会自动帮你拉取 Apache2、MySQL 8.0、PHP 7.4 及其常用扩展如 php-mysql、php-curl、php-gd版本兼容性经过 Canonical 官方测试不会出现 PHP 8.1 跟 MySQL 8.0 的 JSON 函数不兼容这种坑。至于 Snap它把软件打包成沙盒虽然安全但对 Web 服务这种需要深度集成系统用户www-data、频繁读写磁盘wp-content/uploads、监听 80/443 端口的服务来说权限模型太重调试成本远高于收益。所以这个项目的设计起点非常明确用最标准、最透明、最贴近生产环境的方式在 Ubuntu 20.04 上构建一个可审计、可复现、可随时接手维护的 WordPress 基础环境。这不是怀旧而是选择一条学习曲线最陡峭、但根基最扎实的路。2.2 为何锁定 Ubuntu 20.04而非更新的 22.04 或更老的 18.04Ubuntu 的 LTS长期支持版本是服务器领域的事实标准20.04Focal Fossa于 2020 年 4 月发布提供 5 年的安全更新支持直到 2025 年 4 月。这意味着你现在搭建的环境未来三年内只需定期 apt update apt upgrade就能获得关键漏洞修复无需担心大版本升级带来的兼容性地震。对比来看18.04Bionic虽也是 LTS但其默认 PHP 版本为 7.2已于 2020 年底停止官方支持很多新版 WordPress 主题和插件尤其是那些依赖 PHP 7.4 新特性的已不再适配而 22.04Jammy默认 PHP 为 8.1MySQL 为 8.0.28虽然更新但部分老旧但依然活跃的 WordPress 插件比如某些小众的 SEO 工具或支付网关尚未完成全面兼容测试社区里关于“WordPress PHP 8.1 兼容性问题”的讨论至今未绝。更重要的是20.04 的文档生态极其丰富。你在 Google 搜索 “ubuntu 20.04 mysql8.025” 或 “ubuntu 20.04 搜狗输入法”能找到大量真实用户的踩坑记录和解决方案这是新版本短期内无法比拟的优势。另外20.04 的内核5.4对硬件兼容性极佳无论是老款 Xeon 服务器、树莓派 4还是主流云厂商的虚拟机实例都能开箱即用。所以选 20.04 不是守旧而是基于稳定性、生态成熟度和长期维护成本做出的理性决策。它就像一辆开了五万公里的丰田卡罗拉——没有炫酷的新功能但每一个零件都经得起时间考验。2.3 LAMP 栈内部组件的版本协同逻辑LAMP 不是四个独立软件的简单拼凑而是一个精密咬合的齿轮组。Ubuntu 20.04 的官方仓库对它们的版本做了严格匹配Apache 2.4.41这是当时最稳定的 2.4.x 分支对 .htaccess 伪静态规则WordPress 的 Permalink 功能核心支持完善且 mod_rewrite 模块默认启用。MySQL 8.0.25这是 20.04 LTS 生命周期内发布的最后一个 8.0.x 小版本修复了早期 8.0.19-8.0.22 中关于默认认证插件caching_sha2_password的诸多问题。WordPress 5.6 已原生支持此插件但如果你用的是较老的主题或插件仍需在创建数据库用户时显式指定IDENTIFIED WITH mysql_native_password否则连接会失败。PHP 7.4.3这是 PHP 7.x 系列的最终稳定版性能比 7.3 提升约 10%且引入了箭头函数等语法糖让 WordPress 核心代码更简洁。最关键的是它对 MySQLi 和 PDO 扩展的兼容性达到顶峰不会出现 PHP 7.4 连接 MySQL 8.0 报 “Client does not support authentication protocol” 这种经典错误。 这三者的协同体现在一个具体操作上当你执行sudo mysql_secure_installation加固 MySQL 时脚本会询问是否禁用匿名用户、是否禁止 root 远程登录、是否移除 test 数据库——这些选项直接影响 WordPress 安装向导里填写的数据库主机地址localhost 还是 127.0.0.1、用户名root 还是新建的专用用户以及密码强度要求。如果跳过这步后续 WordPress 安装时可能卡在“无法连接数据库”如果盲目禁用所有选项又可能导致本地 PHP 连接失败。因此整个方案的设计是把 Ubuntu 20.04 的官方软件源作为唯一可信源不手动添加第三方 PPA不自行编译安装确保所有组件的 ABI应用二进制接口和配置文件路径完全一致。这种“保守主义”恰恰是生产环境最需要的确定性。3. 核心细节解析与实操要点3.1 Apache 配置不只是启动服务更要理解虚拟主机与重写规则安装完 Apache 后sudo systemctl status apache2显示 active (running) 只是万里长征第一步。真正的关键在于/etc/apache2/sites-available/000-default.conf这个文件。很多新手以为改了 DocumentRoot 就万事大吉却忽略了两个致命细节第一Directory 指令的 AllowOverride 设置。WordPress 的固定链接Permalink功能依赖 .htaccess 文件来重写 URL例如把example.com/?p123变成example.com/hello-world/。而 Apache 默认配置中Directory /var/www/html块里的AllowOverride None会彻底禁用 .htaccess导致你无论怎么在 WordPress 后台设置固定链接页面都 404。必须把它改成AllowOverride All并确保mod_rewrite模块已启用sudo a2enmod rewrite。改完后别忘了sudo systemctl restart apache2。第二ServerName 与 ServerAlias 的显式声明。Ubuntu 20.04 的默认配置里这两行是被注释掉的。如果你的服务器有域名比如 blog.example.com必须在VirtualHost *:80块内取消注释并填写ServerName blog.example.com ServerAlias www.blog.example.com否则当用户通过 IP 地址访问时Apache 会返回默认的 “It works!” 页面而当通过域名访问时由于没有匹配的虚拟主机请求可能被路由到错误的站点或者触发 Apache 的默认 catch-all 行为造成安全隐患。更进一步如果你计划启用 HTTPS这里还必须对应配置 SSL 证书的域名否则浏览器会报证书不匹配。提示修改配置前务必用sudo apache2ctl configtest测试语法。这个命令会扫描所有配置文件输出类似 “Syntax OK” 或具体的错误行号。我见过太多人因为少打一个/Directory标签导致整个 Apache 服务无法启动而configtest能在重启前就揪出问题。3.2 MySQL 8.0 的安全加固与用户权限精细化控制Ubuntu 20.04 的 MySQL 8.0 默认启用了validate_password插件这是一个双刃剑。它强制要求 root 密码必须包含大小写字母、数字和特殊字符长度至少 8 位这极大提升了安全性。但如果你在mysql_secure_installation过程中设置了过于复杂的密码比如MyPssw0rd!2024#后续在 WordPress 的wp-config.php里填写时容易因复制粘贴错误或 Shell 特殊字符如!、#被 Bash 解析而导致连接失败。我的建议是在mysql_secure_installation时为 root 用户设置一个强但“Shell 友好”的密码例如Myp4ssw0rd_2024用下划线代替特殊符号。然后绝对不要用 root 用户运行 WordPress。必须创建一个专用数据库和专用用户CREATE DATABASE wordpress_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER wp_userlocalhost IDENTIFIED WITH mysql_native_password BY WpU$er_2024; GRANT ALL PRIVILEGES ON wordpress_db.* TO wp_userlocalhost; FLUSH PRIVILEGES;这里的关键点有三个一是数据库字符集必须是utf8mb4这是 WordPress 5.0 的硬性要求支持完整的 Unicode包括 emoji二是用户认证插件指定为mysql_native_password这是为了兼容所有 PHP MySQL 扩展三是权限只授予wordpress_db.*而非*.*遵循最小权限原则。很多“WordPress 站点被植入后门”的安全事件根源就在于数据库用户拥有DROP DATABASE或FILE权限攻击者一旦拿到 wp-admin 后台权限就能直接导出整个数据库甚至写入 Webshell 到服务器磁盘。3.3 PHP 7.4 的扩展与配置调优让 WordPress 跑得稳、传得快Ubuntu 20.04 的lamp-server^元包会安装php-mysql,php-curl,php-gd,php-mbstring,php-xml,php-xmlrpc,php-soap,php-intl,php-zip这些 WordPress 强依赖的扩展。但有两个扩展常被忽略却对体验影响巨大php-opcachePHP 字节码缓存能将 PHP 脚本编译后的 opcode 缓存在内存中避免每次请求都重新编译实测可提升 WordPress 页面加载速度 30%-50%。启用命令sudo phpenmod opcache。php-imagick比 GD 库更强大的图像处理扩展WordPress 在生成缩略图thumbnails时如果检测到 Imagick会优先使用它生成的图片质量更高、压缩率更好。安装命令sudo apt install php-imagick然后sudo systemctl restart apache2。PHP 的核心配置在/etc/php/7.4/apache2/php.ini。你需要重点关注三个参数memory_limit 256MWordPress 后台安装插件、生成报表时内存消耗很大128M 经常不够用256M 是稳妥值。upload_max_filesize 64M和post_max_size 100M前者限制单个文件上传大小后者限制整个 POST 请求体大小。WordPress 媒体库上传高清视频或大型主题 ZIP 包时这两个值必须同步调大且post_max_size必须大于upload_max_filesize。注意修改 php.ini 后必须重启 Apachesudo systemctl restart apache2才能生效。PHP-FPM 模式下则需重启php7.4-fpm服务但 Ubuntu 20.04 的标准 LAMP 是模块化模式libapache2-mod-php7.4所以只需重启 Apache。4. 实操过程与核心环节实现4.1 环境初始化从干净的 Ubuntu 20.04 开始假设你已有一台全新的 Ubuntu 20.04 服务器物理机、虚拟机或云服务器均可SSH 登录后第一步永远是更新系统sudo apt update sudo apt upgrade -y这一步看似简单实则至关重要。它会拉取最新的安全补丁修复已知漏洞。例如2023 年曾曝出 Apache 2.4.41 的一个 CVE-2023-25690 缓冲区溢出漏洞仅通过apt upgrade即可修复。更新完成后检查系统状态lsb_release -a # 确认是 Ubuntu 20.04 uname -r # 确认内核版本应为 5.4.x接着安装 LAMP 元包sudo apt install lamp-server^ -y注意lamp-server^末尾的^是 APT 的“任务包”符号它会自动解析并安装所有依赖的子包apache2, mysql-server, php7.4 等。安装过程中MySQL 会弹出交互式界面让你设置 root 密码请务必牢记。安装完毕后验证各服务状态sudo systemctl is-active apache2 # 应返回 active sudo systemctl is-active mysql # 应返回 active php -v # 应显示 PHP 7.4.x此时在浏览器中输入服务器 IP 地址应能看到 Apache 的默认欢迎页 “It works!”。这证明 Web 服务层已通。4.2 创建 WordPress 专属目录与权限设置不要把 WordPress 直接丢进/var/www/html/。这样做会导致权限混乱且不利于多站点管理。创建一个清晰的结构sudo mkdir -p /var/www/wordpress sudo chown -R $USER:$USER /var/www/wordpress sudo chmod -R 755 /var/www/wordpress这里$USER是你的当前 SSH 用户名如ubuntu。chown命令将目录所有权赋予你方便后续用wget下载 WordPresschmod 755确保目录可被 Apache 读取。接着下载并解压 WordPresscd /tmp curl -O https://wordpress.org/latest.tar.gz tar xzvf latest.tar.gz sudo cp -a /tmp/wordpress/. /var/www/wordpress/现在最关键的权限设置来了。WordPress 需要 Apachewww-data 用户能写入wp-content目录以便自动更新主题、插件和上传媒体文件sudo chown -R www-data:www-data /var/www/wordpress sudo find /var/www/wordpress -type d -exec chmod 755 {} \; sudo find /var/www/wordpress -type f -exec chmod 644 {} \; sudo chown -R www-data:www-data /var/www/wordpress/wp-content sudo chmod -R 775 /var/www/wordpress/wp-content这段命令的逻辑是所有目录设为 755所有者可读写执行组和其他人可读执行所有文件设为 644所有者可读写组和其他人只读唯独wp-content及其子目录设为 775组可写因为www-data组包含了 Apache 进程用户。这样既保证了安全性普通用户无法修改核心 PHP 文件又满足了功能性Apache 可以写入上传目录。4.3 配置 Apache 虚拟主机与启用 HTTPS可选但强烈推荐编辑新的虚拟主机配置文件sudo nano /etc/apache2/sites-available/wordpress.conf填入以下内容请将server_domain_or_IP替换为你的实际域名或 IPVirtualHost *:80 ServerAdmin webmasterlocalhost ServerName server_domain_or_IP DocumentRoot /var/www/wordpress Directory /var/www/wordpress/ AllowOverride All Require all granted /Directory ErrorLog ${APACHE_LOG_DIR}/wordpress_error.log CustomLog ${APACHE_LOG_DIR}/wordpress_access.log combined /VirtualHost保存退出后禁用默认站点启用新站点sudo a2dissite 000-default.conf sudo a2ensite wordpress.conf sudo systemctl reload apache2此时浏览器访问http://server_domain_or_IP应直接进入 WordPress 安装向导。但 HTTP 是明文传输不安全。强烈建议立即启用 HTTPS。最简单的方法是使用 Lets Encrypt 的 Certbotsudo apt install certbot python3-certbot-apache -y sudo certbot --apache -d your-domain.comCertbot 会自动修改wordpress.conf添加 443 端口的 SSL 配置并重定向所有 HTTP 请求到 HTTPS。整个过程全自动无需手动编辑 SSL 证书路径。4.4 WordPress 安装向导与 wp-config.php 手动配置访问https://your-domain.com你会看到熟悉的 WordPress 安装页面。但在此之前必须先创建wp-config.php。最安全的方式是手动创建而非依赖向导自动生成cd /var/www/wordpress sudo cp wp-config-sample.php wp-config.php sudo nano wp-config.php找到数据库配置段填入你之前创建的 MySQL 用户信息define(DB_NAME, wordpress_db); define(DB_USER, wp_user); define(DB_PASSWORD, WpU$er_2024); define(DB_HOST, localhost); define(DB_CHARSET, utf8mb4); define(DB_COLLATE, );然后务必生成并填入安全密钥。不要用示例里的随机字符串访问 https://api.wordpress.org/secret-key/1.1/salt/复制返回的 8 组define()语句替换掉wp-config.php里对应的占位符。这些密钥用于加密 cookies 和 nonce是防止 CSRF 攻击的第一道防线。最后添加一行强制 HTTPSdefine(FORCE_SSL_ADMIN, true); if ($_SERVER[HTTP_X_FORWARDED_PROTO] https) { $_SERVER[HTTPS] on; }保存后刷新浏览器即可进入安装向导填写站点标题、管理员用户名、密码和邮箱点击“安装 WordPress”。整个过程不到 2 分钟。5. 常见问题与排查技巧实录5.1 “Error establishing a database connection” —— 数据库连接失败的 5 种可能这是 WordPress 安装时最经典的错误原因五花八门排查必须按顺序进行排查步骤操作命令/方法预期结果与解读1. 检查 MySQL 服务状态sudo systemctl status mysql如果显示inactive (dead)执行sudo systemctl start mysql。常见于服务器重启后 MySQL 未自启。2. 验证 MySQL 用户权限sudo mysql -u wp_user -p -e SELECT USER();输入密码后若返回wp_userlocalhost说明用户存在且密码正确若报错Access denied则密码错误或用户不存在。3. 检查 MySQL 绑定地址sudo grep bind-address /etc/mysql/mysql.conf.d/mysqld.cnf正常应为bind-address 127.0.0.1。如果被改成0.0.0.0且防火墙开放了 3306 端口存在安全风险应改回127.0.0.1。4. 检查 wp-config.php 数据库主机sudo grep DB_HOST /var/www/wordpress/wp-config.php必须是localhostUnix socket 连接或127.0.0.1TCP 连接。localhost在 MySQL 8.0 下有时会走 socket而127.0.0.1强制走 TCP如果 socket 有问题可尝试改为后者。5. 检查 MySQL 认证插件sudo mysql -u root -p -e SELECT user,host,plugin FROM mysql.user WHERE userwp_user;如果plugin列显示caching_sha2_password则需在创建用户时指定IDENTIFIED WITH mysql_native_password否则 PHP 7.4 可能无法连接。我曾在一个客户的服务器上耗时 3 小时才定位到问题wp-config.php里DB_PASSWORD的值被复制时末尾多了一个不可见的空格字符。用sudo cat -A wp-config.php-A参数显示所有隐藏字符才看到$符号后面跟着一个^MWindows 换行符这就是罪魁祸首。所以任何涉及密码的配置务必用cat -A检查。5.2 “The requested URL was not found on this server” —— 伪静态失效的根因分析当你在 WordPress 后台将固定链接设为 “文章名” 格式后访问文章页面却显示 404这几乎 100% 是 Apache 的重写规则没生效。排查链路如下确认 mod_rewrite 已启用sudo a2enmod rewrite然后sudo systemctl restart apache2。确认 AllowOverride 已设为 All检查/etc/apache2/sites-available/wordpress.conf中Directory块内的AllowOverride值。确认 .htaccess 文件存在且可读ls -l /var/www/wordpress/.htaccess权限应为 644所有者为www-data。确认 WordPress 自己生成了规则在 WordPress 后台“设置 固定链接”页面点击“保存更改”WordPress 会自动向.htaccess写入规则。如果该文件是只读的会失败。此时需sudo chmod 644 /var/www/wordpress/.htaccess。终极验证在.htaccess文件顶部添加一行Redirect 301 /test.html /index.php然后访问https://your-domain.com/test.html如果跳转到首页证明重写引擎工作正常问题出在 WordPress 生成的规则本身。5.3 “Unable to create directory wp-content/uploads/” —— 上传失败的权限陷阱这个问题通常出现在wp-content目录权限设置错误时。wp-content目录本身权限应为 755但其下的uploads子目录必须由www-data用户拥有且可写。标准操作是sudo chown -R www-data:www-data /var/www/wordpress/wp-content sudo chmod -R 775 /var/www/wordpress/wp-content但如果wp-content下已有uploads目录且其所有者是root那么chmod -R 775并不能改变所有者www-data依然无权写入。此时必须单独处理sudo chown -R www-data:www-data /var/www/wordpress/wp-content/uploads此外还有一个隐蔽的 SELinux 问题虽然 Ubuntu 默认不启用 SELinux但某些定制镜像可能开启。如果上述操作都无效检查sudo sestatus若为enabled则需执行sudo setsebool -P httpd_can_network_connect 1允许 Apache 网络连接以及sudo setsebool -P httpd_read_user_content 1允许读取用户内容。5.4 “Your site is experiencing technical difficulties” —— 白屏错误的快速诊断法WordPress 5.2 引入了致命错误保护机制当 PHP 报出Fatal error时前台会显示这个友好的白屏而后台会发送邮件通知管理员。要看到真实的错误信息需临时开启 WP_DEBUGsudo nano /var/www/wordpress/wp-config.php找到define(WP_DEBUG, false);改为define(WP_DEBUG, true); define(WP_DEBUG_LOG, true); define(WP_DEBUG_DISPLAY, false);保存后再次触发错误如激活一个有 bug 的插件错误信息会被记录到/var/www/wordpress/wp-content/debug.log。查看日志sudo tail -f /var/www/wordpress/wp-content/debug.log最常见的原因是 PHP 内存不足Allowed memory size of ... exhausted此时需回到php.ini将memory_limit调大。另一个高频原因是插件冲突可进入wp-content/plugins目录将所有插件文件夹重命名如plugin-name-old然后逐个恢复直到找到问题插件。实操心得我给自己立了一条铁律——任何新安装的 WordPress 站点在上线前必做三件事1用sudo apache2ctl configtest检查 Apache 配置2用sudo mysql -u wp_user -p -e SHOW DATABASES;测试数据库连接3用sudo -u www-data php /var/www/wordpress/wp-load.php模拟 Apache 用户执行 WordPress 核心加载如果报错说明 PHP 环境或权限有根本性问题。这三步做完99% 的“安装失败”问题都能提前暴露。