VPS服务器怎么搭建网站?Linux环境部署实操指南

拿到一台 VPS 后,搭建网站不只是安装 Nginx。一个可用的站点还需要正确的域名解析、PHP 运行环境、数据库、目录权限、主机防火墙和 HTTPS 证书。任何一层配置错误,都可能表现为“网站打不开”“出现五百错误”或“上传文件失败”。

这篇文章以常见的 LNMP 架构为例,分别说明 Rocky、RHEL、CentOS 系和 Debian、Ubuntu 系的安装方法。LNMP 中的 L 代表 Linux,N 代表 Nginx,M 可以是 MySQL 或兼容的 MariaDB,P 代表 PHP。文中使用 example.com 作为示例域名,操作时必须替换成自己的域名,并先为现有数据和配置做备份。

部署前规划域名、端口和目录

先确认 VPS 具备公网地址,并且本地可以通过 SSH 登录。网站对外至少需要 TCP 80 和 443 端口,管理用的 SSH 端口只应允许管理员来源。数据库默认端口 3306 不需要向公网开放,因为 Nginx、PHP 和数据库都运行在同一台服务器上,可通过本机套接字或回环地址连接。

建议为每个站点建立独立目录,例如:

/var/www/example.com/
├── public/        # 网站公开目录,Nginx 的 root 指向这里
├── storage/       # 应用可写数据,按框架需要创建
└── releases/      # 可选,用于保留发布版本

把 Nginx 根目录指向 public,可以避免配置文件、源码仓库和环境变量文件被直接下载。不要把 .env、数据库备份和私钥放进公开目录。即使 Nginx 配置了隐藏文件拒绝规则,也应从目录结构上减少误暴露风险。

资源方面,小型博客或企业官网可从两个 vCPU、二到四吉字节内存起步。动态插件多、访问峰值高或数据库较大时,需要更多内存与稳定磁盘。这个范围只是经验起点,应根据 PHP 响应时间、数据库慢查询、内存和磁盘延迟调整。

域名解析可以在安装前配置,也可以等本机验证通过后再切换。至少需要一条 A 记录指向 VPS 的 IPv4 地址;若服务器和网络完整支持 IPv6,再添加 AAAA 记录。www 子域可以使用 A 记录或 CNAME 指向主域名。解析生效时间由 DNS 的 TTL 和缓存决定,切换旧站前应提前降低 TTL,并保留回滚记录。

在两类发行版上安装 LNMP

安装前先查看系统版本,并更新软件包:

cat /etc/os-release

Rocky、RHEL、CentOS 系

现代版本优先使用 dnf:

sudo dnf upgrade --refresh -y
sudo dnf install -y nginx mariadb-server php php-fpm php-mysqlnd php-cli php-gd php-mbstring php-xml php-opcache
sudo systemctl enable --now nginx
sudo systemctl enable --now mariadb
sudo systemctl enable --now php-fpm

旧版 CentOS 可以把 dnf 替换为 yum。检查三个服务状态:

systemctl status nginx --no-pager
systemctl status mariadb --no-pager
systemctl status php-fpm --no-pager

RHEL 兼容发行版的 PHP-FPM 常监听 127.0.0.1:9000,也可能由发行版或管理员改成 Unix 套接字。可以用下面命令确认实际配置:

grep -R '^listen =' /etc/php-fpm.d/
sudo ss -lntp | grep 9000

如果没有输出,不要盲目改 Nginx,应检查 /etc/php-fpm.d/www.conf、服务日志和 Unix 套接字路径。

Debian、Ubuntu 系

使用 apt 安装 Nginx、MariaDB 与 PHP-FPM:

sudo apt update
sudo apt upgrade -y
sudo apt install -y nginx mariadb-server php-fpm php-mysql php-cli php-gd php-mbstring php-xml php-opcache
sudo systemctl enable --now nginx
sudo systemctl enable --now mariadb

PHP-FPM 服务名包含版本号,软件包安装时通常会自动启动。可以查看当前单元和套接字:

systemctl list-units --type=service 'php*-fpm.service'
find /run/php -maxdepth 1 -type s -name 'php*-fpm.sock' -print

后面的 Nginx 配置必须填写这里查到的真实套接字,例如 /run/php/php8.2-fpm.sock。版本会随发行版变化,不应复制一个不匹配的固定路径。

初始化数据库

两类系统都可以运行安全初始化向导:

sudo mariadb-secure-installation

某些版本命令名仍是:

