news 2026/9/12 20:42:53

PostHog 手动开发环境搭建完全指南:从外部服务到 `hogli start` 的逐步实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PostHog 手动开发环境搭建完全指南:从外部服务到 `hogli start` 的逐步实战

PostHog 手动开发环境搭建完全指南:从外部服务到hogli start的逐步实战

【免费下载链接】posthog:hedgehog: PostHog is the leading platform for building self-driving products. Our developer tools – AI observability, analytics, session replay, flags, experiments, error tracking, logs, and more – capture all the context agents need to diagnose problems, uncover opportunities, and ship fixes. Steer it all from Slack, web, desktop, or the MCP.项目地址: https://gitcode.com/GitHub_Trending/po/posthog

PostHog 是一个庞大的单体仓库(monorepo),前端(React/Vite/Kea)、后端(Django)、事件流(Kafka/ClickHouse)、工作流编排(Temporal)、CDP 与 Node.js 服务等组件需要协同运行。本文基于仓库内的 manual-dev-setup.md 手册,系统讲解在不依赖 Flox 自动环境的前提下,如何手动从零搭建一套可用的 PostHog 本地开发环境,涵盖外部服务启动、前端/Node.js/Django 三端依赖准备、数据库迁移、全栈启动与日常开发技巧,并给出仓库内的源码与配置佐证。

重要提示:仓库手册明确指出,本文对应的手动流程已标记为 deprecated(弃用),仓库现在推荐使用基于 Flox 的即时环境搭建(见 developing-locally)。但手动流程依然是理解 PostHog 各组件依赖关系、排查环境问题、以及在不使用 Flox 的场景下搭建环境的宝贵路线图。本文所有命令与配置均以当前仓库实际内容为准。

1. 启动外部服务:基础设施先行

PostHog 的开发环境依赖一整套外部基础设施。在手动搭建流程中,第一步就是通过 Docker Compose 把它们全部拉起来。

1.1 配置/etc/hosts:打通容器间主机名解析

PostHog 的 ClickHouse 与 Kafka 数据服务需要互相通信,为此必须把以下主机名映射到本机:

echo '127.0.0.1 kafka clickhouse clickhouse-coordinator objectstorage' | sudo tee -a /etc/hosts echo '::1 kafka clickhouse clickhouse-coordinator objectstorage' | sudo tee -a /etc/hosts

两条命令分别写入 IPv4 与 IPv6 的解析记录。这些主机名在 docker-compose.dev.yml 的 Caddy 代理配置(extra_hosts: - 'web:host-gateway'等)以及 ClickHouse 的 Kafka 引擎配置(docker-compose.base.yml 中 ClickHouse 服务设置了KAFKA_HOSTS: 'kafka:9092')中都会被引用。

Podman 用户注意:如果使用的是 4.1 及以上版本的 Podman 而非 Docker,宿主机/etc/hosts会默认作为容器的基础 hosts 文件(Docker 则使用容器自身/etc/hosts),可能导致 ClickHouse 容器内主机名解析失败。解决办法是在containers.conf中设置base_hosts_file="none"

1.2 启动 Docker Compose 开发栈

仓库根目录提供了专为本地开发设计的 Compose 文件(注意其头注释明确写明"used ONLY for local development"):

docker compose -f docker-compose.dev.yml up

该文件通过extends继承 docker-compose.base.yml 中的基础服务定义,并覆盖端口映射、资源限制与开发参数。启动后docker ps应能看到类似下面的一整套服务(版本以当前仓库配置为准,与手册中的历史版本略有差异):

容器镜像(当前仓库实际配置)暴露端口用途
posthog-db-1postgres:15.12-alpine5432主关系数据库(用户、组织、功能开关等)
posthog-clickhouse-1clickhouse/clickhouse-server:26.6.2.1588123/9000/9009/9440/8443分析型列式数据库(事件、漏斗等)
posthog-kafka-1redpandadata/redpanda:v25.1.99092事件流中间件(兼容 Kafka 协议)
posthog-zookeeper-1zookeeper:3.7.02181Kafka 协调(Redpanda 与 ClickHouse 均依赖)
posthog-redis-1redis:7.2-alpine6379缓存与任务队列
posthog-maildev-1maildev/maildev:2.0.51025/1080本地邮件捕获与预览
posthog-objectstorage-1seaweedfs19000-19001对象存储(会话录制、批量导出等)
posthog-elasticsearch-1elasticsearch:7.16.29200Temporal 可视化的检索后端
posthog-temporal-1temporalio/auto-setup:1.20.07233工作流编排引擎
posthog-temporal-ui-1temporalio/ui:2.10.38081Temporal 管理界面

