Guides
The admin console
The separate console process, the services its bridge forwards, the file-upload endpoint and its cross-origin protection, and the operations it can perform.
The admin console can run as a separate process or inside ysearch-local.
It serves an embedded React application and proxies a fixed set of generated Connect services to
operator-owned upstream targets, plus one file-upload endpoint. It never
receives object-store credentials and reaches an index only through those
services.
The console uses the upstream API for queries and mutations. Upstream validation and lifecycle restrictions apply to browser requests.
| Service | Used for |
|---|---|
AdminService |
effective configuration and process-level views |
IndexService |
index inventory, schemas, lifecycle |
SearchService |
Query Lab |
IngestService |
document loading |
AdminConsoleService |
console-specific aggregate views |
Plus POST /api/ingest/upload, the file-upload endpoint described below.
The console can apply schemas, load documents, and clean or delete indexes where the upstream server supports those operations.
The console runs three ways, and which one you have decides what is on the other end of the bridge.
Inside ysearch-local. One process runs the complete data plane and
the console together. The console is at http://127.0.0.1:8787 and the data
plane at 127.0.0.1:9500. See local development.
Against a remote server, from a checkout. just admin-local-start builds
a scratch admin image, creates a private container network, and starts a named
Alpine SSH-tunnel container alongside the named scratch runtime. No host SSH
process is detached, and startup carries an EXIT/INT/TERM cleanup trap:
just admin-local-start
open http://127.0.0.1:8787
just admin-local-status
just admin-local-stopOverride the remote and local ports with YSEARCH_ADMIN_REMOTE_HOST,
YSEARCH_ADMIN_REMOTE_USER, YSEARCH_ADMIN_REMOTE_PORT, and
YSEARCH_ADMIN_UI_PORT. The launcher always publishes the HTTP listener on
local loopback.
In Kubernetes. Set spec.adminConsole on a YSearchCluster. The
operator creates a dedicated ServiceAccount, two replicas by default, a
ClusterIP Service, a read-only target ConfigMap, and a restrictive
NetworkPolicy. The Pods run as UID/GID 65532 from a scratch image with a
read-only root filesystem and no automounted service-account token. See
Kubernetes.
Query Lab inspects schemas, selects stored result columns, executes lexical, vector, and hybrid requests, and reports query timings. It shows which fields are indexed and which stored fields can be projected.
The grammars are the ones documented in Lucene and CQP; the console sends the same requests the CLI does.
Open Indexes to create an index — its storage namespace — edit its fields, or upload a JSON, JSONL, XML, or plain-text example up to 1 MiB. The proposal runs on the server and is never applied automatically. Review the field types and options, choose Preview changes, then Apply schema.
Existing fields retain their IDs and types. Additions and enabling stored
values go through the server's ordinary additive schema rules, so the console
cannot make a change the CLI would refuse; see
schemas. You can download the authored
JSON schema for later use with ysearch schema apply.
The directory-based proposal — ysearch schema propose — also saves the
normalized documents you need when source field names or value shapes change.
| Action | Removes | Keeps |
|---|---|---|
| Clean | all documents, catalogs, segments, and pending local ingestion | the schema history and the namespace |
| Delete | the whole index namespace, including its schema | nothing |
Both require typing the exact index name. Both are supported by
ysearch-local and by a direct catalog serve using an exclusive
filesystem data directory. S3-backed servers and distributed node roles
refuse these operations, because a single process cannot stop their other
writers; use a coordinated operator teardown there instead.
Close active search and ingest streams first. A failed delete is not complete:
retry DeleteIndex with the same index name and confirmation to finish
removing any remaining objects, even when the index no longer appears in the
inventory.
Use push for command-line loading or the console's Ingest section to
upload files from the browser.
Pick the index, drop one or more files, and import. The page reports the sealed segment and catalog generation when it finishes, and the documents are searchable on the local upstream server at that point. Other query nodes see the data after they load the published generation.
| Upload | Becomes |
|---|---|
.jsonl, .ndjson |
one document per line |
.json |
an array of documents, or one pretty-printed document |
.txt, .text |
one document, the whole file as its body |
.gz |
decompressed, then read as whatever is underneath — part.jsonl.gz is JSONL |
.tar.gz, .tgz, .tar |
unpacked, each member read by its own name |
Archives are unpacked as a stream. Memory use depends on record size, conversion buffers, and upload concurrency; the full archive is not retained in memory.
A .txt file has no field structure, so the page asks which indexed string
field receives its body, preselecting when the schema offers exactly one. The
file's path inside the archive becomes the document key.
Directories and symlinks are skipped. Unsupported entries, such as a
README.md, an image, or a nested archive, are listed in the summary. An
archive holding a stray
.txt when no field was chosen still imports its JSON; that entry is reported
as skipped rather than failing the import. A record too large to send is
refused by entry and line number while its neighbors load.
| Setting | Default | Bounds |
|---|---|---|
--upload-max-bytes |
2 GiB | the compressed request body |
--upload-max-decompressed-bytes |
16 GiB | what one upload expands to |
--upload-max-entries |
10 000 | document-bearing members per upload |
--upload-concurrency |
2 | simultaneous uploads |
--upload-timeout |
1h | one upload's wall clock |
On ysearch-local the same settings are prefixed --admin-.
When all upload slots are occupied, new requests receive 429 with
Retry-After. Exceeding an upload limit ends the upload with a terminal
error event.
One record may not exceed an ingest batch, because a batch carrying it could
not be delivered: the data plane caps receive at server.max_receive_bytes
(4 MiB by default), which the bridge cannot discover. Such a record is refused
locally by entry path and line number and the import continues, rather than
returning an opaque resource_exhausted that names nothing.
The Ingest section posts to POST /api/ingest/upload on the admin server,
which unpacks and decodes the files and loads them through the index's normal
IngestService stream. The response is application/x-ndjson: one progress
event per line, flushed while the body is still arriving.
Every request must carry X-YSearch-Console: 1, and Sec-Fetch-Site and
Origin, when present, must be same-origin. A refusal is 403.
A script or curl calling the endpoint must send the header too:
curl -H 'X-YSearch-Console: 1' \
-F index=articles -F text_field=body -F file=@corpus.tar.gz \
http://127.0.0.1:8787/api/ingest/uploadThe form fields must precede the files. The index decides which upstream and which schema, and both are needed before the first byte of content arrives.
| Path | Reports |
|---|---|
/livez |
process liveness |
/readyz |
becomes unavailable before graceful drain |
/metrics |
bounded, label-free admin process metrics |
The console's /metrics covers the console process only — six gauges
about its own bridge. The engine's families — ysearch_query_*,
ysearch_ingest_*, ysearch_publisher_*, ysearch_cache_*, and the
rest — come from the data-plane processes, which serve their own exposition on
observability.metrics_listen (default :9550, path /metrics, on by
default). That listener is served by ysearch serve, ysearch node,
ysearchd, and ysearch-local.
Prometheus rules live under observability/alerts and
observability/recording-rules; the starter Grafana dashboard is under
observability/dashboards. See observability and
the metrics reference.
just build-dual-arch emits statically linked Linux amd64 and arm64
binaries and receipts for ysearch, ysearch-operator, and
ysearch-admin. Containerfile.admin copies only the selected admin
binary into a FROM scratch image and runs it as UID/GID 65532. See
containers.
- Local development — running the console beside a local data plane.
- Ingest — the CLI path the upload endpoint feeds into.
- Schemas — the additive rules the console's Apply obeys.
- Observability — scraping the data plane.