Courier talks HTTPS, and you never create, buy or install a certificate. The service asks Let’s Encrypt for one the first time it starts, and renews it by itself from then on.
What happens when the service starts
Section titled “What happens when the service starts”- The service looks for a certificate in
~/.courier-tls, outside the service directory. If there is none, it does not open the sync port yet — clients would only see a refused connection. - It asks Let’s Encrypt (a free, public certificate authority) for a certificate for the address you entered in the app: the server’s public IP, or the domain that points at it.
- Let’s Encrypt proves the address belongs to this server by fetching a small file over port 80. The service listens on 80 only while an order is in progress.
- The certificate arrives, the sync port opens, and the app’s check turns green. A first issuance takes a few seconds; on a slow cross-border network it can take a minute or two.
Nothing else is configured: no email, no DNS records, no certificate files to upload.
What the server has to provide
Section titled “What the server has to provide”- A public address. The certificate is issued for exactly the address you entered.
localhost, a LAN address or a private IP cannot get one. - Port 80 reachable from the internet. Let’s Encrypt checks from its own network, not from your
computer, so the cloud security group must allow the whole internet (source
0.0.0.0/0), and nothing else may listen on 80. The service holds 80 only while it is issuing or renewing. - The server can reach Let’s Encrypt. The service requests certificates over HTTPS from the
server itself, so the server needs an ordinary outbound connection on port 443 (
acme-v02.api.letsencrypt.org). This is not a port to open to the internet: cloud servers allow outbound traffic by default, and only an unusually strict outbound firewall has to allow it. Mainland networks are sometimes slow to get there, which is what the checkcurl -I https://acme-v02.api.letsencrypt.org/directorytests.
In short, the inbound rules are 80 (certificate validation only) and the service port (8443 by default, for Obsidian and the CLI). The 443 above is outbound, not a third inbound rule.
The desktop app checks the ports as part of a deployment, and shows what failed when the check does not pass.
Renewal
Section titled “Renewal”Certificates are short-lived: they last about six days. Every six hours the service checks the one it has and renews it when about three days are left. Renewal uses the same port-80 proof and happens in the background — there is nothing for you to do, but the service has to keep running, and the port-80 rule has to stay in place.
Limits and the things that can go wrong
Section titled “Limits and the things that can go wrong”- Let’s Encrypt rate limits. It issues at most five certificates for the same address in a week. Deleting and redeploying the service does not reset that. Deploy once and leave it; a certificate that is still valid is reused. If the limit is hit, the service retries by itself after the window, and the app shows the reason.
- A new address needs a new certificate. If the server’s public IP changes, deploy again; the service notices that the certificate is for the old address and requests a new one.
- Port 80 has to stay free. A proxy or another web server on 80 blocks issuance and renewal, and
an address that is not reachable from outside (a NAT without port forwarding,
localhost) cannot be validated at all. - You cannot bring your own certificate. Courier only uses the certificate the service issues for its own address; there is no field for an uploaded certificate or a custom authority.
When HTTPS cannot happen at all
Section titled “When HTTPS cannot happen at all”Some networks make it impossible: an address that the internet cannot reach on port 80, a server whose outbound access is blocked, or an address stuck behind Let’s Encrypt’s weekly limit. If you accept the trade-off, the deployment dialog has a checkbox — Deploy over HTTP if the certificate cannot be issued, off by default — and the dialog says what it costs: over HTTP, traffic between your devices and the server is not encrypted, so anyone who can capture it can take your user key and read or change the vault.
Check it only when you would otherwise have no working service, and only on a network you trust.
The deployment still tries HTTPS first; it switches to HTTP only when the service itself recorded a
failed certificate attempt. The app then spells the address http://, tells you in one dialog why
HTTPS failed, and your devices must use the http:// address too. Deploying again with the box
unchecked goes back to HTTPS as soon as a certificate can be obtained.
Upgrading the server binary keeps the current scheme, and so does moving to a new server: an HTTP deployment stays HTTP, and an HTTPS one gets its own new certificate at the new address. Switching between the two is always a deployment from the dialog.
Deleting the service
Section titled “Deleting the service”Deleting the service deletes its database, blobs, logs and binary, but the certificate and its keys
are outside the service directory (~/.courier-tls), so they stay. Deploying again to the same
address reuses them, so it does not spend another certificate from the weekly limit. If the
certificate is close to expiry — or has already expired — by the time you redeploy, the service
requests a new one when it starts.
HTTPS is not the vault encryption
Section titled “HTTPS is not the vault encryption”HTTPS protects the connection between a device and your server: it keeps the traffic unreadable in transit and proves the server is the one you meant to connect to. Vault contents are encrypted on the device before they are sent, so the server only ever stores ciphertext. The two are separate; see End-to-end encryption.
If the certificate does not arrive
Section titled “If the certificate does not arrive”The deployment dialog and the status page show the last attempt and its reason, and the service
retries by itself — first after ten minutes, then less often. The two usual causes are port 80 not
reaching the server from the internet, and the weekly limit above. On the server,
~/.courier-tls/last-issuance.txt holds the last outcome.