手册中的示例docker ps输出展示的 Kafka 镜像为bitnami/kafka:2.8.1-debian-10-r99,而当前仓库的 docker-compose.base.yml 已将 Kafka 服务替换为redpandadata/redpanda:v25.1.9(Redpanda 兼容 Kafka 协议),且 dev 栈通过kafka-init服务使用 docker/kafka/topics.txt 预创建全部 topic。这也解释了手册中"Kafka 是唯一 x86 容器、在 ARM 上可能随机段错误"的提示——Redpanda 在 Apple Silicon 上运行更稳定。

1.3 验证服务健康状态

启动后建议逐项确认服务就绪:

# 查看容器列表与状态 docker ps # 各服务的就绪日志(-n 1 只看最后一行) docker logs posthog-db-1 -n 1 # 期望:database system is ready to accept connections docker logs posthog-redis-1 -n 1 # 期望:Ready to accept connections docker logs posthog-clickhouse-1 -n 1 # 期望:Saved preprocessed configuration ... # ClickHouse 日志写入文件而非 stdout,出问题时直接查看: docker exec posthog-clickhouse-1 cat /var/log/clickhouse-server/clickhouse-server.log docker exec posthog-clickhouse-1 cat /var/log/clickhouse-server/clickhouse-server.err.log

ClickHouse 容器日志中可能出现get_mempolicy: Operation not permitted提示,手册说明这不会影响应用启动。如需彻底确认 ClickHouse 可用,可进入容器执行一条基本查询:

docker exec -it posthog-clickhouse-1 bash clickhouse-client --query "SELECT 1"

常见启动报错排查

报错原因与解法
Error while fetching server API version: 500 Server Error ...Docker Engine 未运行,先启动 Docker/OrbStack
Exit Code 137容器内存耗尽,在 OrbStack 设置中增加 RAM 配额
Ports are not available: exposing port TCP 0.0.0.0:5432本机已有 Postgres 占用 5432 端口,用lsof -i :5432定位并停掉
Permission denied(Linux)参考 Docker 官方文档配置非 root 用户运行,或改用支持 rootless 的 Podman

手册对 Linux 用户给出了停用本机 Postgres 服务的建议流程:

sudo service postgresql stop sudo systemctl disable postgresql.service sudo lsof -i :5432 sudo kill -9 `sudo lsof -t -i :5432`

1.4 本机安装 Postgres 客户端(psycopg2 编译依赖)

即便 Postgres 服务运行在 Docker 内,本机仍需要一份 Postgres(11+)的 CLI 工具与开发库/头文件——pip/uv安装psycopg2时需要它们完成编译。

  • macOS:

    brew install postgresql

    注意:这会同时安装服务端与工具,但安装后不要启动服务,以免与 Docker 容器争抢 5432 端口。

  • Debian 系 Linux(只装客户端与驱动,不装服务端):

    sudo apt install -y postgresql-client postgresql-contrib libpq-dev

    不同发行版包名可能不同(例如postgrespostgres-serverlibpostgres-dev),请以各自发行版仓库为准。

2. 准备前端:nvm + pnpm + Kea 类型生成

2.1 安装 nvm 与固定 Node 版本

前端依赖 nvm 管理 Node 版本,macOS 可用brew install nvm,其他平台按官方安装脚本执行(fish shell 用户可改用 nvm.fish)。

安装后务必把 nvm 加入$PATH,否则命令行会回落到系统 Node.js 版本。然后从仓库根目录读取.nvmrc安装并激活 PostHog 生产环境使用的 Node 版本——当前仓库固定为v24.13.0

nvm install # nvm 会读取仓库根目录的 .nvmrc nvm use

2.2 启用 pnpm(Corepack)

PostHog 使用 pnpm 管理前端依赖,版本通过根目录 package.json 的packageManager字段锁定(当前为pnpm@10.29.3)。用 Corepack 一键激活:

corepack enable pnpm --version # 验证激活的版本

2.3 安装依赖并生成 Kea 类型

pnpm i

随后生成前端大量使用的 Kea 状态管理逻辑的类型定义:

pnpm --filter=@posthog/frontend typegen:write

