在阿里云服务器上通过 Docker 部署多个网站是非常常见且高效的做法。核心思路是利用 Docker Compose 进行编排,结合 Nginx(作为反向X_X)来根据域名将流量分发到不同的容器服务中。
以下是完整的实施步骤和最佳实践方案:
1. 核心架构设计
我们不需要为每个网站单独启动一个 Nginx 容器。通常采用以下架构:
- Web 应用容器:每个网站运行在自己的独立容器中(如 Node.js, Python, PHP, Java 等)。
- Nginx 反向X_X容器:只启动一个 Nginx 容器,配置
server_name匹配不同域名,并将请求转发给对应的 Web 应用容器。 - 数据持久化:使用 Docker Volume 挂载代码、日志或数据库文件,防止容器删除后数据丢失。
2. 具体实施步骤
第一步:准备环境
确保你的阿里云 ECS 已安装 Docker 和 Docker Compose。
# 检查版本
docker --version
docker compose version # 如果提示未找到,可能需要安装 docker-compose-plugin
第二步:创建项目目录结构
在服务器上新建一个工作目录,例如 /opt/docker-sites,并规划好结构:
/opt/docker-sites/
├── docker-compose.yml # 编排文件
├── nginx/ # Nginx 配置文件目录
│ └── default.conf # 虚拟主机配置
├── site-a/ # 网站 A 的数据/代码
│ └── app/
└── site-b/ # 网站 B 的数据/代码
└── app/
第三步:编写 Docker Compose 文件
创建一个 docker-compose.yml,定义 Nginx 和各个网站服务。假设你有两个网站:example.com (Node.js) 和 blog.example.com (Python)。
version: '3.8'
services:
# 1. Nginx 反向X_X层
nginx:
image: nginx:alpine
container_name: web-proxy
ports:
- "80:80"
- "443:443" # 如果有 SSL 证书
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
- ./nginx/ssl:/etc/nginx/ssl # 可选:存放证书
depends_on:
- site-a
- site-b
networks:
- my-network
# 2. 网站 A (Node.js 示例)
site-a:
build: ./site-a/app
container_name: node-app
networks:
- my-network
# 内部端口由代码决定,这里假设是 3000
expose:
- "3000"
# 3. 网站 B (Python Flask 示例)
site-b:
build: ./site-b/app
container_name: flask-app
networks:
- my-network
expose:
- "5000"
networks:
my-network:
driver: bridge
第四步:配置 Nginx 虚拟主机
这是最关键的一步。你需要编辑 ./nginx/default.conf,告诉 Nginx 哪个域名对应哪个后端容器。
upstream site_a_backend {
server site-a:3000; # 这里的 name 必须与 docker-compose.yml 中的 service name 一致
}
upstream site_b_backend {
server site-b:5000;
}
server {
listen 80;
server_name example.com www.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;
}
}
server {
listen 80;
server_name blog.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;
}
}
注意:Nginx 容器内的
site-a和site-b是通过 Docker 网络自动解析的,不需要写 IP 地址。
第五步:启动服务
在项目目录下执行:
docker compose up -d --build
-d: 后台运行。--build: 强制重新构建镜像(如果你修改了 Dockerfile)。
查看状态:
docker compose ps
3. 阿里云特有配置建议
为了让外部用户能访问,你还需要做以下阿里云层面的配置:
A. 安全组设置
登录阿里云控制台 -> ECS 实例 -> 安全组。
- 确保入方向规则允许 80 (HTTP) 和 443 (HTTPS) 端口。
- 如果测试阶段需要 SSH,确保 22 端口开放。
B. DNS 解析
在你的域名服务商处(如阿里云云解析 DNS)添加记录:
A记录:example.com-> 指向你的阿里云服务器公网 IP。A记录:www.example.com-> 指向你的阿里云服务器公网 IP。A记录:blog.example.com-> 指向你的阿里云服务器公网 IP。
C. 获取 HTTPS 证书(生产环境必做)
推荐使用 Certbot 在宿主机或 Docker 中申请 Let’s Encrypt 免费证书。
最简单的做法是在宿主机安装 certbot 并配合 Nginx 插件,或者在 Docker 中挂载卷运行 certbot。
推荐流程:在宿主机运行 certbot certonly --standalone -d example.com -d blog.example.com,然后将生成的证书路径挂载到 Nginx 容器中,并配置 Nginx 的 SSL 部分。
4. 进阶优化建议
- 日志管理:
不要直接在容器里看日志。可以在docker-compose.yml中配置logging驱动,或者将日志输出到宿主机指定目录方便统一收集(如 ELK 栈)。 - 环境变量隔离:
使用.env文件管理不同网站的数据库连接串、API Key 等敏感信息,避免硬编码在代码中。 - 定期备份:
对于数据库(MySQL/PostgreSQL),务必使用 Docker Volume 挂载到宿主机,并编写脚本定期备份这些卷中的数据。 - CI/CD 集成:
可以结合 GitHub Actions 或 GitLab CI,当代码推送时自动构建镜像并更新容器,实现自动化部署。
总结
通过 Docker Compose + Nginx 反向X_X 的模式,你可以在一台阿里云服务器上低成本、高隔离地运行任意数量的网站。只要确保每个网站的服务名在 Compose 文件中唯一,并在 Nginx 配置中正确映射域名即可。
轻量云Cloud