- 发表于
2024年全栈开发技术栈选型与最佳实践

- 作者
- 姓名
- MASON Joey
- https://x.com/JoeyJoeMA
2024年全栈开发技术栈选型与最佳实践
前言
技术栈选型原则
在选择技术栈时,我们需要从以下几个维度进行考量:
1. 降本提效
- 技术选型的首要原则是降本提效,任何脱离这个原则的选型都是不负责任的
- 评估技术栈的学习曲线和维护成本
- 考虑技术栈的生态系统和社区支持
2. 技术成熟度
- 选择社区活跃、文档完善的成熟技术
- 避免使用过于前沿但不稳定的技术
- 确保技术栈有长期维护和更新计划
3. 团队匹配度
- 优先选择团队熟悉的技术栈
- 评估技术栈与团队技能的匹配程度
- 考虑团队的学习能力和接受新技术的意愿
4. 避免过度设计
以下是一些常见的过度设计案例:
- 产品未上线就进行多次重构
- 功能未实现就过度关注性能优化
- 用户基数小却追求极致的扩展性
技术栈概览
前端技术栈
graph TD
A[前端技术栈] --> B[框架]
A --> C[构建工具]
A --> D[UI组件]
A --> E[状态管理]
B --> B1[React 18+]
B --> B2[Next.js 14]
C --> C1[Turbo]
C --> C2[PNPM]
C --> C3[TSUP]
D --> D1[@radix-ui]
D --> D2[Tailwind CSS]
D --> D3[shadcn/ui]
E --> E1[use-immer]
E --> E2[Zustand]
后端技术栈
graph TD
A[后端技术栈] --> B[服务框架]
A --> C[数据存储]
A --> D[API设计]
A --> E[功能模块]
B --> B1[Hono.js]
B --> B2[Next.js API]
C --> C1[Prisma ORM]
C --> C2[Cloudflare D1]
D --> D1[@hono/zod-openapi]
D --> D2[Swagger UI]
E --> E1[邮件服务]
E --> E2[统计分析]
E --> E3[身份认证]
AI 技术栈
graph TD
A[AI技术栈] --> B[开发框架]
A --> C[模型服务]
A --> D[向量数据库]
A --> E[SAAS服务]
B --> B1[Vercel AI SDK]
C --> C1[Azure OpenAI]
C --> C2[Cloudflare AI]
C --> C3[阿里通义]
D --> D1[Cloudflare Vector]
D --> D2[Milvus]
E --> E1[Dify]
E --> E2[Flowise AI]
数据库技术栈
graph TD
A[数据库技术栈] --> B[关系型数据库]
A --> C[文档数据库]
A --> D[图数据库]
A --> E[向量数据库]
B --> B1[MySQL]
B --> B2[PostgreSQL]
C --> C1[MongoDB]
C --> C2[Cloudflare D1]
D --> D1[Neo4j]
E --> E1[Milvus]
中间件技术栈
graph TD
A[中间件技术栈] --> B[消息队列]
A --> C[缓存]
A --> D[搜索引擎]
B --> B1[Kafka]
B --> B2[Redis Stream]
C --> C1[Redis]
C --> C2[Memcached]
D --> D1[Elasticsearch]
D --> D2[Meilisearch]
运维技术栈
graph TD
A[运维技术栈] --> B[部署平台]
A --> C[服务编排]
A --> D[网络服务]
B --> B1[Cloudflare Workers]
B --> B2[Cloudflare Pages]
C --> C1[Docker]
C --> C2[PM2]
D --> D1[Caddy]
D --> D2[Cloudflare DNS]
通用工具包
在开发过程中,以下是一些必不可少的工具包:
zodjs:强大的数据校验和TypeScript类型推导工具
import { z } from 'zod'; // 定义数据模型 const UserSchema = z.object({ id: z.string().uuid(), name: z.string().min(2).max(50), email: z.string().email(), age: z.number().min(0).max(120).optional(), }); // 类型推导 type User = z.infer<typeof UserSchema>; // 数据校验 function createUser(data: unknown): User { return UserSchema.parse(data); }
tsx:用于直接运行TypeScript文件的工具
# 直接运行ts文件 npx tsx src/script.ts # 开发模式运行(支持热重载) npx tsx watch src/server.ts
vitest:现代化的单元测试框架
import { describe, it, expect } from 'vitest'; import { sum } from './math'; describe('math utils', () => { it('should add two numbers correctly', () => { expect(sum(1, 2)).toBe(3); }); });
nanoid:轻量级的ID生成工具
import { nanoid } from 'nanoid'; // 生成唯一ID const id = nanoid(); // "V1StGXR8_Z5jdHi6B-myT" // 指定长度 const shortId = nanoid(10); // "IRFa-VaY2b"
SAAS服务详解
1. Dify - 开源的LLMOps平台
Dify是一个强大的LLMOps平台,它提供了完整的大语言模型应用开发和运营工具链:
核心功能
- Prompt管理:专业的Prompt编排和版本管理
- 多模型支持:支持OpenAI、Azure OpenAI、阿里通义等多个模型服务
- 应用编排:可视化的对话流程设计
- 数据安全:内置数据加密和访问控制
最佳实践
// 使用Dify API构建对话应用
const DIFY_API_KEY = process.env.DIFY_API_KEY;
const DIFY_APP_ID = process.env.DIFY_APP_ID;
async function chatWithDify(message: string) {
const response = await fetch(`https://api.dify.ai/v1/chat-messages`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${DIFY_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
app_id: DIFY_APP_ID,
messages: [{ role: 'user', content: message }],
}),
});
return response.json();
}
2. Umami - 开源网站分析工具
Umami是一个注重隐私的网站分析工具,提供了丰富的数据分析功能:
核心特性
- 无Cookie追踪:符合GDPR等隐私法规
- 实时分析:访问数据实时更新
- 自定义事件:支持追踪自定义行为
- 多站点管理:单一面板管理多个网站
部署配置
# docker-compose.yml
version: '3'
services:
umami:
image: ghcr.io/umami-software/umami:postgresql-latest
ports:
- "3000:3000"
environment:
DATABASE_URL: postgresql://umami:umami@db:5432/umami
DATABASE_TYPE: postgresql
APP_SECRET: your-secret-key
db:
image: postgres:12-alpine
environment:
POSTGRES_DB: umami
POSTGRES_USER: umami
POSTGRES_PASSWORD: umami
volumes:
- ./sql/schema.postgresql.sql:/docker-entrypoint-initdb.d/schema.postgresql.sql:ro
- ./data:/var/lib/postgresql/data
3. Flowise - 可视化AI工作流平台
Flowise是一个强大的AI工作流设计和部署平台:
主要优势
- 可视化编排:拖拽式的工作流设计
- 组件丰富:内置大量AI和数据处理组件
- API集成:自动生成REST API
- 版本控制:工作流版本管理
部署示例
# docker-compose.yml
version: '3.8'
services:
flowise:
image: flowiseai/flowise
ports:
- "3000:3000"
environment:
- DATABASE_PATH=/root/.flowise
- APIKEY_PATH=/root/.flowise
- SECRETKEY_PATH=/root/.flowise
volumes:
- ~/.flowise:/root/.flowise
数据库技术栈详解
1. MySQL - 企业级关系型数据库
性能优化策略
- 索引优化:合理使用复合索引,避免过度索引
- 查询优化:使用EXPLAIN分析执行计划
- 分区策略:根据业务特点选择分区方案
- 主从架构:实现读写分离,提升性能
最佳实践
-- 索引优化示例
CREATE TABLE users (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL,
status TINYINT NOT NULL DEFAULT 1,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- 复合索引
INDEX idx_status_created (status, created_at),
-- 唯一索引
UNIQUE INDEX idx_email (email)
);
-- 分区表示例
CREATE TABLE orders (
id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
amount DECIMAL(10,2) NOT NULL,
created_at TIMESTAMP NOT NULL
)
PARTITION BY RANGE (UNIX_TIMESTAMP(created_at)) (
PARTITION p_2023 VALUES LESS THAN (UNIX_TIMESTAMP('2024-01-01 00:00:00')),
PARTITION p_2024 VALUES LESS THAN (UNIX_TIMESTAMP('2025-01-01 00:00:00'))
);
2. MongoDB - 分布式文档数据库
架构设计要点
- Schema设计:根据查询模式优化文档结构
- 索引策略:创建复合索引支持复杂查询
- 分片集群:水平扩展实现高可用
实践示例
// Schema设计示例
const OrderSchema = new Schema({
userId: { type: ObjectId, ref: 'User', index: true },
items: [{
productId: { type: ObjectId, ref: 'Product' },
quantity: Number,
price: Number
}],
status: { type: String, enum: ['pending', 'paid', 'shipped'], index: true },
totalAmount: Number,
// 复合索引字段
createdAt: { type: Date, default: Date.now }
});
// 创建复合索引
OrderSchema.index({ userId: 1, status: 1, createdAt: -1 });
// 分片配置
db.adminCommand({
shardCollection: "mydb.orders",
key: { userId: "hashed" }
});
3. Neo4j - 图数据库
应用场景
- 社交网络:关系图谱分析
- 推荐系统:基于关系的个性化推荐
- 知识图谱:复杂知识体系构建
查询示例
// 创建用户节点和关系
CREATE (u1:User {id: 1, name: 'Alice'})
CREATE (u2:User {id: 2, name: 'Bob'})
CREATE (u1)-[:FOLLOWS]->(u2)
// 查找二度关系
MATCH (user:User {name: 'Alice'})-[:FOLLOWS*2]->(follower)
RETURN follower.name;
// 最短路径查询
MATCH p=shortestPath(
(user1:User {name: 'Alice'})-[:FOLLOWS*]-(user2:User {name: 'Charlie'})
)
RETURN p;
中间件技术栈详解
1. Kafka - 分布式消息队列
架构特点
- 高吞吐量:分区并行处理
- 可靠性:多副本机制
- 扩展性:支持水平扩展
- 持久化:消息持久化存储
最佳实践
// Kafka生产者示例
import { Kafka } from 'kafkajs';
const kafka = new Kafka({
clientId: 'my-app',
brokers: ['localhost:9092']
});
const producer = kafka.producer();
async function sendMessage() {
await producer.connect();
await producer.send({
topic: 'test-topic',
messages: [
{ key: 'key1', value: JSON.stringify({ hello: 'world' }) }
],
});
}
// Kafka消费者示例
const consumer = kafka.consumer({ groupId: 'test-group' });
async function startConsumer() {
await consumer.connect();
await consumer.subscribe({ topic: 'test-topic', fromBeginning: true });
await consumer.run({
eachMessage: async ({ topic, partition, message }) => {
console.log({
value: message.value.toString(),
});
},
});
}
2. Redis - 高性能缓存
使用场景
- 缓存层:减轻数据库压力
- 会话存储:分布式Session管理
- 消息队列:轻量级消息队列
- 排行榜:实时排名统计
实践示例
import { Redis } from 'ioredis';
const redis = new Redis({
host: 'localhost',
port: 6379,
// 集群配置
cluster: true,
nodes: [
{ host: 'node1', port: 6379 },
{ host: 'node2', port: 6379 },
{ host: 'node3', port: 6379 }
]
});
// 缓存示例
async function cacheUser(userId: string, userData: any) {
await redis.set(`user:${userId}`, JSON.stringify(userData), 'EX', 3600);
}
// 分布式锁
async function acquireLock(lockKey: string, timeout: number) {
const token = Math.random().toString(36);
const acquired = await redis.set(lockKey, token, 'NX', 'EX', timeout);
return acquired ? token : null;
}
// 排行榜实现
async function updateLeaderboard(userId: string, score: number) {
await redis.zadd('leaderboard', score, userId);
// 获取前10名
const top10 = await redis.zrevrange('leaderboard', 0, 9, 'WITHSCORES');
return top10;
}
前端技术栈详解
1. 项目构建 - Turbo + PNPM + Next.js
使用Turbo和PNPM搭建monorepo项目结构:
# 初始化项目
pnpm dlx create-turbo@latest my-turborepo
cd my-turborepo
# 安装依赖
pnpm install
# 创建新的应用或包
pnpm turbo gen workspace
项目结构示例:
.
├── apps/
│ ├── web/ # Next.js主应用
│ └── docs/ # 文档站点
├── packages/
│ ├── ui/ # 共享UI组件
│ ├── config/ # 共享配置
│ └── utils/ # 工具函数
├── turbo.json # Turbo配置
└── package.json # 工作空间配置
turbo.json配置示例:
{
"$schema": "https://turbo.build/schema.json",
"globalDependencies": ["**/.env.*local"],
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**", "!.next/cache/**"]
},
"lint": {},
"dev": {
"cache": false,
"persistent": true
}
}
}
2. UI组件库最佳实践
在现代前端开发中,我们推荐使用 @radix-ui + Tailwind CSS + shadcn/ui 的组合:
@radix-ui 基础组件
import * as Dialog from '@radix-ui/react-dialog';
function ConfirmDialog() {
return (
<Dialog.Root>
<Dialog.Trigger>
<button>打开对话框</button>
</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Overlay className="fixed inset-0 bg-black/50" />
<Dialog.Content className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-white p-6 rounded-lg">
<Dialog.Title>确认操作</Dialog.Title>
<Dialog.Description>
您确定要执行此操作吗?
</Dialog.Description>
<div className="mt-4 flex justify-end gap-2">
<Dialog.Close>
<button>取消</button>
</Dialog.Close>
<button onClick={() => console.log('确认')}>确认</button>
</div>
</Dialog.Content>
</Dialog.Portal>
</Dialog.Root>
);
}
shadcn/ui 高级组件
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
function ProductCard() {
return (
<Card>
<CardHeader>
<CardTitle>产品名称</CardTitle>
<CardDescription>产品描述</CardDescription>
</CardHeader>
<CardContent>
<p>产品详细信息...</p>
</CardContent>
<CardFooter>
<button>立即购买</button>
</CardFooter>
</Card>
);
}
3. 状态管理最佳实践
在Next.js应用中,我们推荐使用轻量级的use-immer来管理状态:
简单组件状态
import { useImmer } from 'use-immer';
function TodoList() {
const [todos, updateTodos] = useImmer([
{ id: 1, text: '学习React', done: false },
{ id: 2, text: '学习Next.js', done: false },
]);
const toggleTodo = (id: number) => {
updateTodos(draft => {
const todo = draft.find(t => t.id === id);
if (todo) todo.done = !todo.done;
});
};
return (
<ul>
{todos.map(todo => (
<li key={todo.id} onClick={() => toggleTodo(todo.id)}>
{todo.text} {todo.done ? '✓' : ''}
</li>
))}
</ul>
);
}
复杂应用状态
import { createStore } from 'zustand';
import { immer } from 'zustand/middleware/immer';
interface Post {
id: number;
title: string;
content: string;
}
interface PostStore {
posts: Post[];
loading: boolean;
addPost: (post: Post) => void;
fetchPosts: () => Promise<void>;
}
const usePostStore = createStore(
immer<PostStore>((set) => ({
posts: [],
loading: false,
addPost: (post) =>
set((state) => {
state.posts.push(post);
}),
fetchPosts: async () => {
set((state) => { state.loading = true });
try {
const response = await fetch('/api/posts');
const posts = await response.json();
set((state) => {
state.posts = posts;
state.loading = false;
});
} catch (error) {
set((state) => { state.loading = false });
console.error('Failed to fetch posts:', error);
}
},
}))
);
后端技术栈详解
1. API接口设计 - OpenAPI规范
使用Hono.js + Zod构建类型安全的API接口:
import { OpenAPIHono } from '@hono/zod-openapi';
import { z } from 'zod';
const app = new OpenAPIHono();
// 定义请求和响应的Schema
const UserSchema = z.object({
id: z.string().uuid(),
name: z.string().min(2),
email: z.string().email(),
});
const CreateUserSchema = UserSchema.omit({ id: true });
// 定义API路由
app.openapi(
'/users',
{
method: 'post',
request: {
body: {
content: {
'application/json': {
schema: CreateUserSchema,
},
},
},
},
responses: {
200: {
content: {
'application/json': {
schema: UserSchema,
},
},
},
},
},
async (c) => {
const data = c.req.valid('json');
const user = await createUser(data);
return c.json(user);
}
);
// 生成OpenAPI文档
app.doc('/docs', {
openapi: '3.0.0',
info: {
title: 'User API',
version: '1.0.0',
},
});
2. 数据库操作 - Prisma ORM
使用Prisma进行数据库操作的最佳实践:
// schema.prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id String @id @default(uuid())
email String @unique
name String
posts Post[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Post {
id String @id @default(uuid())
title String
content String
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
数据库操作示例:
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
// 创建用户和文章
async function createUserWithPosts() {
const user = await prisma.user.create({
data: {
email: 'alice@example.com',
name: 'Alice',
posts: {
create: [
{
title: 'Hello World',
content: 'This is my first post!',
published: true,
},
],
},
},
include: {
posts: true,
},
});
return user;
}
// 查询带分页的文章列表
async function getPublishedPosts(page: number, pageSize: number) {
const posts = await prisma.post.findMany({
where: {
published: true,
},
include: {
author: {
select: {
name: true,
email: true,
},
},
},
skip: (page - 1) * pageSize,
take: pageSize,
orderBy: {
createdAt: 'desc',
},
});
return posts;
}
3. 邮件服务集成
使用React Email + Nodemailer构建现代化的邮件服务:
// email-templates/WelcomeEmail.tsx
import { Html, Head, Body, Container, Text, Button } from '@react-email/components';
export function WelcomeEmail({ username }: { username: string }) {
return (
<Html>
<Head />
<Body style={{
backgroundColor: '#ffffff',
margin: '0 auto',
fontFamily: 'system-ui'
}}>
<Container>
<Text>欢迎 {username} 加入我们!</Text>
<Button
href="https://example.com/get-started"
style={{
backgroundColor: '#000000',
color: '#ffffff',
padding: '12px 20px',
}}
>
开始使用
</Button>
</Container>
</Body>
</Html>
);
}
// email-service.ts
import nodemailer from 'nodemailer';
import { render } from '@react-email/render';
import { WelcomeEmail } from './email-templates/WelcomeEmail';
const transporter = nodemailer.createTransport({
host: process.env.SMTP_HOST,
port: Number(process.env.SMTP_PORT),
secure: true,
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS,
},
});
export async function sendWelcomeEmail(to: string, username: string) {
const html = render(WelcomeEmail({ username }));
await transporter.sendMail({
from: '"团队" <team@example.com>',
to,
subject: '欢迎加入',
html,
});
}
AI技术栈详解
1. Vercel AI SDK集成
使用Vercel AI SDK实现AI功能:
// app/api/chat/route.ts
import { Configuration, OpenAIApi } from 'openai-edge';
import { OpenAIStream, StreamingTextResponse } from 'ai';
const config = new Configuration({
apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(config);
export async function POST(req: Request) {
const { messages } = await req.json();
const response = await openai.createChatCompletion({
model: 'gpt-3.5-turbo',
stream: true,
messages,
});
const stream = OpenAIStream(response);
return new StreamingTextResponse(stream);
}
// app/chat/page.tsx
import { useChat } from 'ai/react';
export default function ChatPage() {
const { messages, input, handleInputChange, handleSubmit } = useChat();
return (
<div className="flex flex-col h-screen">
<div className="flex-1 overflow-y-auto p-4">
{messages.map(message => (
<div key={message.id} className="mb-4">
<strong>{message.role === 'user' ? '你:' : 'AI:'}</strong>
<p>{message.content}</p>
</div>
))}
</div>
<form onSubmit={handleSubmit} className="p-4 border-t">
<input
value={input}
onChange={handleInputChange}
placeholder="输入消息..."
className="w-full p-2 border rounded"
/>
</form>
</div>
);
}
运维技术栈详解
1. Docker部署最佳实践
常用Docker命令
# 服务管理
docker compose up -d # 后台启动所有服务
docker compose down # 停止并移除所有容器
docker compose restart # 重启所有服务
docker compose pull # 拉取最新镜像
# 容器操作
docker ps # 查看运行中的容器
docker container ls # 列出所有容器
docker logs [容器ID] # 查看容器日志
docker logs -f [容器ID] # 实时查看日志
docker exec -it [容器ID] /bin/bash # 进入容器终端
# 镜像管理
docker images # 查看本地镜像
docker pull [镜像名] # 拉取镜像
docker rmi [镜像ID] # 删除镜像
# 数据卷管理
docker volume ls # 查看数据卷
docker volume prune # 清理未使用的数据卷
服务配置示例
MySQL服务
# mysql/docker-compose.yml
version: '3.8'
services:
mysql:
image: mysql:8.0
container_name: mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=your_root_password
- MYSQL_DATABASE=your_database
- MYSQL_USER=your_user
- MYSQL_PASSWORD=your_password
ports:
- "3306:3306"
volumes:
- ./volumes/mysql/data:/var/lib/mysql
- ./volumes/mysql/conf.d:/etc/mysql/conf.d
command: --default-authentication-plugin=mysql_native_password
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
Redis服务
# redis/docker-compose.yml
version: '3.8'
services:
redis:
image: redis:7.0-alpine
container_name: redis
restart: always
ports:
- "6379:6379"
volumes:
- ./volumes/redis/data:/data
- ./volumes/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf
command: redis-server /usr/local/etc/redis/redis.conf
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
PostgreSQL服务
# postgres/docker-compose.yml
version: '3.8'
services:
postgres:
image: postgres:15-alpine
container_name: postgres
restart: always
environment:
- POSTGRES_USER=your_user
- POSTGRES_PASSWORD=your_password
- POSTGRES_DB=your_database
ports:
- "5432:5432"
volumes:
- ./volumes/postgres/data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
interval: 10s
timeout: 5s
retries: 5
应用服务配置
Web应用示例
# app/docker-compose.yml
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
container_name: web_app
restart: always
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=postgresql://user:password@postgres:5432/myapp
- REDIS_URL=redis://redis:6379
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
networks:
default:
name: app_network
external: true
2. Caddy服务器配置
使用Caddy实现自动HTTPS和反向代理:
# Caddyfile
{
email "admin@example.com"
# 全局设置
auto_https off # 在反向代理后面时建议关闭自动HTTPS
admin off # 关闭管理API
}
# 基础配置示例
example.com {
reverse_proxy /api/* localhost:3000
reverse_proxy /* localhost:3001
header {
# 启用HSTS
Strict-Transport-Security "max-age=31536000;"
# 启用CSP
Content-Security-Policy "default-src 'self';"
# 防止点击劫持
X-Frame-Options "DENY"
# 启用XSS过滤
X-XSS-Protection "1; mode=block"
}
log {
output file /var/log/caddy/access.log
format json
}
}
# Dify服务配置
dify.yourdomain.com {
reverse_proxy :8001 {
header_up Host {host}
header_up X-Real-IP {remote}
header_up X-Forwarded-Port {server_port}
}
}
# Umami服务配置
umami.yourdomain.com {
reverse_proxy :3000 {
header_up Host {host}
}
}
# Flowise服务配置
flowise.yourdomain.com {
reverse_proxy :3000 {
header_up Host {host}
}
}
3. 服务部署配置
Dify配置
# dify/docker-compose.yml
version: '3.8'
services:
dify:
image: langgenius/dify-web:latest
container_name: dify
restart: always
environment:
- EXPOSE_NGINX_PORT=8001
- APP_API_URL=http://api:5001
ports:
- "8001:8001"
depends_on:
- api
api:
image: langgenius/dify-api:latest
container_name: dify-api
restart: always
environment:
- POSTGRES_URL=postgresql://dify:dify@postgres:5432/dify
- REDIS_URL=redis://redis:6379/0
volumes:
- ./volumes/dify/data:/app/data
postgres:
image: postgres:15-alpine
container_name: dify-postgres
restart: always
environment:
- POSTGRES_USER=dify
- POSTGRES_PASSWORD=dify
- POSTGRES_DB=dify
volumes:
- ./volumes/dify/postgres:/var/lib/postgresql/data
redis:
image: redis:7-alpine
container_name: dify-redis
restart: always
volumes:
- ./volumes/dify/redis:/data
Umami配置
# umami/docker-compose.yml
version: '3.8'
services:
umami:
image: ghcr.io/umami-software/umami:postgresql-latest
container_name: umami
restart: always
ports:
- "3000:3000"
environment:
DATABASE_URL: postgresql://umami:umami@db:5432/umami
DATABASE_TYPE: postgresql
APP_SECRET: your-random-string-here
depends_on:
db:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "curl http://localhost:3000/api/heartbeat"]
interval: 5s
timeout: 5s
retries: 5
- Table of Contents
- 2024年全栈开发技术栈选型与最佳实践
- 前言
- 技术栈选型原则
- 1. 降本提效
- 2. 技术成熟度
- 3. 团队匹配度
- 4. 避免过度设计
- 技术栈概览
- 前端技术栈
- 后端技术栈
- AI 技术栈
- 数据库技术栈
- 中间件技术栈
- 运维技术栈
- 通用工具包
- SAAS服务详解
- 1. Dify - 开源的LLMOps平台
- 核心功能
- 最佳实践
- 2. Umami - 开源网站分析工具
- 核心特性
- 部署配置
- 3. Flowise - 可视化AI工作流平台
- 主要优势
- 部署示例
- 数据库技术栈详解
- 1. MySQL - 企业级关系型数据库
- 性能优化策略
- 最佳实践
- 2. MongoDB - 分布式文档数据库
- 架构设计要点
- 实践示例
- 3. Neo4j - 图数据库
- 应用场景
- 查询示例
- 中间件技术栈详解
- 1. Kafka - 分布式消息队列
- 架构特点
- 最佳实践
- 2. Redis - 高性能缓存
- 使用场景
- 实践示例
- 前端技术栈详解
- 1. 项目构建 - Turbo + PNPM + Next.js
- 2. UI组件库最佳实践
- @radix-ui 基础组件
- shadcn/ui 高级组件
- 3. 状态管理最佳实践
- 简单组件状态
- 复杂应用状态
- 后端技术栈详解
- 1. API接口设计 - OpenAPI规范
- 2. 数据库操作 - Prisma ORM
- 3. 邮件服务集成
- AI技术栈详解
- 1. Vercel AI SDK集成
- 运维技术栈详解
- 1. Docker部署最佳实践
- 常用Docker命令
- 服务配置示例
- MySQL服务
- Redis服务
- PostgreSQL服务
- 应用服务配置
- Web应用示例
- 2. Caddy服务器配置
- 3. 服务部署配置
- Dify配置
- Umami配置