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 10 months 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/
pnpm-lock.yaml
# 构建产物
dist/
*.log
build/
# 环境变量
.env
.DS_Store
database/*.sqlite3
uploads/
.env.local
.env.production
.env.development
# 日志
logs/
*.log
npm-debug.log*
pnpm-debug.log*
# 数据库
*.sqlite3
*.sqlite
*.db
# PM2
.pm2/
# IDE
.vscode/
.idea/
backup/
*.zip
*.swp
*.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
# 1. 安装依赖
pnpm install:all
```
### 开发
```bash
# 同时启动前后端
# 2. 启动开发服务器
pnpm dev
# 或分别启动
@ -28,12 +25,62 @@ pnpm dev:backend # 后端:http://localhost:3000
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
# 1. 构建项目
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:backend": "cd backend && 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:backend": "cd backend && pnpm run build",
"build:frontend": "cd frontend && pnpm run build",
"install:all": "pnpm install && cd backend && pnpm install && cd ../frontend && pnpm install"
},
"devDependencies": {
"concurrently": "^8.2.2"
"concurrently": "^8.2.2",
"serve": "^14.2.1"
}
}

Loading…
Cancel
Save