Skip to content

Manual Certificates

Supply your own certificate and private key files instead of letting Dwaar provision certificates automatically. Dwaar reads the files at startup, registers the cert with the SNI resolver, and begins serving HTTPS immediately — no ACME challenge, no DNS configuration required.

On every successful config hot-reload, Dwaar swaps in the current cert paths from the Dwaarfile. If you have rotated the files on disk and trigger a reload, the new certificate takes effect without restarting the process.


example.com {
tls /etc/dwaar/tls/example.com.pem /etc/dwaar/tls/example.com.key
reverse_proxy localhost:3000
}

Replace the paths with the absolute paths to your certificate (PEM) and private key (PEM) files.


ScenarioReason
Enterprise CAYour organisation issues certificates from an internal PKI that clients already trust. Automatic ACME issuance is unnecessary.
Pre-provisioned certificatesA platform team or secrets manager (Vault, AWS ACM, cert-manager) provisions and rotates certificates outside of Dwaar.
Air-gapped environmentsNo outbound internet access means ACME HTTP/DNS challenges are not possible.
Wildcard certificatesYou hold a wildcard cert covering *.example.com and want to use it across multiple sites without per-domain ACME issuance.
Custom PKIDevelopment or staging environments use an internal CA whose certificates your test clients trust.

tls <cert_path> <key_path>

Place the tls directive inside a site block. <cert_path> and <key_path> must be absolute paths to readable files on the local filesystem.

ParameterFormatNotes
<cert_path>PEMOne or more -----BEGIN CERTIFICATE----- blocks. Include the full chain: leaf certificate first, then any intermediate certificates. Order matters — see Certificate Chain.
<key_path>PEMSingle -----BEGIN PRIVATE KEY----- or -----BEGIN EC PRIVATE KEY----- block. RSA, ECDSA P-256, and ECDSA P-384 are all supported.

Dwaar does not accept DER-encoded certificates. Convert DER to PEM with:

Terminal window
openssl x509 -inform DER -in cert.der -out cert.pem
openssl pkcs8 -inform DER -in key.der -out key.pem

Dwaar uses a lock-free ArcSwap-backed SNI resolver. When you edit the Dwaarfile and save — or send a POST /reload to the admin API — the config watcher:

  1. Re-parses and compiles the Dwaarfile.
  2. Builds a new cert-path map from all tls <cert> <key> directives.
  3. Atomically swaps the map into the shared DomainConfigMap.
  4. The SNI resolver picks up the new paths on the next TLS handshake via a lock-free ArcSwap::load() — zero copying, no mutex.

The result: rotate a certificate by updating the files on disk and triggering a config reload. In-flight TLS sessions are not terminated; only new handshakes use the updated cert.

Terminal window
# After writing new cert files to disk:
curl -X POST http://localhost:9000/reload

Include the full certificate chain in <cert_path>, ordered leaf-first:

-----BEGIN CERTIFICATE-----
<leaf certificate for example.com>
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
<intermediate CA certificate>
-----END CERTIFICATE-----

Do not include the root CA in the chain file — browsers and TLS clients already carry trusted roots, and including the root increases handshake size without benefit.

If the intermediates are missing, clients that do not cache intermediates (strict mobile browsers, some curl versions) will fail validation with an “unable to get local issuer certificate” error.


# Global options — bind on standard ports
{
http_port 80
https_port 443
}
# Redirect HTTP to HTTPS
http://example.com {
redir https://example.com{uri} 301
}
# HTTPS site using a manually provisioned certificate
example.com {
tls /etc/dwaar/tls/example.com.pem /etc/dwaar/tls/example.com.key
reverse_proxy localhost:3000 {
health_uri /healthz
health_interval 15
}
header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
}

The tls directive overrides automatic provisioning for example.com. All other sites in the same Dwaarfile continue to use their own TLS settings independently.