HitKeep 2.15.1 Docker Compose 部署指南
HitKeep 2.15.1 Docker Compose 部署指南:GHCR 镜像选型与 tag 规则、compose.yml 编排、65532 属主排障实录、初始化建号建站注数验证、数据持久化与运维升级,全部真实服务器实测。
HitKeep 2.15.1 Docker Compose 部署指南
目标:在一台真实 Linux 服务器上,用官方容器镜像 + Docker Compose 把 HitKeep v2.15.1 完整跑起来:镜像选型、编排文件、首次启动排障、初始化管理员、建站注数验证与日常运维。本文所有命令与回显均来自真实部署实录,可直接照抄执行。
一、环境信息
部署实验在以下真实环境完成(HitKeep 本体运行在 Docker 容器中,宿主机为 Ubuntu 26.04.1 LTS):
| 项目 | 值 |
|---|---|
| 宿主操作系统 | Ubuntu 26.04.1 LTS(内核 7.0.0-38-generic,x86_64,6 vCPU / 15Gi 内存) |
| Docker Engine | 29.9.2 |
| Docker Compose | v5.6.1(独立插件) |
| HitKeep 版本 | v2.15.1(ghcr.io/hitkeep/hitkeep:2.15.1) |
| 镜像 digest | sha256:e3f32f572ee56ba449a2514b82df248dca313172b4a03d56e8de19ec09725b58(283MB) |
| 宿主端口 | 8128 → 容器 8080(HTTP) |
| Compose 网络 | hitkeep-net(bridge,10.89.58.0/24) |
| 数据目录 | ./data、./archive、./backups(bind mount) |
| 演示账号 | admin@example.com / q1w2e3r4(仅演示,生产请更换) |
⚠️ 网络降级说明:本实验环境的 Docker 守护进程配置了镜像加速白名单,Docker Hub 路径
pascalebeier/hitkeep的拉取请求被拒("该镜像不在白名单");按实验降级链改用官方 GHCR 镜像一次成功。两个来源均为官方发布渠道(官方 compose.yml 引用 Docker Hub,GHCR 由同一仓库发布)。
二、镜像选型说明
官方同时发布两路容器镜像(2026-11-01 实查):
- Docker Hub:
pascalebeier/hitkeep——官方examples/compose.yml默认引用image: pascalebeier/hitkeep:latest; - GHCR:
ghcr.io/hitkeep/hitkeep——tag 不带 v 前缀:2.15.1/2.15/2/latest/main/snapshot。
选型结论与理由:
- 固定具体小版本,本系列锁定
2.15.1,不用latest(便于回滚与文档对齐); - GHCR 的 tag 规则要记牢:
v2.15.1会得到 404(实测),正确写法是2.15.1; - 拉取后用 digest 留档,便于核对:
docker pull ghcr.io/hitkeep/hitkeep:2.15.1
docker images --digests 'ghcr.io/hitkeep/hitkeep'
实测回显:
ghcr.io/hitkeep/hitkeep:2.15.1 sha256:e3f32f572ee56ba449a2514b82df248dca313172b4a03d56e8de19ec09725b58 283MB
三、前置条件
- Docker Engine 与 Docker Compose 插件已安装(版本见环境信息表);
- 宿主端口 8128 空闲(本文约定:宿主 8128 → 容器 8080,避免与常见 8080 冲突);
- 自定义网段:Docker 网络从规划池取空闲段
10.89.58.0/24,避免与其他 Compose 项目的默认网段漂移冲突; openssl(生成 JWT 密钥);- 磁盘:镜像解压后约 283MB,数据目录随流量增长(本文实验约 94MB)。
四、部署步骤
4.1 准备目录与 .env
mkdir -p hitkeep-stack && cd hitkeep-stack
mkdir -p data archive backups
openssl rand -hex 32
实测回显(本例生成的演示密钥,生产环境请重新生成并妥善保管):
c6d08a8f93cafdef9e5cf7ea850cfeced3918766680b5565e22bbce22a38c311
把生成值写入 .env(与 compose.yml 同目录):
HITKEEP_JWT_SECRET=c6d08a8f93cafdef9e5cf7ea850cfeced3918766680b5565e22bbce22a38c311
4.2 编写 compose.yml
本例在官方 examples/compose.yml 基础上做了三处适配:锁定版本 tag、宿主端口改 8128、bind mount 替代命名卷(便于直接观察与备份)。全文件照录:
name: hitkeep-2.15.1-stack
networks:
hitkeep-net:
driver: bridge
ipam:
config:
- subnet: 10.89.58.0/24
services:
hitkeep:
image: ghcr.io/hitkeep/hitkeep:2.15.1
container_name: hitkeep-2.15.1-app
restart: unless-stopped
networks:
- hitkeep-net
ports:
- "8128:8080"
volumes:
- ./data:/var/lib/hitkeep/data
- ./archive:/var/lib/hitkeep/archive
- ./backups:/var/lib/hitkeep/backups
environment:
HITKEEP_PUBLIC_URL: http://localhost:8128
HITKEEP_JWT_SECRET: ${HITKEEP_JWT_SECRET}
HITKEEP_TRUSTED_PROXIES: ""
HITKEEP_DB_PATH: /var/lib/hitkeep/data/hitkeep.db
HITKEEP_DATA_PATH: /var/lib/hitkeep/data
HITKEEP_ARCHIVE_PATH: /var/lib/hitkeep/archive
HITKEEP_BACKUP_PATH: /var/lib/hitkeep/backups
HITKEEP_BACKUP_INTERVAL: 60
HITKEEP_BACKUP_RETENTION: 24
HITKEEP_SPAM_FILTER_AUTO_UPDATE: "true"
HITKEEP_SPAM_FILTER_UPDATE_INTERVAL: 1440
HITKEEP_SPAM_FILTER_PATH: /var/lib/hitkeep/data/spam-filter.json
HITKEEP_MCP_ENABLED: "true"
HITKEEP_MCP_PATH: /mcp
HITKEEP_MCP_MAX_RANGE_DAYS: 366
两点提醒:
HITKEEP_PUBLIC_URL必须等于浏览器里实际访问的地址(含端口与路径前缀),它同时是签发 JWT 的签发方/受众(见常见问题第 4 条);- compose 项目名取自
name:字段,Docker 会把hitkeep-2.15.1-stack规范化为hitkeep-2151-stack(下文网络名hitkeep-2151-stack_hitkeep-net即由此而来)。
4.3 首次启动与属主排障(实录)
docker compose up -d
如果 bind mount 目录是 root 属主(新建目录的默认状态),容器会陷入崩溃循环——镜像内的 HitKeep 以非 root 用户 65532:65532 运行,无权在 root 目录里建库。docker compose logs hitkeep 中的真实报错(每 1~3 秒重复一次):
{"time":"2026-11-01T03:59:25.920925019Z","level":"ERROR","msg":"Application startup panicked","error":"could not connect to database: open database /var/lib/hitkeep/data/hitkeep.db: database/sql/driver: could not connect to database: IO Error: Cannot open file \"/var/lib/hitkeep/data/hitkeep.db\": Permission denied"}
修正属主后重启:
chown -R 65532:65532 data archive backups
docker compose restart
💡
65532是 Google distroless 镜像惯例的nonroot用户 UID;无论 bind mount 还是命名卷,只要数据目录属主不是它,HitKeep 就起不来。
4.4 首次成功启动日志(实录节选)
属主修正后,首次启动会完成全部数据库迁移与租户拆分。docker compose logs hitkeep 关键行照录:
{"time":"2026-11-01T04:00:07.042275389Z","level":"INFO","msg":"Applying pending database migrations...","count":63}
{"time":"2026-11-01T04:00:07.04323731Z","level":"INFO","msg":"Applying migration","file":"2025_05_11_000000_create_base_tables.sql"}
……(中间共 63 条共享库迁移逐条 Applying,略)……
{"time":"2026-11-01T04:00:09.473089908Z","level":"INFO","msg":"Successfully applied all tenant migrations.","path":"/var/lib/hitkeep/data/tenants/01a19543-bedb-79c5-b343-c105e9498d8f/hitkeep.db.split-work"}
{"time":"2026-11-01T04:00:23.258400977Z","level":"INFO","msg":"Default tenant split is complete","tenant_id":"01a19543-bedb-79c5-b343-c105e9498d8f","tenant_path":"/var/lib/hitkeep/data/tenants/01a19543-bedb-79c5-b343-c105e9498d8f/hitkeep.db"}
{"time":"2026-11-01T04:00:23.536829092Z","level":"INFO","msg":"INFO: TCP: listening on 127.0.0.1:4150","calldepth":3}
{"time":"2026-11-01T04:00:23.536871211Z","level":"INFO","msg":"INFO: HTTP: listening on 127.0.0.1:4151","calldepth":3}
{"time":"2026-11-01T04:00:23.555704046Z","level":"INFO","msg":"HTTP server starting","addr":":8080"}
要点:共享库迁移 63 条、租户库迁移(实测序列编号至 0017_create_search_console_totals_days.sql,含 0013b 子版本变体)全部在首启自动完成;内嵌 NSQ 只绑定 127.0.0.1(不对外);最后 HTTP 服务在容器内 :8080 就绪。
4.5 初始化管理员(首个账号)
浏览器打开 http://localhost:8128 会进入初始化页;脚本化等价操作是 REST 接口(实测):
curl -s -X POST http://localhost:8128/api/initial-user \
-H 'Content-Type: application/json' \
-d '{"email":"admin@example.com","password":"q1w2e3r4","given_name":"Admin","last_name":"User"}' \
-w '\nHTTP:%{http_code}\n'
实测回显(JWT 为演示实例签发,已失效,仅展示格式):
{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiNTIxNGY4MTEtZWE5OC00NWIwLWIzMzYtYjY3ODQ0NjJhMjA0IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MTI4IiwiYXVkIjpbImh0dHA6Ly9sb2NhbGhvc3Q6ODEyOCJdLCJleHAiOjE3OTM1MDY2NTAsImlhdCI6MTc5MzUwNTc1MH0.Tl0gyBVGGRh-8jUiHFDYrdFTEPPcUQZ1Eo38uQZM6jE"}
HTTP:201
注意 token 载荷里 iss/aud 都绑定了 http://localhost:8128——这就是 HITKEEP_PUBLIC_URL。
4.6 登录与会话
curl -s -c hk_cookies.txt -X POST http://localhost:8128/api/login \
-H 'Content-Type: application/json' \
-d '{"email":"admin@example.com","password":"q1w2e3r4"}' \
-w '\nHTTP:%{http_code}\n'
实测回显:
{"status":"ok"}
HTTP:200
用 cookie 查看会话信息:
curl -s -b hk_cookies.txt http://localhost:8128/api/auth/session
实测回显:
{"expires_at":"2026-11-01T04:40:22Z","issued_at":"2026-11-01T04:25:22Z","duration_seconds":900,"warning_seconds":120,"extendable":true,"timing_adjustable":true,"remembered":false,"remember_me_duration_days":30}
默认会话 15 分钟(duration_seconds: 900),过期前 120 秒前端会提示续期,与配置参数 auth-session-minutes: 15、auth-session-warning-seconds: 120 一一对应。
4.7 建站、注数、看数(验证闭环)
建站(HTTP 201,响应含新站点对象):
curl -s -b hk_cookies.txt -X POST http://localhost:8128/api/sites \
-H 'Content-Type: application/json' \
-d '{"domain":"example.com"}'
用列表接口核实(实测回显):
curl -s -b hk_cookies.txt http://localhost:8128/api/sites
[{"id":"816f0e64-a85f-4ab8-95d9-e581aa790393","user_id":"5214f811-ea98-45b0-b336-b6784462a204","domain":"example.com","data_retention_days":365,"retention_synced_from_plan":false,"created_at":"2026-11-01T04:02:36.419946Z"}]
注入一条 pageview(真实浏览器埋点由 hk.js 自动完成,这里用 ingest 接口模拟;session_id 用一个随机 UUID 保持同会话):
curl -s -X POST http://localhost:8128/ingest \
-H 'Content-Type: application/json' \
-H 'Origin: http://example.com' \
-H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/126.0 Safari/537.36' \
-d '{"url":"http://example.com/","referrer":"","session_id":"275b3f0a-5542-4fe1-a2b9-b3dd1a18e61e","screen_width":1920}' \
-w '\nHTTP:%{http_code}\n'
实测回显:响应体为空、状态码 202——HitKeep 先受理再异步入库(内嵌 NSQ 消化),这是它的削峰设计。本系列实验共注入 5 条 pageview 与 2 条自定义事件(signup、purchase,接口为 POST /ingest/event,同样 202)。
查询统计汇总(example.com 的站点 id 见上;回显为重建复测值——首轮注入后 total_pageviews 为 5,重建验证时同命令补注了 1 条故为 6):
curl -s -b hk_cookies.txt \
"http://localhost:8128/api/sites/816f0e64-a85f-4ab8-95d9-e581aa790393/stats" \
| python3 -c "import json,sys; d=json.load(sys.stdin); print({k:d[k] for k in ['live_visitors','total_pageviews','unique_sessions','bounce_rate','avg_session_duration','pages_per_session']})"
实测回显:
{'live_visitors': 0, 'total_pageviews': 6, 'unique_sessions': 1, 'bounce_rate': 0, 'avg_session_duration': 1365.372772, 'pages_per_session': 6}
💡 目标与漏斗的请求体格式容易踩坑:目标必须是
{"name":"注册转化","type":"event","value":"signup"}(type取event或path),漏斗必须是{"name":"注册漏斗","steps":[{"type":"path","value":"/"},{"type":"path","value":"/pricing"},{"type":"event","value":"signup"}]}且至少两步——字段名写成pattern/step都会得到Invalid goal data或Invalid funnel data (need name and at least 2 steps)(实测报错原文)。
4.8 健康检查三连
curl -s http://localhost:8128/healthz # 进程存活
curl -s -o /dev/null -w '%{http_code}' http://localhost:8128/readyz # 租户库就绪
curl -s http://localhost:8128/api/status # 实例状态
实测回显:
ok
200
{"needs_setup":false,"version":"v2.15.1","ask_ai":{"enabled":false,"available":false,"status":"disabled","budget_exhausted":false},"mail_delivery":{"available":false,"status":"unavailable"}}
needs_setup:false 表示已完成初始化;mail_delivery.available:false 是因为本例未配置 SMTP(不影响统计功能)。
4.9 重建与重启(实录)
日常重启用 docker compose restart;彻底重建(等价于换机重部署):
docker compose down
docker compose up -d
实测回显:
=== docker compose down ===
Container hitkeep-2.15.1-app Stopping
Container hitkeep-2.15.1-app Stopped
Container hitkeep-2.15.1-app Removing
Container hitkeep-2.15.1-app Removed
Network hitkeep-2151-stack_hitkeep-net Removing
Network hitkeep-2151-stack_hitkeep-net Removed
=== docker compose up -d ===
Network hitkeep-2151-stack_hitkeep-net Creating
Network hitkeep-2151-stack_hitkeep-net Created
Container hitkeep-2.15.1-app Creating
Container hitkeep-2.15.1-app Created
Container hitkeep-2.15.1-app Starting
Container hitkeep-2.15.1-app Started
约 30 秒后状态转 healthy(数据在 bind mount 里,重建不丢):
NAME IMAGE STATUS PORTS
hitkeep-2.15.1-app ghcr.io/hitkeep/hitkeep:2.15.1 Up 34 seconds (healthy) 7946/tcp, 0.0.0.0:8128->8080/tcp, [::]:8128->8080/tcp
五、数据持久化说明
本例三个 bind mount 与容器内路径的对应关系:
| 宿主目录 | 容器路径 | 内容 |
|---|---|---|
./data | /var/lib/hitkeep/data | 主库 hitkeep.db、租户库目录 tenants/、DuckDB 扩展缓存 .duckdb/、垃圾列表 spam-filter.json、恢复包目录 recovery/ |
./archive | /var/lib/hitkeep/archive | 数据保留期(默认 365 天)之外的历史归档 |
./backups | /var/lib/hitkeep/backups | 自动备份快照(默认每 60 分钟,保留 24 份) |
部署约 40 分钟后的真实目录形态(属主全部是 65532):
total 19592
drwxr-xr-x 5 65532 65532 12288 Nov 1 12:35 .
drwxr-xr-x 5 root root 4096 Nov 1 11:59 ..
drwx------ 3 65532 65532 4096 Nov 1 12:00 .duckdb
-rw-r--r-- 1 65532 65532 19935232 Nov 1 12:35 hitkeep.db
drwx------ 2 65532 65532 4096 Nov 1 12:00 recovery
-rw------- 1 65532 65532 96929 Nov 1 12:35 spam-filter.json
drwxr-xr-x 3 65532 65532 4096 Nov 1 12:00 tenants
三个目录实测占用:data 94M、archive 4.0K、backups 1.4M。备份快照是按时间戳组织的 Parquet 文件集(每张表一个文件),实测结构:
backups/shared/2026-11-01T040053Z/ # 共享库快照(users、sites、webhooks…)
backups/shared/2026-11-01T043537Z/
backups/tenants/01a19543-bedb-79c5-b343-c105e9498d8f/2026-11-01T040053Z/ # 租户库快照(hits、goals…)
backups/tenants/01a19543-bedb-79c5-b343-c105e9498d8f/2026-11-01T043537Z/
💡 若改用官方默认的命名卷,
docker compose down不会删卷,docker compose down -v才会;bind mount 则与项目生命周期解耦,删栈前记得先备份./data。
六、环境变量表
容器版通过 HITKEEP_* 环境变量配置,全部参数有一一对应的 YAML/旗标等价形式(详见《HitKeep 2.15.1 配置参数详解》)。部署最常用的关键项:
| 环境变量 | 作用 | 默认值 | 本例取值 |
|---|---|---|---|
HITKEEP_PUBLIC_URL | 浏览器可见地址,JWT 的签发方/受众 | http://localhost:8080 | http://localhost:8128 |
HITKEEP_JWT_SECRET | JWT 签名密钥(64 位 hex) | 无,必填 | openssl rand -hex 32 生成 |
HITKEEP_TRUSTED_PROXIES | 信任的反代网段 CIDR,* 信任全部 | * | 空(直连) |
HITKEEP_DB_PATH | 主库文件路径 | hitkeep.db | /var/lib/hitkeep/data/hitkeep.db |
HITKEEP_DATA_PATH | 可写数据根目录 | data | /var/lib/hitkeep/data |
HITKEEP_ARCHIVE_PATH | 归档目录 | archive | /var/lib/hitkeep/archive |
HITKEEP_BACKUP_PATH | 备份目标(本地目录或 s3://) | 未设 | /var/lib/hitkeep/backups |
HITKEEP_BACKUP_INTERVAL | 备份间隔(分钟) | 60 | 60 |
HITKEEP_BACKUP_RETENTION | 备份保留份数 | 24 | 24 |
HITKEEP_SPAM_FILTER_AUTO_UPDATE | 垃圾列表自动刷新 | false | true |
HITKEEP_SPAM_FILTER_PATH | 垃圾列表缓存路径 | <data-path>/spam-filter.json | /var/lib/hitkeep/data/spam-filter.json |
HITKEEP_MCP_ENABLED | 只读 MCP 端点开关 | false | true |
HITKEEP_MCP_PATH | MCP HTTP 路径 | /mcp | /mcp |
HITKEEP_MCP_MAX_RANGE_DAYS | MCP 查询日期跨度上限 | 366 | 366 |
HITKEEP_MAIL_* | SMTP 邮件(邀请/重置/报告) | 未设即禁用 | 未配置 |
HITKEEP_SOCIAL_* | Google/GitHub/Microsoft 社交登录 | 未设即隐藏 | 未配置 |
HITKEEP_AI_* | AI 功能(Ask AI/Opportunity) | 关闭 | 未配置 |
七、配置参数说明
HitKeep 的配置读取优先级为:命令行旗标 > 非空环境变量 > YAML 配置文件 > 默认值(官方二进制安装指南原文:"Flags and non-empty environment variables still override file values")。每个旗标都有同名的 HITKEEP_ 环境变量等价物,配置项全集 100 项(旗标与 YAML 键一一对应,其中 24 项敏感参数在生成的模板中默认注释占位)按 17 个分组组织,逐项含义、默认值与生产模板见《HitKeep 2.15.1 配置参数详解》。
快速自检两个命令(在容器内或宿主二进制均可):
docker exec hitkeep-2.15.1-app hitkeep config init --output /tmp/gen.yaml # 生成带注释的全量模板
docker exec hitkeep-2.15.1-app hitkeep config validate --config /tmp/gen.yaml
八、配置文件挂载
团队偏好用 YAML 统一管理配置时,官方推荐流程(来源:官方二进制安装指南)是先 config init 生成模板、config validate 校验,再以 --config 启动——--config 必须放在所有参数最前面。CLI 层实测:
hitkeep config init --output /wk/hitkeep.yaml
# Created configuration file /wk/hitkeep.yaml (文件权限 0600)
hitkeep config validate --config /wk/hitkeep.yaml
# Configuration file /wk/hitkeep.yaml is valid
容器版等价写法是把生成的 YAML 挂进容器并覆盖启动命令:
services:
hitkeep:
image: ghcr.io/hitkeep/hitkeep:2.15.1
volumes:
- ./hitkeep.yaml:/etc/hitkeep/hitkeep.yaml:ro
command: ["--config", "/etc/hitkeep/hitkeep.yaml"]
注意:文件内未设置的项目回落默认值,旗标与非空环境变量仍会覆盖文件值;敏感项(jwt-secret 等)建议留在 .env 而不是写进 YAML。
九、等价 docker run
与本篇 Compose 等价的单命令形式(便于理解 Compose 到底做了什么;实际部署仍推荐 Compose 便于升级与回滚):
docker run -d \
--name hitkeep-2.15.1-app \
--restart unless-stopped \
--network hitkeep-net \
-p 8128:8080 \
-v /opt/hitkeep/data:/var/lib/hitkeep/data \
-v /opt/hitkeep/archive:/var/lib/hitkeep/archive \
-v /opt/hitkeep/backups:/var/lib/hitkeep/backups \
-e HITKEEP_PUBLIC_URL=http://localhost:8128 \
-e HITKEEP_JWT_SECRET=c6d08a8f93cafdef9e5cf7ea850cfeced3918766680b5565e22bbce22a38c311 \
-e HITKEEP_DB_PATH=/var/lib/hitkeep/data/hitkeep.db \
-e HITKEEP_DATA_PATH=/var/lib/hitkeep/data \
-e HITKEEP_ARCHIVE_PATH=/var/lib/hitkeep/archive \
-e HITKEEP_BACKUP_PATH=/var/lib/hitkeep/backups \
ghcr.io/hitkeep/hitkeep:2.15.1
十、常用运维命令
docker compose ps # 状态(healthy 为就绪)
docker compose logs -f --tail 100 hitkeep # 跟踪日志
docker compose restart # 重启
docker compose stop && docker compose start # 停止/启动
docker compose down # 删容器与网络(保留数据)
docker exec hitkeep-2.15.1-app hitkeep -healthcheck # 容器内置健康检查(exit 0 即健康)
内置健康检查实测(镜像自身的 HEALTHCHECK 就是调用这条命令):
docker exec hitkeep-2.15.1-app hitkeep -healthcheck; echo "exit=$?"
实测回显:无输出、exit=0。
升级流程(官方推荐路径):把 compose.yml 中 tag 换成新版本号(如 2.15.2),然后:
docker compose pull && docker compose up -d
数据格式迁移在启动时自动执行(与首启日志中的 Applying pending database migrations 同一机制),降级大版本前先备份 ./data。
十一、常见问题
1. 容器反复重启,日志报 IO Error: Cannot open file ... Permission denied
数据目录属主不是 65532:65532。执行 chown -R 65532:65532 data archive backups 后 docker compose restart(见 4.3 实录)。
2. GHCR 拉取报 404
tag 不带 v 前缀:用 ghcr.io/hitkeep/hitkeep:2.15.1,不是 :v2.15.1(实测)。
3. 配置了镜像加速白名单的环境拉不到 Docker Hub 镜像 改用官方 GHCR 镜像(本文即此路径);两者同为官方渠道,digest 留档核对。
4. 换了访问域名后登录态失效 / 初始化页又出现
HITKEEP_PUBLIC_URL 参与 JWT 签发与校验(iss/aud 绑定,见 4.5 回显),改动它会使既有会话失效;反代场景必须设成浏览器可见地址,并把反代网段配进 HITKEEP_TRUSTED_PROXIES 才能拿到真实访客 IP。
5. 数据目录挂载报错或扩展加载失败
DuckDB 扩展解压到 DATA_PATH/.duckdb/extensions(本例实测存在该目录),官方要求该目录可写且挂载不得带 noexec;只读挂载 ./data 会让首启建库直接失败。
6. 内存占用比预期高
DuckDB 内存上限默认按容器环境自动派生(本例 15Gi 宿主派生 7714MiB,见启动日志 DuckDBMemoryLimit 字段),并非按需占用;限制它用 HITKEEP_DUCKDB_MEMORY_LIMIT(如 2GB),线程数同理 HITKEEP_DUCKDB_THREADS。
7. 端口 7946 是否要暴露
单机部署不用(gossip 集群口,容器内监听 0.0.0.0:7946 但本例未映射);只有组成多节点集群时才在节点间放行,且建议配 --bind-addr=127.0.0.1:7946 类限制避免误暴露。
十二、参考链接
- 官方 Docker Compose 指南:
https://hitkeep.com/guides/installation/docker-compose/ - 官方编排样例:
https://raw.githubusercontent.com/HitKeep/hitkeep/main/examples/compose.yml;环境变量模板:https://raw.githubusercontent.com/HitKeep/hitkeep/main/examples/.env.example - 官方二进制安装指南(
--config与 systemd 口径来源):https://hitkeep.com/guides/installation/binary/ - 反向代理与受信代理:
https://hitkeep.com/guides/installation/trusted-proxies/ - 备份与恢复:
https://hitkeep.com/guides/data/backups-and-restore/ - 配置参考:
https://hitkeep.com/reference/configuration/ - 本系列:认知篇《HitKeep 介绍与选型指南》、配置篇《HitKeep 2.15.1 配置参数详解》、命令篇《HitKeep 2.15.1 常用 CLI 命令与工具详解》;同类产品部署实录可参考《Ubuntu 24.04 安装 GoatCounter 2.7.0 指南》