duckweb_serve
scalar · LOAD duckweb
duckweb_serve(VARCHAR, INTEGER, VARCHAR, VARCHAR) -> VARCHAR
duckweb_serve(VARCHAR, INTEGER, VARCHAR, VARCHAR, ANY) -> VARCHARStarts a server, and returns.
SELECT duckweb_serve('127.0.0.1', 8080, '.', 'app.main');The listener runs on a background thread, so the call returns as soon as the socket is bound — or, when domains is set, as soon as a certificate is in hand. Nothing keeps the process alive by itself: in the CLI that is the REPL, which is why a server started from a script holds stdin open.
Arguments
host |
Interface to bind. 127.0.0.1 unless you mean otherwise. |
port |
Clamped to 0–65535. 0 binds an arbitrary free port. |
assets |
Directory served under /_duckweb/, and the root duckweb_asset resolves against. |
search_path |
Schemas the render query is bound against, e.g. memory.main,app.main. |
options |
Optional struct, below. |
The search path is applied per request rather than inherited, because a request lands on whichever pooled connection is free. Setting it here proves it resolves while there is still a caller to tell.
Options
render- The table function the transport calls for this server, overriding duckweb_render_function. Useful when one process serves two apps.
domains- Comma-separated names to obtain a certificate for and serve over HTTPS. Setting it turns TLS on.
contact- Email address registered with the ACME provider.
cache-
Directory for the account key and certificate. Required when
domainsis set — without it every restart registers and orders again, into rate limits measured in a handful per week. Cache files are keyed by the directory URL, so moving between staging and production orders afresh rather than reusing. directory-
ACME directory URL.
stagingis shorthand for Let’s Encrypt’s staging endpoint; empty means production. root- PEM root to trust instead of the system store, for testing against a private CA.
An unknown option is an error naming the ones that exist, rather than being ignored.
Several servers, one port
Call it more than once with the same host and port and each call adds a site: its own certificate, asset directory, render function and search path, chosen per connection by the TLS server name.
SELECT duckweb_serve('0.0.0.0', 443, '/srv/docs', 'memory.main,docs.main',
{domains: 'example.com', contact: 'me@example.com',
cache: '/var/lib/duckweb/acme'});
SELECT duckweb_serve('0.0.0.0', 443, '/srv/demo', 'memory.main,app.main',
{domains: 'demo.example.com', contact: 'me@example.com',
cache: '/var/lib/duckweb/acme', render: 'demo_render'});Everything that tells two sites apart travels in the options, which is precisely why none of it is a setting: a global would leave no way to say which server a value belonged to.
Sites on one port must agree about TLS — two plain-HTTP servers have nothing to tell them apart — and no two may claim the same name.
Certificates
TLS uses ACME’s TLS-ALPN-01 challenge, answered inside a handshake on the port already being served. That means the certificate cannot be obtained behind a reverse proxy that terminates TLS, and the port must be reachable from the internet as the port the provider will dial.