第 16/30 天
引言
Web 服务器是互联网的基础设施,无论是搭建个人博客、企业官网,还是部署微服务 API,都离不开 Web 服务器。在 Ubuntu 生态中,Nginx 和 Apache 是最主流的两个选择——它们各有优势,适用于不同的场景。
今天,我们将从零开始在 Ubuntu 上搭建 Nginx 和 Apache,深入配置虚拟主机、SSL 证书,并实战反向代理——这是现代 Web 架构中最核心的部署模式之一。无论你是运维新手还是后端开发者,掌握这些技能都是通往生产环境的必经之路。
一、Nginx vs Apache:选型对比
在动手安装之前,先了解两者的核心差异:
| 特性 | Nginx | Apache |
|---|---|---|
| 架构模型 | 事件驱动(异步非阻塞) | 进程/线程模型(每个连接一个进程) |
| 并发处理 | 极高,单进程处理数千连接 | 中等,依赖 MPM 模式 |
| 静态文件性能 | 极优(自带高效静态文件服务) | 良好 |
| 动态内容 | 通过 FastCGI 代理(PHP-FPM) | 原生支持(mod_php) |
| 配置复杂度 | 简洁清晰 | 功能丰富但配置繁重 |
| 模块系统 | 编译时静态模块 | 动态加载模块(DSO) |
| 反向代理 | 原生支持,性能极佳 | 通过 mod_proxy 实现 |
| 适用场景 | 高并发、反向代理、静态资源、负载均衡 | 传统 LAMP 栈、.htaccess 重度用户 |
我的建议: 新项目首选 Nginx——性能更好、配置更简洁、反向代理能力更强。Apache 适合需要大量 .htaccess 覆盖或兼容老项目的场景。
二、安装 Nginx
2.1 从官方仓库安装
Ubuntu 官方源自带 Nginx,但版本可能较旧。推荐添加 Nginx 官方源获取最新稳定版:
# 安装依赖
sudo apt update
sudo apt install -y curl gnupg2 ca-certificates lsb-release
# 添加 Nginx 官方签名密钥
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo gpg --dearmor -o /usr/share/keyrings/nginx-archive-keyring.gpg
# 添加 Nginx 稳定版源
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu $(lsb_release -cs) nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
# 安装
sudo apt update
sudo apt install -y nginx
2.2 验证安装
# 检查版本
nginx -v
# 输出: nginx version: nginx/1.26.x
# 检查服务状态
sudo systemctl status nginx
# 启动并设置开机自启
sudo systemctl start nginx
sudo systemctl enable nginx
此时访问 http://你的服务器IP,应该看到 Nginx 的默认欢迎页面。
2.3 Nginx 目录结构
了解 Nginx 的核心目录结构至关重要:
/etc/nginx/
├── nginx.conf # 主配置文件
├── conf.d/ # 全局配置片段
├── sites-available/ # 可用站点配置(虚拟主机)
├── sites-enabled/ # 已启用站点(软链接到 sites-available)
├── modules-available/ # 可用模块
└── modules-enabled/ # 已启用模块
/var/log/nginx/
├── access.log # 访问日志
└── error.log # 错误日志
/var/www/html/ # 默认网站根目录
/usr/share/nginx/html/ # 部分发行版的默认根目录
三、安装 Apache
3.1 安装 Apache2
sudo apt update
sudo apt install -y apache2
3.2 验证并启动
# 检查版本
apache2 -v
# 输出: Server version: Apache/2.4.62 (Ubuntu)
# 启动服务
sudo systemctl start apache2
sudo systemctl enable apache2
3.3 Apache 目录结构
/etc/apache2/
├── apache2.conf # 主配置文件
├── ports.conf # 端口配置
├── sites-available/ # 可用站点配置
├── sites-enabled/ # 已启用站点(软链接)
├── mods-available/ # 可用模块
├── mods-enabled/ # 已启用模块
└── conf-available/ # 可用配置片段
/var/www/html/ # 默认网站根目录
/var/log/apache2/ # 日志目录
四、配置虚拟主机(Virtual Hosts)
虚拟主机让一台服务器托管多个网站,是 Web 服务器的核心功能。
4.1 Nginx 虚拟主机配置
创建第一个站点配置文件:
# 创建网站目录
sudo mkdir -p /var/www/example.com/html
sudo chown -R $USER:$USER /var/www/example.com/html
sudo chmod -R 755 /var/www/example.com
# 创建测试页面
cat > /var/www/example.com/html/index.html << 'HTML'
<!DOCTYPE html>
<html>
<head><title>Welcome to Example</title></head>
<body>
<h1>Hello from Nginx on Ubuntu!</h1>
<p>This is a virtual host example.</p>
</body>
</html>
HTML
创建 Nginx 站点配置:
# /etc/nginx/sites-available/example.com
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
# 静态文件缓存
location ~* .(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
# 日志配置
access_log /var/log/nginx/example_access.log;
error_log /var/log/nginx/example_error.log;
}
启用站点:
# 创建软链接到 sites-enabled
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
# 测试配置语法
sudo nginx -t
# 重载 Nginx
sudo systemctl reload nginx
4.2 Apache 虚拟主机配置
# 创建网站目录
sudo mkdir -p /var/www/example2.com/html
sudo chown -R $USER:$USER /var/www/example2.com/html
# 创建测试页面
cat > /var/www/example2.com/html/index.html << 'HTML'
<!DOCTYPE html>
<html>
<head><title>Welcome to Example2</title></head>
<body>
<h1>Hello from Apache on Ubuntu!</h1>
<p>This is an Apache virtual host example.</p>
</body>
</html>
HTML
创建 Apache 站点配置:
# /etc/apache2/sites-available/example2.com.conf
<VirtualHost *:80>
ServerAdmin admin@example2.com
ServerName example2.com
ServerAlias www.example2.com
DocumentRoot /var/www/example2.com/html
<Directory /var/www/example2.com/html>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/example2_error.log
CustomLog ${APACHE_LOG_DIR}/example2_access.log combined
</VirtualHost>
启用站点:
# 启用站点
sudo a2ensite example2.com.conf
# 禁用默认站点(可选)
sudo a2dissite 000-default.conf
# 测试配置
sudo apache2ctl configtest
# 重载 Apache
sudo systemctl reload apache2
五、反向代理实战
反向代理是 Nginx 最强大的功能之一——它接收客户端请求,转发给后端服务器(应用服务器、API 服务等),再将结果返回给客户端。这实现了负载均衡、安全隔离、SSL 终结等高级功能。
5.1 反向代理架构示意图
Client ──► Nginx (反向代理) ──► Backend Server (Node.js/Python/Java)
│
├── App 1 (port 3000)
├── App 2 (port 3001)
└── App 3 (port 3002)
5.2 使用 Nginx 反向代理 Node.js 应用
假设你有一个运行在 localhost:3000 的 Node.js 应用:
# /etc/nginx/sites-available/node-app
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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;
proxy_cache_bypass $http_upgrade;
}
# 限制请求体大小(API 上传文件时很重要)
client_max_body_size 50M;
}
5.3 使用 Nginx 反向代理 PHP(PHP-FPM)
Nginx 不自带 PHP 处理能力,需要通过 FastCGI 代理到 PHP-FPM:
server {
listen 80;
server_name blog.example.com;
root /var/www/blog;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ .php$ {
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
5.4 基于路径的反向代理(多服务聚合)
一个域名下代理多个后端服务,通过路径区分:
server {
listen 80;
server_name app.example.com;
# API 服务 — 转发到 Go 后端
location /api/ {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Host $host;
}
# 前端静态文件 — 直接由 Nginx 服务
location /static/ {
alias /var/www/frontend/dist/;
expires 30d;
}
# WebSocket 支持
location /ws/ {
proxy_pass http://127.0.0.1:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
5.5 Apache 反向代理配置
Apache 通过 mod_proxy 实现反向代理:
# 启用必要模块
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_balancer
sudo a2enmod lbmethod_byrequests
sudo systemctl restart apache2
配置反向代理:
<VirtualHost *:80>
ServerName proxy.example.com
# 反向代理到后端
ProxyPass /app1 http://127.0.0.1:3000/
ProxyPassReverse /app1 http://127.0.0.1:3000/
ProxyPass /app2 http://127.0.0.1:5000/
ProxyPassReverse /app2 http://127.0.0.1:5000/
# 负载均衡(多台后端)
<Proxy "balancer://mycluster">
BalancerMember http://127.0.0.1:3000
BalancerMember http://127.0.0.1:3001
ProxySet lbmethod=byrequests
</Proxy>
ProxyPass /balancer balancer://mycluster/
ProxyPassReverse /balancer balancer://mycluster/
</VirtualHost>
六、SSL 证书配置(HTTPS)
6.1 使用 Certbot 自动获取 Let’s Encrypt 证书
# 安装 Certbot
sudo apt install -y certbot python3-certbot-nginx
# 自动获取证书并配置 Nginx
sudo certbot --nginx -d example.com -d www.example.com
# 测试自动续期
sudo certbot renew --dry-run
6.2 Nginx SSL 配置最佳实践
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
# SSL 证书路径
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 ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# HSTS(HTTP Strict Transport Security)
add_header Strict-Transport-Security "max-age=63072000" always;
root /var/www/example.com/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
# HTTP → HTTPS 重定向
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
七、常见问题与排查
Q1: Nginx 配置测试报错如何排查?
# 检查语法
sudo nginx -t
# 检查具体错误行
sudo nginx -T 2>&1 | grep -i error
# 查看错误日志
sudo tail -f /var/log/nginx/error.log
Q2: 端口被占用怎么办?
# 查看端口占用
sudo netstat -tlnp | grep -E ':80|:443'
# 或使用 ss
sudo ss -tlnp | grep -E ':80|:443'
# 如果有其他程序占用了 80 端口,停止它
sudo systemctl stop apache2 # 如果 Apache 占用 80
Q3: Apache 和 Nginx 能否共存?
可以,但不能同时监听相同端口。一个方案是让 Nginx 监听 80/443,Apache 监听其他端口(如 8080),Nginx 反向代理到 Apache:
# Nginx 监听 80,转发动态请求到 Apache:8080
location ~ .php$ {
proxy_pass http://127.0.0.1:8080;
}
Q4: 修改配置后访问仍然是旧页面?
# 清空浏览器缓存
# 或者强制重载 Nginx/Apache
sudo systemctl reload nginx
# 或
sudo systemctl reload apache2
Q5: 反向代理返回 502 Bad Gateway?
# 检查后端服务是否正常运行
curl http://127.0.0.1:3000/health
# 检查 Nginx 错误日志
sudo tail -f /var/log/nginx/error.log
# 常见原因:后端服务未启动、防火墙阻挡、socket 路径错误
八、性能调优建议
Nginx 核心调优参数
# /etc/nginx/nginx.conf 中的核心优化
worker_processes auto; # 自动匹配 CPU 核心数
worker_connections 1024; # 每个 worker 最大连接数
keepalive_timeout 65; # 长连接超时
client_max_body_size 100M; # 上传文件大小限制
sendfile on; # 高效文件传输
tcp_nopush on; # 优化网络包
gzip on; # 启用压缩
gzip_types text/plain text/css application/json application/javascript;
Apache 性能调优
# 切换到事件 MPM(多处理模块)
sudo a2dismod mpm_prefork
sudo a2enmod mpm_event
sudo systemctl restart apache2
总结
今天我们深入学习了 Ubuntu 上 Web 服务器的搭建与配置:
| 技能点 | 掌握程度 |
|---|---|
| Nginx 安装与基础配置 | ✅ 实战 |
| Apache 安装与虚拟主机 | ✅ 实战 |
| 反向代理配置(Nginx + Apache) | ✅ 实战 |
| SSL 证书自动配置(Certbot) | ✅ 实战 |
| 多站点虚拟主机管理 | ✅ 掌握 |
| 性能调优基础 | ✅ 了解 |
下期预告: 第 17 天我们将进入数据库的世界——在 Ubuntu 上部署 MySQL/MariaDB/PostgreSQL,从安装到调优,掌握生产级数据库配置的全部要点。
系列目录
| 天数 | 文章标题 | 链接 |
|---|---|---|
| 第 1 天 | Ubuntu 简介与版本选择 | 阅读 |
| 第 2 天 | 手把手安装 Ubuntu | 阅读 |
| 第 3 天 | Ubuntu 桌面环境初探 | 阅读 |
| 第 4 天 | Ubuntu 终端基础 | 阅读 |
| 第 5 天 | 用户与权限管理 | 阅读 |
| 第 6 天 | 软件包管理 | 阅读 |
| 第 7 天 | 文件与文本操作 | 阅读 |
| 第 8 天 | 系统服务管理 | 阅读 |
| 第 9 天 | 磁盘与文件系统管理 | 阅读 |
| 第 10 天 | 网络配置与管理 | 阅读 |
| 第 11 天 | 进程管理与监控 | 阅读 |
| 第 12 天 | 计划任务与自动化 | 阅读 |
| 第 13 天 | 备份与恢复策略 | 阅读 |
| 第 14 天 | 系统更新与升级管理 | 阅读 |
| 第 15 天 | SSH 远程管理与安全加固 | 阅读 |
| 第 16 天 | Web 服务器搭建 | 👉 本文 |
| 第 17 天 | 数据库服务器部署 | 敬请期待 |
| 第 18 天 | Docker 容器化 | 敬请期待 |
| 第 19 天 | 文件共享服务 | 敬请期待 |
| 第 20 天 | 监控与告警系统 | 敬请期待 |
| 第 21 天 | 邮件服务器基础 | 敬请期待 |
| 第 22 天 | 系统安全加固 | 敬请期待 |
| 第 23 天 | 性能调优与内核参数 | 敬请期待 |
| 第 24 天 | 虚拟化技术 | 敬请期待 |
| 第 25 天 | 容器编排入门 | 敬请期待 |
| 第 26 天 | 高可用与负载均衡 | 敬请期待 |
| 第 27 天 | Ubuntu 自动部署 | 敬请期待 |
| 第 28 天 | 故障排查实战 | 敬请期待 |
| 第 29 天 | Ubuntu 社区与文档 | 敬请期待 |
| 第 30 天 | 30 天回顾总结 | 敬请期待 |















暂无评论内容