教程二 · 全栈项目

个人全栈项目部署

阿里云 ECS 云服务器,支持 Node.js / Python / PHP / Java 等全栈应用,含数据库与 HTTPS

🕐 预计耗时:2–3小时 💰 月费:¥50–150 ⚡ 难度:中级 🌐 适用:前后端分离、API服务
i

核心概念:ECS 全栈部署原理

理解 Nginx 反向代理、进程管理与安全边界

反向代理(Reverse Proxy)原理

Nginx 作为反向代理时,客户端的请求先到达 Nginx,Nginx 再将请求转发给后端服务(Node.js/Python 进程),然后将响应返回给客户端。客户端始终只和 Nginx 通信,后端服务对外不可见。

概念含义作用
反向代理(Nginx)代替后端服务与客户端通信的中间层SSL 卸载、路由分发、静态文件服务
进程管理器(PM2)让 Node.js 进程在后台持续运行并在崩溃时自动重启保证服务高可用
安全组云服务器的网络防火墙,控制哪些端口对外可访问只开放 22/80/443,其他端口关闭
SSL 卸载HTTPS 加密在 Nginx 层解密,后端只处理明文 HTTP简化后端开发,集中管理证书
systemdLinux 系统级进程管理,控制服务的启动/停止/开机自启nginx、MySQL 等都通过 systemd 管理

为什么不直接把后端端口暴露给外网

Node.js 通常监听 3000 端口。如果直接开放 3000 端口对外访问,会有以下问题:

  • 用户需要输入 http://yourdomain.com:3000,体验极差
  • 无法使用标准 HTTPS(443 端口)
  • 应用崩溃后没有自动恢复机制
  • 暴露内部服务信息,增大攻击面

Nginx 监听标准的 80/443 端口,将请求转发给内网的 3000 端口。这样用户访问正常的域名和端口,Nginx 处理 HTTPS,后端只需处理业务逻辑。

⚠️
安全原则:数据库(MySQL 3306、Redis 6379)、内部服务端口绝对不能在安全组中对外开放。只允许来自同一内网(127.0.0.1 或内网 IP)的连接,否则极易遭受暴力破解攻击。

架构概览

👤
用户
浏览器
🌐
域名
DNS
🔒
Nginx
HTTPS + 反向代理
⚙️
后端服务
Node/Python/PHP
🗄️
数据库
MySQL / MongoDB
1

购买 ECS 云服务器

选择合适配置,开放必要端口

推荐配置(个人全栈项目)

配置项推荐值说明
实例规格ecs.t6-c1m2.large(2核2G)个人项目足够,可随时升配
操作系统Ubuntu 22.04 LTS 64位社区支持最好,教程最多
系统盘40GB 高效云盘存放系统和代码
网络带宽按量付费 or 5Mbps 固定访问量小用按量,大用固定
安全组开放 22/80/443 端口SSH、HTTP、HTTPS
付费方式按量付费(测试)/ 包年包月(正式)先按量测试,稳定后再包月省钱

安全组端口配置

22
SSH
远程连接服务器
80
HTTP
网站访问
443
HTTPS
加密网站访问
3000
Node.js
后端服务(可选)
8080
备用
Java/其他服务
3306
MySQL
仅本机访问,不对外开放
🔒
安全警告:MySQL (3306)、Redis (6379) 等数据库端口绝对不要开放到公网,只允许 127.0.0.1 本地访问,否则会被黑客暴力破解。
2

连接并初始化服务器

SSH 登录,更新系统,创建安全用户

SSH 连接

Terminal — 本地机器执行
# 使用密码连接(购买时设置的密码)
ssh root@你的服务器公网IP

# 使用密钥连接(推荐,更安全)
ssh -i ~/.ssh/your-key.pem root@你的服务器公网IP

# 如果提示 "WARNING: UNPROTECTED PRIVATE KEY FILE"
chmod 400 ~/.ssh/your-key.pem

初始化服务器(首次登录执行)

服务器 — 系统初始化
# 更新系统包
apt update && apt upgrade -y

# 创建普通用户(不要一直用 root!)
adduser deploy
usermod -aG sudo deploy

# 安装常用工具
apt install -y curl wget git vim unzip ufw fail2ban

# 配置防火墙
ufw allow OpenSSH
ufw allow 'Nginx Full'
ufw enable
ufw status
3

安装开发环境

根据你的技术栈选择对应安装脚本

Node.js 全栈
Express / Next.js / Nuxt 等
前端后端推荐
Python 全栈
Django / Flask / FastAPI 等
AI集成后端
PHP 全栈
Laravel / WordPress 等
后端成熟
Java 全栈
Spring Boot + Vue/React
高内存企业级

Node.js 环境安装

Terminal — Node.js 安装
# 使用 nvm 安装(推荐,方便管理版本)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
source ~/.bashrc

# 安装 Node.js LTS 版本
nvm install --lts
nvm use --lts

# 验证安装
node -v   # v20.x.x
npm -v    # 10.x.x

# 安装 PM2(进程管理器,保持后台运行)
npm install -g pm2

Python 环境安装

Terminal — Python 安装
# Ubuntu 22.04 自带 Python 3.10,确认版本
python3 --version

# 安装 pip 和 venv
apt install -y python3-pip python3-venv

# 创建虚拟环境(推荐每个项目独立环境)
cd /var/www/myproject
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