sudo mysql_secure_installation

按提示移除匿名用户、禁止远程 root 登录、删除测试库并刷新权限。不同版本对 root 的认证方式不同,不能照搬旧教程强制改成弱密码认证。应用应使用独立数据库和最小权限账号,而不是直接使用 root。

进入数据库控制台后,可执行以下 SQL。请把示例密码替换为随机生成的强密码,并保存在受控的密钥管理位置:

CREATE DATABASE website CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'website_user'@'localhost' IDENTIFIED BY 'REPLACE_WITH_STRONG_PASSWORD';
GRANT ALL PRIVILEGES ON website.* TO 'website_user'@'localhost';
FLUSH PRIVILEGES;

SQL 权限仅覆盖 website 数据库,避免一个站点账号读取其他业务库。生产数据库还要定期导出并把备份复制到另一台主机或对象存储,不能只留在同一块 VPS 磁盘。

创建站点目录并配置 Nginx server

先创建部署用户和站点目录。以下用 deploy 作为文件所有者。Debian、Ubuntu 的 Web 服务组通常是 www-data:

sudo adduser --disabled-password --gecos '' deploy
sudo install -d -o deploy -g www-data -m 2755 /var/www/example.com/public

Rocky、RHEL、CentOS 的 Nginx 组通常是 nginx:

sudo useradd -m -s /bin/bash deploy
sudo install -d -o deploy -g nginx -m 2755 /var/www/example.com/public

若用户已存在,跳过创建命令。2755 中的组继承位可以让新目录沿用站点组,但应用是否需要组写入取决于框架。公开静态文件通常使用目录 755、文件 644;只有上传、缓存或会话目录需要受控写权限。不要执行 chmod -R 777,这会让本机所有用户都能修改网站文件。

创建测试页面:

sudo -u deploy tee /var/www/example.com/public/index.php >/dev/null <<'PHP'

RHEL 系可创建 /etc/nginx/conf.d/example.com.conf:

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    root /var/www/example.com/public;
    index index.php index.html;

    access_log /var/log/nginx/example.com.access.log;
    error_log  /var/log/nginx/example.com.error.log;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        try_files $uri =404;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass 127.0.0.1:9000;
    }

    location ~ /\. {
        deny all;
    }
}

如果 grep -R '^listen =' /etc/php-fpm.d/ 显示的是套接字,fastcgi_pass 必须相应修改。不要同时填写不存在的地址。

Debian、Ubuntu 可创建 /etc/nginx/sites-available/example.com,主体基本相同,但 PHP 转发使用实际套接字:

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    root /var/www/example.com/public;
    index index.php index.html;

    access_log /var/log/nginx/example.com.access.log;
    error_log  /var/log/nginx/example.com.error.log;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        try_files $uri =404;
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
    }

    location ~ /\. {
        deny all;
    }
}

上面的 php8.2-fpm.sock 只是格式示例,必须替换为 find /run/php 查到的真实路径。然后启用站点:

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com

每次修改都先做语法检查,再平滑重载:

sudo nginx -t
sudo systemctl reload nginx
curl -H 'Host: example.com' http://127.0.0.1/

如果 nginx -t 失败,不要重载。根据输出中的文件和行号修正,必要时恢复改动前备份。测试通过后应删除显示环境详情的测试脚本,尤其不要把 phpinfo() 页面长期暴露公网,因为它会泄露路径、模块和配置参数。

处理权限、SELinux 和应用发布

网站代码建议由部署用户持有,Nginx 与 PHP-FPM 只获得读取权限。需要写入的目录单独授权。例如 Debian、Ubuntu 下应用需要写 storage:

sudo install -d -o deploy -g www-data -m 2770 /var/www/example.com/storage
sudo find /var/www/example.com/public -type d -exec chmod 755 {} \;
sudo find /var/www/example.com/public -type f -exec chmod 644 {} \;

RHEL 系把组名换成 nginx,但还要考虑 SELinux。不要直接执行 setenforce 0 长期关闭保护。先安装管理工具并设置内容标签:

sudo dnf install -y policycoreutils-python-utils
sudo semanage fcontext -a -t httpd_sys_content_t '/var/www/example.com(/.*)?'
sudo restorecon -Rv /var/www/example.com

若确实有运行时可写目录,仅给该目录写标签:

sudo semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/example.com/storage(/.*)?'
sudo restorecon -Rv /var/www/example.com/storage

