Appearance
Domains and TLS
toml
[services.web]
port = 8080
domains = [
{ host = "shop.example.com" },
{ host = "example.com", path = "/shop", strip_prefix = true },
]| Key | Default | Meaning |
|---|---|---|
host | — | Hostname, lowercased |
path | / | Path prefix routed to this service |
strip_prefix | false | Remove path before forwarding |
port | the service port | Send this domain to another container port |
protocol | http1 | h2c for plaintext HTTP/2 to the backend (gRPC) |
Only web services take domains. The same host and path twice in one org is an error.
DNS and certificates
Point the host at Duploy; duploy project ingress prints the address or CNAME target to use. Once DNS resolves, Duploy issues a Let's Encrypt certificate and redirects HTTP to HTTPS. Follow it with:
bash
duploy domains
duploy until domain.tls.issued --host shop.example.comOwnership
A host belongs to the org that claimed it first. Claiming a host another org already holds does not fail: it stays pending, gets no route and no certificate, until you prove ownership with a TXT record:
_duploy.shop.example.com TXT "duploy-verify=<your org token>"Duploy checks public resolvers on its own; duploy domain verify shop.example.com checks right away. The token is shown in the panel.
Two ports, one container
Some images serve two things on two ports, such as an S3 API and its console:
toml
[services.storage]
source = { image = "rustfs/rustfs:1.0.1" }
port = 9000
domains = [
{ host = "files.example.com" },
{ host = "console.example.com", port = 9001 },
]Health checks still use the service port.
gRPC
Clients reach the edge over TLS and negotiate HTTP/2. Behind the edge, gRPC needs HTTP/2 end to end because trailers do not survive an HTTP/1.1 hop:
toml
domains = [{ host = "otel.example.com", port = 4317, protocol = "h2c" }]