Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# 忽略环境配置
.env
.env.*

# 忽略依赖和构建产物
node_modules
dist

# 忽略版本控制目录
.git
.gitignore

# 日志文件
*.log
logs/
npm-debug.log*
pnpm-debug.log*
yarn-debug.log*

# IDE/OS 生成的缓存文件
.vscode
.DS_Store
*.swp
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
NODE_ENV=development
MONGODB_URI=mongodb://mongodb:27017/dispatchai
PORT=3000
PORT=4000
JWT_SECRET=AIGne1dnn6DFg4JoDsDHW4eX4M/xZkHTpOdo4N08Cl0=
JWT_ALGORITHM=HS256
JWT_EXPIRE_TIME=3600
Expand Down
23 changes: 23 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
parserOptions: {
project: './tsconfig.json',
tsconfigRootDir: __dirname,
sourceType: 'module',
},
plugins: ['@typescript-eslint', 'prettier', '@darraghor/nestjs-typed'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/strict-type-checked',
'plugin:@typescript-eslint/stylistic-type-checked',
'plugin:@darraghor/nestjs-typed/recommended',
'plugin:prettier/recommended',
],
rules: {
'@typescript-eslint/no-extraneous-class': 'off',
},
ignorePatterns: ['dist/', 'node_modules/'],
};

57 changes: 57 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: ✅ CI - Backend Build & Healthcheck

on:
push:
branches:
- main
pull_request:

jobs:
backend-ci:
runs-on: ubuntu-latest

steps:
- name: 📥 Checkout code
uses: actions/checkout@v3

- name: 🧱 Setup Node.js
uses: actions/setup-node@v3
with:
node-version: 20

- name: 📦 Install dependencies
run: npm install

- name: 📏 Format check (Prettier)
run: npm run format

- name: 🔍 Lint check
run: npm run lint

- name: 🧪 Run tests
run: npm run test

- name: 🏗️ Build project
run: npm run build

- name: 🔍 TypeScript type check
run: npm run type-check

- name: 🐳 Docker build (UAT)
run: docker build -f Dockerfile.uat -t dispatchai-backend:ci .

- name: 🚀 Run container
run: docker run -d -p 4000:4000 --name dispatchai-test dispatchai-backend:ci

- name: 🧳 Docker container logs (for debugging)
run: docker logs dispatchai-test

- name: 🔎 Health check
run: |
for i in {1..20}; do
sleep 5
curl -f http://localhost:4000/health && break || echo "Waiting for the service to be up..."
done

- name: 🧹 Clean up
run: docker rm -f dispatchai-test
42 changes: 42 additions & 0 deletions .github/workflows/deploy-uat.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: 🚀 Deploy Backend to EC2 (UAT)

on:
push:
branches:
- main

jobs:
deploy:
runs-on: ubuntu-latest

steps:
- name: 📦 Checkout code
uses: actions/checkout@v3

- name: 🔐 Setup SSH key
run: |
mkdir -p ~/.ssh
echo "${{ secrets.EC2_SSH_KEY }}" > ~/.ssh/dispatchai_key
chmod 600 ~/.ssh/dispatchai_key
ssh-keyscan -H ${{ secrets.EC2_HOST }} >> ~/.ssh/known_hosts

- name: 📤 Upload backend project to EC2
uses: appleboy/scp-action@master
with:
host: ${{ secrets.EC2_HOST }}
username: ubuntu
key: ${{ secrets.EC2_SSH_KEY }}
source: "." # 上传所有项目文件(受 .gitignore 限制)
target: "/home/ubuntu/deploy/dispatch-backend"
strip_components: 0

- name: 🔁 Restart backend service on EC2
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.EC2_HOST }}
username: ubuntu
key: ${{ secrets.EC2_SSH_KEY }}
script: |
cd /home/ubuntu/deploy/dispatch-backend
docker-compose -f docker-compose.yml -f docker-compose.uat.yml down
docker-compose -f docker-compose.yml -f docker-compose.uat.yml up -d --build
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dist
node_modules
coverage
6 changes: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"singleQuote": true,
"printWidth": 100,
"semi": true,
"trailingComma": "all"
}
14 changes: 1 addition & 13 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,9 @@ FROM node:20-alpine

WORKDIR /app

# Copy package.json and package-lock.json
COPY package*.json ./

# Install dependencies including the NestJS CLI
RUN npm install
RUN npm install -g @nestjs/cli

# Copy application source
COPY . .

# Build the application
RUN npm run build

# Expose the application port
EXPOSE 3000

# Run the application
CMD ["npm", "run", "start"]
CMD ["npm", "run", "start:dev"]
30 changes: 30 additions & 0 deletions Dockerfile.uat
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# ---------- Stage 1: Build ----------
FROM node:20-alpine AS builder

WORKDIR /app

# 拷贝依赖配置并安装全部依赖(包括 dev)
COPY package*.json ./
RUN npm install

# 拷贝源码并构建 dist/
COPY . .
RUN npm run build

# ---------- Stage 2: Runtime ----------
FROM node:20-alpine

WORKDIR /app

# 只复制构建产物和依赖配置
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package*.json ./

# 安装仅生产依赖
RUN npm install --only=production

EXPOSE 4000

# 启动 NestJS 编译后应用
CMD ["node", "dist/main"]

18 changes: 18 additions & 0 deletions docker-compose.uat.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
services:
api:
build:
context: .
dockerfile: Dockerfile.uat
container_name: dispatchai-api
command: ["node", "dist/main"]
environment:
- NODE_ENV=uat
- MONGODB_URI=mongodb://mongodb:27017/dispatchai
- JWT_SECRET=${JWT_SECRET}
- JWT_ALGORITHM=${JWT_ALGORITHM}
- JWT_EXPIRE_TIME=${JWT_EXPIRE_TIME}
volumes: []

mongodb:
image: mongo:latest
container_name: dispatchai-mongodb
Loading