部署上线 #
一、部署前准备 #
1.1 环境变量 #
.env.production:
text
NODE_ENV=production
PORT=3000
DATABASE_URL=mongodb://localhost:27017/myapp
JWT_SECRET=your-production-secret
JWT_EXPIRES_IN=7d
1.2 安全检查清单 #
- [ ] 移除敏感信息
- [ ] 设置环境变量
- [ ] 启用HTTPS
- [ ] 配置CORS
- [ ] 设置安全头
- [ ] 启用日志记录
二、PM2部署 #
2.1 安装PM2 #
bash
npm install pm2 -g
2.2 配置文件 #
ecosystem.config.js:
javascript
module.exports = {
apps: [{
name: 'my-app',
script: './server.js',
instances: 'max',
exec_mode: 'cluster',
autorestart: true,
watch: false,
max_memory_restart: '1G',
env: {
NODE_ENV: 'development'
},
env_production: {
NODE_ENV: 'production'
},
error_file: './logs/error.log',
out_file: './logs/out.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss'
}]
};
2.3 启动命令 #
bash
pm2 start ecosystem.config.js --env production
pm2 save
pm2 startup
2.4 常用命令 #
bash
pm2 list
pm2 logs
pm2 monit
pm2 restart all
pm2 reload all
pm2 stop all
pm2 delete all
三、Docker部署 #
3.1 Dockerfile #
dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
USER node
CMD ["node", "server.js"]
3.2 docker-compose.yml #
yaml
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=mongodb://mongo:27017/myapp
depends_on:
- mongo
- redis
restart: always
mongo:
image: mongo:6
volumes:
- mongo_data:/data/db
restart: always
redis:
image: redis:7-alpine
volumes:
- redis_data:/data
restart: always
volumes:
mongo_data:
redis_data:
3.3 构建和运行 #
bash
docker-compose build
docker-compose up -d
docker-compose logs -f
docker-compose down
四、Nginx配置 #
4.1 反向代理 #
/etc/nginx/sites-available/myapp:
nginx
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$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;
location / {
proxy_pass http://localhost: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;
}
location /static/ {
alias /var/www/myapp/public/;
expires 30d;
add_header Cache-Control "public, immutable";
}
}
4.2 启用配置 #
bash
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
五、SSL证书 #
5.1 Let’s Encrypt #
bash
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
5.2 自动续期 #
bash
sudo certbot renew --dry-run
六、云平台部署 #
6.1 Heroku #
Procfile:
text
web: node server.js
部署命令:
bash
heroku create my-app
heroku config:set DATABASE_URL=xxx
git push heroku main
6.2 Vercel #
vercel.json:
json
{
"version": 2,
"builds": [
{ "src": "server.js", "use": "@vercel/node" }
],
"routes": [
{ "src": "/(.*)", "dest": "/server.js" }
]
}
6.3 AWS #
使用Elastic Beanstalk或EC2:
bash
eb init
eb create production
eb deploy
七、CI/CD #
7.1 GitHub Actions #
.github/workflows/deploy.yml:
yaml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- run: npm ci
- run: npm test
- name: Deploy to server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.SSH_KEY }}
script: |
cd /var/www/myapp
git pull
npm ci --production
pm2 reload all
八、监控和日志 #
8.1 PM2监控 #
bash
pm2 monit
pm2 plus
8.2 日志管理 #
javascript
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json()
),
transports: [
new winston.transports.File({ filename: 'error.log', level: 'error' }),
new winston.transports.File({ filename: 'combined.log' })
]
});
if (process.env.NODE_ENV !== 'production') {
logger.add(new winston.transports.Console({
format: winston.format.simple()
}));
}
module.exports = logger;
8.3 APM工具 #
bash
npm install newrelic
newrelic.js:
javascript
exports.config = {
app_name: ['My App'],
license_key: 'your-license-key',
logging: {
level: 'info'
}
};
九、性能优化 #
9.1 启用压缩 #
javascript
const compression = require('compression');
app.use(compression());
9.2 静态文件缓存 #
javascript
app.use(express.static('public', {
maxAge: '1y',
etag: true
}));
9.3 数据库连接池 #
javascript
mongoose.connect(process.env.DATABASE_URL, {
maxPoolSize: 10,
minPoolSize: 2
});
十、总结 #
部署要点:
| 步骤 | 说明 |
|---|---|
| 环境准备 | 环境变量、安全检查 |
| 进程管理 | PM2集群模式 |
| 容器化 | Docker部署 |
| 反向代理 | Nginx配置 |
| HTTPS | SSL证书 |
| CI/CD | 自动化部署 |
| 监控 | 日志、APM |
恭喜你完成了Express.js的学习之旅!
最后更新:2026-03-28