EasyDrop 是一个轻量级的说说 / 日志服务,提供完整的日志发布、后台管理能力。
它适合用来搭建个人动态站、轻量博客式时间线等小型内容站点。
- 基于时间线的日志发布与展示,支持 Markdown 内容
- 支持日志置顶、隐藏、关闭评论
- 评论系统,支持最新评论列表与按日志查看评论
- 用户注册、登录、退出、个人资料维护、修改密码、修改邮箱
- 后台管理:概览、用户、日志、评论、附件、站点设置
- 附件上传与头像上传,支持本地存储和 S3
- 可选邮件能力:找回密码、邮箱验证、邮箱变更确认
- 可选验证码能力:Turnstile、reCAPTCHA、hCaptcha、GeeTest v4
- 开发模式内置 Swagger 文档
- Go 1.25
- Gin
- Gorm
- Viper
- Wire
- SQLite / MySQL / PostgreSQL
- Redis
- React 19
- TanStack Start + TanStack Router + TanStack Query
- Vite
- Tailwind CSS 4
- Vitest
.
├─ main.go # CLI 入口与应用启动
├─ internal/
│ ├─ config/ # 静态配置加载与默认值
│ ├─ di/ # Wire 依赖注入
│ ├─ router/ # Gin 路由注册
│ ├─ handler/ # HTTP Handler
│ ├─ service/ # 业务逻辑
│ ├─ repo/ # 数据访问层
│ ├─ middleware/ # 鉴权、限流、请求体限制等中间件
│ ├─ model/ # Gorm 模型
│ └─ pkg/ # 数据库、JWT、邮箱、存储、验证码等基础组件
├─ docs/ # Swagger 生成产物
├─ example/ # 示例配置与邮件模板
├─ web/ # 前端项目
└─ data/ # 本地运行时数据目录
- 准备配置与 JWT 密钥。
mkdir -p data
cp example/config.example.yaml data/config.yaml
go run . generate-jwt-token data/jwt --forceWindows PowerShell:
New-Item -ItemType Directory -Force data | Out-Null
Copy-Item example\config.example.yaml data\config.yaml
go run . generate-jwt-token data/jwt --force- 启动后端。
go run .需要自动补齐 JWT 密钥时,可使用:
go run . --auto-generate-jwt- 完成首次初始化。
- 页面方式:访问
http://localhost:8080/init - API 方式:
curl -X POST http://localhost:8080/api/v1/init \
-H "Content-Type: application/json" \
-d '{
"username":"admin",
"nickname":"管理员",
"email":"admin@example.com",
"password":"Admin123456",
"site_name":"EasyDrop",
"site_url":"http://localhost:3000",
"site_announcement":"欢迎使用 EasyDrop",
"allow_register":true
}'初始化只允许一次,再次执行会返回 409 Conflict。
方案 A:使用配置文件(推荐)
mkdir -p data
cp example/config.example.yaml data/config.yamlWindows PowerShell:
New-Item -ItemType Directory -Force data | Out-Null
Copy-Item example\config.example.yaml data\config.yaml方案 B:使用环境变量文件
mkdir -p data
cp .env.example .env
# 或:cp .env.example.full .envWindows PowerShell:
New-Item -ItemType Directory -Force data | Out-Null
Copy-Item .env.example .env
# 或:Copy-Item .env.example.full .envdocker-compose.yml 通过可选的 env_file 读取 .env;文件不存在时不会阻止启动。
当 .env 存在且包含 EASYDROP_ 变量时,会覆盖 data/config.yaml 同名项。
持久化目录统一挂载到 ./data:/app/data,常见文件包括:
data/config.yamldata/easydrop.dbdata/jwt/private.pemdata/jwt/public.pemdata/uploads/...
private.pem与public.pem都不存在:自动生成- 两者都存在:直接启动
- 仅存在一个:启动失败,需手动修复
手动生成命令:
docker compose pull
docker compose run --rm app generate-jwt-token data/jwt --forcedocker compose pull
docker compose up -d默认地址:http://localhost:8080。
镜像已使用 embed_frontend,根路径 / 可直接访问前端页面,API 仍为 /api/v1。
访问:http://localhost:8080/init
docker build -t easydrop .docker-compose.yml 默认拉取 GHCR 已发布镜像,不默认使用本地 build。
cd web
pnpm install
pnpm dev默认访问地址:http://localhost:3000。
前端默认请求 /api/v1;前后端分开运行时可显式指定:
VITE_API_BASE_URL=http://localhost:8080/api/v1 pnpm devWindows PowerShell:
$env:VITE_API_BASE_URL="http://localhost:8080/api/v1"
pnpm dev- 配置文件:
data/config.yaml - 环境变量前缀:
EASYDROP_ - 环境变量覆盖配置文件同名项
示例:
EASYDROP_SERVER_ADDR=:9090
EASYDROP_DB_DRIVER=postgresserver:运行模式、监听地址、超时、可信代理auth_cookie:登录 Cookiedb:sqlite/mysql/postgresredis:Redis 连接rate_limit:限流规则email:SMTPjwt:密钥路径、签发者、过期时间captcha:验证码开关与供应商storage:local/s3token:站内令牌命名空间
- 默认目录:
data/uploads/file、data/uploads/avatar - 默认访问:
/api/file/...、/api/avatar/... - 设置
storage.local.url_prefix后,访问路径变为/api/<prefix>/file/...与/api/<prefix>/avatar/...
- API 前缀:
/api/v1 - Swagger:
/api/swagger/index.html(仅server.mode=development时启用) - 主要分组:
/api/v1/auth/api/v1/init/api/v1/posts/api/v1/comments/api/v1/users/me/api/v1/attachments/api/v1/admin/*
go test ./...
go test -tags embed_frontend ./...cd web
pnpm test- Go 代码使用
gofmt - 不要修改生成文件:
internal/di/wire_gen.godocs/docs.goweb/docs/docs.goweb/src/routeTree.gen.ts
- 默认
go build ./go run .产物仅包含后端 - 需要后端二进制直接托管前端时,先执行
cd web && pnpm build,再用-tags embed_frontend - Docker 官方镜像已完成前端构建并启用
embed_frontend - 若使用反向代理,务必配置
server.trusted_proxies - JWT 密钥应独立管理,不要复用开发环境密钥
- 启用邮件能力前请先完成
email配置 - fork 项目后请同步更新
docker-compose.yml中镜像地址