Skip to content

feat: add Langfuse LXC - #2448

Open
steveonjava wants to merge 3 commits into
community-scripts:mainfrom
steveonjava:langfuse-native-lxc
Open

steveonjava wants to merge 3 commits into
community-scripts:mainfrom
steveonjava:langfuse-native-lxc

Conversation

@steveonjava

@steveonjava steveonjava commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

✍️ Description

New script: Langfuse, an open-source LLM engineering platform (tracing, evaluations, prompt management, metrics), installed natively without Docker.

  • Unprivileged Debian 13 LXC. Defaults are 4 vCPU, 16 GiB RAM and 100 GB disk; during the source build, the container peaked at 11 GiB including page cache.
  • Native PostgreSQL 17, ClickHouse with unclustered migrations, Redis, and single-node SeaweedFS S3 for event storage. All of them are loopback-only.
  • Langfuse web and worker are built from the release tarball with the Node, pnpm and Rust versions the release declares. Web listens on port 3000; the worker stays on loopback.
  • Configuration lives in /opt/langfuse_data/.env and survives updates.
  • The first start creates the admin account (var_admin_email, default admin@example.com; var_admin_pass, generated when empty), a Default project and its API keys through upstream's LANGFUSE_INIT_* variables. The login and keys go to ~/langfuse.creds, the one-time values are then removed from .env, and sign-up stays disabled.
  • Updates are health-gated: the version marker only advances after migrations and both health checks pass. SeaweedFS and golang-migrate follow their own releases.
  • The migration unit only Wants= the local PostgreSQL, ClickHouse, Redis and SeaweedFS units, so any of them can be disabled in favour of an external server configured in .env.

🔗 Related PR / Issue

Link: #2447

✅ Prerequisites (X in brackets)

  • Self-review completed – Code follows project standards.
  • Tested thoroughly – Changes work as expected.
  • No breaking changes – Existing functionality remains intact.
  • No security risks – No hardcoded secrets, unnecessary privilege escalations, or permission issues.

🏗️ arm64 Support (X in brackets)

  • arm64 supported - Tested and supported on arm64.
  • arm64 not tested - Assumed to work on arm64, but testing has not been done.
  • arm64 not supported - Confirmed upstream dependencies or binaries do not support arm64.

🖥️ Tested on (X in brackets)

  • Proxmox VE – Created on a Proxmox VE host and the app works.
  • Incus – Created on an Incus host and the app works.

Application containers run on both; tick what you actually tested. VMs and host tools are Proxmox only.


🛠️ Type of Change (X in brackets)

  • 🐞 Bug fix – Resolves an issue without breaking functionality.
  • ✨ New feature – Adds new, non-breaking functionality.
  • 💥 Breaking change – Alters existing functionality in a way that may require updates.
  • 🆕 New script – A fully functional and tested script or script set.
  • 🌍 Website update – Changes to website-related JSON files or metadata.
  • 🔧 Refactoring / Code Cleanup – Improves readability or maintainability without changing functionality.
  • 📝 Documentation update – Changes to README, AppName.md, CONTRIBUTING.md, or other docs.

🔍 Code & Security Review (X in brackets)

  • Follows CODE-AUDIT.md & CONTRIBUTING.md guidelines
  • Uses correct script structure (AppName.sh, AppName-install.sh, AppName.json)
  • No hardcoded credentials
  • No Docker / Docker Compose – The application is installed bare-metal; Docker is not used.
  • No git pull – Updates use fetch_and_deploy_gh_release, fetch_and_deploy_codeberg_release, fetch_and_deploy_gl_release, or fetch_and_deploy_from_url instead of git pull.

🤖 AI Assistance (X in brackets)

If you used an AI tool (GitHub Copilot, Claude, ChatGPT, etc.) to write or generate any scripts in this PR, you must confirm compliance below.
Select exactly one option.

  • No AI used – Scripts were written without AI assistance.
  • AI was used – I confirm the scripts were built using AGENTS.md and .github/agents/pve-script-creator.agent.md as guidance, and the output has been reviewed and corrected to match those guidelines.

Please describe to which degree, if any, an LLM was used in creating this pull request. Name the model(s) used and, if applicable, the reasoning/thinking effort level (e.g. "Claude Sonnet 4.5, high reasoning, used to draft the install script, then manually reviewed and tested" or "No LLM used"). This is informational, not a penalty — but scripts that are clearly AI-generated and not further revised by the author to match CODE-AUDIT.md / CONTRIBUTING.md may be closed without review.

AI was used to generate the script, with careful attention to existing script patterns and contributor guidelines. The final script has been human-reviewed.


📋 Additional Information (optional)

Candidate branch: steveonjava/ProxmoxVED langfuse-native-lxc (commit 080a14a, on DevScripts main fd53441).

