How-to
HTTPS with Let's Encrypt
Get and renew certificates from Let’s Encrypt automatically, test against the staging CA
first, then redirect HTTP to HTTPS and www. to the bare domain.
ScalWS has its own ACME client (ADR-0018); no certbot is needed. It uses the HTTP-01 challenge only.
Prerequisites
- DNS
A/AAAArecords of every name pointing at the server, includingwww.<domain>when the site serves or redirects it. - Ports 80 and 443 reachable from the internet and ending at ScalWS (not at another web server or a load balancer that redirects). The package’s first install opens them in an active ufw or a running firewalld; otherwise open them yourself (firewall).
- No wildcard names, IP addresses or
localhost: they cannot get HTTP-01 certificates. Use a certificate file for them (see TLS).
1. Listeners and server.acme, against staging first
Edit /etc/scalws/scalws.yaml. Three things are required: a plain-HTTP listener for the
challenges, a TLS listener with acme: true, and server.acme:
include: sites.d/*.yaml
server:
listeners:
- {name: http, address: "0.0.0.0:80"}
- {name: https, address: "0.0.0.0:443", tls: {acme: true}}
acme:
enabled: true
directory: https://acme-staging-v02.api.letsencrypt.org/directory
state_dir: /var/lib/scalws/acme-staging
contact: ["mailto:[email protected]"]
terms_of_service_agreed: trueserver.acme.directory: the staging CA, to stay clear of the production rate limits while you test.server.acme.state_dir: a separate directory for staging. Certificates are kept per site in the state directory and are not ordered again just becausedirectorychanged.server.acme.contact:mailto:addresses only.server.acme.terms_of_service_agreedmust betrue.tls: {acme: true}on the listener serves the ACME certificates.
Apply. A new listener needs a restart under scalwsd.service; the controller binds it on
reload:
sudo scalwsctl check
sudo scalws-controller reload # under scalws-controller
sudo systemctl restart scalwsd # under scalwsd.service2. The site
With server.acme enabled, every site file without a tls
key gets tls: auto: a certificate for all its names. scalwsctl site add needs no
extra option:
sudo scalwsctl site add example.com --root /srv/www/example.com# /etc/scalws/sites.d/example.com.yaml
domain: example.com
root: /srv/www/example.com
www: redirectWith www: redirect (the default of site add for a
name with one dot), www.example.com answers with a 301 to https://example.com,
path and query kept. That redirect is an application of its own with its own certificate,
so www.example.com needs DNS too. www: alias serves www.example.com as part of the
site (one certificate for both names); www: none does not serve it.
In scalws.yaml itself the equivalent is
acme: true on the
application.
3. Watch the order
scalwsctl certs # under scalwsd.service
scalwsctl --socket /run/scalws/web-0/admin.sock certs # under scalws-controllercerts lists each ACME application with its state (ok, pending, error, missing),
days left, names, and the last error with the time of the next retry. Log lines use the
target scalws::acme:
journalctl -u scalwsd | grep scalws::acme
sudo grep '"scalws::acme"' /var/lib/scalws-controller/logs/web-0.logA new certificate is activated without a restart: new handshakes get it, existing
connections keep theirs. Staging certificates are not trusted by browsers;
curl -k https://example.com/ shows that the chain is in place.
4. Switch to production
Remove the directory and state_dir lines (the defaults are the production CA and
/var/lib/scalws/acme), check and reload:
include: sites.d/*.yaml
server:
listeners:
- {name: http, address: "0.0.0.0:80"}
- {name: https, address: "0.0.0.0:443", tls: {acme: true}}
acme:
enabled: true
contact: ["mailto:[email protected]"]
terms_of_service_agreed: truesudo scalwsctl check
sudo scalws-controller reload # or: sudo scalwsctl reload
curl -sI https://example.com/5. Redirect HTTP to HTTPS
Once certs shows ok, add https_redirect
to the site:
domain: example.com
root: /srv/www/example.com
www: redirect
https_redirect: true(site add ... --https-redirect sets it for new sites.) Plain-HTTP requests then get a
301 to the same host, path and query over https:// (always port 443). ACME challenges
are still answered over HTTP, so renewals keep working. ScalWS does not add
Strict-Transport-Security; send it from the application or with
Header set Strict-Transport-Security "max-age=31536000" in an
.htaccess file.
Renewals
Nothing to schedule. The certificate manager checks every ACME application at start,
every check_interval
(default 12h) and after every configuration change, and orders a new certificate when:
- the application has none yet,
- its names changed (an added alias,
wwwchanged), or - it expires within
renew_before(default30d).
Under scalws-controller the instances share the state directory: one places the order,
all of them answer the challenge and load the certificate. The metric
scalws_acme_certificate_expiry_seconds{tenant,app} holds each expiry time, for alerts.
Back up the state directory yourself: scalwsctl backup does not include it.
Common problems
statestayserror: DNS does not point here, port 80 does not reach ScalWS, or a rate limit was hit. A failed order is retried after 5 minutes, then with doubling delays up to 24 hours. The delay is kept in the server’s memory; after fixing DNS or the firewall,sudo systemctl restart scalwsd(sudo systemctl restart scalws-controllerunder the controller) retries at once.ACME HTTP-01 needs a plain HTTP listener: add the port-80 listener.ACME is enabled but no TLS listener has acme: true: addtls: {acme: true}to the HTTPS listener.must be true (the CA's terms of service are accepted on account creation): setterms_of_service_agreed: true.wildcard domains need DNS-01, which is not supported: use a certificate file andtls: manualfor that site.- Browsers warn after switching to production: the staging certificate is still in
use because
state_dirwas not changed back; remove thestate_dirline. - Handshake fails before the first certificate: until an application has its first
certificate, its names get the listener’s
defaultcertificate if there is one, and a failed handshake otherwise.
See also: TLS, quick start, troubleshooting.