# 安装 Gunicorn(生产环境 WSGI 服务器)
pip install gunicorn

安装 MySQL 数据库

Terminal — MySQL 安装
apt install -y mysql-server
systemctl start mysql
systemctl enable mysql

# 安全初始化(设置 root 密码,移除测试库)
mysql_secure_installation

# 创建项目数据库和专用用户
mysql -u root -p
CREATE DATABASE myapp_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'myapp_user'@'localhost' IDENTIFIED BY '强密码123!';
GRANT ALL PRIVILEGES ON myapp_db.* TO 'myapp_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
4

部署项目代码

从 Git 仓库拉取代码,安装依赖,启动服务

Node.js 项目部署示例

Terminal — Node.js 部署
# 克隆代码
mkdir -p /var/www && cd /var/www
git clone https://github.com/你的用户名/你的项目.git myapp
cd myapp

# 安装依赖
npm install --production

# 创建环境变量文件
cp .env.example .env
nano .env
# 填写数据库密码、API Key 等

# 构建(如果是 Next.js / Nuxt 等)
npm run build

# 使用 PM2 启动并保持后台运行
pm2 start npm --name "myapp" -- start

# 设置开机自启
pm2 startup
pm2 save

# 查看运行状态
pm2 status
pm2 logs myapp

Python/Flask/FastAPI 项目部署示例

Terminal — Python 部署
cd /var/www/myapp
source venv/bin/activate
pip install -r requirements.txt

# 创建 Systemd 服务文件(系统级进程管理)
nano /etc/systemd/system/myapp.service
/etc/systemd/system/myapp.service
[Unit]
Description=My Flask/FastAPI App
After=network.target

[Service]
User=deploy
WorkingDirectory=/var/www/myapp
Environment="PATH=/var/www/myapp/venv/bin"
ExecStart=/var/www/myapp/venv/bin/gunicorn \
    --workers 3 \
    --bind unix:/run/myapp.sock \
    app:app

Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target
Terminal — 启动 Python 服务
systemctl daemon-reload
systemctl start myapp
systemctl enable myapp
systemctl status myapp
5

配置 Nginx 反向代理

让 Nginx 接收 80/443 请求,转发给后端服务

安装 Nginx

Terminal
apt install -y nginx
systemctl start nginx
systemctl enable nginx
# 浏览器访问服务器IP,看到 Nginx 欢迎页即成功

Nginx 站点配置(Node.js 反向代理)

/etc/nginx/sites-available/myapp
server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;

    # 前端静态文件(如果是分离部署)
    root /var/www/myapp/dist;
    index index.html;

    # 前端路由(SPA 必须配置)
    location / {
        try_files $uri $uri/ /index.html;
    }

    # API 请求转发给 Node.js 后端
    location /api/ {
        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_cache_bypass $http_upgrade;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
Terminal — 启用配置
ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
nginx -t   # 检查配置语法,必须显示 "ok"
systemctl reload nginx
6

配置 HTTPS 免费证书

Let's Encrypt 免费证书,自动续期,无需任何费用

Terminal — Let's Encrypt 证书
# 确保域名已解析到服务器 IP

# 安装 Certbot
apt install -y certbot python3-certbot-nginx

# 自动申请证书并配置 Nginx
certbot --nginx -d yourdomain.com -d www.yourdomain.com
# 按提示输入邮箱,同意协议,选择是否强制 HTTPS

# 测试自动续期
certbot renew --dry-run

# 查看证书状态
certbot certificates
证书有效期 90 天,Certbot 会通过 Cron 自动续期,完全不需要手动操作。
7

自动化部署(可选)

每次推送代码自动更新服务器,无需手动 SSH

GitHub Actions 自动部署脚本

.github/workflows/deploy.yml
name: Deploy to ECS

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Deploy to server
        uses: appleboy/ssh-action@v1.0.0
        with:
          host: ${{ secrets.SERVER_IP }}
          username: deploy
          key: ${{ secrets.SERVER_SSH_KEY }}
          script: |
            cd /var/www/myapp
            git pull origin main
            npm install --production
            npm run build
            pm2 restart myapp
💡
需要在 GitHub 仓库 Settings → Secrets 中添加 SERVER_IP 和 SERVER_SSH_KEY 两个变量。

常见误区与边界情况

⚠️
误区1:直接用 root 用户运行应用 — 应用程序不应以 root 权限运行。创建专用的 deploy 用户,应用以低权限用户运行,即使被攻击也无法获取系统控制权。
⚠️
误区2:Let's Encrypt 证书不会自动续期 — Certbot 安装后会自动创建 systemd timer 或 cron 任务,每天检查证书是否需要续期。但首次需要用 certbot renew --dry-run 确认自动续期配置正常工作。
⚠️
误区3:Nginx 配置中忘记配置 SPA 路由 — React/Vue 等单页应用需要在 Nginx 配置 try_files $uri $uri/ /index.html,否则直接访问非根路径(如 /about)会返回 404,因为这些路径只在前端路由中存在,服务器上没有对应文件。
小结:ECS 全栈部署的核心链路:SSH 连接 → 安装 Nginx/Node.js/PM2 → 部署代码 → 配置 Nginx 反向代理 → Let's Encrypt 证书 → 可选 GitHub Actions 自动部署。关键原则:不暴露数据库端口,不用 root 运行应用,HTTPS 在 Nginx 层卸载。