bunjs-docker-mastery
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBun.js + Docker Mastery
Bun.js + Docker 精通指南
"Simplicity is the ultimate sophistication." — Leonardo da Vinci
"简洁是终极的复杂。" — 列奥纳多·达·芬奇
Filosofi Inti (20 Tahun Wisdom)
核心理念(20年经验总结)
KISS - Keep It Stupid Simple
KISS - 保持极致简洁
typescript
// ❌ Over-engineering
class UserServiceFactoryAbstractSingletonProxyDecorator { ... }
// ✅ Simple & Clear
const userService = { create, update, delete, findById }typescript
// ❌ 过度设计
class UserServiceFactoryAbstractSingletonProxyDecorator { ... }
// ✅ 简洁清晰
const userService = { create, update, delete, findById }Less is More
少即是多
- 1 file = 1 tanggung jawab (max 200 lines)
- 1 function = 1 task (max 20 lines)
- Jika butuh komentar panjang, refactor kodenya
- Nama yang jelas > komentar yang panjang
- 1个文件 = 1项职责(最多200行)
- 1个函数 = 1个任务(最多20行)
- 如果需要长篇注释,就重构代码
- 清晰的命名 > 冗长的注释
Red Flags (Warning Signs)
警示信号(危险标志)
- File > 300 lines → split
- Function > 30 lines → extract
- Nested callback > 2 level → refactor
- Cyclomatic complexity > 10 → simplify
- type → define proper types
any
- 文件超过300行 → 拆分
- 函数超过30行 → 提取
- 嵌套回调超过2层 → 重构
- 圈复杂度超过10 → 简化
- 使用类型 → 定义正确的类型
any
Quick Start
快速开始
Inisialisasi Project Baru
初始化新项目
bash
undefinedbash
undefinedGunakan script init
使用初始化脚本
./scripts/init-project.sh my-app
./scripts/init-project.sh my-app
Atau manual
或手动操作
bun init
bun add hono zod drizzle-orm pino
bun add -d @types/bun vitest
undefinedbun init
bun add hono zod drizzle-orm pino
bun add -d @types/bun vitest
undefinedStruktur Folder Production-Ready
生产就绪的文件夹结构
src/
├── index.ts # Entry point ONLY (max 20 lines)
├── app.ts # App setup & middleware registration
├── config/
│ ├── index.ts # Export semua config
│ ├── env.ts # Environment validation dengan Zod
│ └── database.ts # Database config
├── routes/
│ ├── index.ts # Route aggregator
│ ├── user.route.ts # User routes
│ └── auth.route.ts # Auth routes
├── controllers/ # HTTP layer ONLY
├── services/ # Business logic
├── repositories/ # Data access layer
├── middlewares/
│ ├── auth.ts # Authentication
│ ├── validate.ts # Request validation
│ └── error.ts # Error handler
├── utils/
│ ├── response.ts # Standard response helper
│ ├── logger.ts # Pino logger setup
│ └── errors.ts # Custom error classes
└── types/
├── index.d.ts # Global types
└── api.types.ts # API request/response typessrc/
├── index.ts # 仅作为入口文件(最多20行)
├── app.ts # 应用设置与中间件注册
├── config/
│ ├── index.ts # 导出所有配置
│ ├── env.ts # 使用Zod验证环境变量
│ └── database.ts # 数据库配置
├── routes/
│ ├── index.ts # 路由聚合器
│ ├── user.route.ts # 用户路由
│ └── auth.route.ts # 认证路由
├── controllers/ # 仅HTTP层
├── services/ # 业务逻辑
├── repositories/ # 数据访问层
├── middlewares/
│ ├── auth.ts # 认证中间件
│ ├── validate.ts # 请求验证中间件
│ └── error.ts # 错误处理中间件
├── utils/
│ ├── response.ts # 标准响应工具
│ ├── logger.ts # Pino日志配置
│ └── errors.ts # 自定义错误类
└── types/
├── index.d.ts # 全局类型
└── api.types.ts # API请求/响应类型Core Patterns
核心模式
1. Entry Point yang Bersih
1. 简洁的入口文件
typescript
// src/index.ts - HANYA INI
import { app } from "./app"
import { env } from "./config/env"
import { logger } from "./utils/logger"
const server = Bun.serve({
port: env.PORT,
fetch: app.fetch,
})
logger.info(`🚀 Server running on ${server.url}`)typescript
// src/index.ts - 仅保留以下内容
import { app } from "./app"
import { env } from "./config/env"
import { logger } from "./utils/logger"
const server = Bun.serve({
port: env.PORT,
fetch: app.fetch,
})
logger.info(`🚀 服务器运行于 ${server.url}`)2. Environment Validation (WAJIB)
2. 环境变量验证(必填)
typescript
// src/config/env.ts
import { z } from "zod"
const envSchema = z.object({
NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
PORT: z.coerce.number().default(3000),
DATABASE_URL: z.string().url(),
JWT_SECRET: z.string().min(32),
REDIS_URL: z.string().url().optional(),
})
export const env = envSchema.parse(process.env)
export type Env = z.infer<typeof envSchema>typescript
// src/config/env.ts
import { z } from "zod"
const envSchema = z.object({
NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
PORT: z.coerce.number().default(3000),
DATABASE_URL: z.string().url(),
JWT_SECRET: z.string().min(32),
REDIS_URL: z.string().url().optional(),
})
export const env = envSchema.parse(process.env)
export type Env = z.infer<typeof envSchema>3. Layered Architecture
3. 分层架构
HTTP Request → Controller → Service → Repository → Database
↓ ↓ ↓
Validation Business Data Access
Logic (Drizzle)HTTP请求 → 控制器 → 服务 → 数据仓库 → 数据库
↓ ↓ ↓
验证逻辑 业务逻辑 数据访问
(使用Drizzle)4. Error Handling yang Proper
4. 规范的错误处理
typescript
// src/utils/errors.ts
export class AppError extends Error {
constructor(
public message: string,
public statusCode: number = 500,
public code: string = "INTERNAL_ERROR"
) {
super(message)
Error.captureStackTrace(this, this.constructor)
}
}
export class NotFoundError extends AppError {
constructor(resource: string) {
super(`${resource} not found`, 404, "NOT_FOUND")
}
}
export class ValidationError extends AppError {
constructor(message: string) {
super(message, 400, "VALIDATION_ERROR")
}
}typescript
// src/utils/errors.ts
export class AppError extends Error {
constructor(
public message: string,
public statusCode: number = 500,
public code: string = "INTERNAL_ERROR"
) {
super(message)
Error.captureStackTrace(this, this.constructor)
}
}
export class NotFoundError extends AppError {
constructor(resource: string) {
super(`${resource} 不存在`, 404, "NOT_FOUND")
}
}
export class ValidationError extends AppError {
constructor(message: string) {
super(message, 400, "VALIDATION_ERROR")
}
}5. Response Standard
5. 标准响应格式
typescript
// src/utils/response.ts
export const ok = <T>(data: T) => ({ success: true, data })
export const created = <T>(data: T) => ({ success: true, data })
export const error = (message: string, code: string) => ({
success: false,
error: { message, code }
})typescript
// src/utils/response.ts
export const ok = <T>(data: T) => ({ success: true, data })
export const created = <T>(data: T) => ({ success: true, data })
export const error = (message: string, code: string) => ({
success: false,
error: { message, code }
})Docker Best Practices
Docker最佳实践
Multi-stage Build (Production)
多阶段构建(生产环境)
dockerfile
undefineddockerfile
undefinedBuild stage
构建阶段
FROM oven/bun:1-alpine AS builder
WORKDIR /app
COPY package.json bun.lockb ./
RUN bun install --frozen-lockfile --production=false
COPY . .
RUN bun run build
FROM oven/bun:1-alpine AS builder
WORKDIR /app
COPY package.json bun.lockb ./
RUN bun install --frozen-lockfile --production=false
COPY . .
RUN bun run build
Production stage
生产阶段
FROM oven/bun:1-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
FROM oven/bun:1-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
Security: Non-root user
安全:使用非root用户
RUN addgroup -g 1001 -S nodejs &&
adduser -S bunjs -u 1001 USER bunjs
adduser -S bunjs -u 1001 USER bunjs
COPY --from=builder --chown=bunjs:nodejs /app/dist ./dist
COPY --from=builder --chown=bunjs:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=bunjs:nodejs /app/package.json ./
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
CMD ["bun", "run", "dist/index.js"]
undefinedRUN addgroup -g 1001 -S nodejs &&
adduser -S bunjs -u 1001 USER bunjs
adduser -S bunjs -u 1001 USER bunjs
COPY --from=builder --chown=bunjs:nodejs /app/dist ./dist
COPY --from=builder --chown=bunjs:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=bunjs:nodejs /app/package.json ./
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
CMD ["bun", "run", "dist/index.js"]
undefinedDocker Compose (Development)
Docker Compose(开发环境)
Lihat
assets/project-template/docker/docker-compose.yml请查看
assets/project-template/docker/docker-compose.ymlDebugging Mastery
调试精通
Common Crash Points & Solutions
常见崩溃点与解决方案
| Issue | Penyebab | Solusi |
|---|---|---|
| Memory leak | Uncleared intervals/listeners | Cleanup di graceful shutdown |
| Connection pool exhausted | Tidak release connection | Gunakan |
| Race condition | Async tanpa proper await | Promise.all dengan error handling |
| Uncaught Promise rejection | Missing try-catch | Global error handler |
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 内存泄漏 | 未清理定时器/监听器 | 在优雅关闭时进行清理 |
| 连接池耗尽 | 未释放连接 | 使用 |
| 竞态条件 | 异步操作未正确使用await | 结合错误处理使用Promise.all |
| 未捕获Promise拒绝 | 缺少try-catch | 全局错误处理 |
Debugging Tools
调试工具
typescript
// Bun native debugger
bun --inspect src/index.ts
// Memory profiling
bun --smol src/index.ts // Low memory mode
// Trace async operations
process.on("unhandledRejection", (reason, promise) => {
logger.error({ reason, promise }, "Unhandled Rejection")
})typescript
// Bun原生调试器
bun --inspect src/index.ts
// 内存分析
bun --smol src/index.ts // 低内存模式
// 追踪异步操作
process.on("unhandledRejection", (reason, promise) => {
logger.error({ reason, promise }, "未捕获的Promise拒绝")
})References (Detailed Guides)
参考资料(详细指南)
- Clean Code Patterns: See references/clean-code-patterns.md
- Debugging Deep Dive: See references/debugging-guide.md
- Library Arsenal (20+ recommended): See references/library-arsenal.md
- Docker Advanced Patterns: See references/docker-patterns.md
- Testing Strategy: See references/testing-strategy.md
- 整洁代码模式: 查看 references/clean-code-patterns.md
- 深度调试指南: 查看 references/debugging-guide.md
- 推荐库集合(20+个): 查看 references/library-arsenal.md
- Docker高级模式: 查看 references/docker-patterns.md
- 测试策略: 查看 references/testing-strategy.md
Scripts
脚本
- - Initialize new project dengan template
scripts/init-project.sh - - Healthcheck endpoint template
scripts/healthcheck.ts
- - 使用模板初始化新项目
scripts/init-project.sh - - 健康检查端点模板
scripts/healthcheck.ts
Assets
资源
- - Full project boilerplate siap pakai
assets/project-template/
- - 可直接使用的完整项目模板
assets/project-template/
Checklist Sebelum Production
生产环境上线前检查清单
- Environment variables validated dengan Zod
- Graceful shutdown implemented
- Health check endpoint
/health - Structured logging dengan Pino
- Error handling global
- Rate limiting
- CORS configured
- Security headers (helmet)
- Database connection pooling
- Docker multi-stage build
- CI/CD pipeline
- Monitoring & alerting ready
- 使用Zod验证环境变量
- 实现优雅关闭
- 健康检查端点
/health - 使用Pino进行结构化日志
- 全局错误处理
- 速率限制
- CORS配置
- 安全头(helmet)
- 数据库连接池
- Docker多阶段构建
- CI/CD流水线
- 监控与告警就绪