Browse Source

Enhance deployment process and project structure. Added deployment scripts for Windows and Linux, a comprehensive deployment guide, and Docker support. Updated .gitignore to include additional files and directories. Introduced PM2 configuration for process management and health checks for backend and frontend ser

deploy
dash 2 weeks ago
parent
commit
0f154e78bf
  1. 45
      .gitignore
  2. 366
      DEPLOY.md
  3. 264
      DEPLOYMENT-GUIDE.md
  4. 61
      README.md
  5. 17
      backend/.dockerignore
  6. 51
      backend/Dockerfile
  7. 93
      deploy.ps1
  8. 99
      deploy.sh
  9. 48
      docker-compose.yml
  10. 75
      docker-deploy.sh
  11. 56
      docker-test.bat
  12. 53
      docker-test.sh
  13. 50
      ecosystem.config.js
  14. 14
      frontend/.dockerignore
  15. 42
      frontend/Dockerfile
  16. 72
      nginx.conf
  17. 9
      package.json

45
.gitignore

@ -1,12 +1,45 @@
# 依赖
node_modules/ node_modules/
pnpm-lock.yaml
# 构建产物
dist/ dist/
*.log build/
# 环境变量
.env .env
.DS_Store .env.local
database/*.sqlite3 .env.production
uploads/ .env.development
# 日志
logs/
*.log
npm-debug.log*
pnpm-debug.log*
# 数据库
*.sqlite3
*.sqlite
*.db
# PM2
.pm2/
# IDE
.vscode/ .vscode/
.idea/ .idea/
backup/ *.swp
*.zip *.swo
*~
# 系统文件
.DS_Store
Thumbs.db
# 上传文件
uploads/
# 临时文件
tmp/
temp/

366
DEPLOY.md

@ -0,0 +1,366 @@
# 部署指南
本项目提供多种部署方式,推荐使用 **PM2 一键部署**,简单快捷。
## 🚀 方案一:PM2 一键部署(推荐)
最简单的部署方式,适合 VPS、云服务器等场景。
### Windows 部署
```powershell
# 1. 运行部署脚本
.\deploy.ps1
```
### Linux/macOS 部署
```bash
# 1. 添加执行权限
chmod +x deploy.sh
# 2. 运行部署脚本
./deploy.sh
```
### 部署脚本会自动完成:
1. ✅ 检查并安装必要工具(Node.js、pnpm、PM2)
2. ✅ 安装项目依赖
3. ✅ 构建前后端项目
4. ✅ 创建生产环境配置
5. ✅ 运行数据库迁移
6. ✅ 使用 PM2 启动服务
7. ✅ 配置开机自启动
### 常用命令
```bash
# 查看服务状态
pm2 status
# 查看日志
pm2 logs
# 查看指定服务日志
pm2 logs just-demo-backend
pm2 logs just-demo-frontend
# 重启服务
pm2 restart all
pm2 restart just-demo-backend
# 停止服务
pm2 stop all
# 删除服务
pm2 delete all
```
### 访问地址
部署成功后,可通过以下地址访问:
- 前端:http://localhost:5500
- 后端:http://localhost:3000
---
## 🐳 方案二:Docker Compose 部署
适合需要容器化部署的场景。
### 1. 创建 Dockerfile
**backend/Dockerfile:**
```dockerfile
FROM node:18-alpine
WORKDIR /app
# 安装 pnpm
RUN npm install -g pnpm
# 复制依赖文件
COPY package.json pnpm-lock.yaml ./
# 安装依赖
RUN pnpm install --prod
# 复制构建产物
COPY dist ./dist
COPY database ./database
COPY knexfile.js ./
# 创建上传目录
RUN mkdir -p uploads
EXPOSE 3000
CMD ["node", "dist/app.js"]
```
**frontend/Dockerfile:**
```dockerfile
FROM node:18-alpine
WORKDIR /app
# 安装 serve
RUN npm install -g serve
# 复制构建产物
COPY dist ./dist
EXPOSE 5500
CMD ["serve", "dist", "-p", "5500", "-s"]
```
### 2. 创建 docker-compose.yml
```yaml
version: '3.8'
services:
backend:
build:
context: ./backend
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- PORT=3000
- JWT_SECRET=${JWT_SECRET}
- FRONTEND_URL=http://localhost:5500
volumes:
- ./backend/database:/app/database
- ./backend/uploads:/app/uploads
restart: always
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
ports:
- "5500:5500"
depends_on:
- backend
restart: always
```
### 3. 部署
```bash
# 构建项目
pnpm build
# 启动容器
docker-compose up -d
# 查看日志
docker-compose logs -f
# 停止容器
docker-compose down
```
---
## ☁️ 方案三:云平台部署
### 3.1 Vercel + Railway
**前端部署到 Vercel:**
1. 在 Vercel 导入项目
2. 设置构建配置:
- Build Command: `cd frontend && pnpm install && pnpm build`
- Output Directory: `frontend/dist`
**后端部署到 Railway:**
1. 在 Railway 创建新项目
2. 连接 GitHub 仓库
3. 设置环境变量:
```
NODE_ENV=production
PORT=3000
JWT_SECRET=your-secret-key
FRONTEND_URL=your-vercel-url
```
### 3.2 Render
1. 在 Render 创建 Web Service
2. 后端配置:
- Build Command: `cd backend && pnpm install && pnpm build`
- Start Command: `cd backend && node dist/app.js`
3. 前端配置:
- Build Command: `cd frontend && pnpm install && pnpm build`
- Publish Directory: `frontend/dist`
---
## 📝 生产环境配置
### 必要的环境变量
`backend/.env` 文件中配置:
```env
NODE_ENV=production
PORT=3000
JWT_SECRET=你的超级密钥-至少32字符
FRONTEND_URL=http://your-frontend-domain.com
UPLOAD_DIR=uploads
```
### 生成安全的 JWT_SECRET
```bash
# Linux/macOS
openssl rand -base64 32
# Windows PowerShell
[Convert]::ToBase64String((1..32 | ForEach-Object { Get-Random -Maximum 256 }))
```
---
## 🔒 安全建议
1. **修改 JWT_SECRET**:不要使用默认密钥
2. **配置 HTTPS**:使用 nginx + Let's Encrypt
3. **限制文件上传大小**:防止恶意上传
4. **定期备份数据库**:备份 `backend/database/*.sqlite3`
5. **配置防火墙**:只开放必要端口
---
## 🌐 使用 Nginx 反向代理(可选)
### 安装 Nginx
```bash
# Ubuntu/Debian
sudo apt update
sudo apt install nginx
# CentOS/RHEL
sudo yum install nginx
```
### 配置文件
创建 `/etc/nginx/sites-available/just-demo`:
```nginx
server {
listen 80;
server_name your-domain.com;
# 前端
location / {
proxy_pass http://localhost:5500;
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;
}
# 后端 API
location /api {
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;
}
}
```
### 启用配置
```bash
sudo ln -s /etc/nginx/sites-available/just-demo /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
```
---
## 🔧 故障排查
### 服务无法启动
```bash
# 查看详细日志
pm2 logs --lines 100
# 检查端口占用
# Linux/macOS
lsof -i :3000
# Windows
netstat -ano | findstr :3000
```
### 数据库错误
```bash
# 重新运行迁移
cd backend
pnpm migrate:rollback:prod
pnpm migrate:prod
```
### 前端无法访问后端
检查 `backend/.env` 中的 `FRONTEND_URL` 配置是否正确。
---
## 📊 性能优化
1. **启用 PM2 集群模式**:充分利用多核 CPU
2. **配置 Nginx 缓存**:加快静态资源访问
3. **使用 CDN**:加速前端资源加载
4. **定期清理日志**:防止日志文件过大
---
## 🔄 更新部署
```bash
# 1. 拉取最新代码
git pull
# 2. 重新构建
pnpm build
# 3. 重启服务
pm2 restart all
# 或使用部署脚本
./deploy.sh
```
---
## 📞 技术支持
如遇问题,请检查:
1. Node.js 版本是否 >= 16
2. 端口 3000 和 5500 是否被占用
3. 数据库文件是否有读写权限
4. 环境变量是否配置正确

264
DEPLOYMENT-GUIDE.md

@ -0,0 +1,264 @@
# 部署方案快速对比
选择最适合你的部署方式 🚀
## 📊 方案对比
| 方案 | 难度 | 适用场景 | 优点 | 缺点 |
|------|------|---------|------|------|
| **PM2 一键部署** ⭐推荐 | ⭐ 简单 | VPS、云服务器 | 最简单、一键部署、进程管理 | 需要服务器 |
| **Docker Compose** | ⭐⭐ 中等 | 容器化需求 | 环境隔离、易迁移 | 需要学习 Docker |
| **云平台部署** | ⭐ 简单 | 快速上线 | 免费额度、自动扩展 | 可能有费用 |
| **传统部署** | ⭐⭐⭐ 复杂 | 完全自定义 | 完全控制 | 配置复杂 |
---
## 🎯 方案一:PM2 一键部署(最简单)
### 适用场景
- ✅ 你有一台 VPS 或云服务器
- ✅ 想要最快速的部署方式
- ✅ 需要进程管理和自动重启
- ✅ 想要开机自启动
### 部署步骤
#### Windows
```powershell
# 一行命令搞定
.\deploy.ps1
```
#### Linux/macOS
```bash
# 一行命令搞定
chmod +x deploy.sh && ./deploy.sh
```
### 特点
- ⚡ **部署时间**: 3-5 分钟
- 🎯 **一键完成**: 自动安装、构建、启动
- 🔄 **自动重启**: 崩溃自动恢复
- 📊 **进程监控**: PM2 提供完整的监控
- 🚀 **开机自启**: 服务器重启自动启动
### 访问地址
- 前端:`http://你的服务器IP:5500`
- 后端:`http://你的服务器IP:3000`
---
## 🐳 方案二:Docker 部署
### 适用场景
- ✅ 需要环境隔离
- ✅ 多个项目部署
- ✅ 需要容器编排
- ✅ 跨平台部署
### 部署步骤
```bash
# 一键 Docker 部署
chmod +x docker-deploy.sh && ./docker-deploy.sh
# 或手动部署
docker-compose up -d
```
### 特点
- ⚡ **部署时间**: 5-10 分钟(首次构建)
- 📦 **环境隔离**: 不污染宿主机环境
- 🔧 **易迁移**: 可在任何支持 Docker 的环境运行
- 🔄 **自动重启**: 容器崩溃自动恢复
---
## ☁️ 方案三:云平台部署
### 3.1 Vercel(前端)+ Railway(后端)
#### 前端部署到 Vercel
1. Fork/导入项目到 GitHub
2. 在 Vercel 导入仓库
3. 配置构建:
```
Root Directory: frontend
Build Command: pnpm install && pnpm build
Output Directory: dist
```
#### 后端部署到 Railway
1. 在 Railway 创建新项目
2. 连接 GitHub 仓库
3. 设置环境变量(自动生成)
4. 自动部署
### 特点
- ⚡ **部署时间**: 5-10 分钟
- 💰 **免费额度**: 都有免费版本
- 🌍 **全球 CDN**: 访问速度快
- 🔄 **自动部署**: Git push 自动部署
---
### 3.2 Render(All-in-One)
#### 一站式部署
1. 注册 Render 账号
2. 连接 GitHub 仓库
3. 创建两个 Web Services:
- **Backend**:
- Build: `cd backend && pnpm install && pnpm build`
- Start: `cd backend && node dist/app.js`
- **Frontend**:
- Build: `cd frontend && pnpm install && pnpm build`
- Static Site
- Publish: `frontend/dist`
### 特点
- ⚡ **部署时间**: 10-15 分钟
- 💰 **免费计划**: 每月有免费额度
- 🔄 **自动部署**: Git push 触发
- 🔒 **免费 SSL**: 自动配置 HTTPS
---
## 🎮 方案四:手动部署
### 适用场景
- ✅ 需要完全自定义配置
- ✅ 学习部署流程
- ✅ 特殊环境要求
### 部署步骤
```bash
# 1. 克隆项目
git clone <your-repo>
cd just-demo
# 2. 安装依赖
pnpm install:all
# 3. 构建
pnpm build
# 4. 配置环境变量
cp backend/.env.example backend/.env
# 编辑 backend/.env
# 5. 数据库迁移
cd backend && pnpm migrate:prod && cd ..
# 6. 启动后端
cd backend && node dist/app.js &
# 7. 启动前端
cd frontend && npx serve dist -p 5500 &
```
---
## 🔧 配置 Nginx 反向代理(可选)
如果你使用 PM2 或手动部署,可以配置 Nginx:
```bash
# 1. 安装 Nginx
sudo apt install nginx # Ubuntu/Debian
# 2. 配置
sudo cp nginx.conf /etc/nginx/sites-available/just-demo
sudo ln -s /etc/nginx/sites-available/just-demo /etc/nginx/sites-enabled/
# 3. 修改域名
sudo nano /etc/nginx/sites-available/just-demo
# 将 your-domain.com 改为你的域名
# 4. 重启 Nginx
sudo nginx -t
sudo systemctl reload nginx
```
---
## 📱 快速决策指南
### 我该选哪个方案?
#### 🏃 我想最快部署
→ **选择 PM2 一键部署**
```bash
# Windows
.\deploy.ps1
# Linux/macOS
./deploy.sh
```
#### 💰 我没有服务器/想省钱
→ **选择云平台部署**
- Vercel(前端免费)
- Railway(后端有免费额度)
- Render(全栈免费)
#### 🐳 我想要容器化
→ **选择 Docker 部署**
```bash
./docker-deploy.sh
```
#### 🎓 我想学习部署流程
→ **选择手动部署**
- 完整了解每个步骤
- 便于排查问题
---
## 🆘 遇到问题?
### PM2 方案
```bash
pm2 logs # 查看日志
pm2 status # 查看状态
pm2 restart all # 重启服务
```
### Docker 方案
```bash
docker-compose logs -f # 查看日志
docker-compose ps # 查看状态
docker-compose restart # 重启服务
```
### 云平台
- 查看部署日志
- 检查环境变量
- 查看服务状态
---
## 📚 详细文档
- [完整部署指南](./DEPLOY.md)
- [项目说明](./README.md)
---
## 🎉 开始部署
选择一个方案,立即开始:
```bash
# PM2(推荐)
./deploy.sh # Linux/macOS
.\deploy.ps1 # Windows
# Docker
./docker-deploy.sh
# 查看详细文档
cat DEPLOY.md
```

61
README.md

@ -11,16 +11,13 @@
## 快速开始 ## 快速开始
### 安装依赖 ### 开发环境
```bash ```bash
# 1. 安装依赖
pnpm install:all pnpm install:all
```
### 开发
```bash # 2. 启动开发服务器
# 同时启动前后端
pnpm dev pnpm dev
# 或分别启动 # 或分别启动
@ -28,12 +25,62 @@ pnpm dev:backend # 后端:http://localhost:3000
pnpm dev:frontend # 前端:http://localhost:5173 pnpm dev:frontend # 前端:http://localhost:5173
``` ```
### 构建 ### 生产部署 🚀
#### 一键部署(推荐)
**Windows:**
```powershell
.\deploy.ps1
```
**Linux/macOS:**
```bash
chmod +x deploy.sh
./deploy.sh
```
部署脚本会自动完成:
- ✅ 检查并安装必要工具(Node.js、pnpm、PM2)
- ✅ 安装项目依赖
- ✅ 构建前后端项目
- ✅ 创建生产环境配置
- ✅ 运行数据库迁移
- ✅ 使用 PM2 启动服务
- ✅ 配置开机自启动
部署成功后访问:
- 前端:http://localhost:5500
- 后端:http://localhost:3000
#### 手动部署
```bash ```bash
# 1. 构建项目
pnpm build pnpm build
# 2. 创建环境配置
cp backend/.env.example backend/.env
# 编辑 backend/.env 修改配置
# 3. 运行数据库迁移
cd backend && pnpm migrate:prod && cd ..
# 4. 启动服务
pnpm start
``` ```
#### 常用命令
```bash
pm2 status # 查看服务状态
pm2 logs # 查看日志
pm2 restart all # 重启服务
pm2 stop all # 停止服务
```
📖 详细部署说明请查看 [DEPLOY.md](./DEPLOY.md)
## 项目结构 ## 项目结构
``` ```

17
backend/.dockerignore

@ -0,0 +1,17 @@
node_modules
npm-debug.log
pnpm-debug.log
dist
build
.git
.gitignore
*.md
.env
.env.local
.vscode
.idea
*.log
uploads
database/*.sqlite3
database/*.db

51
backend/Dockerfile

@ -0,0 +1,51 @@
FROM node:18-alpine AS builder
WORKDIR /app
# 安装 pnpm
RUN npm install -g pnpm
# 复制依赖文件
COPY package.json pnpm-lock.yaml ./
# 安装依赖
RUN pnpm install --frozen-lockfile
# 复制源代码
COPY . .
# 构建
RUN pnpm build
# 生产阶段
FROM node:18-alpine
WORKDIR /app
# 安装必要工具
RUN apk add --no-cache wget && \
npm install -g pnpm
# 只安装生产依赖
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --prod --frozen-lockfile
# 复制构建产物和必要文件
COPY --from=builder /app/dist ./dist
COPY knexfile.js ./
# 创建必要的目录
RUN mkdir -p uploads database && \
chown -R node:node /app
# 使用非 root 用户
USER node
EXPOSE 3000
# 健康检查
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
CMD wget --quiet --tries=1 --spider http://localhost:3000/api/health || exit 1
CMD ["node", "dist/app.js"]

93
deploy.ps1

@ -0,0 +1,93 @@
# 一键部署脚本 - Windows PowerShell
# 使用方法: .\deploy.ps1
$ErrorActionPreference = "Stop"
Write-Host "🚀 开始部署 Just-Demo 项目..." -ForegroundColor Cyan
# 1. 检查 Node.js
Write-Host "`n📦 检查 Node.js..." -ForegroundColor Blue
if (-not (Get-Command node -ErrorAction SilentlyContinue)) {
Write-Host "❌ Node.js 未安装,请先安装 Node.js (v16+)" -ForegroundColor Red
Write-Host "下载地址: https://nodejs.org/" -ForegroundColor Yellow
exit 1
}
Write-Host "✅ Node.js 版本: $(node -v)" -ForegroundColor Green
# 2. 检查 pnpm,如果没有则安装
Write-Host "`n📦 检查 pnpm..." -ForegroundColor Blue
if (-not (Get-Command pnpm -ErrorAction SilentlyContinue)) {
Write-Host "pnpm 未安装,正在安装..." -ForegroundColor Yellow
npm install -g pnpm
}
Write-Host "✅ pnpm 版本: $(pnpm -v)" -ForegroundColor Green
# 3. 检查 PM2,如果没有则安装
Write-Host "`n📦 检查 PM2..." -ForegroundColor Blue
if (-not (Get-Command pm2 -ErrorAction SilentlyContinue)) {
Write-Host "PM2 未安装,正在安装..." -ForegroundColor Yellow
npm install -g pm2
npm install -g pm2-windows-startup
pm2-startup install
}
Write-Host "✅ PM2 已安装" -ForegroundColor Green
# 4. 安装依赖
Write-Host "`n📦 安装项目依赖..." -ForegroundColor Blue
pnpm install:all
# 5. 构建项目
Write-Host "`n🔨 构建项目..." -ForegroundColor Blue
pnpm build
# 6. 创建生产环境配置
Write-Host "`n⚙️ 创建生产环境配置..." -ForegroundColor Blue
if (-not (Test-Path "backend\.env")) {
# 生成随机密钥
$bytes = New-Object byte[] 32
$rng = [System.Security.Cryptography.RandomNumberGenerator]::Create()
$rng.GetBytes($bytes)
$jwtSecret = [Convert]::ToBase64String($bytes)
@"
NODE_ENV=production
PORT=3000
JWT_SECRET=$jwtSecret
FRONTEND_URL=http://localhost:5500
UPLOAD_DIR=uploads
"@ | Out-File -FilePath "backend\.env" -Encoding UTF8
Write-Host "✅ 已创建 backend\.env" -ForegroundColor Green
} else {
Write-Host "✅ backend\.env 已存在" -ForegroundColor Green
}
# 7. 运行数据库迁移
Write-Host "`n🗄️ 运行数据库迁移..." -ForegroundColor Blue
Set-Location backend
pnpm migrate:prod
Set-Location ..
# 8. 使用 PM2 启动服务
Write-Host "`n🚀 使用 PM2 启动服务..." -ForegroundColor Blue
pm2 delete just-demo-backend 2>$null
pm2 start ecosystem.config.js
# 9. 保存 PM2 配置
Write-Host "`n💾 保存 PM2 配置..." -ForegroundColor Blue
pm2 save
# 10. 显示服务状态
Write-Host "`n📊 服务状态:" -ForegroundColor Cyan
pm2 status
Write-Host "`n🎉 部署成功!" -ForegroundColor Green
Write-Host "`n访问地址:" -ForegroundColor Cyan
Write-Host " - 前端: http://localhost:5500" -ForegroundColor White
Write-Host " - 后端: http://localhost:3000" -ForegroundColor White
Write-Host "`n常用命令:" -ForegroundColor Cyan
Write-Host " pm2 status # 查看服务状态" -ForegroundColor White
Write-Host " pm2 logs # 查看日志" -ForegroundColor White
Write-Host " pm2 restart all # 重启所有服务" -ForegroundColor White
Write-Host " pm2 stop all # 停止所有服务" -ForegroundColor White
Write-Host ""

99
deploy.sh

@ -0,0 +1,99 @@
#!/bin/bash
# 一键部署脚本 - Linux/macOS
# 使用方法: chmod +x deploy.sh && ./deploy.sh
set -e # 遇到错误立即退出
echo "🚀 开始部署 Just-Demo 项目..."
# 颜色定义
GREEN='\033[0;32m'
BLUE='\033[0;34m'
RED='\033[0;31m'
NC='\033[0m' # No Color
# 1. 检查 Node.js
echo -e "${BLUE}📦 检查 Node.js...${NC}"
if ! command -v node &> /dev/null; then
echo -e "${RED}❌ Node.js 未安装,请先安装 Node.js (v16+)${NC}"
exit 1
fi
echo -e "${GREEN}✅ Node.js 版本: $(node -v)${NC}"
# 2. 检查 pnpm,如果没有则安装
echo -e "${BLUE}📦 检查 pnpm...${NC}"
if ! command -v pnpm &> /dev/null; then
echo "pnpm 未安装,正在安装..."
npm install -g pnpm
fi
echo -e "${GREEN}✅ pnpm 版本: $(pnpm -v)${NC}"
# 3. 检查 PM2,如果没有则安装
echo -e "${BLUE}📦 检查 PM2...${NC}"
if ! command -v pm2 &> /dev/null; then
echo "PM2 未安装,正在安装..."
npm install -g pm2
fi
echo -e "${GREEN}✅ PM2 已安装${NC}"
# 4. 安装依赖
echo -e "${BLUE}📦 安装项目依赖...${NC}"
pnpm install:all
# 5. 构建项目
echo -e "${BLUE}🔨 构建项目...${NC}"
pnpm build
# 6. 创建生产环境配置
echo -e "${BLUE}⚙️ 创建生产环境配置...${NC}"
if [ ! -f backend/.env ]; then
cat > backend/.env << EOF
NODE_ENV=production
PORT=3000
JWT_SECRET=$(openssl rand -base64 32)
FRONTEND_URL=http://localhost:5500
UPLOAD_DIR=uploads
EOF
echo -e "${GREEN}✅ 已创建 backend/.env${NC}"
else
echo -e "${GREEN}✅ backend/.env 已存在${NC}"
fi
# 7. 运行数据库迁移
echo -e "${BLUE}🗄️ 运行数据库迁移...${NC}"
cd backend
pnpm migrate:prod
cd ..
# 8. 使用 PM2 启动服务
echo -e "${BLUE}🚀 使用 PM2 启动服务...${NC}"
pm2 delete just-demo-backend 2>/dev/null || true
pm2 start ecosystem.config.js
# 9. 保存 PM2 配置(开机自启动)
echo -e "${BLUE}💾 配置 PM2 开机自启动...${NC}"
pm2 save
pm2 startup
# 10. 显示服务状态
echo ""
echo -e "${GREEN}✅ 部署完成!${NC}"
echo ""
echo "📊 服务状态:"
pm2 status
echo ""
echo -e "${GREEN}🎉 部署成功!${NC}"
echo ""
echo "访问地址:"
echo " - 前端: http://localhost:5500"
echo " - 后端: http://localhost:3000"
echo ""
echo "常用命令:"
echo " pm2 status # 查看服务状态"
echo " pm2 logs # 查看日志"
echo " pm2 restart all # 重启所有服务"
echo " pm2 stop all # 停止所有服务"
echo ""

48
docker-compose.yml

@ -0,0 +1,48 @@
version: '3.8'
services:
backend:
build:
context: ./backend
dockerfile: Dockerfile
container_name: just-demo-backend
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- PORT=3000
- JWT_SECRET=${JWT_SECRET:-your-secret-key-please-change}
- FRONTEND_URL=${FRONTEND_URL:-http://localhost:5500}
- UPLOAD_DIR=uploads
volumes:
- ./backend/database:/app/database
- ./backend/uploads:/app/uploads
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3000/api/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
container_name: just-demo-frontend
ports:
- "5500:5500"
depends_on:
- backend
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:5500"]
interval: 30s
timeout: 10s
retries: 3
start_period: 20s
networks:
default:
name: just-demo-network

75
docker-deploy.sh

@ -0,0 +1,75 @@
#!/bin/bash
# Docker 一键部署脚本
# 使用方法: chmod +x docker-deploy.sh && ./docker-deploy.sh
set -e
echo "🐳 开始 Docker 部署..."
# 颜色定义
GREEN='\033[0;32m'
BLUE='\033[0;34m'
RED='\033[0;31m'
NC='\033[0m'
# 1. 检查 Docker
echo -e "${BLUE}📦 检查 Docker...${NC}"
if ! command -v docker &> /dev/null; then
echo -e "${RED}❌ Docker 未安装${NC}"
echo "请访问 https://docs.docker.com/get-docker/ 安装 Docker"
exit 1
fi
echo -e "${GREEN}✅ Docker 版本: $(docker --version)${NC}"
# 2. 检查 Docker Compose
echo -e "${BLUE}📦 检查 Docker Compose...${NC}"
if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then
echo -e "${RED}❌ Docker Compose 未安装${NC}"
exit 1
fi
echo -e "${GREEN}✅ Docker Compose 已安装${NC}"
# 3. 创建环境配置
echo -e "${BLUE}⚙️ 创建环境配置...${NC}"
if [ ! -f .env ]; then
JWT_SECRET=$(openssl rand -base64 32)
cat > .env << EOF
JWT_SECRET=$JWT_SECRET
FRONTEND_URL=http://localhost:5500
EOF
echo -e "${GREEN}✅ 已创建 .env${NC}"
else
echo -e "${GREEN}✅ .env 已存在${NC}"
fi
# 4. 构建和启动容器
echo -e "${BLUE}🔨 构建和启动容器...${NC}"
docker-compose down
docker-compose build --no-cache
docker-compose up -d
# 5. 等待服务启动
echo -e "${BLUE}⏳ 等待服务启动...${NC}"
sleep 5
# 6. 显示容器状态
echo -e "${GREEN}✅ 部署完成!${NC}"
echo ""
echo "📊 容器状态:"
docker-compose ps
echo ""
echo -e "${GREEN}🎉 部署成功!${NC}"
echo ""
echo "访问地址:"
echo " - 前端: http://localhost:5500"
echo " - 后端: http://localhost:3000"
echo ""
echo "常用命令:"
echo " docker-compose ps # 查看容器状态"
echo " docker-compose logs -f # 查看日志"
echo " docker-compose restart # 重启服务"
echo " docker-compose down # 停止服务"
echo ""

56
docker-test.bat

@ -0,0 +1,56 @@
@echo off
echo 🐳 开始 Docker 构建测试...
echo.
echo [1/4] 检查 Docker 环境...
docker --version >nul 2>&1
if errorlevel 1 (
echo ❌ Docker 未安装或未启动
pause
exit /b 1
)
echo ✅ Docker 已就绪
echo.
echo [2/4] 停止旧容器...
docker-compose down
echo.
echo [3/4] 构建镜像(这可能需要几分钟)...
docker-compose build --no-cache
if errorlevel 1 (
echo ❌ 构建失败
pause
exit /b 1
)
echo ✅ 构建成功
echo.
echo [4/4] 启动容器...
docker-compose up -d
if errorlevel 1 (
echo ❌ 启动失败
pause
exit /b 1
)
echo.
echo ⏳ 等待服务启动(10秒)...
timeout /t 10 /nobreak >nul
echo.
echo 📊 容器状态:
docker-compose ps
echo.
echo 🎉 部署完成!
echo.
echo 访问地址:
echo 前端: http://localhost:5500
echo 后端: http://localhost:3000
echo.
echo 查看日志: docker-compose logs -f
echo 停止服务: docker-compose down
echo.
pause

53
docker-test.sh

@ -0,0 +1,53 @@
#!/bin/bash
# Docker 构建测试脚本
echo "🐳 开始 Docker 构建测试..."
echo ""
echo "[1/4] 检查 Docker 环境..."
if ! command -v docker &> /dev/null; then
echo "❌ Docker 未安装或未启动"
exit 1
fi
echo "✅ Docker 已就绪"
echo ""
echo "[2/4] 停止旧容器..."
docker-compose down
echo ""
echo "[3/4] 构建镜像(这可能需要几分钟)..."
docker-compose build --no-cache
if [ $? -ne 0 ]; then
echo "❌ 构建失败"
exit 1
fi
echo "✅ 构建成功"
echo ""
echo "[4/4] 启动容器..."
docker-compose up -d
if [ $? -ne 0 ]; then
echo "❌ 启动失败"
exit 1
fi
echo ""
echo "⏳ 等待服务启动(10秒)..."
sleep 10
echo ""
echo "📊 容器状态:"
docker-compose ps
echo ""
echo "🎉 部署完成!"
echo ""
echo "访问地址:"
echo " 前端: http://localhost:5500"
echo " 后端: http://localhost:3000"
echo ""
echo "查看日志: docker-compose logs -f"
echo "停止服务: docker-compose down"
echo ""

50
ecosystem.config.js

@ -0,0 +1,50 @@
// PM2 配置文件
module.exports = {
apps: [
{
name: 'just-demo-backend',
script: './backend/dist/app.js',
cwd: './',
instances: 1,
autorestart: true,
watch: false,
max_memory_restart: '500M',
env: {
NODE_ENV: 'production',
PORT: 3000
},
env_production: {
NODE_ENV: 'production',
PORT: 3000
},
error_file: './logs/backend-error.log',
out_file: './logs/backend-out.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
merge_logs: true,
// 自动重启策略
min_uptime: '10s',
max_restarts: 10,
// 启动延迟
listen_timeout: 3000,
kill_timeout: 5000
},
{
name: 'just-demo-frontend',
script: 'serve',
cwd: './frontend',
args: 'dist -p 5500 -s',
instances: 1,
autorestart: true,
watch: false,
max_memory_restart: '200M',
env: {
NODE_ENV: 'production'
},
error_file: './logs/frontend-error.log',
out_file: './logs/frontend-out.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
merge_logs: true
}
]
};

14
frontend/.dockerignore

@ -0,0 +1,14 @@
node_modules
npm-debug.log
pnpm-debug.log
dist
build
.git
.gitignore
*.md
.env
.env.local
.vscode
.idea
*.log

42
frontend/Dockerfile

@ -0,0 +1,42 @@
FROM node:18-alpine AS builder
WORKDIR /app
# 安装 pnpm
RUN npm install -g pnpm
# 复制依赖文件
COPY package.json pnpm-lock.yaml ./
# 安装依赖
RUN pnpm install --frozen-lockfile
# 复制源代码
COPY . .
# 构建
RUN pnpm build
# 生产阶段
FROM node:18-alpine
WORKDIR /app
# 安装必要工具
RUN apk add --no-cache wget && \
npm install -g serve
# 复制构建产物
COPY --from=builder /app/dist ./dist
# 使用非 root 用户
RUN chown -R node:node /app
USER node
EXPOSE 5500
HEALTHCHECK --interval=30s --timeout=10s --start-period=20s --retries=3 \
CMD wget --quiet --tries=1 --spider http://localhost:5500 || exit 1
CMD ["serve", "dist", "-p", "5500", "-s"]

72
nginx.conf

@ -0,0 +1,72 @@
server {
listen 80;
server_name your-domain.com; # 修改为你的域名
# Gzip 压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/json;
# 前端静态文件
location / {
proxy_pass http://localhost:5500;
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_cache_valid 200 1d;
proxy_cache_bypass $http_upgrade;
add_header X-Cache-Status $upstream_cache_status;
}
# 后端 API
location /api {
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;
# 超时设置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# 上传文件访问
location /uploads {
proxy_pass http://localhost:3000/uploads;
proxy_http_version 1.1;
proxy_set_header Host $host;
# 缓存上传的文件
expires 30d;
add_header Cache-Control "public, immutable";
}
# 日志
access_log /var/log/nginx/just-demo-access.log;
error_log /var/log/nginx/just-demo-error.log;
}
# HTTPS 配置(使用 Let's Encrypt)
# server {
# listen 443 ssl http2;
# server_name 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_protocols TLSv1.2 TLSv1.3;
# ssl_ciphers HIGH:!aNULL:!MD5;
#
# # ... 其他配置同上
# }

9
package.json

@ -7,14 +7,19 @@
"dev": "concurrently \"pnpm run dev:backend\" \"pnpm run dev:frontend\"", "dev": "concurrently \"pnpm run dev:backend\" \"pnpm run dev:frontend\"",
"dev:backend": "cd backend && pnpm run dev", "dev:backend": "cd backend && pnpm run dev",
"dev:frontend": "cd frontend && pnpm run dev", "dev:frontend": "cd frontend && pnpm run dev",
"start": "cd backend && pnpm run start:p", "start": "pm2 start ecosystem.config.js",
"stop": "pm2 stop all",
"restart": "pm2 restart all",
"status": "pm2 status",
"logs": "pm2 logs",
"build": "pnpm run build:backend && pnpm run build:frontend", "build": "pnpm run build:backend && pnpm run build:frontend",
"build:backend": "cd backend && pnpm run build", "build:backend": "cd backend && pnpm run build",
"build:frontend": "cd frontend && pnpm run build", "build:frontend": "cd frontend && pnpm run build",
"install:all": "pnpm install && cd backend && pnpm install && cd ../frontend && pnpm install" "install:all": "pnpm install && cd backend && pnpm install && cd ../frontend && pnpm install"
}, },
"devDependencies": { "devDependencies": {
"concurrently": "^8.2.2" "concurrently": "^8.2.2",
"serve": "^14.2.1"
} }
} }

Loading…
Cancel
Save