Koa部署实战:Docker、PM2、Nginx全方位部署指南
前言
还在为Koa应用的生产环境部署而烦恼吗?面对复杂的服务器配置、进程管理、负载均衡等问题,很多开发者感到无从下手。本文将为你提供一套完整的Koa应用部署解决方案,涵盖Docker容器化、PM2进程管理和Nginx反向代理三大核心部署方式,助你轻松应对各种生产环境挑战。
通过本文,你将掌握:
- ✅ Koa应用生产环境最佳实践配置
- ✅ Docker容器化部署完整流程
- ✅ PM2进程管理与监控方案
- ✅ Nginx负载均衡与SSL配置
- ✅ 多环境部署策略与自动化脚本
Koa应用生产环境准备
环境要求检查
Koa 3.0+ 要求Node.js版本≥18,首先确保生产环境满足要求:
# 检查Node.js版本
node --version
# 检查npm版本
npm --version
生产环境依赖优化
在部署前,需要优化package.json配置:
{
"name": "koa-app",
"version": "1.0.0",
"description": "Koa production application",
"main": "app.js",
"scripts": {
"start": "node app.js",
"dev": "nodemon app.js",
"test": "jest",
"build": "npm run lint && npm test",
"lint": "eslint .",
"clean": "rm -rf node_modules && rm -f package-lock.json"
},
"engines": {
"node": ">=18.0.0",
"npm": ">=8.0.0"
},
"dependencies": {
"koa": "^3.0.0",
"koa-router": "^12.0.0",
"koa-bodyparser": "^4.4.0",
"koa-static": "^5.0.0",
"koa-helmet": "^7.0.0",
"koa-compress": "^5.1.0"
},
"devDependencies": {
"nodemon": "^3.0.0",
"eslint": "^8.0.0",
"jest": "^29.0.0"
}
}
生产环境应用配置
创建生产环境专用的配置文件:
// config/production.js
module.exports = {
// 服务器配置
server: {
port: process.env.PORT || 3000,
host: '0.0.0.0',
trustProxy: true
},
// 日志配置
logging: {
level: 'info',
file: '/var/log/koa-app/app.log',
rotation: {
size: '10m',
interval: '1d',
compress: true
}
},
// 安全配置
security: {
cors: {
origin: process.env.ALLOWED_ORIGINS || '*',
credentials: true
},
rateLimit: {
windowMs: 15 * 60 * 1000, // 15分钟
max: 100 // 每个IP限制100次请求
}
},
// 数据库配置
database: {
url: process.env.DATABASE_URL,
pool: {
max: 20,
min: 5,
acquire: 30000,
idle: 10000
}
}
};
Docker容器化部署
Dockerfile配置
创建优化的Dockerfile:
# 使用官方Node.js镜像
FROM node:18-alpine
# 设置工作目录
WORKDIR /app
# 复制package.json和package-lock.json
COPY package*.json ./
# 安装依赖(区分生产环境和开发环境)
RUN npm ci --only=production && \
npm cache clean --force
# 复制应用代码
COPY . .
# 创建非root用户
RUN addgroup -g 1001 -S nodejs && \
adduser -S koa -u 1001
# 更改文件所有权
RUN chown -R koa:nodejs /app
# 切换到非root用户
USER koa
# 暴露端口
EXPOSE 3000
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
# 启动应用
CMD ["node", "app.js"]
Docker Compose配置
创建docker-compose.yml用于多服务部署:
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- PORT=3000
- DATABASE_URL=postgresql://user:pass@db:5432/koaapp
depends_on:
- db
restart: unless-stopped
networks:
- koa-network
db:
image: postgres:15-alpine
environment:
- POSTGRES_DB=koaapp
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
volumes:
- postgres_data:/var/lib/postgresql/data
restart: unless-stopped
networks:
- koa-network
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./ssl:/etc/nginx/ssl
depends_on:
- app
restart: unless-stopped
networks:
- koa-network
volumes:
postgres_data:
networks:
koa-network:
driver: bridge
构建和运行脚本
创建部署脚本:
#!/bin/bash
# deploy.sh
# 设置变量
APP_NAME="koa-app"
VERSION="1.0.0"
DOCKER_REGISTRY="your-registry.com"
# 构建Docker镜像
echo "Building Docker image..."
docker build -t ${APP_NAME}:${VERSION} .
# 打标签
docker tag ${APP_NAME}:${VERSION} ${DOCKER_REGISTRY}/${APP_NAME}:${VERSION}
docker tag ${APP_NAME}:${VERSION} ${DOCKER_REGISTRY}/${APP_NAME}:latest
# 推送镜像
echo "Pushing image to registry..."
docker push ${DOCKER_REGISTRY}/${APP_NAME}:${VERSION}
docker push ${DOCKER_REGISTRY}/${APP_NAME}:latest
# 部署到服务器
echo "Deploying to production..."
ssh user@production-server << EOF
docker pull ${DOCKER_REGISTRY}/${APP_NAME}:latest
docker-compose down
docker-compose up -d
docker system prune -f
EOF
echo "Deployment completed successfully!"
PM2进程管理部署
PM2配置文件
创建ecosystem.config.js:
module.exports = {
apps: [{
name: 'koa-app',
script: 'app.js',
instances: 'max',
exec_mode: 'cluster',
env: {
NODE_ENV: 'development',
PORT: 3000
},
env_production: {
NODE_ENV: 'production',
PORT: 3000
},
// 日志配置
log_file: '/var/log/koa-app/combined.log',
out_file: '/var/log/koa-app/out.log',
error_file: '/var/log/koa-app/error.log',
// 进程管理
autorestart: true,
watch: false,
max_memory_restart: '1G',
// 高级配置
node_args: '--max-old-space-size=4096',
ignore_watch: [
'node_modules',
'logs',
'.git'
],
// 环境变量
env: {
PORT: 3000,
NODE_ENV: 'production'
}
}],
// 部署配置
deploy: {
production: {
user: 'deploy',
host: ['server1.example.com', 'server2.example.com'],
ref: 'origin/main',
repo: 'git@github.com:user/koa-app.git',
path: '/var/www/koa-app',
'post-deploy': 'npm install && pm2 reload ecosystem.config.js --env production',
env: {
NODE_ENV: 'production'
}
}
}
};
PM2部署脚本
#!/bin/bash
# pm2-deploy.sh
# 设置环境
ENV=${1:-production}
APP_NAME="koa-app"
echo "Starting deployment for $APP_NAME in $ENV environment..."
# 安装依赖
npm install --production
# 停止现有应用
pm2 delete $APP_NAME 2>/dev/null || true
# 启动应用
pm2 start ecosystem.config.js --env $ENV
# 保存PM2配置
pm2 save
# 设置开机自启
pm2 startup
# 监控应用状态
echo "Application status:"
pm2 show $APP_NAME
echo "Deployment completed. Monitoring logs:"
pm2 logs $APP_NAME --lines 20
PM2监控和运维
# 查看应用状态
pm2 status
# 监控实时日志
pm2 logs koa-app
# 查看应用信息
pm2 show koa-app
# 重启应用
pm2 restart koa-app
# 重载应用(零停机部署)
pm2 reload koa-app
# 监控资源使用
pm2 monit
# 生成启动脚本
pm2 startup
# 保存当前进程列表
pm2 save
# 列出所有进程
pm2 list
# 停止所有应用
pm2 stop all
# 删除应用
pm2 delete koa-app
Nginx反向代理配置
Nginx主配置文件
创建nginx.conf:
# /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
http {
# 基础配置
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
# 性能优化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
# Gzip压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss application/atom+xml image/svg+xml;
# 上传限制
client_max_body_size 100M;
client_body_buffer_size 128k;
# 包含服务器配置
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Koa应用服务器配置
创建koa-app.conf:
# /etc/nginx/conf.d/koa-app.conf
upstream koa_servers {
# 负载均衡配置
server 127.0.0.1:3000 weight=1;
server 127.0.0.1:3001 weight=1;
server 127.0.0.1:3002 weight=1;
# 会话保持(可选)
# ip_hash;
# 最少连接数
# least_conn;
# 健康检查
keepalive 32;
}
server {
listen 80;
server_name your-domain.com www.your-domain.com;
# 安全头
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# 静态文件服务
location /static/ {
alias /var/www/koa-app/static/;
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# 媒体文件
location /media/ {
alias /var/www/koa-app/uploads/;
expires 6M;
access_log off;
}
# API路由
location /api/ {
proxy_pass http://koa_servers;
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;
# 超时设置
proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
}
# 健康检查端点
location /health {
proxy_pass http://koa_servers;
access_log off;
}
# 根路径
location / {
proxy_pass http://koa_servers;
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;
}
# 错误页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
SSL证书配置
# SSL配置示例
server {
listen 443 ssl http2;
server_name your-domain.com www.your-domain.com;
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
# SSL优化
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;
# HSTS
add_header Strict-Transport-Security "max-age=63072000" always;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# 其他配置与HTTP版本相同
location / {
proxy_pass http://koa_servers;
# ... 其他代理配置
}
}
# HTTP重定向到HTTPS
server {
listen 80;
server_name your-domain.com www.your-domain.com;
return 301 https://$server_name$request_uri;
}
部署流程与最佳实践
部署流程图
环境变量管理
创建.env.production文件:
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



