在阿里云服务器上通过 Docker 部署多个网站是一个非常常见且高效的做法。核心思路是利用 Nginx(或 Caddy) 作为反向X_X容器,根据域名将流量分发到不同的后端应用容器。
以下是完整的实施步骤和最佳实践方案:
1. 架构设计
我们将采用以下标准架构:
- Nginx 容器:负责监听 80/443 端口,根据
Host头将请求转发给对应的业务容器。 - 业务容器:每个网站一个独立的容器(如 WordPress、Node.js 应用、Python Flask 等)。
- Docker Compose:用于编排和管理所有容器,确保它们协同工作。
2. 准备工作
确保你的阿里云服务器已安装 Docker 和 Docker Compose。
# 检查版本
docker --version
docker-compose --version
如果未安装,请运行官方安装脚本(以 Ubuntu 为例):
curl -fsSL https://get.docker.com | bash -s docker
sudo usermod -aG docker $USER
newgrp docker # 刷新用户组权限
3. 目录结构规划
建议创建一个统一的项目目录,例如 /opt/docker-multi-site,并建立如下结构:
/opt/docker-multi-site/
├── docker-compose.yml # 主编排文件
├── nginx/
│ └── nginx.conf # Nginx 配置文件
├── site-a/ # 网站 A 的代码和数据
│ ├── app.py (示例)
│ └── .env
└── site-b/ # 网站 B 的代码和数据
└── ...
4. 编写配置文件
A. 创建 Nginx 配置文件 (nginx/nginx.conf)
这是实现多站点的关键。我们需要配置 server 块来匹配不同的域名。
# /opt/docker-multi-site/nginx/nginx.conf
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 定义上游服务
upstream site_a_backend {
server site-a:5000; # 对应 site-a 容器的内部 IP 和端口
}
upstream site_b_backend {
server site-b:3000; # 对应 site-b 容器的内部 IP 和端口
}
# 网站 A 配置 (假设域名为 a.example.com)
server {
listen 80;
server_name a.example.com;
location / {
proxy_pass http://site_a_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
# 网站 B 配置 (假设域名为 b.example.com)
server {
listen 80;
server_name b.example.com;
location / {
proxy_pass http://site_b_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
# 可选:默认兜底页面
server {
listen 80;
server_name _;
return 404 "默认页面";
}
}
B. 编写 Docker Compose 文件 (docker-compose.yml)
这里定义了 Nginx 和各个网站的容器网络关系。
version: '3.8'
services:
# 1. Nginx 反向X_X层
nginx:
image: nginx:alpine
container_name: multi-site-nginx
ports:
- "80:80"
- "443:443" # 如果有 SSL,需映射此端口
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
# 如果有静态资源,可挂载更多卷
networks:
- app-network
depends_on:
- site-a
- site-b
restart: always
# 2. 网站 A (示例:Python Flask)
site-a:
build: ./site-a
container_name: site-a-app
environment:
- FLASK_ENV=production
networks:
- app-network
restart: always
# 注意:这里不需要暴露端口到宿主机,Nginx 会通过内部网络访问它
# 3. 网站 B (示例:Node.js)
site-b:
build: ./site-b
container_name: site-b-app
networks:
- app-network
restart: always
networks:
app-network:
driver: bridge
注意:在
nginx.conf中提到的site-a:5000,其中的site-a是 Docker Compose 中定义的 Service 名称,Docker 会自动解析为容器 IP。
5. 部署与启动
- 准备业务代码:确保
site-a和site-b目录下有正确的Dockerfile或源码。 - 进入目录:
cd /opt/docker-multi-site - 启动服务:
docker-compose up -d - 查看状态:
docker-compose ps
6. 关键注意事项(生产环境必读)
A. 域名解析 (DNS)
在阿里云控制台(云解析 DNS)中,将 a.example.com 和 b.example.com 的 A 记录都指向你的阿里云服务器公网 IP。
- 前提:你已经在阿里云安全组中放行了 80 和 443 端口。
B. HTTPS 证书 (SSL)
生产环境必须使用 HTTPS。推荐使用 Certbot 或 Let’s Encrypt 配合 Nginx。
- 方案一(推荐):在 Nginx 容器中集成
acme.sh或certbot自动申请证书。 - 方案二(简单):在宿主机申请证书,然后挂载到 Nginx 容器。
# 宿主机操作 certbot --nginx -d a.example.com -d b.example.com # 将生成的 certs 挂载到 docker-compose.yml 的 nginx 服务中
C. 数据持久化
如果网站涉及数据库(MySQL, Redis)或用户上传的文件,务必使用 Volume 挂载,否则容器删除后数据会丢失。
volumes:
db_data:
uploads_site_a:
D. 阿里云安全组
登录阿里云 ECS 控制台 -> 实例详情 -> 安全组 -> 配置规则。
确保入方向规则包含:
- TCP 80 (HTTP)
- TCP 443 (HTTPS)
- (可选) SSH 22 (仅允许特定 IP 访问,不要对 0.0.0.0/0 开放)
总结
通过 Docker Compose + Nginx 反向X_X,你可以轻松在单台阿里云服务器上隔离并运行多个不同技术栈的网站。这种方案不仅节省成本,还便于通过 Git 管理配置和一键重启服务。
CLOUD云计算