结论: 在一台服务器上搭建网站的完整流程是六步:初始化系统与安全基线 → 放行 80/443 端口 → 安装并配置 Nginx → 部署站点文件 → 域名解析到服务器 IP → 配置 HTTPS 证书并验证。全程约 30 分钟,核心命令约 20 条,本文以 Ubuntu 24.04 LTS + Nginx 1.24+ 为例给出可直接复制执行的完整流程。
引言:为什么很多人卡在"网站打不开"这一步?
买完服务器、装完 Nginx、传完网页文件,浏览器却打不开——这是新手建站最高频的卡点。原因通常不是 Nginx 配错,而是以下四件事中的某一件没做:
- 端口没放行:云控制台的安全组与系统防火墙是两层,只放行一层访问就会超时。
- 域名没解析:直接访问 IP 可以,访问域名不行,说明 DNS 记录没生效。
- 大陆节点没备案:域名解析到大陆节点但未完成 ICP 备案(通常 7~20 个工作日),会被接入商拦截。
- Nginx 监听配置不匹配:
server_name与实际访问域名不一致,请求落到了默认站点。
本文按"能跑通"的思路组织:每一步都给出命令和验证方法,每完成一步就验证一次,确保问题在当场暴露,而不是堆到最后一起排查。
在开始之前,先明确本文的适用前提与范围。本文针对的是在一台已经购买好的 Linux 服务器上,从零部署一个可通过域名访问的网站,涵盖静态站点与最常见的动态站点入口配置。操作系统以 Ubuntu 24.04 LTS 为例,Web 服务器使用 Nginx;如果你使用的是 CentOS、Rocky Linux 或 Debian,命令的差异只在包管理器与防火墙工具两处,本文同样给出对应版本。
另外一个前置判断是节点位置。如果你的服务器在中国大陆节点,域名必须先完成 ICP 备案(通常 7~20 个工作日)才能通过 80/443 端口对外提供服务;如果是香港、美国、新加坡等海外节点,则无需备案,部署完成后即可访问。这一点会直接影响你的上线时间规划,建议在开始部署前先确认清楚,必要时采用"海外节点先上线、备案通过后再迁回大陆"的并行方案,避免长时间空等。
第一步:系统初始化与安全基线
结论先行:拿到服务器后先做安全基线,再部署业务。这一步能挡掉绝大多数自动化扫描与暴力破解。
# 1. 确认系统版本(本文以 Ubuntu 24.04 LTS 为例)
cat /etc/os-release
uname -a
# 2. 更新系统补丁
sudo apt update && sudo apt upgrade -y
# 3. 设置时区为上海,避免日志时间与本地不符
sudo timedatectl set-timezone Asia/Shanghai
timedatectl status
# 4. 创建普通运维账号并赋予 sudo 权限
sudo adduser ops
sudo usermod -aG sudo ops
# 5. 在本地机器生成密钥并拷贝到服务器(本地执行,<服务器IP> 换成实际地址)
ssh-keygen -t ed25519 -C "ops@web" -f ~/.ssh/id_ed25519_web
ssh-copy-id -i ~/.ssh/id_ed25519_web.pub ops@<服务器IP>验证密钥登录成功后,再禁用密码登录与 root 直登:
# 在服务器上执行
sudo tee /etc/ssh/sshd_config.d/harden.conf >/dev/null <<'EOF'
Port 2222
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
PermitEmptyPasswords no
MaxAuthTries 3
EOF
sudo sshd -t && sudo systemctl restart ssh重要提醒:修改 SSH 端口前,必须先在云控制台安全组放行 2222 端口,并另开一个终端确认新端口可登录,再关闭 22 端口。否则会把自己锁在服务器外面。
第二步:放行 80/443 端口(两层都要做)
结论先行:必须同时放行云控制台安全组和系统防火墙,缺一层网站就访问不了。
- 云控制台安全组(Security Group):在云厂商控制台的"安全组/防火墙"页面添加入站规则,放行 TCP 22(或你的 SSH 端口)、80、443。
- 系统防火墙(ufw / firewalld):在服务器内放行对应端口。
# Ubuntu / Debian 使用 ufw
sudo apt install -y ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 2222/tcp comment 'ssh'
sudo ufw allow 80/tcp comment 'http'
sudo ufw allow 443/tcp comment 'https'
sudo ufw --force enable
sudo ufw status verbose若使用 CentOS / RHEL / Rocky Linux,则使用 firewalld:
# CentOS / RHEL 使用 firewalld
sudo systemctl enable --now firewalld
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --list-all验证端口是否真正在监听:
# 查看监听端口(应能看到 80 与 443)
sudo ss -tlnp | egrep ':80|:443|:2222'
# 本地自测(应返回 HTTP 状态码)
curl -s -o /dev/null -w "本地访问状态码: %{http_code}\n" http://127.0.0.1/第三步:安装并配置 Nginx
# 安装 Nginx
sudo apt install -y nginx
# 设置开机自启并启动
sudo systemctl enable --now nginx
nginx -v # 查看版本,Ubuntu 24.04 源通常为 1.24 及以上
systemctl status nginx --no-pager部署站点目录与首页
# 创建站点根目录
sudo mkdir -p /var/www/example.com
sudo chown -R www-data:www-data /var/www/example.com
# 写入一个测试首页
sudo tee /var/www/example.com/index.html >/dev/null <<'EOF'
我的第一个站点
网站已成功部署在服务器上
EOF写入站点配置(Nginx 配置)
# /etc/nginx/sites-available/example.com
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.html index.htm;
access_log /var/log/nginx/example.access.log;
error_log /var/log/nginx/example.error.log;
location / {
try_files $uri $uri/ =404;
}
# 静态资源缓存 7 天,减少回源
location ~* \.(js|css|png|jpg|jpeg|gif|svg|ico|woff2)$ {
expires 7d;
add_header Cache-Control "public";
}
}启用站点并检查语法:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default # 移除默认站点,避免抢占
sudo nginx -t
sudo systemctl reload nginxnginx -t 输出 syntax is ok 与 test is successful 后才算配置正确。
如果要部署动态站点(PHP 或 Node.js)
上面的配置适用于纯静态站点。如果部署的是 PHP 站点(如 WordPress、Typecho),需要额外安装 PHP-FPM(FastCGI Process Manager,FastCGI 进程管理器),并在 Nginx 中通过 fastcgi_pass 把 PHP 请求转发给它;如果部署的是 Node.js 应用,则通常让应用监听本地回环地址(如 127.0.0.1:3000),再用 Nginx 做反向代理(Reverse Proxy)转发请求。
PHP 场景的关键配置片段如下:
# PHP 站点:把 .php 请求交给 PHP-FPM 处理
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock; # 版本号按实际安装的 PHP 调整
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}Node.js 场景的关键配置片段如下:
# Node.js 应用:Nginx 反向代理到本地 3000 端口
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}两种方式的共同点是:应用本身只监听 127.0.0.1,不对公网暴露端口,由 Nginx 统一在 80/443 上对外服务。这样既减少了暴露面,也便于统一做 HTTPS、压缩与缓存。
第四步:把域名解析到服务器 IP
在域名注册商或 DNS 服务商处添加记录:
| 记录类型 | 主机记录 | 记录值 | 说明 |
|---|---|---|---|
| A | @ | 服务器公网 IPv4 | 主域名指向服务器 |
| A | www | 服务器公网 IPv4 | www 前缀指向服务器 |
| AAAA | @ | 服务器 IPv6(若有) | 启用 IPv6 访问 |
| CNAME | cdn | CDN 提供的 CNAME | 可选,静态资源加速 |
验证解析是否生效:
# 在任意机器上查询(把 example.com 换成你的域名)
dig +short A example.com
dig +short A www.example.com
# 验证 HTTP 访问与连接到的 IP
curl -s -o /dev/null -w "状态码: %{http_code} 连接IP: %{remote_ip} 耗时: %{time_total}s\n" http://example.com判读要点:dig 返回的 IP 必须等于你的服务器公网 IP;若不一致,说明解析未生效或存在缓存,DNS 生效通常需要几分钟到几十分钟。若 IP 正确但访问超时,回到第二步检查端口放行。
第五步:配置 HTTPS 证书
结论先行:用 Let's Encrypt 免费证书,通过 certbot 自动签发,Nginx 插件可一键完成配置与自动续期。
# 安装 certbot 与 Nginx 插件
sudo apt install -y certbot python3-certbot-nginx
# 自动签发并修改 Nginx 配置(需先确保 80 端口可访问且域名已解析到本机)
sudo certbot --nginx -d example.com -d www.example.com \
--agree-tos -m you@example.com --redirect
# 验证自动续期是否可用(干跑测试)
sudo certbot renew --dry-run
# 查看证书到期时间
sudo certbot certificates--redirect 参数会自动把 HTTP 请求 301 跳转到 HTTPS。执行后 Nginx 配置会变成类似下面的结构:
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_session_cache shared:SSL:10m;
root /var/www/example.com;
index index.html;
add_header Strict-Transport-Security "max-age=31536000" always;
location / {
try_files $uri $uri/ =404;
}
}注意:中国大陆节点的服务器,域名必须先完成 ICP 备案才能正常对外提供 80/443 服务;香港、美国等海外节点无需备案,可直接签发证书并访问。
第六步:收尾验证与上线自查
# 1) HTTPS 访问验证
curl -s -o /dev/null -w "HTTPS 状态码: %{http_code}\n" https://example.com
# 2) 检查证书链与有效期
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -subject -dates
# 3) 查看访问日志,确认请求真的进来了
sudo tail -20 /var/log/nginx/example.access.log
# 4) 查看错误日志(排错首选)
sudo tail -20 /var/log/nginx/example.error.log
# 5) 确认 Nginx 开机自启
systemctl is-enabled nginx上线后的三项加固
- 自动续期检查:
certbot默认通过 systemd timer 自动续期,用systemctl list-timers | grep certbot确认定时器存在。 - 定期备份:站点目录与 Nginx 配置建议每日增量备份到异地存储。
- 监控告警:至少监控 CPU、内存、磁盘、带宽四项,并对网站存活做 HTTP 探测。
#!/usr/bin/env bash
# site_healthcheck.sh —— 网站存活自检,失败则重启 Nginx 并记录
# 用法:sudo bash site_healthcheck.sh
LOG=/var/log/site_healthcheck.log
URL="https://example.com/"
CODE=$(curl -s -o /dev/null -m 8 -w "%{http_code}" "$URL")
if [ "$CODE" != "200" ]; then
echo "$(date '+%F %T') 异常状态码=${CODE},尝试重启 nginx" >> "$LOG"
systemctl restart nginx
sleep 3
CODE2=$(curl -s -o /dev/null -m 8 -w "%{http_code}" "$URL")
echo "$(date '+%F %T') 重启后状态码=${CODE2}" >> "$LOG"
fi
# 加入 crontab:每 5 分钟执行一次
# (crontab -l 2>/dev/null; echo "*/5 * * * * /usr/bin/bash /usr/local/bin/site_healthcheck.sh") | crontab -
企业QQ咨询




