Working with Let's Encrypt using Roxy-WI
Applies to Roxy-WI 9.1 and later.
Certificate lifecycle in 9.1
Use the SSL certificates page to manage Let's Encrypt certificates. In 9.1, issuance, renewal and HAProxy deployment run through Scheduler, Operations and RabbitMQ in both package and container installations. The table shows status, expiry, next check/retry and an Actions menu with diagnostics and recent operations.
New UI requests follow Save draft → Check setup (staging) → Issue certificate. Drafts are not issued automatically. Keep the application processes and persistent storage available for certificate work.
Prepare the challenge and targets
- Use domains you control and a working contact email. Wildcard certificates require a DNS challenge.
- For DNS validation, use Cloudflare, DigitalOcean, Linode or Route53 credentials with access to the required zones. Certbot and the DNS plugins run in Operations and are installed with Roxy-WI.
- For Stand alone, public HTTP port 80 must forward
/.well-known/acme-challenge/to port 8888 on the selected server. Check public DNS and firewall routing. That server needs Python 3, SSH and noninteractive sudo (or root SSH); Certbot is installed through its package manager if absent. - Check SSH access to the selected HAProxy server and its HA children in the same group, certificate directory permissions, configuration paths and Runtime API access using
haproxy_sock_port. - For Docker HAProxy, mount the certificate directory persistently and configure the correct container name. Atomic replacement does not support individual certificate file mounts. Reload requires HAProxy as PID 1 in master-worker mode (
-Wor-Ws) with the USR2 signal.
Save, check and issue
- Open SSL certificates → Create. Choose a server, challenge type, domains, email and optional description. For DNS challenges, select a profile or enter certificate-specific credentials.
- Click Save draft. Review the saved domain list and target servers.
- Choose Check setup (staging). It checks DNS/CAA, SSH, the certificate directory, HAProxy configuration and Runtime API, then performs a real staging challenge. Read the results for every domain and target.
- Fix any reported issue and repeat the check. Production issuance requires a successful check of the current configuration and DNS profile within the last 24 hours. Editing the draft or rotating profile credentials requires a new check.
- Choose Issue certificate and follow the operation result. Verify each target's deployment status and the certificate presented by the service.
A staging test does not replace or deploy a production certificate. Diagnostics distinguish CAA, DNS credentials, propagation and HTTP validation failures. API clients retain direct issuance by default; use draft: true, then PATCH actions preflight and issue to follow the draft workflow.
Reuse a DNS profile
Open DNS profiles → Add DNS profile on the SSL page. Enter a name, provider and token. Route53 uses an Access key ID and Secret access key. Profiles belong to the current Roxy-WI group and can be reused by its certificates.
For example, save a Route53 profile for your zone, choose it in a new DNS certificate draft, enter example.com and *.example.com using your own domain, then follow the staging and issuance steps above.
Credentials are encrypted with secret_phrase and excluded from API responses. Editing a profile rotates the credentials used by subsequent operations. Profiles in use cannot be deleted. Configure DNS propagation delay for Cloudflare, DigitalOcean or Linode when needed; Route53 uses the plugin's own polling.
Renewal, retries and alerts
Scheduler checks active certificates every 12 hours. Certbot decides when renewal is due using ACME Renewal Information (ARI) and its lifetime rules. Imported certificates use ARI with a lifetime-based fallback until a managed Certbot lineage exists. Renewal is no longer a monthly cron command on the Roxy-WI host.
Normal failures retry after 5 and 10 minutes. ACME rate limits preserve the provider's Retry-After deadline and block early production retries, including after edits. Use the active certificate's menu for an edit, renewal check, staging test or retry, and inspect the next retry time before trying again.
Expiry/recovery checks run every five minutes. Alerts are sent at 14, 7, 3 and 1 days before expiry, at expiry, after repeated failures or failed rollback, and on recovery. They use the target server's HAProxy alert routing and deduplicated queued delivery.
Deployment, rollback and deletion
Roxy-WI checks the key, exact certificate names and validity before atomically replacing the PEM, validating HAProxy configuration and reloading. It verifies a new HAProxy worker and the loaded certificate fingerprint through the Runtime API. A certificate not referenced by a bind is reported as stored but unused. Editing domains keeps the PEM filename stable.
If an HA target fails, all attempted targets are rolled back. Interrupted rollback or finalization is persisted and retried before new issuance. Editing and deletion remain blocked while recovery is pending; inspect the per-target result. After three failed replacement attempts and successful rollback, renewal of the previous applied configuration resumes; edit to submit another replacement.
Deleting a managed certificate stops renewal and removes its managed ACME material after cleanup succeeds. It retains deployed PEM files and does not revoke the certificate. Failed cleanup remains visible and retryable.
Preserve lib_path/letsencrypt, the database and secret_phrase together. All Operations replicas need the same shared filesystem and key. Standalone issuers also keep isolated state under /var/lib/roxy-wi/letsencrypt on the managed server.
Completed/failed operation history is retained for 30 days, with active and latest operations preserved. Set ROXYWI_LE_HISTORY_RETENTION_DAYS on Scheduler to change this; 0 disables pruning.
Migrate cron-managed certificates
Database migration encrypts stored tokens and pauses imported schedules until cutover completes. Perform the cutover on the original package host using its updated Roxy-WI Python environment.
- Apply database migrations, finish existing LE setup operations and stop Web, Scheduler and Operations.
- Temporarily stop cron/crond and Certbot timers on the Roxy-WI host and standalone issuer hosts. Wait for active Certbot or certificate rsync commands to finish.
- As root on the original Roxy-WI host, run
/path/to/roxy-wi-python roxy_wi.py migrate-le-cron. - Resolve reported certificate/key mismatches or duplicate PEM ownership and rerun the command if necessary. Schedules activate only after all affected hosts complete migration.
- Restart cron and the stopped Certbot timers. For a move to containers, transfer the database and shared LE storage, preserve its key, set storage ownership for Operations (UID/GID 10001 in the default image), and leave the source Roxy-WI processes stopped before starting the destination.
The command imports existing certificate/key pairs, removes only Roxy-WI LE cron entries and archives their renewal configurations so Certbot timers cannot renew them in parallel. It preserves live/archive files and unrelated cron jobs and lineages. Root-only backups are stored in /var/backups/roxy-wi-letsencrypt on affected hosts.
Do not run this migration inside a container: it cannot see the original cron and ACME state. The first scheduled run verifies and deploys imported material, obtaining a replacement when needed.
Upload an existing certificate
Manual uploads remain available on the SSL page: select the server, enter a certificate name, select PEM, KEY or CRT, paste the file contents and click Upload. A manual upload does not create a managed Let's Encrypt renewal schedule.