香港服务器Linux系统部署电商网站,按哪些步骤配置Nginx、PHP与数据库?
在香港服务器的 Linux 系统上部署电商网站,建议先固定一套可验证的运行环境,再按“系统检查 → Nginx → PHP-FPM → MariaDB → 网站代码 → HTTPS → 验收”的顺序实施。下面以 Ubuntu Server 24.04 LTS、Nginx、PHP 8.3、PHP-FPM、MariaDB 10.11 为参考环境,网站采用 PHP 前端控制器结构,站点目录为 /var/www/shop/current/public。
部署前应准备好服务器 sudo 权限、域名及其 DNS 管理权限,并确认安全组或上游防火墙允许 TCP 22、80、443 端口。示例中的域名使用 shop.example.com,数据库名、用户名和密码均为示例值,正式上线时应替换为独立且足够复杂的凭据。
一、先确定运行环境和上线目标
1. 参考环境
| 项目 | 参考值 | 检查方式 |
|---|---|---|
| 操作系统 | Ubuntu Server 24.04 LTS | cat /etc/os-release |
| Web 服务 | Nginx | nginx -v |
| PHP 运行方式 | PHP-FPM 8.3 | php-fpm8.3 -v |
| 数据库 | MariaDB 10.11 | mariadb --version |
| 网站目录 | /var/www/shop/current/public | readlink -f /var/www/shop/current |
| 数据库监听 | 本机 127.0.0.1 | ss -lntp | grep 3306 |
| 域名 | shop.example.com | dig +short shop.example.com |
Ubuntu 24.04 的软件包和服务名称与 Ubuntu 22.04、Debian 版本可能不同。如果系统不是 Ubuntu 24.04,不要直接套用 PHP 服务名,先执行以下命令确认软件包:
cat /etc/os-release
apt-cache policy nginx php8.3-fpm mariadb-server
如果仓库中没有 php8.3-fpm,应根据网站程序支持的 PHP 版本选择对应软件包,而不是强行混用不同版本的 PHP 扩展。
2. 上线前的必要准备
- 域名的 A 记录指向服务器公网 IPv4 地址。
- 如果设置了 AAAA 记录,必须确保服务器同时配置并放通 IPv6,否则部分访问者可能优先访问不可用的 IPv6 地址。
- 已确认网站程序支持 PHP 8.3、MariaDB 或 MySQL 兼容协议。
- 已准备网站源代码、依赖包、静态资源和数据库备份。
- 已规划备份目录,例如
/var/backups/shop。 - 正式切换前安排维护窗口,特别是执行数据库迁移、PHP 重启或 Nginx 配置切换时。
小型电商站点可以把 2 核 CPU、4 GB 内存作为初始参考,但这不是固定要求。商品数量、图片处理、订单并发、搜索和后台任务都会影响实际资源需求。
二、系统检查、更新和防火墙
先确认当前登录用户具有 sudo 权限,并记录系统状态:
whoami
sudo -v
hostnamectl
df -h
free -h
确认磁盘空间后再更新系统。apt upgrade 可能更新库文件并重启部分服务,应在维护窗口执行:
sudo apt update
sudo apt upgrade
配置防火墙时,必须先放行当前 SSH 端口,再启用防火墙,避免远程锁定。如果 SSH 使用的不是 22 端口,应把下面的 22/tcp 替换为实际端口。
sudo apt install -y ufw
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw status
sudo ufw enable
sudo ufw status verbose
预期可以看到 SSH、HTTP、HTTPS 规则均为 ALLOW。如果启用后 SSH 断开,应通过服务器控制台执行以下回滚命令:
sudo ufw disable
数据库不需要对公网开放。除非有明确的远程管理需求,否则不要添加 3306/tcp 的公网放行规则。
三、安装 Nginx、PHP-FPM 与 MariaDB
安装网站常见依赖:
sudo apt install -y \
nginx \
mariadb-server \
mariadb-client \
php8.3-fpm \
php8.3-cli \
php8.3-mysql \
php8.3-curl \
php8.3-mbstring \
php8.3-xml \
php8.3-zip \
php8.3-gd \
php8.3-intl \
unzip
如果网站程序还需要图片处理、缓存或其他扩展,应以程序文档中的依赖清单为准。安装完成后启动服务:
sudo systemctl enable --now nginx
sudo systemctl enable --now php8.3-fpm
sudo systemctl enable --now mariadb
逐项验证版本和服务状态:

nginx -v
php -v
php-fpm8.3 -v
mariadb --version
systemctl is-active nginx
systemctl is-active php8.3-fpm
systemctl is-active mariadb
ls -l /run/php/php8.3-fpm.sock
三个 systemctl is-active 应返回 active,并且 PHP-FPM Socket 文件存在。Nginx 后续配置中的 fastcgi_pass 必须与这个 Socket 路径一致。
四、调整 PHP-FPM 参数
电商网站通常需要处理商品图片、订单提交和后台表单,建议将 PHP 参数放在独立配置文件中,便于后续回滚。下面的值是适用于中小型站点的参考值,不代表所有程序都必须使用相同配置。
先备份已有自定义配置:
if [ -f /etc/php/8.3/fpm/conf.d/99-shop.ini ]; then
sudo cp -a /etc/php/8.3/fpm/conf.d/99-shop.ini \
/etc/php/8.3/fpm/conf.d/99-shop.ini.bak
fi
写入配置:
sudo tee /etc/php/8.3/fpm/conf.d/99-shop.ini > /dev/null <<'EOF'
memory_limit = 256M
upload_max_filesize = 20M
post_max_size = 25M
max_execution_time = 60
max_input_vars = 5000
date.timezone = Asia/Hong_Kong
display_errors = Off
log_errors = On
EOF
post_max_size 应大于 upload_max_filesize,否则表单包含文件时可能出现参数丢失。生产环境不应打开 display_errors,否则 PHP 路径、数据库信息等错误细节可能直接暴露给访客。
检查 PHP 配置并重启 PHP-FPM:
sudo php-fpm8.3 -t
sudo systemctl restart php8.3-fpm
systemctl is-active php8.3-fpm
如果重启失败,先查看错误,不要反复重启:
sudo journalctl -u php8.3-fpm -n 80 --no-pager
若新配置导致服务无法启动,可以恢复备份:
sudo cp -a /etc/php/8.3/fpm/conf.d/99-shop.ini.bak \
/etc/php/8.3/fpm/conf.d/99-shop.ini
sudo php-fpm8.3 -t
sudo systemctl restart php8.3-fpm
五、初始化 MariaDB 和网站数据库
先执行安全初始化:
sudo mariadb-secure-installation
根据提示删除匿名用户、禁止远程 root 登录、删除测试数据库。Ubuntu 和 MariaDB 的 root 认证方式可能不同,不建议为了方便而强制改成公网密码登录。
确认数据库只监听本机:
sudo mariadb -e "SHOW VARIABLES LIKE 'bind_address';"
sudo ss -lntp | grep 3306
如果数据库监听在 0.0.0.0:3306,而网站和数据库位于同一台服务器,可以编辑 MariaDB 配置,使其仅接受本机连接:
sudo cp -a /etc/mysql/mariadb.conf.d/50-server.cnf \
/etc/mysql/mariadb.conf.d/50-server.cnf.bak
sudoedit /etc/mysql/mariadb.conf.d/50-server.cnf
在 [mysqld] 段确认或加入:
bind-address = 127.0.0.1
保存后重启数据库。此操作会短暂中断数据库连接,执行前应确认没有正在进行的订单写入:
sudo systemctl restart mariadb
sudo systemctl is-active mariadb
sudo ss -lntp | grep 3306
然后创建业务数据库和专用账号。下面的 SQL 只适用于首次创建,REPLACE_WITH_STRONG_PASSWORD 必须替换成真实密码,不要把真实密码提交到代码仓库。
sudo mariadb
在 MariaDB 提示符中执行:
CREATE DATABASE shop_db
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
CREATE USER 'shop_app'@'127.0.0.1'
IDENTIFIED BY 'REPLACE_WITH_STRONG_PASSWORD';
GRANT ALL PRIVILEGES ON shop_db.*
TO 'shop_app'@'127.0.0.1';
FLUSH PRIVILEGES;
EXIT;
测试业务账号能否通过 TCP 连接:
mariadb -h 127.0.0.1 -u shop_app -p shop_db \
-e "SELECT DATABASE(), CURRENT_USER(), 1 AS connection_ok;"
预期结果中应显示 shop_db、shop_app@127.0.0.1 和 connection_ok 为 1。如果网站配置使用 DB_HOST=localhost,它可能改走 Unix Socket,此时数据库用户的主机部分也要与连接方式保持一致,不能只修改其中一处。
六、准备网站代码和目录权限
推荐使用版本目录和 current 软链接,便于发布新版本和快速回滚:
sudo adduser --disabled-password --gecos "" deploy
sudo usermod -aG www-data deploy
sudo install -d -o deploy -g www-data -m 0750 /var/www/shop
sudo install -d -o deploy -g www-data -m 0750 /var/www/shop/releases
sudo install -d -o deploy -g www-data -m 0750 /var/www/shop/shared
假设本次版本目录为 20261003-01,将已经构建好的网站文件上传到:
/var/www/shop/releases/20261003-01
如果程序使用 Composer,建议以 deploy 用户执行依赖安装,不要用 root 生成 vendor 目录:
sudo -u deploy composer install \
--working-dir=/var/www/shop/releases/20261003-01 \
--no-dev \
--classmap-authoritative
该命令仅适用于项目已经安装并确认可用 Composer 的情况。前端资源应在发布前完成构建,生产服务器只上传最终需要的资源。
设置文件和目录权限:
sudo chown -R deploy:www-data /var/www/shop/releases/20261003-01
sudo find /var/www/shop/releases/20261003-01 \
-type d -exec chmod 750 {} \;
sudo find /var/www/shop/releases/20261003-01 \
-type f -exec chmod 640 {} \;
如果应用有缓存、上传或日志目录,只给这些明确目录写权限。例如:
sudo chmod 770 /var/www/shop/releases/20261003-01/storage
sudo chmod 770 /var/www/shop/releases/20261003-01/storage/cache
sudo chmod 770 /var/www/shop/releases/20261003-01/storage/uploads
目录名称必须以实际程序为准,不要为了排错直接执行 chmod -R 777。过宽权限会让网站代码、配置和上传文件暴露在不必要的风险中。
切换当前版本:
sudo ln -sfn /var/www/shop/releases/20261003-01 \
/var/www/shop/current
sudo chown -h deploy:www-data /var/www/shop/current
readlink -f /var/www/shop/current
七、配置网站环境变量
多数 PHP 电商程序需要配置应用环境、数据库连接和站点地址。建议将敏感配置放在 shared 目录,而不是放在公开目录 public 中:
sudo install -o deploy -g www-data -m 640 /dev/null \
/var/www/shop/shared/.env
sudoedit /var/www/shop/shared/.env
常见配置结构如下,实际变量名应以网站程序的配置要求为准:
APP_ENV=production
APP_DEBUG=false
APP_URL=https://shop.example.com
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=shop_db
DB_USERNAME=shop_app
DB_PASSWORD=REPLACE_WITH_STRONG_PASSWORD
如果程序要求在版本目录下存在 .env,可以建立指向共享配置的软链接:
sudo -u deploy ln -sfn ../../shared/.env \
/var/www/shop/releases/20261003-01/.env
修改环境变量后,部分程序需要清理配置缓存或重新生成应用密钥。此类命令与框架有关,应使用该程序官方提供的生产环境命令,并在执行数据库迁移前先备份数据库。
八、配置 Nginx 连接 PHP-FPM
创建站点配置:

sudo tee /etc/nginx/sites-available/shop.conf > /dev/null <<'EOF'
server {
listen 80;
listen [::]:80;
server_name shop.example.com;
root /var/www/shop/current/public;
index index.php index.html;
client_max_body_size 25m;
access_log /var/log/nginx/shop_access.log;
error_log /var/log/nginx/shop_error.log;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_read_timeout 60s;
}
location ~ /\.(?!well-known).* {
deny all;
access_log off;
log_not_found off;
}
}
EOF
该配置适用于以 index.php 作为入口的常见 PHP 应用。如果程序的公开目录不是 public,必须把 root 改成程序实际的 Web 根目录,不能把包含 .env、vendor 或配置文件的项目根目录直接暴露给 Nginx。
启用站点并检查配置:
sudo ln -sfn /etc/nginx/sites-available/shop.conf \
/etc/nginx/sites-enabled/shop.conf
sudo nginx -t
sudo systemctl reload nginx
如果默认站点影响域名匹配,可以先备份再停用:
if [ -L /etc/nginx/sites-enabled/default ]; then
sudo cp -a /etc/nginx/sites-enabled/default \
/etc/nginx/sites-enabled/default.bak
sudo unlink /etc/nginx/sites-enabled/default
fi
sudo nginx -t
sudo systemctl reload nginx
停用默认站点后如果新配置有误,可恢复:
sudo ln -sfn /etc/nginx/sites-available/default \
/etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl reload nginx
九、先用 HTTP 验证,再启用 HTTPS
配置 DNS 后,先确认解析结果:
dig +short shop.example.com
返回的地址应为服务器公网 IP。随后从服务器本机测试 Nginx:
curl -I -H 'Host: shop.example.com' http://127.0.0.1/
常见正常结果包括 200 OK、301 Moved Permanently 或应用自身的登录跳转。如果返回 404,优先检查 root 和 current 软链接;如果返回 502 Bad Gateway,重点检查 PHP-FPM Socket 和服务状态。
在确认 HTTP 可访问、DNS 已生效后,再申请证书:
sudo apt install -y certbot python3-certbot-nginx
sudo cp -a /etc/nginx/sites-available/shop.conf \
/etc/nginx/sites-available/shop.conf.before-https
sudo certbot --nginx -d shop.example.com
如果还要使用 www.shop.example.com,必须先为该域名配置 DNS,再把它加入 -d 参数。证书工具会修改 Nginx 配置,执行前应保留备份;修改后验证:
sudo nginx -t
sudo systemctl reload nginx
curl -I https://shop.example.com/
sudo certbot renew --dry-run
如果证书申请失败,常见原因是 DNS 尚未生效、80 端口未放行、域名指向错误地址或 Nginx 配置无法通过检测。先修复原因,不要反复申请。
十、逐层验证部署结果
1. 验证服务和监听端口
systemctl is-active nginx
systemctl is-active php8.3-fpm
systemctl is-active mariadb
sudo ss -lntp | grep -E ':80|:443|:3306'
Nginx 应监听 80 或 443,MariaDB 最好只监听 127.0.0.1:3306。如果发现数据库监听公网地址,应回到 MariaDB 绑定配置和防火墙规则检查。
2. 验证 PHP 是否能被 Nginx 执行
临时创建测试文件:
printf '%s\n' ' /dev/null
sudo chown deploy:www-data /var/www/shop/current/public/__health.php
sudo chmod 640 /var/www/shop/current/public/__health.php
curl -sS https://shop.example.com/__health.php
正常应返回:
PHP_OK
验证完成后必须删除测试文件,避免留下可被外部访问的调试入口:
sudo rm -f /var/www/shop/current/public/__health.php
3. 验证应用和数据库
通过浏览器或命令行检查:
curl -sS -o /dev/null -w '%{http_code}\n' \
https://shop.example.com/
应用层至少应完成以下测试:

- 首页、商品列表和商品详情可以打开。
- 后台登录不会出现 PHP 报错。
- 加入购物车后会话保持正常。
- 测试订单能够写入数据库。
- 图片上传大小符合预期。
- 订单后台可以读取刚刚生成的数据。
- 应用日志中没有持续出现数据库连接失败或权限错误。
十一、常见失败处理
| 现象 | 优先检查 | 处理方向 |
|---|---|---|
| 域名无法打开 | DNS、A/AAAA 记录、80/443 端口 | 确认解析地址和防火墙规则 |
| Nginx 返回 403 | root、目录执行权限、入口文件 | 确认 public/index.php 存在,目录至少允许 Nginx 穿透 |
| Nginx 返回 404 | server_name、root、try_files | 检查是否命中了默认站点,确认软链接目标 |
| Nginx 返回 502 | PHP-FPM 状态和 Socket 路径 | 执行 ls /run/php/,使 fastcgi_pass 与实际版本一致 |
| 页面返回 500 | 应用日志、PHP-FPM 日志、环境变量 | 检查数据库凭据、应用密钥和缓存权限 |
| SQLSTATE Access denied | 用户名、密码、数据库用户主机部分 | 确认 DB_HOST 与 'shop_app'@'127.0.0.1' 一致 |
| 上传返回 413 | Nginx client_max_body_size | 调整 Nginx 后同步检查 PHP 的 post_max_size |
| 证书申请失败 | DNS、80 端口、Nginx 配置 | 先完成 HTTP 访问,再重新执行证书申请 |
| 页面显示源码而非运行结果 | PHP location 或 PHP-FPM 未连接 | 检查 location ~ \.php$ 和 FPM 服务 |
查看日志时,先从最近记录开始,避免被旧错误干扰:
sudo tail -n 80 /var/log/nginx/shop_error.log
sudo tail -n 80 /var/log/nginx/shop_access.log
sudo journalctl -u php8.3-fpm -n 80 --no-pager
sudo journalctl -u mariadb -n 80 --no-pager
十二、上线前备份和失败回滚
1. 备份配置与数据库
修改 Nginx、PHP 或数据库配置前,保留当前文件:
sudo install -d -m 700 /var/backups/shop
sudo tar -C /etc/nginx -czf \
/var/backups/shop/nginx-$(date +%F-%H%M%S).tar.gz \
sites-available sites-enabled
sudo cp -a /etc/php/8.3/fpm/conf.d/99-shop.ini \
/var/backups/shop/99-shop.ini.$(date +%F-%H%M%S)
sudo mariadb-dump \
--single-transaction \
--routines \
--events \
shop_db | sudo tee \
/var/backups/shop/shop_db-$(date +%F-%H%M%S).sql > /dev/null
数据库备份命令会读取当前数据库内容;正式环境应确认备份文件可读,并将备份复制到独立存储位置。仅把备份留在同一块系统盘,无法覆盖磁盘损坏等风险。
2. 回滚网站代码
发布新版本前,先记录当前版本:
readlink -f /var/www/shop/current
如果新版本出现 PHP 错误、模板错误或功能异常,可切回上一个版本:
sudo ln -sfn /var/www/shop/releases/20260920-01 \
/var/www/shop/current
sudo nginx -t
sudo systemctl reload nginx
代码回滚通常只需要切换软链接并重新加载 Nginx。不要在没有数据库备份的情况下贸然回滚数据库结构,因为新版本可能已经执行了字段或数据迁移。
3. 回滚配置和数据库
Nginx 配置回滚前先检查备份文件,再测试并加载:
sudo cp -a /var/backups/shop/nginx-YYYY-MM-DD-HHMMSS.tar.gz /tmp/
sudo tar -C /etc/nginx -xzf /tmp/nginx-YYYY-MM-DD-HHMMSS.tar.gz
sudo nginx -t
sudo systemctl reload nginx
数据库恢复属于有数据覆盖风险的操作,只能在确认当前数据已备份、网站已进入维护状态后执行:
sudo mariadb shop_db < /var/backups/shop/shop_db-YYYY-MM-DD-HHMMSS.sql
恢复前应停止订单写入或启用应用维护模式,否则恢复过程中的新订单可能丢失。数据库恢复完成后,再验证商品、用户和订单数据,并检查应用日志。
十三、最终验收清单
- [ ] 操作系统版本、PHP 版本和数据库版本与网站程序兼容。
- [ ] Nginx、PHP-FPM、MariaDB 均为
active。 - [ ] 域名解析到正确的服务器地址。
- [ ] 22、80、443 端口按需放行,3306 未暴露给公网。
- [ ] Nginx
root指向实际公开目录,而不是项目根目录。 - [ ] PHP-FPM Socket 路径与 Nginx 配置一致。
- [ ] 数据库使用独立业务账号,未让网站使用 root。
- [ ]
.env、配置文件和上传目录没有被公开访问。 - [ ] HTTP、HTTPS、PHP 执行、数据库连接和应用首页均验证通过。
- [ ] 测试订单、后台登录和文件上传完成验证。
- [ ] 网站代码、Nginx、PHP 和数据库均有可用回滚副本。
- [ ] 已删除临时健康检查文件和调试文件。
- [ ] 已记录当前发布版本,出现故障时可以切回上一版本。