Kea 是 PostHog 前端的状态管理框架,其kea()逻辑会在运行时动态生成 reducer/selector 等,TypeScript 无法静态推导,因此必须借助 typegen 工具把类型写入.kea-typegen相关文件。如果只想迭代某一个 logic 文件,用:

pnpm --filter=@posthog/frontend typegen:file <path-to-logic-file>

<path>可以是绝对路径、仓库相对路径(如frontend/src/scenes/foo/fooLogic.ts)或前端相对路径(如src/scenes/foo/fooLogic.ts)。

首次运行 typegen 可能陷入死循环,此时按Ctrl+C取消,git reset --hard丢弃所有改动后重新运行pnpm typegen:write,第二轮生成完成后可能还需要再丢弃一次改动。

3. 准备 Node.js 服务:brotli + Rust 工具链

PostHog 的部分 Node.js 服务(CDP 工作流、会话录制、日志摄取等,见 hogli.yaml 中 nodejs 单元的说明)在构建时需要系统库与 Rust 工具链。

  • macOS:

    brew install brotli rustup rustup default stable rustup-init # 选择 1 使用默认安装
  • Debian 系 Linux:

    sudo apt install -y brotli curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # 选择 1 使用默认安装

然后安装 Node.js 服务的全部依赖(服务本体稍后统一启动):

pnpm --filter=@posthog/nodejs install

常见报错与解法

报错解法
ld: symbol(s) not found for architecture arm64OpenSSL 构建标志来自错误位置。执行export CPPFLAGS=-I/opt/homebrew/opt/openssl/includeexport LDFLAGS=-L/opt/homebrew/opt/openssl/lib后重装
import gyp # noqa: E402缺少python-setuptools,macOS 上brew install python-setuptools
Node.js 服务启动异常进入nodejs目录执行pnpm rebuildpnpm i重建原生模块

4. 准备 Django 后端:SAML 依赖 + Python 3.13 + uv

4.1 SAML 相关的系统依赖

SAML 认证依赖xmlsec,需要系统级库支持:

  • macOS:

    brew install libxml2 libxmlsec1 pkg-config
  • Debian 系 Linux:

    sudo apt install -y libxml2 libxmlsec1-dev libffi-dev pkg-config

4.2 安装 Python 3.13

  • macOS:brew install python@3.13

  • Debian 系 Linux(使用 deadsnakes PPA):

    sudo add-apt-repository ppa:deadsnakes/ppa -y sudo apt update sudo apt install python3.13 python3.13-venv python3.13-dev -y

手册特别强调:虚拟环境外请始终使用python3而非python(后者在某些系统上仍指向 Python 2.x);若通过 deadsnakes 安装了多个 Python 3 版本,请使用python3.13精确指定。也可以用 pyenv 管理多版本。

4.3 安装 uv 并同步依赖

uv是 PostHog 后端首选的 Python 虚拟环境与依赖管理工具,安装后任何pip命令都可以前缀uv提速。一条命令完成建环境与装依赖:

uv sync

该命令读取根目录的 pyproject.toml 与uv.lock。若创建环境时出现Failed to parse警告(与pyproject.toml解析有关),只要末尾出现Activate with:行即说明环境创建成功。随后激活虚拟环境:

# bash/zsh 等 source .venv/bin/activate # fish source .venv/bin/activate.fish

Apple Silicon Mac 用户:首次安装 Python 包时必须指定自定义 OpenSSL 头文件(用于编译grpciopsycopg2):

brew install openssl CFLAGS="-I /opt/homebrew/opt/openssl/include $(python3.13-config --includes)" LDFLAGS="-L /opt/homebrew/opt/openssl/lib" GRPC_PYTHON_BUILD_SYSTEM_OPENSSL=1 GRPC_PYTHON_BUILD_SYSTEM_ZLIB=1 uv sync

此后只要这两个包未变更,直接uv sync即可。若出现ERROR: Could not build wheels for xmlsec,需要核对 xmlsec 的已知编译问题。

5. 准备数据库:运行迁移脚本

此时后端代码已就绪,Postgres 与 ClickHouse 容器也在运行,但两者都是空白库,需要执行迁移创建全部表结构:

cargo install sqlx-cli # 若尚未安装 DEBUG=1 ./bin/migrate

注意./bin/migrate是仓库根目录下的 shell 脚本(bin/migrate),并非 Django 自带的manage.py migrate的别名。

5.1bin/migrate到底做了什么