Tested on Proxmox VE 9.2.21 (kernel 7.0.14) from a local checkout of 080a14a with core 1ed2485 (source-origin guide, variant 2). The run used mode=mydefaults, with var_disk=30 because of the test host's free space, and supplied var_admin_email and a var_admin_pass containing # $ % ; & *.

  • Install: completed in 25.5 min with no warnings. All services were active, web/worker health and ready endpoints returned 200, and only port 3000 is reachable from outside the container. The test confirmed:
    • the supplied email and password were used as given, ~/langfuse.creds is mode 600, and its login and API keys work; a wrong password gets no session;
    • the admin owns the Default organization and project, sign-up returns "Sign up is disabled." and .env keeps no LANGFUSE_INIT_* values;
    • the password appears only in the creds file (helper log, container files and journal checked);
    • the API returns 401 for anonymous requests and wrong keys;
    • an OTLP generation span was ingested and read back via /api/public/v2/observations, with usage 1000/500 counted once and gpt-4o cost 0.0075 USD;
    • each batch writes its event object to local S3, and anonymous S3 access gets 403.
  • Dependency restarts: restarting PostgreSQL, ClickHouse, Redis, or SeaweedFS did not restart Langfuse, and it stayed healthy.
  • Update, already current: 13 s, "No update available" for SeaweedFS, golang-migrate and Langfuse; nothing was touched.
  • Update, tools only: with the SeaweedFS and golang-migrate markers rewound, both were redeployed in 54 s, and SeaweedFS passed its health check. Langfuse was not touched.
  • Update, forced: with the Langfuse marker rewound, the full update path completed in 11 min. .env, the S3 identity and the creds file stayed byte-identical; the new build started, and the marker advanced only after health passed.
  • Reboot: web was ready in about 13 s, and every earlier trace was still readable.
  • External Redis: with .env pointed at another Redis and redis-server masked, Langfuse started and kept working, including after a reboot.
  • Key revocation: an API key deleted in the UI stays deleted after a restart.
  • Every update, reboot and Redis step was followed by the full functional check, which passed each time.

Langfuse v4 defaults to the events_only write mode, so OTLP and the v2 read APIs are the supported path. arm64 and Incus were not tested.


📦 Application Requirements (for new scripts)

⚠️ Do not remove this section.
It is used by automated PR validation checks.
If this PR is not a new script submission, leave the checkboxes unchecked.

Required for 🆕 New script submissions.
Pull requests that do not meet these requirements may be closed without review.

  • The application is at least 6 months old
  • The application is actively maintained
  • The application has 600+ GitHub stars
  • Official release tarballs are published
  • I understand that not all scripts will be accepted due to various reasons and criteria by the community-scripts ORG

🌐 Source

- Create the admin, a Default project and its API keys through upstream's
  LANGFUSE_INIT_* variables on first start, save them to ~/langfuse.creds,
  then drop the one-time values from .env and keep sign-up disabled.
- Update SeaweedFS and golang-migrate from their own releases.
- Let langfuse-migrate want, not require, the local PostgreSQL, ClickHouse,
  Redis and SeaweedFS units, so an external server can replace one.
- Explain the build-time DOCKER_BUILD flag and drop it from the runtime .env.
- Read var_admin_pass (declared in app_vars, exported from the ct script)
  and use it for the first-start admin account.
- Generate a password when it is empty, or when it is shorter than
  Langfuse's 8-character minimum or holds spaces, quotes or backslashes
  that systemd's EnvironmentFile parser would alter.
@github-actions

Copy link
Copy Markdown
Contributor

Try this script

ct/langfuse.sh, run in the Proxmox VE shell or on an Incus host:

COMMUNITY_SCRIPTS_URL=https://raw.githubusercontent.com/steveonjava/ProxmoxVED/langfuse-native-lxc \
bash -c "$(curl -fsSL https://raw.githubusercontent.com/steveonjava/ProxmoxVED/langfuse-native-lxc/ct/langfuse.sh)"

COMMUNITY_SCRIPTS_URL is not optional for ct/. Fetching the ct/ script from a
branch does not tell the engine where that branch is — with bash -c "$(curl …)"
there is no file on disk for the scripts root to be derived from, so it would fall
back to upstream main and look for the install script there.

Against a core branch as well

Add COMMUNITY_SCRIPTS_CORE_URL=https://raw.githubusercontent.com/OWNER/core/BRANCH
to test an engine change at the same time. The two resolve independently.

Useful flags while testing

dev_mode=net logs every fetch with status and duration, so you can confirm the
branch is really being used. dev_mode=keep stops a failed build from deleting
the container along with the evidence.

@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

✅ Requirements check passed. Thanks for fixing the description — the stale mark has been removed.

@github-actions github-actions Bot added requirements missing PR description misses template items; closes after 7 days unless fixed or keep-open stale new script and removed requirements missing PR description misses template items; closes after 7 days unless fixed or keep-open stale labels Oct 19, 2026
@steveonjava
steveonjava marked this pull request as ready for review October 19, 2026 04:48
@steveonjava
steveonjava requested a review from a team as a code owner October 19, 2026 04:48

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant