All checks were successful
ci/woodpecker/tag/release Pipeline was successful
464 lines
20 KiB
Markdown
464 lines
20 KiB
Markdown
# Configuration Reference
|
|
|
|
Audience: administrators, operators, and advanced users who write YAML configuration for `distributor`.
|
|
|
|
This is the canonical user-facing configuration reference. CLI syntax lives in [CLI](cli.md), operations guidance lives in [Operations](operations.md), recovery guidance lives in [Troubleshooting](troubleshooting.md), and file-format contracts live under [Integrations](integrations/source-bundle.md).
|
|
|
|
## Config File Loading
|
|
|
|
`distributor run --config <path>` and `distributor serve --config <path>` load the YAML file at `<path>`. If `--config` is omitted, commands use:
|
|
|
|
```text
|
|
/usr/local/etc/distributor/config.yml
|
|
```
|
|
|
|
YAML decoding rejects unknown fields. Defaults are applied after decoding and before validation.
|
|
|
|
Runtime backend support is command-specific:
|
|
|
|
- `run`, `validate --config`, and `inspect --config` execute `local`, `ssh`, and `s3` sources.
|
|
- `run`, `reconcile-state`, and `prune` execute `local`, `ssh`, and `s3` destinations.
|
|
- `serve` uses `http_upload` sources through the HTTP upload API and publishes to configured `local`, `ssh`, and `s3` destinations.
|
|
- `http_upload` is valid only as a source backend.
|
|
|
|
## Minimal Working Config
|
|
|
|
```yaml
|
|
pipelines:
|
|
- id: reports
|
|
source:
|
|
backend: local
|
|
path: /var/spool/distributor/reports
|
|
destinations:
|
|
- id: archive
|
|
backend: local
|
|
path: /srv/reports/archive
|
|
```
|
|
|
|
This publishes source files only. It uses default validation, additive workflow, preserve-relative path mapping, source-only publish policy, disabled pruning, and default HTTP server values.
|
|
|
|
## Production-Oriented Config
|
|
|
|
```yaml
|
|
server:
|
|
http:
|
|
bind: 127.0.0.1:8080
|
|
staging_root: /var/spool/distributor
|
|
max_upload_size: 20MB
|
|
queue_size: 16
|
|
max_concurrency: 1
|
|
retention: 24h
|
|
secrets:
|
|
directory: /run/secrets/distributor
|
|
pipelines:
|
|
- id: reports
|
|
source:
|
|
backend: local
|
|
path: /var/spool/distributor/reports
|
|
validation:
|
|
on_digest_mismatch: fail
|
|
destinations:
|
|
- id: archive
|
|
backend: local
|
|
path: /srv/reports/archive
|
|
workflow: additive
|
|
publish:
|
|
source: true
|
|
html: false
|
|
path_mapping:
|
|
mode: preserve_relative
|
|
retention:
|
|
prune:
|
|
enabled: false
|
|
```
|
|
|
|
## HTTP Upload Source Config
|
|
|
|
HTTP upload sources are configured on pipelines and served by `distributor serve`. Upload tokens are resolved from the process environment or `secrets.directory`; literal bearer tokens are not configured in YAML.
|
|
|
|
```yaml
|
|
server:
|
|
http:
|
|
bind: 127.0.0.1:8080
|
|
staging_root: /var/spool/distributor
|
|
max_upload_size: 20MB
|
|
queue_size: 16
|
|
max_concurrency: 1
|
|
retention: 24h
|
|
upload_tokens:
|
|
- id: weather-reporter
|
|
token_env: WEATHER_UPLOAD_TOKEN
|
|
allow_pipelines:
|
|
- weather-daily
|
|
pipelines:
|
|
- id: weather-daily
|
|
source:
|
|
backend: http_upload
|
|
destinations:
|
|
- id: archive
|
|
backend: local
|
|
path: /srv/reports/archive
|
|
```
|
|
|
|
`upload_tokens` is required when any pipeline source uses `http_upload`. Each token record resolves its bearer token value from the process environment or `secrets.directory`. `allow_pipelines` lists configured upload pipeline ids that the token may submit to.
|
|
|
|
For `http_upload` sources, `staging_path` defaults to `<server.http.staging_root>/<pipeline id>`. `max_upload_size` defaults to `server.http.max_upload_size`.
|
|
|
|
## Top-Level Fields
|
|
|
|
### `server.http`
|
|
|
|
`server.http` controls the HTTP upload server used by `serve`.
|
|
|
|
- `bind`: optional TCP bind address. Default: `127.0.0.1:8080`.
|
|
- `staging_root`: optional root used to default `http_upload` source staging paths. Default: `/var/spool/distributor`.
|
|
- `max_upload_size`: optional default upload limit for HTTP upload sources. Default: `20MB`.
|
|
- `queue_size`: optional upload admission queue size. Default: `16`.
|
|
- `max_concurrency`: optional upload worker concurrency. Default: `1`.
|
|
- `retention`: optional in-memory completed-run retention duration. Default: `24h`.
|
|
|
|
Numeric server values and durations must be greater than zero after defaults are applied.
|
|
|
|
### `secrets`
|
|
|
|
- `directory`: optional directory of secret files used by the config-owned credential resolver.
|
|
|
|
See [Secrets](#secrets) for resolution rules.
|
|
|
|
### `upload_tokens`
|
|
|
|
`upload_tokens` configures bearer tokens for `distributor serve`. It is required when any pipeline source backend is `http_upload` and is invalid when no upload pipelines are configured.
|
|
|
|
Each token has:
|
|
|
|
- `id`: required unique slug-like identifier for the token record.
|
|
- `token_env`: required environment variable or secret-file name containing the bearer token value.
|
|
- `allow_pipelines`: required non-empty list of configured pipeline ids whose source backend is `http_upload`.
|
|
|
|
Token values must resolve to non-empty strings and must be unique across token records. Every configured upload pipeline must be allowed by at least one token.
|
|
|
|
### `pipelines`
|
|
|
|
`pipelines` is required and must contain at least one pipeline.
|
|
|
|
Each pipeline has:
|
|
|
|
- `id`: required unique slug-like identifier.
|
|
- `source`: required source backend config.
|
|
- `validation`: optional validation policy.
|
|
- `destinations`: required non-empty destination list.
|
|
|
|
Slug-like identifiers must start with a letter or number and may contain letters, numbers, `.`, `_`, and `-`.
|
|
|
|
## Backend Reference
|
|
|
|
### Local Backend
|
|
|
|
Local backends can be used as sources and destinations.
|
|
|
|
```yaml
|
|
backend: local
|
|
path: /srv/distributor/archive
|
|
```
|
|
|
|
- `backend`: required value `local`.
|
|
- `path`: required local filesystem root for this backend.
|
|
|
|
### SSH/SFTP Backend
|
|
|
|
SSH backends use native SFTP and can be used as sources and destinations. Adapter behavior is documented in [SSH/SFTP Integration](integrations/ssh-sftp.md).
|
|
|
|
```yaml
|
|
backend: ssh
|
|
host: ssh.example.com
|
|
user: distributor
|
|
port: 22
|
|
path: /srv/distributor/archive
|
|
ssh_key_file: /home/distributor/.ssh/id_ed25519
|
|
known_hosts: /home/distributor/.ssh/known_hosts
|
|
host_key_policy: strict
|
|
```
|
|
|
|
- `backend`: required value `ssh`.
|
|
- `host`: required SSH host.
|
|
- `path`: required remote root path.
|
|
- `user`: optional SSH username. If omitted, the adapter uses the current OS user when available.
|
|
- `port`: optional TCP port. Default: `22`.
|
|
- `ssh_key_file`: optional private key path.
|
|
- `known_hosts`: optional OpenSSH `known_hosts` path.
|
|
- `host_key_policy`: optional host key policy. Default: `accept-new`.
|
|
|
|
Accepted host key policy values are `strict` or boolean `true`, `accept-new`, and `off` or boolean `false`. Authentication uses SSH agent identities when `SSH_AUTH_SOCK` is available, then `ssh_key_file` when configured. Password authentication is not configured in YAML.
|
|
|
|
### S3-Compatible Backend
|
|
|
|
S3 backends can be used as sources and destinations. Adapter behavior is documented in [S3-Compatible Storage Integration](integrations/s3.md).
|
|
|
|
```yaml
|
|
backend: s3
|
|
endpoint: https://s3.example.com
|
|
bucket: reports
|
|
prefix: distributor/archive
|
|
region: us-east-1
|
|
force_path_style: true
|
|
credentials:
|
|
access_key_id_env: DISTRIBUTOR_S3_ACCESS_KEY_ID
|
|
secret_access_key_env: DISTRIBUTOR_S3_SECRET_ACCESS_KEY
|
|
```
|
|
|
|
- `backend`: required value `s3`.
|
|
- `endpoint`: required S3-compatible endpoint URL.
|
|
- `bucket`: required bucket name.
|
|
- `prefix`: optional backend root prefix. Leading and trailing slashes are trimmed; the remaining value must be a clean relative slash-separated path.
|
|
- `region`: optional region. Default: `us-east-1`.
|
|
- `force_path_style`: optional addressing mode toggle. Default: `true`.
|
|
- `credentials.access_key_id_env`: optional environment variable or secret-file name for the access key id.
|
|
- `credentials.secret_access_key_env`: optional environment variable or secret-file name for the secret access key.
|
|
|
|
The S3 credential variable names must either both be configured or both be omitted. When omitted, the AWS SDK default credential chain is used. When configured, both values must resolve to non-empty strings through the process environment or `secrets.directory`.
|
|
|
|
### HTTP Upload Source Backend
|
|
|
|
HTTP upload backends are valid only as pipeline sources and are served by `distributor serve`. The API contract is documented in [HTTP Upload API Contract](integrations/http-upload.md).
|
|
|
|
```yaml
|
|
backend: http_upload
|
|
staging_path: /var/spool/distributor/weather-daily
|
|
max_upload_size: 20MB
|
|
```
|
|
|
|
- `backend`: required value `http_upload`.
|
|
- `staging_path`: optional staging path. Default: `<server.http.staging_root>/<pipeline id>`.
|
|
- `max_upload_size`: optional per-source upload limit. Default: `server.http.max_upload_size`.
|
|
|
|
## Validation Policy
|
|
|
|
```yaml
|
|
validation:
|
|
on_digest_mismatch: fail
|
|
```
|
|
|
|
- `validation.on_digest_mismatch`: optional. Default and only accepted value: `fail`.
|
|
|
|
Source bundle digest mismatches fail validation before destination writes occur. The manifest file-format contract is documented in [Source Bundle Contract](integrations/source-bundle.md).
|
|
|
|
## Destination Fields
|
|
|
|
Each destination embeds a backend config at the destination level and may also configure workflow, publishing, transforms, path mapping, links, and retention.
|
|
|
|
```yaml
|
|
destinations:
|
|
- id: archive
|
|
backend: local
|
|
path: /srv/reports/archive
|
|
workflow: additive
|
|
publish:
|
|
source: true
|
|
html: false
|
|
path_mapping:
|
|
mode: preserve_relative
|
|
```
|
|
|
|
- `id`: required unique slug-like identifier within the pipeline.
|
|
- Backend fields: required according to the selected destination backend.
|
|
- `workflow`: optional catalog update workflow. Default: `additive`.
|
|
- `publish`: optional publish policy. Default: source-only publication.
|
|
- `transform`: required only when publishing generated HTML.
|
|
- `path_mapping`: optional destination path mapping policy.
|
|
- `links`: optional public URL metadata policy.
|
|
- `retention`: optional managed-output retention policy.
|
|
|
|
Destination ids must be unique within a pipeline.
|
|
|
|
Pre-workflow destination policy keys for state mode, conflict handling,
|
|
ownership adoption, and per-comparison copy decisions are not accepted config
|
|
fields. YAML files containing those keys fail during config loading.
|
|
|
|
## Destination Workflow
|
|
|
|
```yaml
|
|
workflow: additive
|
|
```
|
|
|
|
- `workflow`: optional. Accepted values are `additive` and `replacement`; default is `additive`.
|
|
|
|
`additive` writes planned outputs into the catalog and retains unrelated catalog-managed outputs in the same destination bundle path. Existing catalog records for planned paths are replaced by the current publication. A planned path that exists in storage but is not recorded in valid catalog state fails as unmanaged content unless `run --force` selects `force_replace`.
|
|
|
|
`replacement` writes planned outputs for the current pipeline and destination, and removes catalog outputs owned by the same pipeline and destination when those outputs are omitted from the new plan. Outputs owned by other pipeline/destination pairs remain catalog-managed. Replacement workflow is normal managed behavior and does not require `--force`.
|
|
|
|
Use `replacement` for stable latest-style destinations where the current owner should publish exactly the currently planned output set. Use `additive` when a destination root intentionally accumulates outputs over time or receives disjoint outputs from multiple configured destinations.
|
|
|
|
## Publish And Transform Policy
|
|
|
|
### Source-Only Publication
|
|
|
|
```yaml
|
|
publish:
|
|
source: true
|
|
html: false
|
|
```
|
|
|
|
`publish.source` controls whether source manifest files are copied to the destination.
|
|
|
|
### Markdown-To-HTML Publication
|
|
|
|
```yaml
|
|
publish:
|
|
source: false
|
|
html: true
|
|
transform:
|
|
markdown_to_html:
|
|
enabled: true
|
|
mode: sidecar
|
|
css_href: /assets/report.css
|
|
```
|
|
|
|
`publish.html` controls whether generated HTML outputs are published. When `publish.html` is `true`, `transform.markdown_to_html.enabled` must also be `true`.
|
|
|
|
Markdown transform fields:
|
|
|
|
- `transform.markdown_to_html.enabled`: enables Markdown-to-HTML generation for this destination.
|
|
- `transform.markdown_to_html.mode`: optional. Accepted values are `sidecar` and `index`; default is `sidecar` when a Markdown transform block is present.
|
|
- `transform.markdown_to_html.input`: optional source manifest path for `index` mode only.
|
|
- `transform.markdown_to_html.css_href`: optional stylesheet href to link from generated HTML.
|
|
|
|
`sidecar` mode renders every manifest-listed `.md` file to a same-directory `.html` output. `index` mode renders one Markdown source to `index.html` at the destination bundle path. If `index` mode omits `input`, the selected source bundle must contain exactly one Markdown file.
|
|
|
|
`css_href` may be an absolute `http` or `https` URL, a root-relative path such as `/assets/report.css`, or a relative URL path such as `assets/report.css`. Query strings are allowed. `distributor` injects the href as a `<link rel="stylesheet">` element but does not copy, publish, verify, or manage the CSS file solely because `css_href` is set.
|
|
|
|
At least one output type must be enabled. Enabled Markdown transforms are rejected when `publish.html` is `false`, `input` is rejected unless `mode` is `index`, and `css_href` is rejected when the Markdown transform is disabled.
|
|
|
|
## Destination Path Mapping
|
|
|
|
```yaml
|
|
path_mapping:
|
|
mode: preserve_relative
|
|
```
|
|
|
|
- `path_mapping.mode`: optional. Accepted values are `preserve_relative` and `fixed`; default is `preserve_relative`.
|
|
|
|
`preserve_relative` publishes each discovered source bundle at the same path relative to the destination backend root.
|
|
|
|
`fixed` publishes one selected source bundle directly at the destination backend root. Fixed destinations select the newest discovered source bundle by manifest `created` timestamp. If multiple bundles have the same timestamp, the source-root-relative bundle path in ascending order wins.
|
|
|
|
Fixed mapping is useful for stable latest-style paths. Preview fixed destinations with `run --dry-run`, especially before using `--force`.
|
|
|
|
## Destination Links
|
|
|
|
```yaml
|
|
links:
|
|
base_url: https://reports.example.com/archive
|
|
primary: auto
|
|
```
|
|
|
|
- `links.base_url`: required when `links` is present. It must be an absolute `http` or `https` URL with a host and no query string or fragment.
|
|
- `links.primary`: optional. Accepted values are `auto`, `html`, and `source`; default is `auto` when `links` is present.
|
|
|
|
`distributor` does not infer public URLs from backend config. Destination state URL fields are documented in [Destination State Contract](integrations/destination-state.md). Output URLs are built from `links.base_url`, the destination bundle path, and output paths using URL path semantics. `index.html` outputs produce directory-style URLs that omit the filename.
|
|
|
|
Primary URL policies:
|
|
|
|
- `auto`: prefer `index.html`, then generated HTML, then source outputs.
|
|
- `html`: use the first generated HTML output.
|
|
- `source`: use the first copied source output.
|
|
|
|
If no output matches the primary policy, per-output URLs may still be recorded and no primary URL is reported for the run.
|
|
|
|
## Retention Policy
|
|
|
|
```yaml
|
|
retention:
|
|
prune:
|
|
enabled: false
|
|
older_than: 168h
|
|
keep_latest: 3
|
|
```
|
|
|
|
- `retention.prune.enabled`: optional boolean. Default is `false`.
|
|
- `retention.prune.older_than`: optional duration. When pruning is enabled, outputs older than this duration are eligible for pruning.
|
|
- `retention.prune.keep_latest`: optional non-negative integer. When pruning is enabled, this many newest managed outputs are preserved before age-based pruning is considered.
|
|
|
|
When `retention.prune.enabled` is `true`, at least one of `older_than` or `keep_latest` is required. `older_than` must be greater than zero, and `keep_latest` must be zero or greater.
|
|
|
|
Pruning uses catalog output `updated_at` timestamps from destination state. If both `keep_latest` and `older_than` are set, the newest `keep_latest` outputs are preserved first, then age-based pruning is applied to the remaining managed outputs.
|
|
|
|
The `prune` command is scoped to the selected pipeline and destination owner. `prune --dry-run` reports selected managed outputs without writing. `prune --apply` deletes only selected managed output paths and rewrites destination state after confirmed deletes. It does not delete unmanaged files or `.distributor.json`, and it does not run automatically after `run`.
|
|
|
|
## Size And Duration Values
|
|
|
|
Upload size fields must be YAML strings with an integer and one of these suffixes:
|
|
|
|
- `B`
|
|
- `KB`
|
|
- `MB`
|
|
- `GB`
|
|
|
|
Suffix multipliers use powers of 1024. Values must be greater than zero after defaults are applied.
|
|
|
|
Duration fields must be YAML strings accepted by Go duration parsing, such as `24h`, `90m`, or `168h`. Values must be greater than zero after defaults are applied.
|
|
|
|
## Defaults
|
|
|
|
Defaults are applied after YAML decoding and before validation:
|
|
|
|
- `server.http.bind: 127.0.0.1:8080`
|
|
- `server.http.staging_root: /var/spool/distributor`
|
|
- `server.http.max_upload_size: 20MB`
|
|
- `server.http.queue_size: 16`
|
|
- `server.http.max_concurrency: 1`
|
|
- `server.http.retention: 24h`
|
|
- `validation.on_digest_mismatch: fail`
|
|
- SSH `port: 22`
|
|
- SSH `host_key_policy: accept-new`
|
|
- S3 `region: us-east-1`
|
|
- S3 `prefix`: leading and trailing slashes trimmed
|
|
- S3 `force_path_style: true`
|
|
- `http_upload` source `staging_path: <server.http.staging_root>/<pipeline id>`
|
|
- `http_upload` source `max_upload_size: server.http.max_upload_size`
|
|
- `workflow: additive`
|
|
- `publish.source: true` and `publish.html: false`
|
|
- `transform.markdown_to_html.mode: sidecar` when a Markdown transform block is present and mode is omitted
|
|
- `path_mapping.mode: preserve_relative`
|
|
- `links.primary: auto` when a `links` block is present and `primary` is omitted
|
|
- `retention.prune.enabled: false`
|
|
|
|
## Secrets
|
|
|
|
Do not put literal secrets in config files. `secrets.directory` lets deployments provide credential values as files:
|
|
|
|
```yaml
|
|
secrets:
|
|
directory: /run/secrets/distributor
|
|
```
|
|
|
|
Each regular file in the directory becomes an internal credential environment value named by the filename. Valid filenames match `[A-Za-z_][A-Za-z0-9_]*`. Directories are ignored. Symlinks to regular files are followed. Exactly one trailing LF or CRLF is trimmed from each file; other whitespace is preserved.
|
|
|
|
Credential resolution checks the real process environment first, then `secrets.directory`. If both define the same name with different values, `run` emits a warning with the variable name and uses the real environment value. Secret values are not printed. The process environment is not modified, so SDK default credential chains see only real process environment variables.
|
|
|
|
Fields resolved through this resolver:
|
|
|
|
- `credentials.access_key_id_env`
|
|
- `credentials.secret_access_key_env`
|
|
- `upload_tokens[].token_env`
|
|
|
|
## Maintained Examples
|
|
|
|
Maintained examples live under [examples](../examples/). Config tests load these YAML files.
|
|
|
|
Local examples:
|
|
|
|
- `local-to-local.yml`: minimal local-to-local config using absolute sample paths; load-tested, but paths should be adapted before running.
|
|
- `local-publish.yml`: runnable local source publication used by the README quickstart.
|
|
- `local-html.yml`: local sidecar HTML publication.
|
|
- `local-index.yml`: local `index.html` publication.
|
|
- `fan-out.yml`: local fan-out publication to source and HTML destinations.
|
|
- `archive-and-latest.yml`: local archive plus fixed latest publication.
|
|
- `additive-workflow.yml`: two destinations publishing disjoint outputs into one catalog-managed root.
|
|
- `replacement-workflow.yml`: fixed-path replacement workflow for a stable latest-style output set.
|
|
- `http-upload-local.yml`: local HTTP upload server config; requires `DISTRIBUTOR_EXAMPLE_UPLOAD_TOKEN` in the process environment or as a secret-file name before running `serve`.
|
|
|
|
Environment-gated remote examples:
|
|
|
|
- `ssh-destination.yml`: local-to-SSH publication; replace host, user, path, key, and known-host values for an SSH/SFTP endpoint you control.
|
|
- `s3-destination.yml`: local-to-S3 publication; replace endpoint, bucket, prefix, region, and credential variable names for an S3-compatible service you control.
|