从源码看,bin/migrate 是一个聚合迁移入口,按 scope 分发执行:

  • clickhouse:后台并行运行python manage.py migrate_clickhousepython manage.py sync_replicated_schema
  • postgres:运行 Djangomanage.py migrate --noinput,内置最多 10 次重试(MIGRATE_MAX_RETRIES),重试间隔指数退避(默认从 3 秒起、倍增系数 2),并通过report_migration_metric上报耗时与尝试次数;若设置了POSTHOG_POSTGRES_DIRECT_HOST则走default_direct直连(绕过 PgBouncer 以支持lock_timeout);
  • product databases / persons / async / cyclotron / behavioral-cohorts / flags-read-store / temporal-schedules / tasks-oauth等更多 scope,各自对应不同的数据库与迁移工具(如 Rust 侧的migrate-cyclotron-nodemigrate-behavioral-cohortsmigrate-flags-read-store)。

在本地开发(DEBUG=1)下,persons 迁移会先--ensure-database确保 persons 库存在再执行;temporal-schedules 与 tasks-oauth 等生产专用步骤会被跳过。

5.2 常见迁移报错

报错解法
fe_sendauth: no password supplied数据库设置了密码但DATABASE_URL未带用户密码。执行export DATABASE_URL=postgres://posthog:posthog@localhost:5432/posthog
psycopg2相关错误(ARM 机器)参考 psycopg2 官方 issue 中针对 ARM 的编译/安装步骤
迁移连不上库确保容器正在运行(前台窗口或独立终端),迁移与容器是两回事

6. 启动 PostHog:一条命令拉起全部服务

6.1hogli start

基础设施、三端依赖与迁移都就绪后,启动整个 PostHog(后端、worker、Node.js 服务、前端,同时运行):

hogli start

hogli是仓库根目录 hogli.yaml 定义的统一开发者命令行工具。从配置看,start命令会拉起 django、frontend、celery、nodejs、ingestion、postgresql、redis、kafka、clickhouse、temporal 等全部服务单元。它内部调用bin/start脚本,通过 phrocs(PostHog 自研的进程运行器,基于 Bubble Tea 构建,见 tools/phrocs/README.md)把开发进程集中在一个终端窗口内管理,支持tab切换焦点、r重启进程、q退出等快捷键。

