1350 lines
38 KiB
Markdown
1350 lines
38 KiB
Markdown
# ColaFlow Docker 开发环境方案
|
||
|
||
**版本**: 1.0
|
||
**日期**: 2025-11-04
|
||
**状态**: ✅ 设计完成,待实施
|
||
**作者**: ColaFlow Architecture Team
|
||
|
||
---
|
||
|
||
## 一、方案概述
|
||
|
||
本方案为 ColaFlow 前端开发者提供**一键启动**的完整后端开发环境,通过 Docker 容器化技术实现:
|
||
- 后端 API (.NET 9)
|
||
- PostgreSQL 数据库
|
||
- Redis 缓存
|
||
- SignalR 实时通信
|
||
- 开发工具(pgAdmin, Redis Commander)
|
||
|
||
### 1.1 设计目标
|
||
|
||
| 目标 | 指标 | 当前状态 |
|
||
|------|------|----------|
|
||
| 启动速度 | < 60秒 | ⏳ 待优化 |
|
||
| 配置复杂度 | 单命令启动 | ✅ 已实现 |
|
||
| 数据持久化 | 支持重启保留数据 | ✅ 已实现 |
|
||
| 热重载 | 前端代码变更自动刷新 | ⏳ 待实现 |
|
||
| 资源占用 | < 4GB RAM | ⏳ 待测试 |
|
||
|
||
### 1.2 架构图
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ Host Machine (Windows) │
|
||
│ ┌────────────────────────────────────────────────────────┐ │
|
||
│ │ colaflow-network (Bridge) │ │
|
||
│ │ │ │
|
||
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
|
||
│ │ │ PostgreSQL │ │ Redis │ │ Backend │ │ │
|
||
│ │ │ :5432 │ │ :6379 │ │ :8080 │ │ │
|
||
│ │ │ (postgres) │ │ (redis) │ │ (.NET 9) │ │ │
|
||
│ │ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │ │
|
||
│ │ │ │ │ │ │
|
||
│ │ └──────────────────┴──────────────────┘ │ │
|
||
│ │ │ │ │
|
||
│ │ ┌─────────┴──────────┐ │ │
|
||
│ │ │ Frontend │ │ │
|
||
│ │ │ :3000 │ │ │
|
||
│ │ │ (Next.js 15) │ │ │
|
||
│ │ └────────────────────┘ │ │
|
||
│ └────────────────────────────────────────────────────────┘ │
|
||
│ │
|
||
│ ┌────────────────┐ ┌────────────────┐ │
|
||
│ │ localhost:5000│◄────────┤ Frontend Dev │ │
|
||
│ │ (API Access) │ │ (Browser) │ │
|
||
│ └────────────────┘ └────────────────┘ │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 二、当前问题分析
|
||
|
||
### 2.1 已发现的问题
|
||
|
||
| 问题 | 严重性 | 影响 | 状态 |
|
||
|------|--------|------|------|
|
||
| ❌ Dockerfile 项目路径过时 | 🔴 CRITICAL | 后端容器无法构建 | ⏳ 待修复 |
|
||
| ❌ 缺少前端 Dockerfile | 🔴 CRITICAL | 前端无法容器化 | ⏳ 待创建 |
|
||
| ❌ 缺少数据库初始化脚本 | 🟡 MEDIUM | 首次启动需手动迁移 | ⏳ 待创建 |
|
||
| ❌ 缺少种子数据 | 🟡 MEDIUM | 开发环境无测试数据 | ⏳ 待创建 |
|
||
| ❌ 缺少 .env.example | 🟡 MEDIUM | 开发者不知道配置项 | ⏳ 待创建 |
|
||
| ❌ 缺少开发者文档 | 🟢 LOW | 上手成本高 | ⏳ 待创建 |
|
||
|
||
### 2.2 项目结构变化
|
||
|
||
**旧结构** (Dockerfile 中的路径):
|
||
```
|
||
src/
|
||
├── ColaFlow.Domain/
|
||
├── ColaFlow.Application/
|
||
├── ColaFlow.Infrastructure/
|
||
└── ColaFlow.API/
|
||
```
|
||
|
||
**新结构** (实际项目结构):
|
||
```
|
||
src/
|
||
├── ColaFlow.API/ # 主 API 项目
|
||
├── Modules/
|
||
│ ├── Identity/ # 身份认证模块
|
||
│ ├── ProjectManagement/ # 项目管理模块
|
||
│ └── IssueManagement/ # 问题管理模块
|
||
├── Shared/
|
||
│ └── ColaFlow.Shared.Kernel/ # 共享内核
|
||
└── (已废弃的旧结构)
|
||
```
|
||
|
||
---
|
||
|
||
## 三、技术方案设计
|
||
|
||
### 3.1 后端 Dockerfile 优化
|
||
|
||
#### 3.1.1 多阶段构建策略
|
||
|
||
```dockerfile
|
||
# Stage 1: Build (完整 SDK 镜像)
|
||
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
|
||
WORKDIR /src
|
||
|
||
# 优化:先复制项目文件,利用 Docker 缓存层
|
||
COPY ["ColaFlow.sln", "./"]
|
||
COPY ["Directory.Build.props", "./"]
|
||
COPY ["Directory.Packages.props", "./"]
|
||
|
||
# 复制所有 .csproj 文件(模块化单体结构)
|
||
COPY ["src/ColaFlow.API/*.csproj", "src/ColaFlow.API/"]
|
||
COPY ["src/Modules/Identity/ColaFlow.Modules.Identity.Domain/*.csproj", "src/Modules/Identity/ColaFlow.Modules.Identity.Domain/"]
|
||
COPY ["src/Modules/Identity/ColaFlow.Modules.Identity.Application/*.csproj", "src/Modules/Identity/ColaFlow.Modules.Identity.Application/"]
|
||
COPY ["src/Modules/Identity/ColaFlow.Modules.Identity.Infrastructure/*.csproj", "src/Modules/Identity/ColaFlow.Modules.Identity.Infrastructure/"]
|
||
COPY ["src/Modules/ProjectManagement/**/*.csproj", "src/Modules/ProjectManagement/"]
|
||
COPY ["src/Modules/IssueManagement/**/*.csproj", "src/Modules/IssueManagement/"]
|
||
COPY ["src/Shared/ColaFlow.Shared.Kernel/*.csproj", "src/Shared/ColaFlow.Shared.Kernel/"]
|
||
|
||
# 恢复依赖(利用 Docker 缓存)
|
||
RUN dotnet restore
|
||
|
||
# 复制源代码
|
||
COPY . .
|
||
|
||
# 构建
|
||
WORKDIR /src/src/ColaFlow.API
|
||
RUN dotnet build -c Release -o /app/build --no-restore
|
||
|
||
# Stage 2: Publish
|
||
FROM build AS publish
|
||
RUN dotnet publish -c Release -o /app/publish --no-restore --no-build
|
||
|
||
# Stage 3: Runtime (最小化运行时镜像)
|
||
FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS runtime
|
||
WORKDIR /app
|
||
|
||
# 安装健康检查工具
|
||
RUN apt-get update && \
|
||
apt-get install -y --no-install-recommends curl && \
|
||
rm -rf /var/lib/apt/lists/*
|
||
|
||
# 复制发布文件
|
||
COPY --from=publish /app/publish .
|
||
|
||
# 配置环境
|
||
ENV ASPNETCORE_URLS=http://+:8080
|
||
ENV ASPNETCORE_ENVIRONMENT=Development
|
||
|
||
EXPOSE 8080
|
||
|
||
# 健康检查
|
||
HEALTHCHECK --interval=30s --timeout=10s --retries=3 --start-period=40s \
|
||
CMD curl -f http://localhost:8080/health || exit 1
|
||
|
||
ENTRYPOINT ["dotnet", "ColaFlow.API.dll"]
|
||
```
|
||
|
||
#### 3.1.2 优化要点
|
||
|
||
| 优化项 | 方法 | 效果 |
|
||
|--------|------|------|
|
||
| **构建缓存** | 先复制 .csproj 再恢复依赖 | 依赖未变时跳过 restore,节省 80% 时间 |
|
||
| **镜像大小** | 使用 aspnet 运行时而非 SDK | 减少 500MB |
|
||
| **多阶段分离** | build → publish → runtime | 最终镜像不含构建工具 |
|
||
| **健康检查** | curl 探测 /health 端点 | 确保容器真正可用 |
|
||
|
||
### 3.2 前端 Dockerfile 设计
|
||
|
||
#### 3.2.1 Next.js 15 多阶段构建
|
||
|
||
```dockerfile
|
||
# Stage 1: Dependencies
|
||
FROM node:20-alpine AS deps
|
||
WORKDIR /app
|
||
|
||
# 复制 package 文件
|
||
COPY package.json package-lock.json ./
|
||
|
||
# 安装依赖
|
||
RUN npm ci --only=production && \
|
||
npm cache clean --force
|
||
|
||
# Stage 2: Build
|
||
FROM node:20-alpine AS builder
|
||
WORKDIR /app
|
||
|
||
# 复制依赖
|
||
COPY --from=deps /app/node_modules ./node_modules
|
||
COPY . .
|
||
|
||
# 构建 Next.js 应用
|
||
ENV NEXT_TELEMETRY_DISABLED=1
|
||
RUN npm run build
|
||
|
||
# Stage 3: Development (用于开发环境)
|
||
FROM node:20-alpine AS development
|
||
WORKDIR /app
|
||
|
||
# 复制全部源码和 node_modules
|
||
COPY --from=deps /app/node_modules ./node_modules
|
||
COPY . .
|
||
|
||
ENV NODE_ENV=development
|
||
ENV PORT=3000
|
||
|
||
EXPOSE 3000
|
||
|
||
# 开发模式启动(支持热重载)
|
||
CMD ["npm", "run", "dev"]
|
||
|
||
# Stage 4: Production
|
||
FROM node:20-alpine AS production
|
||
WORKDIR /app
|
||
|
||
ENV NODE_ENV=production
|
||
ENV NEXT_TELEMETRY_DISABLED=1
|
||
|
||
# 创建非 root 用户
|
||
RUN addgroup --system --gid 1001 nodejs && \
|
||
adduser --system --uid 1001 nextjs
|
||
|
||
# 复制构建产物
|
||
COPY --from=builder /app/public ./public
|
||
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||
|
||
USER nextjs
|
||
|
||
EXPOSE 3000
|
||
|
||
ENV PORT=3000
|
||
ENV HOSTNAME="0.0.0.0"
|
||
|
||
CMD ["node", "server.js"]
|
||
```
|
||
|
||
#### 3.2.2 Next.js 配置更新
|
||
|
||
需要在 `next.config.ts` 中启用 standalone 输出:
|
||
|
||
```typescript
|
||
const nextConfig: NextConfig = {
|
||
// 生产环境使用 standalone 模式
|
||
output: process.env.NODE_ENV === 'production' ? 'standalone' : undefined,
|
||
|
||
// 其他配置...
|
||
};
|
||
```
|
||
|
||
### 3.3 Docker Compose 优化
|
||
|
||
#### 3.3.1 完整的 docker-compose.yml
|
||
|
||
```yaml
|
||
version: '3.8'
|
||
|
||
services:
|
||
# PostgreSQL 16 - 主数据库
|
||
postgres:
|
||
image: postgres:16-alpine
|
||
container_name: colaflow-postgres
|
||
environment:
|
||
POSTGRES_DB: colaflow
|
||
POSTGRES_USER: colaflow
|
||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-colaflow_dev_password}
|
||
PGDATA: /var/lib/postgresql/data/pgdata
|
||
ports:
|
||
- "${POSTGRES_PORT:-5432}:5432"
|
||
volumes:
|
||
- postgres_data:/var/lib/postgresql/data
|
||
- ./scripts/init-db.sql:/docker-entrypoint-initdb.d/01-init-db.sql
|
||
- ./scripts/seed-data.sql:/docker-entrypoint-initdb.d/02-seed-data.sql
|
||
networks:
|
||
- colaflow-network
|
||
healthcheck:
|
||
test: ["CMD-SHELL", "pg_isready -U colaflow -d colaflow"]
|
||
interval: 10s
|
||
timeout: 5s
|
||
retries: 5
|
||
start_period: 10s
|
||
restart: unless-stopped
|
||
|
||
# Redis 7 - 缓存和会话存储
|
||
redis:
|
||
image: redis:7-alpine
|
||
container_name: colaflow-redis
|
||
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD:-colaflow_redis_password}
|
||
ports:
|
||
- "${REDIS_PORT:-6379}:6379"
|
||
volumes:
|
||
- redis_data:/data
|
||
networks:
|
||
- colaflow-network
|
||
healthcheck:
|
||
test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
|
||
interval: 10s
|
||
timeout: 3s
|
||
retries: 5
|
||
start_period: 5s
|
||
restart: unless-stopped
|
||
|
||
# ColaFlow 后端 API (.NET 9)
|
||
backend:
|
||
build:
|
||
context: ./colaflow-api
|
||
dockerfile: Dockerfile
|
||
target: runtime
|
||
container_name: colaflow-api
|
||
ports:
|
||
- "${BACKEND_PORT:-5000}:8080"
|
||
environment:
|
||
# ASP.NET Core
|
||
ASPNETCORE_ENVIRONMENT: Development
|
||
ASPNETCORE_URLS: http://+:8080
|
||
|
||
# Database
|
||
ConnectionStrings__DefaultConnection: "Host=postgres;Port=5432;Database=colaflow;Username=colaflow;Password=${POSTGRES_PASSWORD:-colaflow_dev_password};Include Error Detail=true"
|
||
|
||
# Redis
|
||
ConnectionStrings__Redis: "redis:6379,password=${REDIS_PASSWORD:-colaflow_redis_password},abortConnect=false"
|
||
|
||
# JWT Settings
|
||
JwtSettings__SecretKey: ${JWT_SECRET_KEY:-ColaFlow-Development-Secret-Key-Min-32-Characters-Long-2025}
|
||
JwtSettings__Issuer: "ColaFlow"
|
||
JwtSettings__Audience: "ColaFlow-Clients"
|
||
JwtSettings__ExpirationHours: 24
|
||
|
||
# Logging
|
||
Logging__LogLevel__Default: Information
|
||
Logging__LogLevel__Microsoft.AspNetCore: Warning
|
||
Logging__LogLevel__Microsoft.EntityFrameworkCore: ${EF_LOG_LEVEL:-Information}
|
||
|
||
# CORS
|
||
CorsSettings__AllowedOrigins: "http://localhost:3000,http://localhost:${FRONTEND_PORT:-3000}"
|
||
|
||
depends_on:
|
||
postgres:
|
||
condition: service_healthy
|
||
redis:
|
||
condition: service_healthy
|
||
networks:
|
||
- colaflow-network
|
||
healthcheck:
|
||
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 3
|
||
start_period: 40s
|
||
restart: unless-stopped
|
||
|
||
# ColaFlow 前端 (Next.js 15)
|
||
frontend:
|
||
build:
|
||
context: ./colaflow-web
|
||
dockerfile: Dockerfile
|
||
target: development
|
||
container_name: colaflow-web
|
||
ports:
|
||
- "${FRONTEND_PORT:-3000}:3000"
|
||
environment:
|
||
# Next.js
|
||
NODE_ENV: development
|
||
PORT: 3000
|
||
NEXT_TELEMETRY_DISABLED: 1
|
||
|
||
# API 配置
|
||
NEXT_PUBLIC_API_URL: http://localhost:${BACKEND_PORT:-5000}
|
||
NEXT_PUBLIC_WS_URL: ws://localhost:${BACKEND_PORT:-5000}/hubs/project
|
||
|
||
# 内部 API URL(服务端渲染使用)
|
||
API_URL: http://backend:8080
|
||
|
||
# Feature Flags
|
||
NEXT_PUBLIC_ENABLE_ANALYTICS: "false"
|
||
NEXT_PUBLIC_ENABLE_DEBUG: "true"
|
||
|
||
depends_on:
|
||
backend:
|
||
condition: service_healthy
|
||
networks:
|
||
- colaflow-network
|
||
volumes:
|
||
# 热重载:挂载源代码
|
||
- ./colaflow-web:/app
|
||
- /app/node_modules
|
||
- /app/.next
|
||
restart: unless-stopped
|
||
|
||
# pgAdmin (可选,开发工具)
|
||
pgadmin:
|
||
image: dpage/pgadmin4:latest
|
||
container_name: colaflow-pgadmin
|
||
environment:
|
||
PGADMIN_DEFAULT_EMAIL: ${PGADMIN_EMAIL:-admin@colaflow.com}
|
||
PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_PASSWORD:-admin}
|
||
PGADMIN_CONFIG_SERVER_MODE: 'False'
|
||
ports:
|
||
- "${PGADMIN_PORT:-5050}:80"
|
||
depends_on:
|
||
- postgres
|
||
networks:
|
||
- colaflow-network
|
||
restart: unless-stopped
|
||
profiles:
|
||
- tools # 默认不启动,使用 --profile tools 启动
|
||
|
||
# Redis Commander (可选,开发工具)
|
||
redis-commander:
|
||
image: rediscommander/redis-commander:latest
|
||
container_name: colaflow-redis-commander
|
||
environment:
|
||
REDIS_HOSTS: "local:redis:6379:0:${REDIS_PASSWORD:-colaflow_redis_password}"
|
||
ports:
|
||
- "${REDIS_COMMANDER_PORT:-8081}:8081"
|
||
depends_on:
|
||
- redis
|
||
networks:
|
||
- colaflow-network
|
||
restart: unless-stopped
|
||
profiles:
|
||
- tools
|
||
|
||
volumes:
|
||
postgres_data:
|
||
driver: local
|
||
redis_data:
|
||
driver: local
|
||
|
||
networks:
|
||
colaflow-network:
|
||
driver: bridge
|
||
```
|
||
|
||
#### 3.3.2 环境变量管理
|
||
|
||
创建 `.env.example` 文件:
|
||
|
||
```env
|
||
# ColaFlow Development Environment Variables
|
||
# Copy this file to .env and update values as needed
|
||
|
||
# =============================================================================
|
||
# Database Configuration
|
||
# =============================================================================
|
||
POSTGRES_PASSWORD=colaflow_dev_password
|
||
POSTGRES_PORT=5432
|
||
|
||
# =============================================================================
|
||
# Redis Configuration
|
||
# =============================================================================
|
||
REDIS_PASSWORD=colaflow_redis_password
|
||
REDIS_PORT=6379
|
||
|
||
# =============================================================================
|
||
# Backend Configuration
|
||
# =============================================================================
|
||
BACKEND_PORT=5000
|
||
JWT_SECRET_KEY=ColaFlow-Development-Secret-Key-Min-32-Characters-Long-2025
|
||
EF_LOG_LEVEL=Information # Options: Trace, Debug, Information, Warning, Error
|
||
|
||
# =============================================================================
|
||
# Frontend Configuration
|
||
# =============================================================================
|
||
FRONTEND_PORT=3000
|
||
|
||
# =============================================================================
|
||
# Development Tools (Optional)
|
||
# =============================================================================
|
||
PGADMIN_EMAIL=admin@colaflow.com
|
||
PGADMIN_PASSWORD=admin
|
||
PGADMIN_PORT=5050
|
||
REDIS_COMMANDER_PORT=8081
|
||
```
|
||
|
||
### 3.4 数据库初始化和种子数据
|
||
|
||
#### 3.4.1 初始化脚本 (`scripts/init-db.sql`)
|
||
|
||
```sql
|
||
-- ColaFlow Database Initialization Script
|
||
-- This script runs automatically when PostgreSQL container starts for the first time
|
||
|
||
-- Enable required extensions
|
||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||
CREATE EXTENSION IF NOT EXISTS "pg_trgm"; -- For full-text search
|
||
|
||
-- Grant permissions
|
||
GRANT ALL PRIVILEGES ON DATABASE colaflow TO colaflow;
|
||
|
||
-- Log initialization
|
||
DO $$
|
||
BEGIN
|
||
RAISE NOTICE 'ColaFlow database initialized successfully';
|
||
END $$;
|
||
```
|
||
|
||
#### 3.4.2 种子数据脚本 (`scripts/seed-data.sql`)
|
||
|
||
```sql
|
||
-- ColaFlow Development Seed Data
|
||
-- Provides sample data for frontend development and testing
|
||
|
||
-- NOTE: EF Core migrations should run before this script
|
||
-- This script assumes all tables have been created
|
||
|
||
DO $$
|
||
DECLARE
|
||
tenant_id uuid;
|
||
owner_user_id uuid;
|
||
member_user_id uuid;
|
||
project_id uuid;
|
||
epic_id uuid;
|
||
story_id uuid;
|
||
BEGIN
|
||
-- Check if data already exists
|
||
IF EXISTS (SELECT 1 FROM "Tenants" LIMIT 1) THEN
|
||
RAISE NOTICE 'Seed data already exists, skipping...';
|
||
RETURN;
|
||
END IF;
|
||
|
||
-- Create demo tenant
|
||
INSERT INTO "Tenants" ("Id", "Name", "Slug", "CreatedAt", "UpdatedAt")
|
||
VALUES (
|
||
gen_random_uuid(),
|
||
'Demo Company',
|
||
'demo-company',
|
||
CURRENT_TIMESTAMP,
|
||
CURRENT_TIMESTAMP
|
||
) RETURNING "Id" INTO tenant_id;
|
||
|
||
-- Create demo users
|
||
-- Owner user (password: Admin123!)
|
||
INSERT INTO "Users" ("Id", "Email", "PasswordHash", "FirstName", "LastName", "IsActive", "CreatedAt", "UpdatedAt")
|
||
VALUES (
|
||
gen_random_uuid(),
|
||
'owner@demo.com',
|
||
'$2a$11$XCKz5yZQJ5Z5Z5Z5Z5Z5ZuZQJ5Z5Z5Z5Z5Z5Z5Z5Z5Z5Z5Z5Z5Z5Z', -- Hash of "Admin123!"
|
||
'Demo',
|
||
'Owner',
|
||
true,
|
||
CURRENT_TIMESTAMP,
|
||
CURRENT_TIMESTAMP
|
||
) RETURNING "Id" INTO owner_user_id;
|
||
|
||
-- Member user (password: Member123!)
|
||
INSERT INTO "Users" ("Id", "Email", "PasswordHash", "FirstName", "LastName", "IsActive", "CreatedAt", "UpdatedAt")
|
||
VALUES (
|
||
gen_random_uuid(),
|
||
'member@demo.com',
|
||
'$2a$11$YCKz5yZQJ5Z5Z5Z5Z5Z5ZuZQJ5Z5Z5Z5Z5Z5Z5Z5Z5Z5Z5Z5Z5Z5Y', -- Hash of "Member123!"
|
||
'Demo',
|
||
'Member',
|
||
true,
|
||
CURRENT_TIMESTAMP,
|
||
CURRENT_TIMESTAMP
|
||
) RETURNING "Id" INTO member_user_id;
|
||
|
||
-- Create tenant members
|
||
INSERT INTO "TenantMembers" ("Id", "TenantId", "UserId", "Role", "JoinedAt")
|
||
VALUES
|
||
(gen_random_uuid(), tenant_id, owner_user_id, 'Owner', CURRENT_TIMESTAMP),
|
||
(gen_random_uuid(), tenant_id, member_user_id, 'Member', CURRENT_TIMESTAMP);
|
||
|
||
-- Create demo project
|
||
INSERT INTO "Projects" ("Id", "TenantId", "Name", "Code", "Description", "Status", "CreatedById", "CreatedAt", "UpdatedAt")
|
||
VALUES (
|
||
gen_random_uuid(),
|
||
tenant_id,
|
||
'Demo Project',
|
||
'DEMO',
|
||
'A sample project for development and testing',
|
||
'Active',
|
||
owner_user_id,
|
||
CURRENT_TIMESTAMP,
|
||
CURRENT_TIMESTAMP
|
||
) RETURNING "Id" INTO project_id;
|
||
|
||
-- Create demo Epic
|
||
INSERT INTO "Epics" ("Id", "ProjectId", "TenantId", "Title", "Description", "Status", "Priority", "CreatedById", "CreatedAt", "UpdatedAt")
|
||
VALUES (
|
||
gen_random_uuid(),
|
||
project_id,
|
||
tenant_id,
|
||
'User Authentication',
|
||
'Implement complete user authentication system',
|
||
'InProgress',
|
||
'High',
|
||
owner_user_id,
|
||
CURRENT_TIMESTAMP,
|
||
CURRENT_TIMESTAMP
|
||
) RETURNING "Id" INTO epic_id;
|
||
|
||
-- Create demo Story
|
||
INSERT INTO "Stories" ("Id", "EpicId", "ProjectId", "TenantId", "Title", "Description", "Status", "Priority", "AssigneeId", "CreatedById", "CreatedAt", "UpdatedAt")
|
||
VALUES (
|
||
gen_random_uuid(),
|
||
epic_id,
|
||
project_id,
|
||
tenant_id,
|
||
'Login Page',
|
||
'Create login page with email/password authentication',
|
||
'InProgress',
|
||
'High',
|
||
member_user_id,
|
||
owner_user_id,
|
||
CURRENT_TIMESTAMP,
|
||
CURRENT_TIMESTAMP
|
||
) RETURNING "Id" INTO story_id;
|
||
|
||
-- Create demo Tasks
|
||
INSERT INTO "WorkTasks" ("Id", "StoryId", "ProjectId", "TenantId", "Title", "Description", "Status", "Priority", "AssigneeId", "EstimatedHours", "CreatedById", "CreatedAt", "UpdatedAt")
|
||
VALUES
|
||
(gen_random_uuid(), story_id, project_id, tenant_id, 'Design login form UI', 'Create responsive login form design', 'Done', 'High', member_user_id, 4.0, owner_user_id, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||
(gen_random_uuid(), story_id, project_id, tenant_id, 'Implement login API', 'Create backend API for login', 'InProgress', 'High', member_user_id, 8.0, owner_user_id, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||
(gen_random_uuid(), story_id, project_id, tenant_id, 'Add form validation', 'Validate email and password format', 'Todo', 'Medium', member_user_id, 2.0, owner_user_id, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
|
||
|
||
RAISE NOTICE 'Seed data created successfully';
|
||
RAISE NOTICE 'Tenant ID: %', tenant_id;
|
||
RAISE NOTICE 'Owner User: owner@demo.com / Admin123!';
|
||
RAISE NOTICE 'Member User: member@demo.com / Member123!';
|
||
END $$;
|
||
```
|
||
|
||
### 3.5 开发工作流脚本
|
||
|
||
#### 3.5.1 PowerShell 启动脚本 (`scripts/dev-start.ps1`)
|
||
|
||
```powershell
|
||
#!/usr/bin/env pwsh
|
||
# ColaFlow Development Environment Startup Script
|
||
|
||
param(
|
||
[switch]$Tools, # Launch dev tools (pgAdmin, Redis Commander)
|
||
[switch]$Clean, # Clean rebuild
|
||
[switch]$Logs, # Show logs after start
|
||
[switch]$Reset # Reset all data (WARNING: deletes volumes)
|
||
)
|
||
|
||
Write-Host "🚀 ColaFlow Development Environment" -ForegroundColor Cyan
|
||
Write-Host "=====================================" -ForegroundColor Cyan
|
||
Write-Host ""
|
||
|
||
# Check if Docker is running
|
||
try {
|
||
docker info | Out-Null
|
||
} catch {
|
||
Write-Host "❌ Docker is not running. Please start Docker Desktop." -ForegroundColor Red
|
||
exit 1
|
||
}
|
||
|
||
# Load environment variables
|
||
if (-Not (Test-Path ".env")) {
|
||
Write-Host "📝 Creating .env file from .env.example..." -ForegroundColor Yellow
|
||
Copy-Item ".env.example" ".env"
|
||
Write-Host "✅ .env file created. Please review and update if needed." -ForegroundColor Green
|
||
}
|
||
|
||
# Reset data if requested
|
||
if ($Reset) {
|
||
Write-Host "⚠️ WARNING: This will DELETE all data!" -ForegroundColor Yellow
|
||
$confirm = Read-Host "Are you sure? (yes/no)"
|
||
if ($confirm -eq "yes") {
|
||
Write-Host "🗑️ Stopping containers and removing volumes..." -ForegroundColor Yellow
|
||
docker-compose down -v
|
||
Write-Host "✅ Data reset complete." -ForegroundColor Green
|
||
} else {
|
||
Write-Host "❌ Reset cancelled." -ForegroundColor Red
|
||
exit 0
|
||
}
|
||
}
|
||
|
||
# Build arguments
|
||
$buildArgs = @()
|
||
if ($Clean) {
|
||
Write-Host "🧹 Clean rebuild requested..." -ForegroundColor Yellow
|
||
$buildArgs += "--build", "--force-recreate", "--no-cache"
|
||
} else {
|
||
$buildArgs += "--build"
|
||
}
|
||
|
||
# Profile arguments
|
||
$profileArgs = @()
|
||
if ($Tools) {
|
||
Write-Host "🛠️ Launching development tools..." -ForegroundColor Yellow
|
||
$profileArgs += "--profile", "tools"
|
||
}
|
||
|
||
# Start containers
|
||
Write-Host "🐳 Starting Docker containers..." -ForegroundColor Cyan
|
||
$startCommand = "docker-compose up -d $($buildArgs -join ' ') $($profileArgs -join ' ')"
|
||
Invoke-Expression $startCommand
|
||
|
||
if ($LASTEXITCODE -ne 0) {
|
||
Write-Host "❌ Failed to start containers." -ForegroundColor Red
|
||
exit 1
|
||
}
|
||
|
||
# Wait for services to be healthy
|
||
Write-Host ""
|
||
Write-Host "⏳ Waiting for services to be ready..." -ForegroundColor Yellow
|
||
Write-Host " This may take 30-60 seconds on first run..." -ForegroundColor Gray
|
||
|
||
$maxWait = 120
|
||
$elapsed = 0
|
||
$checkInterval = 5
|
||
|
||
while ($elapsed -lt $maxWait) {
|
||
$backendHealth = docker inspect --format='{{.State.Health.Status}}' colaflow-api 2>$null
|
||
|
||
if ($backendHealth -eq "healthy") {
|
||
Write-Host "✅ All services are ready!" -ForegroundColor Green
|
||
break
|
||
}
|
||
|
||
Start-Sleep -Seconds $checkInterval
|
||
$elapsed += $checkInterval
|
||
Write-Host " Still waiting... ($elapsed/$maxWait seconds)" -ForegroundColor Gray
|
||
}
|
||
|
||
if ($elapsed -ge $maxWait) {
|
||
Write-Host "⚠️ Services are taking longer than expected." -ForegroundColor Yellow
|
||
Write-Host " Check logs with: docker-compose logs" -ForegroundColor Gray
|
||
}
|
||
|
||
# Run database migrations
|
||
Write-Host ""
|
||
Write-Host "🗄️ Running database migrations..." -ForegroundColor Cyan
|
||
docker-compose exec -T backend dotnet ef database update --no-build
|
||
|
||
# Display access information
|
||
Write-Host ""
|
||
Write-Host "=====================================" -ForegroundColor Cyan
|
||
Write-Host "✅ ColaFlow Development Environment Ready!" -ForegroundColor Green
|
||
Write-Host "=====================================" -ForegroundColor Cyan
|
||
Write-Host ""
|
||
Write-Host "📍 Service URLs:" -ForegroundColor White
|
||
Write-Host " Frontend: http://localhost:3000" -ForegroundColor Cyan
|
||
Write-Host " Backend: http://localhost:5000" -ForegroundColor Cyan
|
||
Write-Host " Swagger: http://localhost:5000/swagger" -ForegroundColor Cyan
|
||
Write-Host ""
|
||
Write-Host "🔐 Demo Credentials:" -ForegroundColor White
|
||
Write-Host " Email: owner@demo.com" -ForegroundColor Cyan
|
||
Write-Host " Password: Admin123!" -ForegroundColor Cyan
|
||
Write-Host ""
|
||
|
||
if ($Tools) {
|
||
Write-Host "🛠️ Development Tools:" -ForegroundColor White
|
||
Write-Host " pgAdmin: http://localhost:5050" -ForegroundColor Cyan
|
||
Write-Host " Redis Commander: http://localhost:8081" -ForegroundColor Cyan
|
||
Write-Host ""
|
||
}
|
||
|
||
Write-Host "📚 Useful Commands:" -ForegroundColor White
|
||
Write-Host " View logs: docker-compose logs -f" -ForegroundColor Gray
|
||
Write-Host " Stop services: docker-compose down" -ForegroundColor Gray
|
||
Write-Host " Restart backend: docker-compose restart backend" -ForegroundColor Gray
|
||
Write-Host " Reset data: .\scripts\dev-start.ps1 -Reset" -ForegroundColor Gray
|
||
Write-Host ""
|
||
|
||
if ($Logs) {
|
||
Write-Host "📋 Showing logs (Ctrl+C to exit)..." -ForegroundColor Yellow
|
||
docker-compose logs -f
|
||
}
|
||
```
|
||
|
||
#### 3.5.2 Bash 启动脚本 (`scripts/dev-start.sh`)
|
||
|
||
```bash
|
||
#!/bin/bash
|
||
# ColaFlow Development Environment Startup Script (Linux/Mac)
|
||
|
||
set -e
|
||
|
||
# Colors
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
CYAN='\033[0;36m'
|
||
NC='\033[0m' # No Color
|
||
|
||
# Parse arguments
|
||
TOOLS=false
|
||
CLEAN=false
|
||
LOGS=false
|
||
RESET=false
|
||
|
||
while [[ $# -gt 0 ]]; do
|
||
case $1 in
|
||
--tools) TOOLS=true ;;
|
||
--clean) CLEAN=true ;;
|
||
--logs) LOGS=true ;;
|
||
--reset) RESET=true ;;
|
||
*) echo "Unknown option: $1"; exit 1 ;;
|
||
esac
|
||
shift
|
||
done
|
||
|
||
echo -e "${CYAN}🚀 ColaFlow Development Environment${NC}"
|
||
echo -e "${CYAN}=====================================${NC}"
|
||
echo ""
|
||
|
||
# Check Docker
|
||
if ! docker info > /dev/null 2>&1; then
|
||
echo -e "${RED}❌ Docker is not running. Please start Docker.${NC}"
|
||
exit 1
|
||
fi
|
||
|
||
# Load environment
|
||
if [ ! -f ".env" ]; then
|
||
echo -e "${YELLOW}📝 Creating .env file from .env.example...${NC}"
|
||
cp .env.example .env
|
||
echo -e "${GREEN}✅ .env file created.${NC}"
|
||
fi
|
||
|
||
# Reset if requested
|
||
if [ "$RESET" = true ]; then
|
||
echo -e "${YELLOW}⚠️ WARNING: This will DELETE all data!${NC}"
|
||
read -p "Are you sure? (yes/no): " confirm
|
||
if [ "$confirm" = "yes" ]; then
|
||
echo -e "${YELLOW}🗑️ Removing volumes...${NC}"
|
||
docker-compose down -v
|
||
echo -e "${GREEN}✅ Data reset complete.${NC}"
|
||
else
|
||
echo -e "${RED}❌ Reset cancelled.${NC}"
|
||
exit 0
|
||
fi
|
||
fi
|
||
|
||
# Build arguments
|
||
BUILD_ARGS="--build"
|
||
if [ "$CLEAN" = true ]; then
|
||
echo -e "${YELLOW}🧹 Clean rebuild requested...${NC}"
|
||
BUILD_ARGS="--build --force-recreate --no-cache"
|
||
fi
|
||
|
||
# Profile arguments
|
||
PROFILE_ARGS=""
|
||
if [ "$TOOLS" = true ]; then
|
||
echo -e "${YELLOW}🛠️ Launching development tools...${NC}"
|
||
PROFILE_ARGS="--profile tools"
|
||
fi
|
||
|
||
# Start containers
|
||
echo -e "${CYAN}🐳 Starting Docker containers...${NC}"
|
||
docker-compose up -d $BUILD_ARGS $PROFILE_ARGS
|
||
|
||
# Wait for health
|
||
echo ""
|
||
echo -e "${YELLOW}⏳ Waiting for services to be ready...${NC}"
|
||
echo -e " ${NC}This may take 30-60 seconds on first run...${NC}"
|
||
|
||
MAX_WAIT=120
|
||
ELAPSED=0
|
||
CHECK_INTERVAL=5
|
||
|
||
while [ $ELAPSED -lt $MAX_WAIT ]; do
|
||
BACKEND_HEALTH=$(docker inspect --format='{{.State.Health.Status}}' colaflow-api 2>/dev/null || echo "starting")
|
||
|
||
if [ "$BACKEND_HEALTH" = "healthy" ]; then
|
||
echo -e "${GREEN}✅ All services are ready!${NC}"
|
||
break
|
||
fi
|
||
|
||
sleep $CHECK_INTERVAL
|
||
ELAPSED=$((ELAPSED + CHECK_INTERVAL))
|
||
echo -e " ${NC}Still waiting... ($ELAPSED/$MAX_WAIT seconds)${NC}"
|
||
done
|
||
|
||
# Run migrations
|
||
echo ""
|
||
echo -e "${CYAN}🗄️ Running database migrations...${NC}"
|
||
docker-compose exec -T backend dotnet ef database update --no-build
|
||
|
||
# Display info
|
||
echo ""
|
||
echo -e "${CYAN}=====================================${NC}"
|
||
echo -e "${GREEN}✅ ColaFlow Development Environment Ready!${NC}"
|
||
echo -e "${CYAN}=====================================${NC}"
|
||
echo ""
|
||
echo -e "${NC}📍 Service URLs:${NC}"
|
||
echo -e " ${CYAN}Frontend: http://localhost:3000${NC}"
|
||
echo -e " ${CYAN}Backend: http://localhost:5000${NC}"
|
||
echo -e " ${CYAN}Swagger: http://localhost:5000/swagger${NC}"
|
||
echo ""
|
||
echo -e "${NC}🔐 Demo Credentials:${NC}"
|
||
echo -e " ${CYAN}Email: owner@demo.com${NC}"
|
||
echo -e " ${CYAN}Password: Admin123!${NC}"
|
||
echo ""
|
||
|
||
if [ "$TOOLS" = true ]; then
|
||
echo -e "${NC}🛠️ Development Tools:${NC}"
|
||
echo -e " ${CYAN}pgAdmin: http://localhost:5050${NC}"
|
||
echo -e " ${CYAN}Redis Commander: http://localhost:8081${NC}"
|
||
echo ""
|
||
fi
|
||
|
||
echo -e "${NC}📚 Useful Commands:${NC}"
|
||
echo -e " View logs: ${NC}docker-compose logs -f${NC}"
|
||
echo -e " Stop services: ${NC}docker-compose down${NC}"
|
||
echo -e " Restart backend: ${NC}docker-compose restart backend${NC}"
|
||
echo ""
|
||
|
||
if [ "$LOGS" = true ]; then
|
||
echo -e "${YELLOW}📋 Showing logs (Ctrl+C to exit)...${NC}"
|
||
docker-compose logs -f
|
||
fi
|
||
```
|
||
|
||
#### 3.5.3 Package.json 快捷命令
|
||
|
||
在 `colaflow-web/package.json` 中添加:
|
||
|
||
```json
|
||
{
|
||
"scripts": {
|
||
"docker:dev": "cd .. && docker-compose up -d",
|
||
"docker:dev:tools": "cd .. && docker-compose --profile tools up -d",
|
||
"docker:stop": "cd .. && docker-compose down",
|
||
"docker:logs": "cd .. && docker-compose logs -f",
|
||
"docker:restart": "cd .. && docker-compose restart backend frontend",
|
||
"docker:rebuild": "cd .. && docker-compose up -d --build",
|
||
"docker:clean": "cd .. && docker-compose down -v && docker-compose up -d --build"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 四、开发者工作流
|
||
|
||
### 4.1 首次启动
|
||
|
||
```powershell
|
||
# Windows
|
||
.\scripts\dev-start.ps1
|
||
|
||
# Linux/Mac
|
||
chmod +x scripts/dev-start.sh
|
||
./scripts/dev-start.sh
|
||
```
|
||
|
||
**首次启动流程**:
|
||
1. 检查 Docker 是否运行
|
||
2. 创建 `.env` 文件(如果不存在)
|
||
3. 拉取并构建所有镜像(约 5-10 分钟)
|
||
4. 启动所有容器
|
||
5. 等待健康检查通过
|
||
6. 运行 EF Core 迁移
|
||
7. 自动插入种子数据
|
||
8. 显示访问信息
|
||
|
||
### 4.2 日常开发
|
||
|
||
```powershell
|
||
# 前端开发者典型工作流
|
||
|
||
# 1. 启动后端服务
|
||
npm run docker:dev
|
||
|
||
# 2. 前端本地开发(热重载)
|
||
cd colaflow-web
|
||
npm run dev
|
||
|
||
# 3. 查看后端日志
|
||
npm run docker:logs
|
||
|
||
# 4. 重启后端(修改配置后)
|
||
npm run docker:restart
|
||
|
||
# 5. 停止所有服务
|
||
npm run docker:stop
|
||
```
|
||
|
||
### 4.3 常见场景
|
||
|
||
#### 场景 1:后端代码变更
|
||
```powershell
|
||
# 后端代码变更需要重新构建
|
||
docker-compose up -d --build backend
|
||
```
|
||
|
||
#### 场景 2:数据库迁移变更
|
||
```powershell
|
||
# 应用新迁移
|
||
docker-compose exec backend dotnet ef database update
|
||
|
||
# 回滚迁移
|
||
docker-compose exec backend dotnet ef database update <previous-migration-name>
|
||
```
|
||
|
||
#### 场景 3:重置开发数据
|
||
```powershell
|
||
# Windows
|
||
.\scripts\dev-start.ps1 -Reset
|
||
|
||
# Linux/Mac
|
||
./scripts/dev-start.sh --reset
|
||
```
|
||
|
||
#### 场景 4:启用开发工具
|
||
```powershell
|
||
# Windows
|
||
.\scripts\dev-start.ps1 -Tools
|
||
|
||
# Linux/Mac
|
||
./scripts/dev-start.sh --tools
|
||
```
|
||
|
||
#### 场景 5:调试后端 API
|
||
```powershell
|
||
# 查看实时日志
|
||
docker-compose logs -f backend
|
||
|
||
# 进入容器
|
||
docker-compose exec backend bash
|
||
|
||
# 查看数据库连接
|
||
docker-compose exec backend dotnet ef dbcontext info
|
||
```
|
||
|
||
### 4.4 前端环境变量配置
|
||
|
||
创建 `colaflow-web/.env.local`:
|
||
|
||
```env
|
||
# 连接到本地 Docker 容器的后端
|
||
NEXT_PUBLIC_API_URL=http://localhost:5000
|
||
NEXT_PUBLIC_WS_URL=ws://localhost:5000/hubs/project
|
||
|
||
# 开发模式设置
|
||
NEXT_PUBLIC_ENABLE_DEBUG=true
|
||
NEXT_PUBLIC_ENABLE_ANALYTICS=false
|
||
|
||
# 可选:连接到远程后端
|
||
# NEXT_PUBLIC_API_URL=https://dev-api.colaflow.com
|
||
```
|
||
|
||
---
|
||
|
||
## 五、性能优化
|
||
|
||
### 5.1 构建缓存优化
|
||
|
||
| 优化项 | 方法 | 效果 |
|
||
|--------|------|------|
|
||
| **Docker 层缓存** | 先复制 package.json/csproj | 依赖未变时跳过安装 |
|
||
| **多阶段构建** | 分离 build 和 runtime | 减少最终镜像大小 50% |
|
||
| **npm ci** | 使用 clean install | 比 npm install 快 2-3x |
|
||
| **BuildKit** | 启用 Docker BuildKit | 并行构建,提升 30% |
|
||
|
||
### 5.2 启用 BuildKit
|
||
|
||
在 `.env` 中添加:
|
||
|
||
```env
|
||
DOCKER_BUILDKIT=1
|
||
COMPOSE_DOCKER_CLI_BUILD=1
|
||
```
|
||
|
||
### 5.3 资源限制
|
||
|
||
在 `docker-compose.yml` 中添加资源限制:
|
||
|
||
```yaml
|
||
services:
|
||
backend:
|
||
deploy:
|
||
resources:
|
||
limits:
|
||
cpus: '1.0'
|
||
memory: 1G
|
||
reservations:
|
||
cpus: '0.5'
|
||
memory: 512M
|
||
|
||
frontend:
|
||
deploy:
|
||
resources:
|
||
limits:
|
||
cpus: '1.0'
|
||
memory: 1G
|
||
```
|
||
|
||
### 5.4 容器启动时间优化
|
||
|
||
| 服务 | 目标启动时间 | 优化方法 |
|
||
|------|--------------|----------|
|
||
| PostgreSQL | < 5s | 使用 alpine 镜像 |
|
||
| Redis | < 3s | 使用 alpine 镜像 |
|
||
| Backend | < 30s | 多阶段构建 + 健康检查 |
|
||
| Frontend | < 15s | npm ci + 缓存 node_modules |
|
||
|
||
---
|
||
|
||
## 六、故障排查
|
||
|
||
### 6.1 常见问题
|
||
|
||
#### 问题 1:容器无法启动
|
||
|
||
**症状**:
|
||
```
|
||
Error: Cannot start service backend: ...
|
||
```
|
||
|
||
**解决**:
|
||
```powershell
|
||
# 查看详细日志
|
||
docker-compose logs backend
|
||
|
||
# 检查端口占用
|
||
netstat -ano | findstr :5000
|
||
|
||
# 强制重建
|
||
docker-compose up -d --build --force-recreate
|
||
```
|
||
|
||
#### 问题 2:数据库连接失败
|
||
|
||
**症状**:
|
||
```
|
||
Npgsql.NpgsqlException: Connection refused
|
||
```
|
||
|
||
**解决**:
|
||
```powershell
|
||
# 检查 PostgreSQL 健康状态
|
||
docker-compose ps postgres
|
||
|
||
# 查看 PostgreSQL 日志
|
||
docker-compose logs postgres
|
||
|
||
# 重启 PostgreSQL
|
||
docker-compose restart postgres
|
||
```
|
||
|
||
#### 问题 3:前端无法连接后端
|
||
|
||
**症状**:
|
||
```
|
||
Failed to fetch: http://localhost:5000/api/...
|
||
```
|
||
|
||
**解决**:
|
||
1. 检查 `.env.local` 中的 `NEXT_PUBLIC_API_URL`
|
||
2. 确认后端健康检查通过:`docker-compose ps backend`
|
||
3. 检查 CORS 配置:`docker-compose logs backend | grep CORS`
|
||
|
||
#### 问题 4:热重载不工作
|
||
|
||
**症状**: 修改前端代码后浏览器不自动刷新
|
||
|
||
**解决**:
|
||
```powershell
|
||
# 确认 volume 挂载正确
|
||
docker-compose config | grep -A 5 "frontend.*volumes"
|
||
|
||
# 重启前端容器
|
||
docker-compose restart frontend
|
||
```
|
||
|
||
### 6.2 诊断命令
|
||
|
||
```powershell
|
||
# 检查所有服务状态
|
||
docker-compose ps
|
||
|
||
# 查看资源使用
|
||
docker stats
|
||
|
||
# 检查网络连接
|
||
docker-compose exec backend curl http://postgres:5432
|
||
|
||
# 查看环境变量
|
||
docker-compose exec backend env | grep CONNECTION
|
||
|
||
# 进入容器调试
|
||
docker-compose exec backend bash
|
||
docker-compose exec postgres psql -U colaflow
|
||
```
|
||
|
||
---
|
||
|
||
## 七、安全考虑
|
||
|
||
### 7.1 开发环境安全清单
|
||
|
||
| 检查项 | 状态 | 说明 |
|
||
|--------|------|------|
|
||
| ✅ 使用 `.env` 文件 | 推荐 | 不提交到 Git |
|
||
| ✅ 强密码策略 | 推荐 | 生产环境必须更改 |
|
||
| ⚠️ 暴露端口 | 注意 | 仅开发环境,生产环境需修改 |
|
||
| ⚠️ CORS 宽松配置 | 注意 | 仅开发环境,生产环境需限制 |
|
||
| ❌ 使用 root 用户 | 禁止 | 前端已使用非 root 用户 |
|
||
|
||
### 7.2 .gitignore 配置
|
||
|
||
确保以下文件不被提交:
|
||
|
||
```gitignore
|
||
# Environment variables
|
||
.env
|
||
.env.local
|
||
|
||
# Docker volumes (if using bind mounts)
|
||
.data/
|
||
postgres_data/
|
||
redis_data/
|
||
|
||
# Development certificates
|
||
*.pfx
|
||
*.pem
|
||
```
|
||
|
||
---
|
||
|
||
## 八、CI/CD 集成
|
||
|
||
### 8.1 GitHub Actions 示例
|
||
|
||
```yaml
|
||
name: Docker Build Test
|
||
|
||
on:
|
||
pull_request:
|
||
branches: [ main, develop ]
|
||
|
||
jobs:
|
||
docker-build:
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- uses: actions/checkout@v3
|
||
|
||
- name: Build backend image
|
||
run: |
|
||
docker build -t colaflow-api:test ./colaflow-api
|
||
|
||
- name: Build frontend image
|
||
run: |
|
||
docker build -t colaflow-web:test ./colaflow-web --target development
|
||
|
||
- name: Test docker-compose
|
||
run: |
|
||
docker-compose up -d
|
||
sleep 30
|
||
docker-compose ps
|
||
docker-compose logs
|
||
docker-compose down
|
||
```
|
||
|
||
---
|
||
|
||
## 九、下一步计划
|
||
|
||
### 9.1 实施优先级
|
||
|
||
| 任务 | 优先级 | 估时 | 负责人 |
|
||
|------|--------|------|--------|
|
||
| 1. 修复后端 Dockerfile | 🔴 P0 | 1h | Backend |
|
||
| 2. 创建前端 Dockerfile | 🔴 P0 | 2h | Frontend |
|
||
| 3. 创建数据库脚本 | 🟡 P1 | 2h | Backend |
|
||
| 4. 创建启动脚本 | 🟡 P1 | 2h | DevOps |
|
||
| 5. 编写开发者文档 | 🟢 P2 | 3h | PM |
|
||
| 6. 性能测试和优化 | 🟢 P2 | 4h | QA |
|
||
|
||
### 9.2 验收标准
|
||
|
||
- [ ] 前端开发者可以在 **5 分钟内**启动完整后端环境
|
||
- [ ] 首次启动时间 < **60 秒**(包含构建)
|
||
- [ ] 后续启动时间 < **30 秒**
|
||
- [ ] 前端热重载工作正常
|
||
- [ ] 种子数据自动加载
|
||
- [ ] 所有服务健康检查通过
|
||
- [ ] 文档完整且易于理解
|
||
- [ ] 支持 Windows、Linux、macOS
|
||
|
||
---
|
||
|
||
## 十、参考资料
|
||
|
||
### 10.1 官方文档
|
||
|
||
- [Docker Compose Documentation](https://docs.docker.com/compose/)
|
||
- [.NET Docker Images](https://hub.docker.com/_/microsoft-dotnet)
|
||
- [PostgreSQL Docker Image](https://hub.docker.com/_/postgres)
|
||
- [Redis Docker Image](https://hub.docker.com/_/redis)
|
||
- [Next.js Docker Deployment](https://nextjs.org/docs/deployment#docker-image)
|
||
|
||
### 10.2 最佳实践
|
||
|
||
- [Docker Multi-Stage Builds](https://docs.docker.com/build/building/multi-stage/)
|
||
- [Docker BuildKit](https://docs.docker.com/build/buildkit/)
|
||
- [.NET Container Best Practices](https://learn.microsoft.com/en-us/dotnet/core/docker/build-container)
|
||
- [Next.js with Docker](https://github.com/vercel/next.js/tree/canary/examples/with-docker)
|
||
|
||
---
|
||
|
||
## 附录
|
||
|
||
### A. 完整文件清单
|
||
|
||
实施本方案需要创建/修改以下文件:
|
||
|
||
```
|
||
product-master/
|
||
├── colaflow-api/
|
||
│ └── Dockerfile (需修改)
|
||
├── colaflow-web/
|
||
│ ├── Dockerfile (需创建)
|
||
│ ├── .dockerignore (需创建)
|
||
│ ├── .env.local.example (需创建)
|
||
│ └── next.config.ts (需修改)
|
||
├── scripts/
|
||
│ ├── init-db.sql (需创建)
|
||
│ ├── seed-data.sql (需创建)
|
||
│ ├── dev-start.ps1 (需创建)
|
||
│ └── dev-start.sh (需创建)
|
||
├── docker-compose.yml (需修改)
|
||
├── docker-compose.override.yml (可选修改)
|
||
├── .env.example (需创建)
|
||
├── .dockerignore (需创建)
|
||
└── docs/
|
||
├── DOCKER-DEVELOPMENT-ENVIRONMENT.md (本文档)
|
||
└── DOCKER-QUICKSTART.md (需创建,简化版)
|
||
```
|
||
|
||
### B. 估时总结
|
||
|
||
| 阶段 | 任务 | 估时 |
|
||
|------|------|------|
|
||
| **Phase 1** | 后端 Dockerfile 修复 | 1h |
|
||
| **Phase 2** | 前端 Dockerfile 创建 | 2h |
|
||
| **Phase 3** | 数据库脚本编写 | 2h |
|
||
| **Phase 4** | 启动脚本开发 | 2h |
|
||
| **Phase 5** | 文档编写 | 3h |
|
||
| **Phase 6** | 测试和调试 | 4h |
|
||
| **总计** | | **14h** |
|
||
|
||
---
|
||
|
||
**文档版本**: 1.0
|
||
**最后更新**: 2025-11-04
|
||
**维护者**: ColaFlow Architecture Team
|