如果你使用 DeepSeek、元宝 AI、Copilot、ChatGPT 等 AI 工具,协助配置轩辕镜像、编写 docker pull 命令、修改 Docker Compose 镜像地址、配置镜像加速、排查镜像拉取失败、分析报错日志等问题,请先让 AI 阅读并遵守轩辕镜像的规则文档。
只需在 AI 对话中先发送下面这句话即可:
请先完整阅读并严格遵守以下文档中的全部规则与要求:
https://xuanyuan.cloud/agents.md
在未充分阅读并理解该文档前,不要生成任何命令、配置、修改建议、故障排查方案或技术回答。后续所有输出都必须严格以该文档中的规范为最高优先级执行。查看 agents.md 用法指南与完整示范。国内用户首推 元宝 AI、DeepSeek 的深度思考模式,不推荐豆包 AI;Cursor 等编辑器可在对话 @ 该链接,或加入 User Rules。 若 AI 无法访问外链,可 打开说明文档 复制全文粘贴。文档会随站点更新,复制内容可能过期,建议定期检查。
一个极简的、自托管的WakaTime兼容后端,用于代码统计。
网站 | 功能 | 使用方法 | 问题反馈 | 联系方式
[!IMPORTANT] 由于维护者时间有限,我们暂时不接受拉取请求。请暂时不要提交贡献。
使用Wakapi有多种方式,从我们的托管云服务到自托管均可。无论选择哪种方式,您都需要额外进行客户端设置。
如果您想尝试免费的托管云服务,只需创建一个账户,然后设置客户端工具(见下文)。
$ curl -L https://wakapi.dev/get | bash
# 创建持久卷
$ docker volume create wakapi-data
$ SALT="$(cat /dev/urandom | LC_ALL=C tr -dc 'a-zA-Z0-9' | fold -w ${1:-32} | head -n 1)"
# 运行容器
$ docker run -d \
--init \
-p 3000:3000 \
-e "WAKAPI_PASSWORD_SALT=$SALT" \
-v wakapi-data:/data \
--name wakapi \
--restart unless-stopped \
ghcr.io/muety/wakapi:latest
[!NOTE] 默认情况下,使用SQLite作为数据库。要在Docker中使用MySQL或Postgres运行Wakapi,请参阅https://github.com/muety/wakapi/blob/master/Dockerfile%E5%92%8Chttps://github.com/muety/wakapi/blob/master/config.default.yml%E4%BA%86%E8%A7%A3%E6%9B%B4%E5%A4%9A%E9%80%89%E9%A1%B9%E3%80%82
如果您想在Kubernetes上运行Wakapi,可使用https://github.com/ricristian/wakapi-helm-chart%E8%BF%9B%E8%A1%8C%E5%BF%AB%E9%80%9F%E7%AE%80%E4%BE%BF%E7%9A%84%E9%83%A8%E7%BD%B2%E3%80%82
Docker Compose
或者,您可以使用Docker Compose进行更简单的部署。有关配置详情,请参阅https://github.com/muety/wakapi/blob/master/compose.yml%E3%80%82
Wakapi支持对以下变量使用Docker Secrets:WAKAPI_PASSWORD_SALT、WAKAPI_DB_PASSWORD、WAKAPI_MAIL_SMTP_PASS。您可以将它们作为密钥文件挂载,或直接作为环境变量传递。
示例
export WAKAPI_PASSWORD_SALT=changeme
export WAKAPI_DB_PASSWORD=changeme
export WAKAPI_MAIL_SMTP_PASS=changeme
docker compose up -d
如果您在使用SQLite作为数据库时希望将数据持久化到本地目录,请确保在Docker Compose配置中设置正确的user选项,以避免权限问题。
# 构建并安装
# 或者:go build -o wakapi
$ go install github.com/muety/wakapi@latest
# 获取默认配置并自定义
$ curl -o wakapi.yml https://raw.githubusercontent.com/muety/wakapi/master/config.default.yml
$ vi wakapi.yml
# 运行
$ ./wakapi -config wakapi.yml
[!NOTE] 有关安全配置等最佳实践,请查看
config.yml中的注释。
💡 当独立运行Wakapi(不使用Docker)时,建议将其作为SystemD服务运行。
Wakapi依赖开源的https://github.com/wakatime/wakatime-cli%E5%AE%A2%E6%88%B7%E7%AB%AF%E5%B7%A5%E5%85%B7%E3%80%82%E8%A6%81%E4%B8%BAWakapi%E6%94%B6%E9%9B%86%E7%BB%9F%E8%AE%A1%E6%95%B0%E6%8D%AE%EF%BC%8C%E6%82%A8%E9%9C%80%E8%A6%81%E8%BF%9B%E8%A1%8C%E8%AE%BE%E7%BD%AE%E3%80%82
~/.wakatime.cfg文件,如下所示。[settings]
# 您的Wakapi服务器URL,使用云服务器时为'https://wakapi.dev/api'
api_url = http://localhost:3000/api
# 您的Wakapi API密钥(创建账户后从Web界面获取)
api_key = 406fe41f-6d69-4183-a4cc-121e0c524c2b
此外,您还可以选择设置https://github.com/muety/wakapi/wiki/Advanced-Setup:-Client-side-proxy%E3%80%82
WakaTime集成
您可以并行使用WakaTime和Wakapi,即让您的编码活动在两个系统中都被跟踪。这可以通过客户端(推荐) 在系统级或项目级进行配置,或使用Wakapi的中继功能(设置 → 集成)将心跳转发到WakaTime。
示例:
[settings]
api_key = defaults-to-this-api-key-when-not-defined-below
[api_urls]
.* = https://wakapi.dev/api|wakapi-api-key
.* = https://api.wakatime.com/api/v1|waka-api-key
有关详情,请参阅https://github.com/wakatime/wakatime-cli/blob/develop/USAGE.md#api-urls-section%E3%80%82
您可以通过配置文件(默认:config.yml,可通过-c参数自定义)或环境变量指定配置选项。以下是所有选项的概述。
| YAML 键 / 环境变量 | 默认值 | 描述 |
|---|---|---|
env / ENVIRONMENT | dev | 是否使用开发或生产环境设置 |
app.leaderboard_enabled / WAKAPI_LEADERBOARD_ENABLED | true | 是否启用公开排行榜 |
app.leaderboard_scope / WAKAPI_LEADERBOARD_SCOPE | 7_days | 公开排行榜的聚合时间间隔(允许的值参见https://github.com/muety/wakapi/blob/7d156cd3edeb93af2997bd95f***b0aabef0c9/config/config.go#L71%EF%BC%89 |
app.leaderboard_generation_time / WAKAPI_LEADERBOARD_GENERATION_TIME | 0 0 6 * * *,0 0 18 * * * | 每日重新计算排行榜的一个或多个时间点 |
app.leaderboard_require_auth / WAKAPI_LEADERBOARD_REQUIRE_AUTH | false | 是否仅允许已登录用户访问排行榜 |
app.aggregation_time / WAKAPI_AGGREGATION_TIME | 0 15 2 * * * | 每日为所有用户定期生成摘要的时间点 |
app.report_time_weekly / WAKAPI_REPORT_TIME_WEEKLY | 0 0 18 * * 5 | 每周发送电子邮件报告的星期几和时间 |
app.data_cleanup_time / WAKAPI_DATA_CLEANUP_TIME | 0 0 6 * * 0 | 执行数据清理操作的时间(参见 app.data_retention_months) |
app.optimize_database_time / WAKAPI_OPTIMIZE_DATABASE_TIME | 0 0 8 1 * * | 执行数据库清理的时间(SQLite、Postgres 执行 vacuum,MySQL 执行表优化) |
app.import_enabled / WAKAPI_IMPORT_ENABLED | true | 是否允许从 WakaTime 或其他 Wakapi 实例导入数据 |
app.import_batch_size / WAKAPI_IMPORT_BATCH_SIZE | 50 | 从外部服务导入时插入数据库的心跳批次大小 |
app.import_backoff_min / WAKAPI_IMPORT_BACKOFF_MIN | 5 | 用户尝试再次数据导入前的“冷却”期(分钟) |
app.import_max_rate / WAKAPI_IMPORT_MAX_RATE | 24 | 成功数据导入后用户再次尝试导入前的最小等待小时数 |
app.import_hosts_whitelist / WAKAPI_IMPORT_HOSTS_WHITELIST | - | data导入的白名单主机名列表(允许通配符,空列表表示允许所有) |
app.inactive_days / WAKAPI_INACTIVE_DAYS | 7 | 判定用户为非活跃状态的天数(仅用于指标) |
app.heartbeat_max_age / WAKAPI_HEARTBEAT_MAX_AGE | 4320h | 心跳的最大可接受时长(参见 ParseDuration) |
app.warm_caches / WAKAPI_WARM_CACHES | true | 是否在启动时执行初始缓存预热 |
app.custom_languages | - | 从文件扩展名到语言名称的映射 |
app.avatar_url_template / WAKAPI_AVATAR_URL_TEMPLATE | (参见 config.default.yml) | 外部用户头像图片的 URL 模板(例如来自 Dicebear 或 Gravatar) |
app.date_format / WAKAPI_DATE_FORMAT | Mon, 02 Jan 2006 | 用于格式化人类可读日期的 Go 时间格式字符串(参见 Time.Format) |
app.datetime_format / WAKAPI_DATETIME_FORMAT | Mon, 02 Jan 2006 15:04 | 用于格式化人类可读日期时间的 Go 时间格式字符串(参见 Time.Format) |
app.support_contact / WAKAPI_SUPPORT_CONTACT | hostmaster@wakapi.dev | 页面上显示的支持联系电子邮件地址 |
app.data_retention_months / WAKAPI_DATA_RETENTION_MONTHS | -1 | 用户数据(心跳)的最大保留期(月)(-1 表示无限制) |
app.max_inactive_months / WAKAPI_MAX_INACTIVE_MONTHS | 12 | 非活跃月数达到此值后删除无数据的用户账户(-1 表示无限制) |
server.port / WAKAPI_PORT | 3000 | 监听端口 |
server.listen_ipv4 / WAKAPI_LISTEN_IPV4 | 127.0.0.1 | 监听的 IPv4 网络地址(设为 '-' 以禁用 IPv4) |
server.listen_ipv6 / WAKAPI_LISTEN_IPV6 | ::1 | 监听的 IPv6 网络地址(设为 '-' 以禁用 IPv6) |
server.listen_socket / WAKAPI_LISTEN_SOCKET | - | 监听的 UNIX 套接字(设为 '-' 以禁用 UNIX 套接字) |
server.listen_socket_mode / WAKAPI_LISTEN_SOCKET_MODE | 0666 | 创建 UNIX 套接字的权限模式 |
server.log_format / WAKAPI_LOG_FORMAT | text | 结构化日志格式(纯文本或 JSON)(选项:text、json) |
server.timeout_sec / WAKAPI_TIMEOUT_SEC | 30 | 请求超时时间(秒) |
server.tls_cert_path / WAKAPI_TLS_CERT_PATH | - | SSL 服务器证书路径(留空表示不使用 HTTPS) |
server.tls_key_path / WAKAPI_TLS_KEY_PATH | - | SSL 服务器私钥路径(留空表示不使用 HTTPS) |
server.base_path / WAKAPI_BASE_PATH | / | Web 基础路径(在代理下子路径运行时更改) |
server.public_url / WAKAPI_PUBLIC_URL | http://localhost:3000 | Wakapi 实例的公开访问 URL |
security.disable_local_auth / WAKAPI_DISABLE_LOCAL_AUTH | false | 是否禁用本地凭据(用户名和密码)登录,以强制使用 OIDC 提供商登录 |
security.disable_webauthn / WAKAPI_DISABLE_WEBAUTHN | true | 是否禁用 WebAuthn 登录(安全密钥、生物识别等) |
security.password_salt / WAKAPI_PASSWORD_SALT | - | 用于密码哈希的盐值 |
security.insecure_cookies / WAKAPI_INSECURE_COOKIES | true | 是否允许通过 HTTP 传输 Cookie。对于生产环境,强烈建议通过 HTTPS 提供 Wakapi 服务并将此值设为 false。 |
security.cookie_max_age / WAKAPI_COOKIE_MAX_AGE | 172800 | 身份验证 Cookie 的生命周期(秒),设为 0 则使用会话 Cookie |
security.allow_signup / WAKAPI_ALLOW_SIGNUP | true | 是否启用本地用户注册 |
security.oidc_allow_signup / WAKAPI_OIDC_ALLOW_SIGNUP | true | 是否启用通过 OIDC 注册用户 |
security.oidc_insecure / WAKAPI_OIDC_INSECURE | false | 跳过 OIDC 提供商的 TLS 证书验证(仅用于调试!) |
security.signup_captcha / WAKAPI_SIGNUP_CAPTCHA | false | 注册表单是否需要解决 CAPTCHA |
security.invite_codes / WAKAPI_INVITE_CODES | true | 是否启用通过邀请码注册。主要用于禁用公开注册的场景(邀请制服务器)。 |
security.disable_frontpage / WAKAPI_DISABLE_FRONTPAGE | false | 是否禁用着陆页(对个人实例有用) |
请参阅我们的 Swagger API 文档。
$ go install github.com/swaggo/swag/cmd/swag@latest
$ swag init -o static/docs
你可以将 Wakapi 统计数据导出到 Prometheus,以便在 Grafana 仪表板等工具中查看。操作方法如下。
# 1. 启动启用该功能的 Wakapi
$ export WAKAPI_EXPOSE_METRICS=true
$ ./wakapi
# 2. 获取你的 API 密钥并进行哈希处理
$ echo " " | base64
# 3. 将 Prometheus 抓取配置添加到你的 prometheus.yml 中(见下文)
抓取配置示例
# prometheus.yml
#(假设你的 Wakapi 实例在 localhost:3000 上运行)
scrape_configs:
- job_name: 'wakapi'
scrape_interval: 1m
metrics_path: '/api/metrics'
bearer_token: ' '
static_configs:
- targets: [ 'localhost:3000' ]
Grafana
还有一个由 https://github.com/MacroPower/wakatime_exporter 作者提供的 优质 Grafana 仪表板。
Wakapi 可与 WakaTime 良好配合。一方面,你可以将 Wakapi 的 心跳数据转发 到 WakaTime,从而同时有效使用这两个服务。此外,还可以从 WakaTime 导入历史数据,以保持两个服务之间的数据一致性。这两项功能都可以在你的 Wakapi 实例的设置页面的“集成”部分启用。
Wakapi 还与 https://github.com/anuraghazra/github-readme-stats#wakatime-week-stats 集成,可为你生成精美的卡片。以下是一个示例。使用此功能时,不要忘记在 设置 -> 权限 下启用公开数据。
点击查看代码
预览:
点击查看代码
- uses: lowlighter/metrics@latest
with:
# ... 其他选项
plugin_wakatime: yes
plugin_wakatime_token: ${{ secrets.WAKATIME_TOKEN }} # 必需
plugin_wakatime_days: 7 # 显示上周统计数据
plugin_wakatime_sections: time, projects, projects-graphs # 显示时间和项目部分以及项目图表
plugin_wakatime_limit: 4 # 每个图表显示 4 个条目
plugin_wakatime_url: http://wakapi.dev # Wakatime URL 端点
plugin_wakatime_user: .user.login # 用户
https://github.com/wakatime/browser-wakatime 插件允许你在 WakaTime(当然也包括 Wakapi)中跟踪你的网页浏览记录。访问过的网站将在摘要中显示为“文件”。按照以下说明开始使用:
https://wakapi.dev/api/compat/wakatime/v1(或者,将 wakapi.dev 替换为你的自托管实例主机名)[!NOTE] 插件只会偶尔同步心跳数据,因此可能需要一些时间才能在 Wakapi 上显示。要“强制”同步,只需打开插件主对话框即可。
如果你使用的是 GNOME 桌面,可以通过一种简单的方式在状态栏中显示你今天的编码统计数据。
只需安装 Executor 扩展,并添加以下命令作为状态栏指示器:
~/.wakatime/wakatime-cli-linux-amd64 --today
为保持精简,所有JS和CSS资源均作为静态文件包含并提交至Git。TailwindCSS 和 Iconify 需要额外的构建步骤。为仅在开发时需要此步骤,已编译的资源也会提交至Git。
$ yarn
$ yarn build # 或:yarn watch
可通过编辑 scripts/bundle_icons.js 中的 icons 数组添加新图标。
预压缩
如需预压缩文件,请运行以下命令:
# 先安装brotli
$ sudo apt install brotli # 或:sudo dnf install brotli
# 监视、构建并压缩
$ yarn watch:compress
# 或者:仅构建并压缩
$ yarn build:all:compress
# 或者:仅压缩
$ yarn compress
由于Wakapi严重依赖WakaTime提供的概念,他们的常见问题 在很大程度上也适用于Wakapi。你可能会在那里找到答案。
哪些数据会发送到Wakapi?
文件名 项目名 编辑器名 你的计算机主机名 你在编辑器中每次操作的时间戳 ...
详情请参见相关的 WakaTime常见问题部分。
如果你自行托管Wakapi,则可以控制所有数据。不过,如果你使用我们的Web服务并担心隐私问题,也可以排除或混淆 某些文件或项目名称。
如果我处于离线状态会怎样?
所有数据都会在你的设备上本地缓存,一旦重新联网就会批量发送。
Wakapi是如何诞生的?
Wakapi始于我还是学生的时候,当时我想跟踪自己编码时间的详细统计数据。虽然我是WakaTime的忠实粉丝,但那时我不想每月支付9***。幸运的是,WakaTime的大部分内容都是开源的!
Wakapi与WakaTime相比如何?
Wakapi是WakaTime的一个小子集,功能少得多。WakaTime的一些很酷但Wakapi缺失的功能包括:
排行榜 可嵌入图表 个人目标 团队/组织支持 额外集成(如与GitLab等) 更丰富的API
WakaTime物有所值。不过,如果你只需要基本统计数据,并且希望对自己的数据拥有主权,那么Wakapi可能是你的选择。
时长是如何计算的?
从心跳推断编码时间的方法与WakaTime类似,参见他们的文档。传统上,WakaTime会在每次长时间中断前的心跳默认填充2分钟。现在,经过https://github.com/muety/wakapi/issues/675 中提到的重构后,Wakapi的逻辑与WakaTime基本相同,包括可手动配置的超时时间(默认10分钟)。
以下是一个示例(圆圈表示心跳):
|---o---o--------------o---o---|
| |10s| 3m |10s| |
中间的3分钟如何处理并不明确。开发者是休息了3分钟,还是只是没有发送心跳(例如,开发者盯着屏幕试图找到解决方案,但没有实际输入代码)?
使用10分钟超时:3分20秒 使用2分钟超时:20秒 以前(使用2分钟超时+填充):10秒+2分钟+10秒=2分20秒
另一个示例参见https://github.com/muety/wakapi/issues/716#issuecomment-2668887035%E3%80%82
Go)JavaScript)Nim)YAML)开源 coding 是我的热情所在,我希望有一天能全职从事开源工作并以此为生。所以如果你喜欢这个项目,请考虑支持它🙂。你可以通过请我喝杯咖啡 或成为GitHub赞助者进行***。每一笔小额***都非常感谢,也会激励我继续改进Wakapi!
我非常感谢 https://github.com/alanhamlett 和WakaTime团队的努力,并感谢他们的软件是开源的。
此外,感谢 server.camp 为Wakapi.dev***服务器基础设施。
MIT @ Ferdinand Mütsch
来自真实用户的反馈,见证轩辕镜像的优质服务