bin/start还承担了环境预检职责(bin/start):如果.env.local中存在 1Password 引用(op://前缀),会自动通过op run --env-file解析密钥;同时用flock加独占锁防止重复启动;多个 worktree 共享名为posthog的 Compose 项目。

如需按需定制服务集合,用交互式向导生成配置文件,之后hogli start会自动采用:

hogli dev:setup

macOS/Linux 用户首次运行hogli start时会自动安装 phrocs(通过 Homebrew Tapposthog/tap或仓库内源码构建)。

手册提示:若出现Configuration property "enable.ssl.certificate.verification" not supported in this build: OpenSSL not available at build time,说明环境中 OpenSSL 版本不对,需设置对应的环境变量后重新hogli start

6.2 验证与演示数据

启动完成后打开http://localhost:8010查看应用(8010 端口由 docker-compose.dev.yml 中 proxy 服务的 Caddy 容器映射到内部 Django 的 8000 端口,Caddy 还按路径把/e/i/v0/*等流量反向代理给 capture、feature-flags、plugins 等独立服务)。

首次启动若报layout.html is not defined,请等待前端编译完成再刷新。

为让新实例获得可直接操作的演示数据,运行:

DEBUG=1 ./manage.py generate_demo_data

该命令是仓库内的 Django 管理命令(generate_demo_data.py),支持通过--help查看参数。首次启动时也可用内置测试账号登录:用户名test@posthog.com,密码12345678

7. 日常开发:项目结构、分支与常用命令

环境就绪后,你可以在 http://localhost:8010 上看到 PostHog 应用,并随意修改代码(Django 与 Vite 均带热重载)。仓库结构介绍可参考 project-structure;提交变更时请基于master新建分支。

基于 hogli.yaml,日常开发还可使用以下高频命令:

类别命令说明
服务控制hogli up -d/hogli stop后台模式启动 / 停止开发进程(Docker 容器保持运行)
服务控制hogli docker:services:down停止全部 Docker 基础设施服务
服务控制hogli docker:services:remove停止服务并清除全部数据卷(完全重置)
健康检查hogli doctor开发环境快速体检
健康检查hogli doctor:ports预检开发栈所需宿主机端口
数据库hogli db:pg/hogli db:ch连接本地 Postgres / ClickHouse
数据库hogli db:dump/hogli db:restorePostgres 备份与恢复
迁移hogli migrations:run并行运行全部迁移(ClickHouse、Postgres、async)
迁移hogli migrations:check/hogli migrations:status校验迁移就绪 / 查看迁移差异
演示数据hogli dev:demo-data生成演示数据(等价于python manage.py generate_demo_data
测试hogli test自动检测测试类型(Python/Jest/Playwright/Rust/Go)并运行
代码质量hogli lint/hogli format运行 Python + JS/TS 的 lint / 格式化
构建hogli build运行代码生成流水线(含智能变更检测)
状态hogli dev:reset完整重置:清卷、迁移、加载演示数据、同步开关

8. 走向推荐路径:Flox 即时环境

手册开头明确建议新开发者改用 Flox 方案(developing-locally),其核心优势是:所有开发者获得完全一致的、可复现的工具与依赖版本,无需逐项手动安装。hogli.yaml的 services 元数据也印证了这一点——flox 被描述为"管理可复现开发环境,所有开发者获得完全相同的工具与依赖版本"。

手动流程虽然繁琐,但每一步都对应着 PostHog 真实的组件依赖:/etc/hosts对应容器间服务发现、Postgres 客户端对应psycopg2编译、brotli/Rust 对应 Node.js 原生模块、bin/migrate对应多数据库的迁移编排、hogli start对应 phrocs 进程编排。理解这套手动流程,能让你在 Flox 环境出问题时依然可以定位并修复底层环境故障。

参考链接

  • 本文主要依据:manual-dev-setup.md
  • 开发 Compose 覆盖:docker-compose.dev.yml
  • 基础 Compose 服务:docker-compose.base.yml
  • 开发者命令行定义:hogli.yaml
  • 聚合迁移脚本:bin/migrate
  • 进程运行器:tools/phrocs/README.md
  • 演示数据管理命令:generate_demo_data.py
  • Kafka topic 清单:docker/kafka/topics.txt

【免费下载链接】posthog:hedgehog: PostHog is the leading platform for building self-driving products. Our developer tools – AI observability, analytics, session replay, flags, experiments, error tracking, logs, and more – capture all the context agents need to diagnose problems, uncover opportunities, and ship fixes. Steer it all from Slack, web, desktop, or the MCP.项目地址: https://gitcode.com/GitHub_Trending/po/posthog

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 20:41:30

从Selenium到WinAppDriver:Windows桌面UI自动化框架的设计与实践

简介&#xff1a;面向Windows桌面应用自动化测试场景&#xff0c;基于Python语言与微软WinAppDriver驱动构建了一套可直接落地的UI测试框架。WinAppDriver兼容Selenium WebDriver协议&#xff0c;可驱动UWP与传统Win32桌面应用&#xff0c;框架在此基础上封装了测试基类、运行包…

作者头像 李华
网站建设 2026/9/12 20:33:07

2026用AI做问卷确实省时间,但题目质量还得自己把关

测评说明&#xff1a;本文为调研从业者实测记录&#xff0c;记录 2026 年四款线上问卷工具公开 AI 出题相关功能参数&#xff0c;面向 AI 辅助问卷设计场景&#xff0c;记录各渠道可支持能力。仅陈述客观功能与规则&#xff0c;不作优劣判定与选型推荐。测试基于各平台公开标准…

作者头像 李华
网站建设 2026/9/12 20:32:34

凝练了上百篇顶刊的 GPT-5.6 论文润色方法,效果极佳!

各位同仁好,我是七哥。一个在高校里从事人工智能 相关领域研究,钻研用大模型AI实操的学术人。可以和七哥交流学术写作或Gemini、GPT、Claude 等大模型 学术实操相关问题,多多交流,相互成就,共同进步。 如果一篇论文的核心观点足够扎实,却因为语言表达不够精准、逻辑衔…

作者头像 李华
网站建设 2026/9/12 20:32:00

手机日志与设备调试工具

Android / iOS 双平台日志调试工具&#xff0c;抓日志再也不用敲命令了 GitHub 地址&#xff1a;https://github.com/carterking888/phone_log_tool.git 做安卓 / iOS 测试或开发的同学大概都有这种体验&#xff1a;排查问题时要一边敲 adb logcat、adb shell、ls、pull&#…

作者头像 李华