DocsInfrastructure
Custom SSL certificates
Use your own certificate for application domains instead of automatic Let's Encrypt: upload once, pick per domain.
- Upload
- Integrations → SSL certificates (owner/admin)
- Attach
- Application → Domain tab, per HTTPS domain
- Applies to
- Application domains only
When to use it
By default an HTTPS domain uses automatic Let's Encrypt. A custom certificate helps when:
- your company requires a certificate from an internal CA or a specific CA;
- you already own a paid wildcard certificate to use for many subdomains;
- you use Cloudflare Origin CA behind the Cloudflare proxy;
- the server's network can't be reached by Let's Encrypt (e.g. no inbound port 80).
Uploading a certificate
Integrations → SSL certificates
Only owners/admins see this card. Click Upload.
Fill in the name, certificate, and private key
Paste the PEM content or click Choose file to read a
.pem/.crtfile and the key from your computer (read in the browser). Requirements:- PEM format: a
-----BEGIN CERTIFICATE-----block for the certificate and-----BEGIN PRIVATE KEY-----(or RSA/EC) for the key. - The certificate may be a bundle: the server certificate first, then the intermediates (the chain). A wrong order is rejected.
- The private key must not be protected by a passphrase. Remove it first, e.g.
openssl pkey -in key.pem -out key-nopass.pem. - The key must match the certificate, and the certificate must not be expired.
- The name must be unique.
- PEM format: a
Click Upload
aoox reads the names the certificate covers (including wildcards), its issuer, and its expiry date. The private key can't be viewed again once saved.
The card lists each certificate's name, the domains it covers, the issuer, the expiry date, and how many domains use it.
Attaching it to a domain
On the application's Domain tab, every HTTPS domain has a Certificate choice:
- Automatic (Let's Encrypt) — the default; the proxy requests its own certificate.
- One of the certificates you uploaded. Only those that cover the host can be picked; the others show as disabled with “does not cover host”.
The same choice is available when adding a new domain (once HTTPS is on). Changing it needs the developer role or higher; viewers only see which certificate is in use. A domain without HTTPS has no such choice. Picking Automatic again returns the domain to Let's Encrypt.
Wildcards
No certificate of your own? With a Cloudflare connection aoox can issue a wildcard certificate itself through ACME DNS-01, see Cloudflare DNS.
A *.example.com certificate covers one level: app.example.com yes, but a.b.example.com and example.com itself no. This is the same rule browsers use; a certificate that lists both example.com and *.example.com serves both.
Expiry and renewal
- The card shows a badge: green (normal), amber (under 14 days), red (already expired). The Domain tab flags domains whose certificate is close to or past its expiry.
- aoox sends a notification (the certificate failure kind) when 14 days or less remain, and again once it has expired; at most once per 24 hours per certificate. Only certificates that a domain uses are warned about.
- An expired custom certificate does not fall back to Let's Encrypt: browsers will reject that domain until you renew it or pick Automatic.
To renew, click Update on the certificate and paste the new certificate and key. The name stays, and every domain using it follows automatically. The new content must still cover the domains already using it; otherwise the update is rejected (400).
Deleting
The delete button opens a confirmation dialog. A certificate that a domain still uses can't be deleted (409): move the domain to another certificate or to Let's Encrypt first.
Limits
- For application domains only. The domains for the panel and the local registry keep using ACME.
- On an older proxy install that cannot read custom certificates yet, the proxy container is recreated once (a few seconds) when the first custom certificate is used; its ports and ACME settings are kept. A newer proxy needs no recreate, and replacing a certificate's content restarts nothing.
- Certificates and their assignments are not included in a project export/import (imported domains use Let's Encrypt) and are not restored by an instance restore; upload them again if needed.
Security
0600 permissions in the proxy volume. The API never returns it, and it never appears in logs or notifications. Still limit who is an owner/admin, and remove a certificate whose key has leaked.Common pitfalls
| Symptom | Cause & fix |
|---|---|
| 400: key does not match | The key is not the pair of the first certificate in the bundle. Put the server certificate first, the chain after it. |
| 400: key is encrypted | Remove the passphrase first (openssl pkey), then upload again. |
| 400: already expired | Upload a certificate that is still valid. |
| 409: name already used | Pick another name, or update the existing certificate. |
| A certificate can't be picked for a domain | It does not cover that host (remember a wildcard is one level only). |
| The browser still rejects it | Incomplete chain: include the intermediates in the bundle. Or the domain isn't pointed at this server yet. |
Next steps
Found a mistake? Edit this page on GitHub ↗