Skip to content

Configuration Compilation

This document describes how xp2p turns operator-facing configuration (TOML + optional JSON snippets) into the final xray-core runtime configuration.

The goal is to:

  • Keep human-editable inputs small and stable.
  • Allow safe user extensions without editing generated files.
  • Produce a deterministic, validated final Xray JSON config.

Sources of Truth

xp2p treats configuration as layered inputs.

Desired Inputs (operator-editable)

Managed behavior is configured through TOML and can be edited manually or via CLI/UI:

  • CONFIG_ROOT/xp2p-client.toml
  • CONFIG_ROOT/xp2p-server.toml

User extensions are provided as JSON snippets under role config directories:

  • CONFIG_ROOT/config-client/*.json
  • CONFIG_ROOT/config-server/*.json

xp2p reads these JSON files and merges them into the final Xray configuration. xp2p must not rewrite them.

Build Artifacts (runtime outputs)

xp2p compiles inputs into a final Xray JSON configuration file that is used at runtime:

  • CONFIG_ROOT/.state/live/config-client/xray.json
  • CONFIG_ROOT/.state/live/config-server/xray.json

These files are generated by the service/apply layer and must not be edited manually.

Directory Layout

  • Desired inputs
  • CONFIG_ROOT/xp2p-*.toml
  • CONFIG_ROOT/config-*/ (JSON snippets)
  • Service state and runtime artifacts
  • CONFIG_ROOT/.state/apply.request
  • CONFIG_ROOT/.state/apply.error
  • CONFIG_ROOT/.state/live/config-*/xray.json
  • CONFIG_ROOT/.state/lkg/config-*/xray.json (optional)
  • CONFIG_ROOT/audit.log

The .state directory stores service/apply metadata and compiled runtime artifacts. It does not mirror Desired inputs.

Compilation Pipeline

For each role (client/server), the service/apply layer performs:

  1. Load Desired TOML (CONFIG_ROOT/xp2p-*.toml).
  2. Load Desired JSON snippets from CONFIG_ROOT/config-*/ (if present).
  3. Build the managed base Xray configuration from TOML (endpoints, routing, inbounds, logs, reverse bridges, etc.).
  4. Merge user snippets into the managed base according to deterministic rules.
  5. Validate the final config (structure, reserved tag collisions, required sections).
  6. Write the final config to .state/live/config-*/xray.json atomically.
  7. Start/restart Xray using the final JSON file only.

Merge Rules

xp2p merges JSON snippets into the managed base in a role-specific way. The merge is explicit and deterministic.

Supported Extension Files

JSON snippets live in:

  • CONFIG_ROOT/config-client/
  • CONFIG_ROOT/config-server/

All files are optional. For discoverability, xp2p ships blank templates in:

  • config_templates/extensions/config-client/
  • config_templates/extensions/config-server/

Client

  • routing.rules.after-xp2p-system.json
  • Shape: { "rules": [ ... ] }
  • Inserted after managed endpoint-bypass + system glue rules.
  • Use for high-priority rules that should win over redirects/forwards.
  • routing.rules.after-xp2p-managed.json
  • Shape: { "rules": [ ... ] }
  • Inserted after all managed rules and before the full-tunnel rule (when enabled).
  • Use for additional rules that should not override core safety rules.
  • inbounds.append.json
  • Shape: { "inbounds": [ ... ] }
  • Appended to managed inbounds.
  • outbounds.append.json
  • Shape: { "outbounds": [ ... ] }
  • Appended to managed outbounds.

Server

  • routing.rules.after-xp2p-system.json (same meaning as client)
  • routing.rules.after-xp2p-managed.json (same meaning as client)
  • inbounds.append.json (append to managed inbounds)
  • outbounds.append.json (append to managed outbounds)

Reserved Namespace

xp2p reserves identifiers it manages (tags, remarks, internal routing domains).

The following are reserved by default:

  • proxy-* (endpoint outbounds)
  • *.rev (reverse bridge domains)
  • xp2p-* (internal tags and glue components)

User snippets must not introduce collisions with reserved identifiers unless an explicit override mode is enabled.

Routing Rule Order

The final routing rule order is stable:

  1. Managed endpoint bypass rules (used for safe tunnel reachability).
  2. Managed system rules (reverse/marker glue, internal responders).
  3. Managed redirect/forward rules.
  4. User rules (optional) inserted at extension points (see Supported Extension Files above).
  5. Managed full-tunnel rule (when enabled).

If user routing snippets are present, they are inserted at the configured extension points only.

Outbounds, Inbounds, and Other Sections

User snippets can add additional objects, but xp2p-managed objects remain authoritative.

Common supported extension points:

  • Additional inbounds
  • Additional outbounds
  • Additional routing.rules
  • DNS and policy sections (if provided by Xray)

For safety, xp2p rejects:

  • Attempts to delete managed objects.
  • Attempts to modify reserved tags without override mode.
  • Attempts to add objects with invalid or conflicting tags.

Commands for Inspection

xp2p provides inspection commands that do not change runtime state.

Render Final Xray JSON

Render the exact JSON that would be used at runtime:

xp2p client render xray --live --output -
xp2p server render xray --live --output -

Render the configuration compiled from Desired inputs (without applying it):

xp2p client render xray --desired --output -
xp2p server render xray --desired --output -

Debug Bundle

Collect a self-contained archive for troubleshooting:

xp2p client debug bundle --output /tmp/xp2p-client-debug.zip
xp2p server debug bundle --output /tmp/xp2p-server-debug.zip

The bundle includes:

  • Desired inputs (xp2p-*.toml and config-*/ snippets)
  • apply.request / apply.error (when present)
  • final xray.json
  • audit.log
  • service logs under XP2P_LOG_ROOT

Operational Notes

  • Operators edit TOML and JSON snippets only.
  • The service/apply layer compiles and validates configs into xray.json.
  • Runtime processes always use the live compiled xray.json only.