使用数据库时,如果 PHP 通过本机 TCP 连接而被 SELinux 拒绝,应先查看审计日志确认原因,再决定是否启用相应布尔值。不能看到五百错误就关闭 SELinux。常用排查命令如下:

sudo ausearch -m AVC -ts recent
sudo journalctl -u php-fpm -n 100 --no-pager
sudo tail -n 100 /var/log/nginx/example.com.error.log

正式发布时,先把新版本上传到独立目录,安装依赖并做健康检查,再切换软链接或替换站点路径。保留上一个可运行版本能加快回滚。数据库结构变更必须单独备份,并确认旧程序能否兼容新结构,不能只回滚代码。

敏感配置不应提交到 Git。数据库密码、邮件凭据和第三方令牌可放在站点公开目录之外的配置文件中,限制为应用用户可读。备份文件也不要使用 .bak 后缀直接留在 public 下,因为 Nginx 可能把它当普通文件下载。

配置 DNS、放行 80/443 并启用 HTTPS

在 DNS 管理处添加 A 记录后,可以从本地检查解析:

nslookup example.com

也可以在 Linux 终端使用:

getent ahosts example.com

确认结果指向新 VPS,再放行网络。云平台安全组需要入站允许 TCP 80 和 443,来源通常是公网;SSH 仍只允许管理员地址。安全组放行后,还要配置系统防火墙。

Rocky、RHEL、CentOS 使用 firewalld:

sudo systemctl enable --now firewalld
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload
sudo firewall-cmd --list-all

Debian、Ubuntu 使用 UFW:

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

风险提示:启用主机防火墙前,必须确认实际 SSH 端口已放行,并保留当前连接。若误封,可通过云控制台终端执行 sudo ufw disable,或修复 firewalld 规则。不要在没有控制台救援手段时远程一次性修改 SSH 端口和防火墙。

DNS 生效且 80 端口可访问后,可申请 HTTPS 证书。Debian、Ubuntu 可安装 Certbot 的 Nginx 插件:

sudo apt update
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com

RHEL 兼容发行版需先确保软件仓库提供对应包,再安装:

sudo dnf install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com

Certbot 会验证域名是否指向当前服务器,因此解析错误、端口未开放或反向代理拦截都会导致失败。签发后测试自动续期:

sudo certbot renew --dry-run

最后分别访问 HTTP 与 HTTPS,确认 HTTP 是否按预期跳转、证书域名是否匹配、PHP 页面是否正常。还应检查访问日志、错误日志和证书续期定时器。若站点有表单登录,应在 HTTPS 正常后再开放真实用户访问。

常见问题

浏览器显示五百错误,先查什么?

先运行 nginx -t,再查看站点错误日志和 PHP-FPM 日志。常见原因是 PHP 套接字路径写错、文件权限不足、应用配置缺失或数据库连接失败,不要直接把目录改成 777。

出现五零二 Bad Gateway 怎么办?

通常是 Nginx 无法连接 PHP-FPM。检查 PHP-FPM 服务是否运行、listen 配置与 fastcgi_pass 是否一致、套接字权限是否允许 Nginx 访问,并查看对应服务日志。

域名已经解析,为什么仍显示旧网站?

可能是本地或递归 DNS 缓存尚未过期,也可能访问了 www 与主域名中的另一个记录。分别查询 A、AAAA 记录,确认没有旧 IPv6 地址,并等待 TTL 到期。

可以把 MySQL 3306 端口开放公网吗?

同机部署完全没有必要。跨服务器访问也应优先走私有网络,并把来源限制为应用服务器。若必须远程管理,使用 VPN 或 SSH 隧道,不要对全网开放数据库端口。

快照能替代网站备份吗?

不能。快照可能与 VPS 位于同一平台,也可能只提供崩溃一致性。网站应定期备份数据库和上传文件到独立存储,并实际恢复到测试环境验证。

总结

  • LNMP 建站要同时处理 Nginx、数据库、PHP-FPM、域名、权限和防火墙,不能只完成软件安装。
  • Nginx 的站点根目录应指向公开子目录,数据库和 PHP 套接字使用实际环境值,修改后先执行语法检查再重载。
  • 代码由部署用户持有,只给必要目录写权限;不要使用 777,RHEL 系优先正确配置 SELinux 标签。
  • 安全组与主机防火墙都要放行 80/443,SSH 只允许受控来源,数据库端口不对公网开放。
  • HTTPS 签发后要验证自动续期,网站数据还需异地备份和恢复演练,不能只依赖本机或单个平台快照。