Skip to content

Domains and TLS ​

toml
[services.web]
port = 8080
domains = [
  { host = "shop.example.com" },
  { host = "example.com", path = "/shop", strip_prefix = true },
]
KeyDefaultMeaning
host—Hostname, lowercased
path/Path prefix routed to this service
strip_prefixfalseRemove path before forwarding
portthe service portSend this domain to another container port
protocolhttp1h2c 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.com

Ownership ​

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" }]

Duploy — our nodes, your file.