You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2026/03/12 03:37:50 UTC
(skywalking-graalvm-distro) branch main updated (68ebc83 -> ce00a5c)
This is an automated email from the ASF dual-hosted git repository.
wusheng pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-graalvm-distro.git
from 68ebc83 Update BanyanDB to e1ba421, bump Istio to 1.28.0, add baseline e2e case
new b59ce67 Restructure docs for end users: add quick-start, features, FAQ
new ce00a5c Add TTLDefinition to native image reflect-config for /status/config/ttl endpoint
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
CLAUDE.md | 10 +-
.../server/buildtools/precompiler/Precompiler.java | 4 +-
docs/README.md | 106 ++++------------
docs/distro-policy.md | 4 +-
docs/faq.md | 138 +++++++++++++++++++++
docs/{ => internals}/config-init-immigration.md | 0
docs/{ => internals}/dsl-immigration.md | 0
docs/{ => internals}/oal-immigration.md | 0
docs/menu.yml | 22 ++--
docs/quick-start.md | 82 ++++++++++++
docs/supported-features.md | 132 ++++++++++++++++++++
11 files changed, 396 insertions(+), 102 deletions(-)
create mode 100644 docs/faq.md
rename docs/{ => internals}/config-init-immigration.md (100%)
rename docs/{ => internals}/dsl-immigration.md (100%)
rename docs/{ => internals}/oal-immigration.md (100%)
create mode 100644 docs/quick-start.md
create mode 100644 docs/supported-features.md
(skywalking-graalvm-distro) 02/02: Add TTLDefinition to native image reflect-config for /status/config/ttl endpoint
Posted by wu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
wusheng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-graalvm-distro.git
commit ce00a5cd56d166edfe9139a06968ff70f19cdb31
Author: Wu Sheng <wu...@foxmail.com>
AuthorDate: Thu Mar 12 11:37:41 2026 +0800
Add TTLDefinition to native image reflect-config for /status/config/ttl endpoint
The baseline e2e test failed because the REST endpoint /status/config/ttl
returns TTLDefinition, which Jackson cannot serialize in native image without
reflection metadata. MetricsTTL and RecordsTTL were already covered by the
GraphQL type scanner, but the wrapper TTLDefinition was not.
---
.../skywalking/oap/server/buildtools/precompiler/Precompiler.java | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/build-tools/precompiler/src/main/java/org/apache/skywalking/oap/server/buildtools/precompiler/Precompiler.java b/build-tools/precompiler/src/main/java/org/apache/skywalking/oap/server/buildtools/precompiler/Precompiler.java
index 82007f2..11630e5 100644
--- a/build-tools/precompiler/src/main/java/org/apache/skywalking/oap/server/buildtools/precompiler/Precompiler.java
+++ b/build-tools/precompiler/src/main/java/org/apache/skywalking/oap/server/buildtools/precompiler/Precompiler.java
@@ -1372,7 +1372,9 @@ public class Precompiler {
"org.apache.skywalking.oap.server.core.alarm.AlarmMessage",
// LALOutputBuilder SPI: ServiceLoader instantiates to call name() for short-name resolution
"org.apache.skywalking.oap.server.analyzer.provider.trace.parser.listener.DatabaseSlowStatementBuilder",
- "org.apache.skywalking.oap.server.analyzer.provider.trace.parser.listener.SampledTraceBuilder"
+ "org.apache.skywalking.oap.server.analyzer.provider.trace.parser.listener.SampledTraceBuilder",
+ // TTL status REST endpoint: Jackson serializes TTLDefinition returned by /status/config/ttl
+ "org.apache.skywalking.oap.server.core.storage.ttl.TTLDefinition"
};
for (String className : configPojos) {
entries.add(fullAccessEntry(className));
(skywalking-graalvm-distro) 01/02: Restructure docs for end users: add quick-start, features, FAQ
Posted by wu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
wusheng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-graalvm-distro.git
commit b59ce67374e93eaab6b596ea842c9cccbb6ee811
Author: Wu Sheng <wu...@foxmail.com>
AuthorDate: Thu Mar 12 10:11:22 2026 +0800
Restructure docs for end users: add quick-start, features, FAQ
- Add docs/quick-start.md, docs/supported-features.md, docs/faq.md
- Move internal build-time docs to docs/internals/
- Update docs/README.md with user-facing and contributor sections
- Update menu.yml, distro-policy.md, CLAUDE.md links accordingly
---
CLAUDE.md | 10 +-
docs/README.md | 106 ++++--------------
docs/distro-policy.md | 4 +-
docs/faq.md | 138 ++++++++++++++++++++++++
docs/{ => internals}/config-init-immigration.md | 0
docs/{ => internals}/dsl-immigration.md | 0
docs/{ => internals}/oal-immigration.md | 0
docs/menu.yml | 22 ++--
docs/quick-start.md | 82 ++++++++++++++
docs/supported-features.md | 132 +++++++++++++++++++++++
10 files changed, 393 insertions(+), 101 deletions(-)
diff --git a/CLAUDE.md b/CLAUDE.md
index 8204bd3..ac59bbc 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -8,7 +8,7 @@
- `oap-graalvm-server/` — GraalVM-ready OAP server module (JVM distro) with same-FQCN replacement classes and comprehensive test suites.
- `oap-graalvm-native/` — Native image module: `native-maven-plugin` configuration, native-specific `log4j2.xml`, `log4j2-reflect-config.json`, and native distribution assembly.
- `docker/` — `Dockerfile.native` (runtime image) and `docker-compose.yml` (BanyanDB + OAP native).
-- `docs/` — Documentation: distro-policy, configuration, DSL pre-compilation (OAL/MAL/LAL/Hierarchy), config initialization.
+- `docs/` — User-facing docs (quick-start, features, FAQ, configuration) and `docs/internals/` for build-time immigration details.
- Root-level Maven + Makefile — Orchestrates building on top of the submodule.
## Key Principles
@@ -26,7 +26,7 @@
- **MeterSystem**: `MeterSystem.create()` uses Javassist to generate ~1188 meter function subclasses. Run at build time, export `.class` files. Separate from MAL DSL compilation.
- **Same-FQCN replacement**: Classes in `oap-libs-for-graalvm/*/src/main/java/` with the same fully-qualified class name as upstream classes are repackaged via `maven-shade-plugin` (original `.class` excluded). Used for v2 `DSL.java` (MAL/LAL), `MeterSystem.java`, `CompiledHierarchyRuleProvider.java`, etc.
- **Classpath scanning**: Guava `ClassPath.from()` used in multiple places. Run at build-time pre-compilation as verification gate, export static class index.
-- **Config loading**: `YamlConfigLoaderUtils.copyProperties()` replaced with same-FQCN version that uses Lombok setters instead of `Field.setAccessible()`. See [docs/config-init-immigration.md](docs/config-init-immigration.md).
+- **Config loading**: `YamlConfigLoaderUtils.copyProperties()` replaced with same-FQCN version that uses Lombok setters instead of `Field.setAccessible()`. See [docs/internals/config-init-immigration.md](docs/internals/config-init-immigration.md).
- **Reflection metadata**: Precompiler auto-generates `reflect-config.json` by scanning Armeria HTTP handlers, GraphQL resolvers/types, config POJOs, and OAL/MAL/LAL/Hierarchy manifests. `log4j2-reflect-config.json` is manually maintained for Log4j2 plugin classes.
- **Native image**: `oap-graalvm-native` uses `native-maven-plugin` with `-Pnative` profile. Console-only `log4j2.xml` avoids RollingFile reflection chain. ~203MB binary, boots to full module init.
@@ -35,7 +35,7 @@
- **LAL**: Verify pre-compiled `LalExpression` classes produce identical results. Covers all 8 LAL YAML files.
- **Hierarchy**: Verify pre-compiled hierarchy rule classes match fresh v2 compilation.
-See [docs/dsl-immigration.md](docs/dsl-immigration.md) for details.
+See [docs/internals/dsl-immigration.md](docs/internals/dsl-immigration.md) for details.
## Build Commands
@@ -48,7 +48,7 @@ make build-distro
# Precompiler only
mvn -pl build-tools/precompiler install -DskipTests
-# Run MAL tests only
+# Run tests
mvn -pl oap-graalvm-server test
# Native image (requires GraalVM with native-image)
@@ -71,4 +71,4 @@ docker compose -f docker/docker-compose.yml up
- **Storage**: BanyanDB
- **Cluster**: Standalone, Kubernetes
- **Configuration**: Kubernetes
-- **Receivers/Query/Analyzers/Alarm/Telemetry/Other**: Full feature set (see docs/distro-policy.md for details)
\ No newline at end of file
+- **Receivers/Query/Analyzers/Alarm/Telemetry/Other**: Full feature set (see docs/distro-policy.md for details)
diff --git a/docs/README.md b/docs/README.md
index 239ec14..cabe177 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -2,80 +2,36 @@
**GraalVM native-image distribution of Apache SkyWalking OAP Server.**
-This project produces a self-contained native binary of the SkyWalking OAP backend.
-It wraps the upstream [Apache SkyWalking](https://github.com/apache/skywalking) repository
-as a git submodule and applies build-time transformations to eliminate all GraalVM-incompatible
-patterns — without modifying upstream source code.
+A self-contained native binary of the SkyWalking OAP backend — faster startup,
+lower memory, single-binary deployment. All your existing SkyWalking agents, UI,
+and tooling work unchanged.
-## Why Native Image
-
-- **Fast startup** — native binary boots directly to full module initialization
-- **Lower memory footprint** — no JIT compiler, no class-loading overhead
-- **Single binary deployment** — ~203MB self-contained executable, ideal for containers and cloud-native environments
-
-## How It Works
-
-SkyWalking OAP relies on runtime code generation and dynamic class loading in several subsystems.
-This distro moves all of that to build time:
-
-| Subsystem | Runtime Pattern | Build-Time Solution |
-|-----------|----------------|---------------------|
-| **OAL** (metrics) | Javassist generates ~1285 classes at startup | OAL v2 engine runs at build time, exports `.class` files and manifests |
-| **MAL** (meters) | ANTLR4 + Javassist compiles ~1250 expressions at startup | MAL v2 compiler runs at build time via `MALClassGenerator.setClassOutputDir()` |
-| **LAL** (logs) | ANTLR4 + Javassist compiles ~10 scripts at startup | LAL v2 compiler runs at build time via `LALClassGenerator.setClassOutputDir()` |
-| **Hierarchy** | ANTLR4 + Javassist compiles ~4 rules at startup | Hierarchy v2 compiler runs at build time via `HierarchyRuleClassGenerator.setClassOutputDir()` |
-| **Config loading** | `Field.setAccessible()` + reflection | `ConfigInitializerGenerator` produces setter-based `YamlConfigLoaderUtils` |
-| **Classpath scanning** | Guava `ClassPath.from()` at startup | Build-time manifests under `META-INF/annotation-scan/` |
-| **Module wiring** | ServiceLoader SPI discovery | `FixedModuleManager` with hardcoded module/provider construction |
-
-All replacement classes use the **same-FQCN** (fully-qualified class name) technique: a replacement
-class with the identical package and name is repackaged via `maven-shade-plugin`, excluding the
-original from the upstream JAR. No classpath ordering tricks needed.
-
-## Module Selection
-
-The distro ships with a full feature set. Module/provider selection is fixed at build time:
-
-- **Storage**: BanyanDB
-- **Cluster**: Standalone, Kubernetes
-- **Configuration**: Kubernetes
-- **Receivers**: All (trace, JVM, meter, log, browser, OTel, mesh, Envoy, Zipkin, Zabbix, Telegraf, AWS Firehose, Cilium, eBPF, async-profiler, pprof, CLR, Kafka fetcher)
-- **Analyzers**: Trace, Log, Event
-- **Query**: GraphQL, PromQL, LogQL, Zipkin, Status
-- **Alarm, Telemetry, Exporter, Health Check, AI Pipeline**: All enabled
-
-See [Distribution Policy](distro-policy.md) for the complete module table and architecture details.
+## For Users
-## Prerequisites
+- [Quick Start](quick-start.md) — get running in under 5 minutes
+- [Supported Features](supported-features.md) — what's included, optional modules, compatibility
+- [Configuration](configuration.md) — environment variables and module settings
+- [Pre-Built Docker Images](docker-image.md) — pull and run from GHCR
+- [FAQ](faq.md) — common questions and troubleshooting
-- **GraalVM JDK 25** with `native-image` installed
-- **Maven 3.9+**
-- **Docker** (for container builds and docker-compose)
+## For Contributors
-## Build Commands
+- [Compiling from Source](compiling.md) — build JVM distro, native image, and Docker image
+- [Distribution Policy](distro-policy.md) — module table, architecture constraints, build workflow
-```bash
-# Full build (precompiler + tests + JVM distro)
-JAVA_HOME=$GRAALVM_HOME make build-distro
+### Build-Time Internals
-# Precompiler only
-JAVA_HOME=$GRAALVM_HOME mvn -pl build-tools/precompiler install -DskipTests
+These docs describe how the distro moves runtime code generation to build time:
-# Run tests only
-JAVA_HOME=$GRAALVM_HOME mvn -pl oap-graalvm-server test
+- [DSL Pre-Compilation](internals/dsl-immigration.md) — unified OAL/MAL/LAL/Hierarchy build-time compilation via ANTLR4 + Javassist v2
+- [OAL Pre-Compilation](internals/oal-immigration.md) — OAL-specific details: Javassist class export, annotation scan manifests
+- [Config Initialization](internals/config-init-immigration.md) — reflection-free config loading via generated setters
-# Native image
-JAVA_HOME=$GRAALVM_HOME make native-image
-
-# Docker native image (cross-compile on macOS)
-make native-image-macos
-
-# Package into Docker image
-make docker-native
+## Why Native Image
-# Run with Docker Compose (BanyanDB + OAP native)
-docker compose -f docker/docker-compose.yml up
-```
+- **Fast startup** — native binary boots directly to full module initialization
+- **Lower memory footprint** — no JIT compiler, no class-loading overhead
+- **Single binary deployment** — ~203MB self-contained executable, ideal for containers
## Project Structure
@@ -91,23 +47,3 @@ skywalking-graalvm-distro/
├── docker/ # Dockerfile.native + docker-compose.yml
└── docs/ # Documentation
```
-
-## Test Suites
-
-Build-time pre-compilation is validated by dual-path comparison tests:
-
-- **MAL**: Verify pre-compiled `MalExpression` classes produce identical results to fresh v2 compilation
-- **LAL**: Verify pre-compiled `LalExpression` classes produce identical results to fresh v2 compilation
-- **Hierarchy**: Verify pre-compiled hierarchy rule classes match fresh v2 compilation
-
-Tests require actual data flow — no vacuous empty-result agreements.
-
-## Further Reading
-
-- [Distribution Policy](distro-policy.md) — full module table, architecture constraints, build workflow
-- [Compiling from Source](compiling.md) — build JVM distro, native image, and Docker image step by step
-- [Pre-Built Docker Images](docker-image.md) — pull and run the CI-built native image from GHCR
-- [Configuration](configuration.md) — all available settings, environment variables, and differences from upstream
-- [DSL Pre-Compilation](dsl-immigration.md) — unified OAL/MAL/LAL/Hierarchy build-time compilation via ANTLR4 + Javassist v2
-- [OAL Pre-Compilation](oal-immigration.md) — OAL-specific details: Javassist class export, annotation scan manifests
-- [Config Initialization](config-init-immigration.md) — reflection-free config loading via generated setters
diff --git a/docs/distro-policy.md b/docs/distro-policy.md
index 44f8f92..6168eb4 100644
--- a/docs/distro-policy.md
+++ b/docs/distro-policy.md
@@ -44,7 +44,7 @@ Since upstream PR #13723, all four SkyWalking DSL compilers (OAL, MAL, LAL, Hier
### Approach (Simplified)
Run all four v2 compilers at build time via their native exposed APIs (`setClassOutputDir()`, `setClassNameHint()`, `setGeneratedFilePath()`). Capture generated `.class` files into the precompiler output JAR. At runtime, same-FQCN replacement loaders find these classes by name instead of compiling them.
-**Details**: [dsl-immigration.md](dsl-immigration.md) | [oal-immigration.md](oal-immigration.md)
+**Details**: [dsl-immigration.md](internals/dsl-immigration.md) | [oal-immigration.md](internals/oal-immigration.md)
### OAL
- `OALEngineV2.start()` processes all 9 OAL defines at build time.
@@ -96,7 +96,7 @@ Run all four v2 compilers at build time via their native exposed APIs (`setClass
2. **Simplified config file**: Only knobs for selected providers
3. **Config loading**: **No reflection.** Build-time tool scans all `ModuleConfig` subclass fields → generates same-FQCN replacement of `YamlConfigLoaderUtils` that uses Lombok setters and VarHandle to set config fields directly. Eliminates `Field.setAccessible`/`field.set` and the need for `reflect-config.json` for config classes.
-**Details**: [config-init-immigration.md](config-init-immigration.md)
+**Details**: [config-init-immigration.md](internals/config-init-immigration.md)
### What Was Built
- `FixedModuleManager` — direct module/provider construction via `ModuleDefine.prepare()` overload, no SPI
diff --git a/docs/faq.md b/docs/faq.md
new file mode 100644
index 0000000..331ad00
--- /dev/null
+++ b/docs/faq.md
@@ -0,0 +1,138 @@
+# FAQ
+
+## General
+
+### How is this different from upstream Apache SkyWalking?
+
+This is a **distribution** of the same Apache SkyWalking OAP server, compiled as a GraalVM
+native image. The observability features are identical. The differences are:
+
+- **Native binary** instead of JVM — faster startup, lower memory
+- **BanyanDB only** — no Elasticsearch/H2/MySQL/PostgreSQL support
+- **Fixed module set** — modules are selected at build time, not via SPI
+- **No runtime code generation** — all DSL compilation happens at build time
+
+Your existing SkyWalking agents, UI, and tooling work unchanged.
+
+### Can I use Elasticsearch as storage?
+
+No. This distro only supports BanyanDB. The Elasticsearch storage plugin requires
+dynamic class loading patterns that are incompatible with GraalVM native image.
+
+If you need Elasticsearch, use the standard upstream SkyWalking distribution.
+
+### Can I use the standard SkyWalking UI?
+
+Yes. The SkyWalking Booster UI connects to the OAP server via the same GraphQL API
+on port 12800. No changes needed.
+
+### What agents are compatible?
+
+All official SkyWalking agents work with this distro — they communicate via the same
+gRPC/HTTP protocols. OpenTelemetry agents sending OTLP data also work.
+
+---
+
+## Deployment
+
+### What are the system requirements?
+
+- **CPU**: amd64 or arm64
+- **Memory**: ~512MB minimum, 1GB+ recommended for production
+- **Storage**: BanyanDB instance (can run on same host or separately)
+- **OS**: Linux (native binary). Docker images based on `debian:bookworm-slim`
+
+### How do I run in Kubernetes?
+
+1. Deploy BanyanDB (see [BanyanDB docs](https://skywalking.apache.org/docs/skywalking-banyandb/latest/readme/))
+2. Deploy the OAP native image with:
+ ```yaml
+ env:
+ - name: SW_STORAGE_BANYANDB_TARGETS
+ value: "banyandb:17912"
+ - name: SW_CLUSTER
+ value: "kubernetes"
+ - name: SW_CLUSTER_K8S_NAMESPACE
+ value: "skywalking"
+ ```
+3. Configure health checks on port 12800 (`/healthcheck`)
+
+### How do I enable Zipkin support?
+
+Set two environment variables:
+
+```bash
+SW_RECEIVER_ZIPKIN=default # Zipkin span receiver on port 9411
+SW_QUERY_ZIPKIN=default # Zipkin query API on port 9412
+```
+
+### How do I configure alarms?
+
+Mount a custom `alarm-settings.yml` into the container at `/skywalking/config/alarm-settings.yml`.
+The alarm configuration format is the same as upstream SkyWalking.
+See [Alarm documentation](https://skywalking.apache.org/docs/main/next/en/setup/backend/backend-alarm/).
+
+---
+
+## Troubleshooting
+
+### The native binary fails to start
+
+Check for these common issues:
+
+1. **BanyanDB not reachable**: Ensure `SW_STORAGE_BANYANDB_TARGETS` points to a running BanyanDB.
+ The OAP server will retry but may fail if BanyanDB is not available during schema installation.
+
+2. **Port conflicts**: The default ports (12800, 11800) may be in use. Check with `netstat` or `ss`.
+
+3. **Insufficient memory**: The native binary needs at least ~400MB of heap. If running in a
+ container with tight limits, increase the memory allocation.
+
+### Logs show "Unknown config type" warnings
+
+This means an environment variable is set for a module that isn't included in the distro.
+For example, setting `SW_STORAGE=elasticsearch` will produce a warning because
+Elasticsearch isn't available. Check [Supported Features](supported-features.md) for
+the list of included modules.
+
+### How do I change the log level?
+
+Set the `SW_LOG_LEVEL` environment variable:
+
+```bash
+SW_LOG_LEVEL=DEBUG # Options: TRACE, DEBUG, INFO, WARN, ERROR
+```
+
+The native image uses console-only logging (no file rotation).
+
+---
+
+## Building
+
+### Do I need GraalVM to use this distro?
+
+No. Pre-built Docker images are available at `ghcr.io/apache/skywalking-graalvm-distro`.
+GraalVM is only needed if you want to build from source.
+
+### What GraalVM version is required for building?
+
+GraalVM JDK 25 with `native-image` installed. The Makefile auto-detects it via sdkman
+or `JAVA_HOME`.
+
+### The native image build runs out of memory
+
+The native image build requires ~8GB RAM. Set Maven memory limits:
+
+```bash
+export MAVEN_OPTS="-Xmx4g"
+make native-image
+```
+
+### How do I cross-compile for Linux on macOS?
+
+```bash
+make native-image-macos
+```
+
+This runs the native-image build inside a Docker container, producing a Linux binary
+while reusing your host Maven cache.
diff --git a/docs/config-init-immigration.md b/docs/internals/config-init-immigration.md
similarity index 100%
rename from docs/config-init-immigration.md
rename to docs/internals/config-init-immigration.md
diff --git a/docs/dsl-immigration.md b/docs/internals/dsl-immigration.md
similarity index 100%
rename from docs/dsl-immigration.md
rename to docs/internals/dsl-immigration.md
diff --git a/docs/oal-immigration.md b/docs/internals/oal-immigration.md
similarity index 100%
rename from docs/oal-immigration.md
rename to docs/internals/oal-immigration.md
diff --git a/docs/menu.yml b/docs/menu.yml
index a979768..eee6b31 100644
--- a/docs/menu.yml
+++ b/docs/menu.yml
@@ -18,8 +18,12 @@
catalog:
- name: "Welcome"
path: "/readme"
- - name: "Distribution Policy"
- path: "/distro-policy"
+ - name: "Quick Start"
+ path: "/quick-start"
+ - name: "Supported Features"
+ path: "/supported-features"
+ - name: "FAQ"
+ path: "/faq"
- name: "Setup"
catalog:
- name: "Compiling from Source"
@@ -28,13 +32,13 @@ catalog:
path: "/docker-image"
- name: "Configuration"
path: "/configuration"
- - name: "Build-Time Immigration"
+ - name: "Architecture"
catalog:
+ - name: "Distribution Policy"
+ path: "/distro-policy"
+ - name: "DSL Pre-Compilation"
+ path: "/internals/dsl-immigration"
- name: "OAL Pre-Compilation"
- path: "/oal-immigration"
- - name: "MAL Transpilation"
- path: "/mal-immigration"
- - name: "LAL Transpilation"
- path: "/lal-immigration"
+ path: "/internals/oal-immigration"
- name: "Config Initialization"
- path: "/config-init-immigration"
+ path: "/internals/config-init-immigration"
diff --git a/docs/quick-start.md b/docs/quick-start.md
new file mode 100644
index 0000000..2c867cd
--- /dev/null
+++ b/docs/quick-start.md
@@ -0,0 +1,82 @@
+# Quick Start
+
+Get the SkyWalking GraalVM native OAP server running in under 5 minutes.
+
+## Option 1: Docker Compose (Recommended)
+
+Pull and start BanyanDB + OAP native server:
+
+```bash
+git clone https://github.com/apache/skywalking-graalvm-distro.git
+cd skywalking-graalvm-distro
+
+# Start BanyanDB + OAP native image
+docker compose -f docker/docker-compose.yml up
+```
+
+The OAP server is ready when you see the module init table in logs. Verify:
+
+```bash
+curl http://localhost:12800/healthcheck
+```
+
+### Connect Your Application
+
+Point your SkyWalking agent to the OAP server:
+
+```bash
+# Java agent example
+java -javaagent:skywalking-agent.jar \
+ -Dskywalking.collector.backend_service=localhost:11800 \
+ -jar your-app.jar
+```
+
+Or send OpenTelemetry data:
+
+```bash
+# OTLP gRPC endpoint
+export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:11800
+```
+
+### Ports
+
+| Port | Service |
+|------|---------|
+| 12800 | REST API (GraphQL query, health check, HTTP receivers) |
+| 11800 | gRPC (agent data collection, OTLP) |
+| 17912 | BanyanDB |
+
+## Option 2: Docker Run
+
+If you already have BanyanDB running:
+
+```bash
+docker run -d \
+ -p 12800:12800 \
+ -p 11800:11800 \
+ -e SW_STORAGE_BANYANDB_TARGETS=<banyandb-host>:17912 \
+ -e SW_CLUSTER=standalone \
+ -e SW_CONFIGURATION=none \
+ ghcr.io/apache/skywalking-graalvm-distro:latest
+```
+
+## Option 3: Build from Source
+
+See [Compiling from Source](compiling.md) for full build instructions.
+
+```bash
+# Quick build + run
+git clone --recurse-submodules https://github.com/apache/skywalking-graalvm-distro.git
+cd skywalking-graalvm-distro
+make init-skywalking # first time only
+make build-distro
+make native-image
+make docker-native
+docker compose -f docker/docker-compose.yml up
+```
+
+## What's Next
+
+- [Configuration](configuration.md) — all environment variables and module settings
+- [Pre-Built Docker Images](docker-image.md) — image tags, architectures, GHCR details
+- [Supported Features](supported-features.md) — what's included in this distro
diff --git a/docs/supported-features.md b/docs/supported-features.md
new file mode 100644
index 0000000..f8d17ed
--- /dev/null
+++ b/docs/supported-features.md
@@ -0,0 +1,132 @@
+# Supported Features
+
+This distro packages the Apache SkyWalking OAP server as a GraalVM native image with a
+**fixed module set**. All modules and providers are selected at build time — there is no
+runtime SPI discovery or dynamic module loading.
+
+## What's Included
+
+### Storage
+
+| Provider | Status |
+|----------|--------|
+| **BanyanDB** | Included (default) |
+| Elasticsearch | Not included |
+| H2 / MySQL / PostgreSQL / OpenSearch | Not included |
+
+### Cluster
+
+| Provider | Status |
+|----------|--------|
+| **Standalone** | Included (default) |
+| **Kubernetes** | Included |
+| ZooKeeper / Consul / Etcd / Nacos | Not included |
+
+### Configuration
+
+| Provider | Status |
+|----------|--------|
+| **none** | Included |
+| **k8s-configmap** | Included (default) |
+| Apollo / Consul / Etcd / Nacos / ZooKeeper / gRPC | Not included |
+
+### Data Receivers
+
+All receivers are included:
+
+| Receiver | Protocol | Notes |
+|----------|----------|-------|
+| Trace (SkyWalking) | gRPC | Java, .NET, Go, Python, Node.js, PHP, Rust, Ruby agents |
+| JVM Metrics | gRPC | Java agent JVM metrics |
+| CLR Metrics | gRPC | .NET CLR metrics |
+| Meter (SkyWalking) | gRPC | Custom meter protocol |
+| Log | gRPC / HTTP | SkyWalking log protocol |
+| Browser | gRPC | Browser JS agent |
+| Event | gRPC | K8s events, custom events |
+| Profile | gRPC | On-demand profiling |
+| Async Profiler | gRPC | Java async-profiler |
+| pprof | gRPC | Go pprof profiling |
+| OpenTelemetry | gRPC (OTLP) | Metrics + Logs via OTLP |
+| Envoy / Istio ALS | gRPC | Access log service, metrics |
+| Zipkin | HTTP | Zipkin v2 spans (disabled by default) |
+| Zabbix | TCP | Zabbix agent protocol (disabled by default) |
+| Telegraf | gRPC | Telegraf metrics |
+| AWS Firehose | HTTP | CloudWatch metrics via Firehose |
+| Kafka Fetcher | Kafka | Traces, metrics, logs from Kafka (disabled by default) |
+| Cilium Fetcher | gRPC | Hubble flow data (disabled by default) |
+| eBPF | gRPC | eBPF profiling data (Rover) |
+
+### Query APIs
+
+| API | Port | Notes |
+|-----|------|-------|
+| **GraphQL** | 12800 | Primary query API for SkyWalking UI |
+| **PromQL** | 9090 | Prometheus-compatible query |
+| **LogQL** | 3100 | Loki-compatible log query |
+| **Zipkin** | 9412 | Zipkin v2 query API (disabled by default) |
+| **Status** | 12800 | Debugging and status queries |
+
+### Analyzers
+
+| Analyzer | Included |
+|----------|----------|
+| Trace Analyzer | Yes |
+| Log Analyzer (LAL) | Yes |
+| Event Analyzer | Yes |
+
+### Other Modules
+
+| Module | Status |
+|--------|--------|
+| Alarm | Included (webhook, gRPC hooks) |
+| Telemetry | Prometheus (self-monitoring metrics on port 1234) |
+| Exporter | Included (disabled by default) |
+| Health Checker | Included |
+| AI Pipeline | Included (baseline prediction) |
+
+## Optional Modules
+
+These modules are disabled by default. Enable them with environment variables:
+
+| Module | Enable With |
+|--------|-------------|
+| Zipkin Receiver | `SW_RECEIVER_ZIPKIN=default` |
+| Zipkin Query | `SW_QUERY_ZIPKIN=default` |
+| Zabbix Receiver | `SW_RECEIVER_ZABBIX=default` |
+| Kafka Fetcher | `SW_KAFKA_FETCHER=default` |
+| Cilium Fetcher | `SW_CILIUM_FETCHER=default` |
+| Exporter | `SW_EXPORTER=default` |
+
+## Differences from Upstream SkyWalking
+
+| Aspect | Upstream | This Distro |
+|--------|----------|-------------|
+| Runtime | JVM (JDK 11+) | GraalVM native image |
+| Startup | Compiles DSL rules at boot (~30s) | Pre-compiled at build time (instant) |
+| Binary | ~200MB+ of JARs + JVM | ~203MB self-contained binary |
+| Storage | ES, BanyanDB, H2, MySQL, PG, ... | BanyanDB only |
+| Cluster | ZK, K8s, Consul, Etcd, Nacos | Standalone, K8s |
+| Config | All dynamic config providers | K8s ConfigMap or none |
+| Module loading | SPI discovery at runtime | Fixed at build time |
+
+## Compatibility
+
+- **SkyWalking agents**: All official SkyWalking agents are compatible (Java, .NET, Go, Python, Node.js, PHP, Rust, Ruby, C++, Satellite)
+- **SkyWalking UI**: Fully compatible — use the standard SkyWalking Booster UI
+- **OpenTelemetry**: OTLP metrics and logs via gRPC
+- **Zipkin**: Zipkin v2 API (receiver + query) when enabled
+- **Prometheus**: PromQL query API for Grafana integration
+- **BanyanDB**: Requires BanyanDB as the storage backend
+
+## Architecture
+
+```
+ ┌──────────────────────────────────┐
+ │ SkyWalking GraalVM Native OAP │
+Agents ──gRPC──────►│ │
+OTLP ──gRPC────────►│ Receivers → Analyzers → Storage │──► BanyanDB
+Zipkin ──HTTP──────►│ │
+ │ Query APIs (GraphQL/PromQL/...) │◄── SkyWalking UI
+ │ Alarm → Webhooks │
+ └──────────────────────────────────┘
+```