Provides
Declares what network endpoints a component exposes. Value is an array of objects.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name |
string |
no | -- | Endpoint name for cross-references (e.g. api, metrics) |
protocol |
enum |
yes | -- | http, https, tcp, udp, grpc, ws |
port |
integer |
yes | -- | Container port (1-65535) |
bind |
string |
no | 0.0.0.0 |
Bind address |
exposed |
boolean |
no | false |
Whether the port is reachable from outside the host. Most components in a multi-component app are internal services — only frontends and API gateways typically need exposed: true. |
spec |
map<string, string> |
no | -- | API spec references (e.g. openapi: file:docs/openapi.yaml) |
tls |
string or object |
no | -- | Names one supports: entry of type certificate on the same component: the certificate this listener serves when native TLS is selected. See Native TLS. |
at |
string or string[] |
no | -- | The names this listener answers at, relative to the app host: "@", a DNS label, "*" or "*.*". See Host names under the app host. |
Each provides entry's protocol describes what that component's own listener
speaks on that entry's port, in the configuration this Launchfile describes. It
never describes a public endpoint's scheme. A provider may publish an https://
URL while forwarding cleartext HTTP to a component declaring protocol: http;
that is not a mismatch and no tool may report it as one. The app's primary public
scheme is $app.scheme, derived from $app.url; every other published endpoint's
public address is $app.endpoints.<name>.*, reachable by the entry's name:
(Per-endpoint properties, D-63) — a
supplied publication context still asserts the primary's address only
(D-58 rule 4). Declaring one listener configuration
says nothing about the other configurations an app supports — a consumer MUST NOT
infer from protocol: http that a component cannot be configured to serve TLS.
provides:
- name: api
protocol: http
port: 3000
exposed: true
spec:
openapi: file:docs/openapi.yamlNative TLS with a certificate binding
Some apps terminate TLS on their own listener when they are given a certificate. tls: says so, by naming one supports: entry of type certificate on the same component (D-61):
provides:
- name: web
protocol: http # the baseline listener (D-59)
port: 3000
exposed: true
tls: server-cert # shorthand for `tls: { certificate: server-cert }`
supports:
- name: server-cert
type: certificate
set_env:
GITEA__server__PROTOCOL: https
GITEA__server__HTTP_PORT: "3000"
GITEA__server__CERT_FILE: $cert_file
GITEA__server__KEY_FILE: $key_file
env:
GITEA__server__PROTOCOL: http"I serve HTTP on 3000. I can serve HTTPS on that same listener with this certificate; here is the wiring."
Declared and effective. Every provides entry has a declared protocol and port — the fields in the file — and an effective protocol and port, which is what the listener speaks in the configuration the deployment selected. They are equal unless a bound certificate is active; then the effective protocol is https and the effective port is the declared port:. Validation, tooling and the audit surface read the declared value; every URL-emitting expression derived from a listener ($components.<name>.url, $components.<name>.<endpoint>.url with its protocol, and $app.url where the provider computes it from its own publication of that listener) reads the effective one. An orchestrator-supplied publication context still wins (PROVIDERS.md §7).
Five rules bind the binding:
- It binds one entry, by identity. The named entry must exist in the same component's
supports:and declaretype: certificate. A certificate named by twoprovidesentries is a validation error, active or not. Naming arequires:entry is a validation error too: required native TLS is out of scope here. The bound entry must speak an HTTP-family protocol —http,https,wsorgrpc— because an active binding makes its effective protocolhttps;tls:on atcporudpentry is a validation error naming the entry, the same family line anhttps-originendpoint:draws. - Availability is not activation. A certificate being available does not turn the binding on — the consumer selects native TLS, outside the file, the same way any other optional resource is selected (D-8).
- Active
set_envbeatsenv:. With the binding active the app receivesGITEA__server__PROTOCOL: httpsfromset_env, not thehttpitsenv:declares; inactive, theenv:value applies unchanged and the binding's keys are absent. This holds for everyset_envbinding, not only certificates — see PROVIDERS.md §7. - It composes with
https-origin, and implies nothing about it. A certificate binding does not by itself satisfy anhttps-originentry, and anhttps-originentry does not imply a certificate. An app may declare both, either, or neither. - Delivery, then refuse or run the baseline.
cert_fileandkey_filearrive through the provider's supplied-resource channel (D-56) and the provider does not verify them. Selected but missing either one, or selected on a provider that cannot activate native TLS, fails before launch naming the entry — never a silent fall back to HTTP. Not selected, the component runs its declared HTTP baseline.
A reader that ignores tls: and the certificate entry launches the declared baseline, which is correct rather than degraded: nobody selected the capability.
Host names under the app host
Some apps serve different surfaces on different host names from one listener: the server reads the Host header and picks a surface. at: says which names a published listener answers at (D-68). Every name is relative to the app host, the value of $app.host. The file never names the app host itself.
provides:
- name: https
protocol: https
port: 443
exposed: true
at: ["@", dash, auth, "*", "*.*"]"Publish this listener. It answers at my host, at dash. and auth. under it, at every other name one label below it, and at every name two labels below it."
at: dash is shorthand for at: [dash]. Nothing expands into extra provides entries: one listener stays one entry, with one name:.
Six rules bind the field:
- Three kinds of value.
"@"is the app host itself. A label, such asdash, is the namedash.<app host>: one lowercase DNS label of at most 63 characters, with no leading or trailing hyphen and no--in its third and fourth characters. A pattern is"*", every name exactly one label below the app host, or"*.*", every name exactly two labels below it.*.dash,dash.*, a dotted label and a deeper pattern are validation errors. Labels are lowercase because DNS compares names without case. - Absent means today. Present means exactly this. A file with no
at:keeps today's meaning. An entry that declaresat:answers at the listed names and no others. Without"@"in the list the app does not answer at the app host, and the platform may put anything there. This describes the app; it is not a filter a provider must apply. A provider that publishes a bare port cannot stop another name from reaching the listener, and is not asked to. - Where it is valid. Only on an entry with
exposed: true: an unpublished listener has no public name. Only on an HTTP-family listener —http,https,wsorgrpc; ontcporudpit is a validation error naming the entry and its protocol, the same family linetls:and anhttps-originendpoint:draw. - A value occurs once per app, across all components. A second entry that declares
dash, or a second"*", is a validation error naming both entries. So each name reaches at most one listener: an exact label matches first, otherwise the pattern of that depth, and no other precedence exists. An entry withoutat:answers at the app host, so the app's primary endpoint (https-originrule 3) holds"@"without declaring it; a second entry that declares"@"beside such a primary is the same error. A primary entry that declaresat:without"@"is valid and draws avalidatewarning:$app.urlthen names a host nothing in the app serves. - Set up the names, or report them. For each value a provider sets up what it can: requests for a matching name reach this entry's listener with the requested host in
Host, DNS resolves the name, and the provider serves a certificate valid for the name where it terminates TLS. A provider that publishes the listener directly, with no edge of its own that routes by host name, already delivers every request with itsHostintact. For every value a provider does not fully set up, it launches the component and reports at the end of provisioning: the entry, the names, where requests arrive, and the operator's options — map the name with a hosts file or DNS, or use a provider that routes host names. The report is mandatory; a launch that says nothing is non-conformant. One case refuses: a provider whose own edge routes by host name, and would drop a declared name it did not route, routes every declared value or refuses the component before launch, naming the entry and the value. Under an orchestrator-supplied public URL the provider never infers that a value is set up; it launches and returns the same report to the orchestrator, which decides what to do with it. See PROVIDERS.md §7 and §10. at:changes no reference value.$app.*and$app.endpoints.<name>.*resolve exactly as they do without it. The app builds its own addresses from$app.host,$app.schemeand$app.authority.
Declare only the names the app answers at in the configuration the file describes. A reader that predates at: ignores the field, publishes one host and reports nothing, which is today's result for such an app, not a new one.