acme.sh is a pure shell ACME client: no Python, no system packages, runs as a normal user, and supports DNS APIs for well over a hundred providers. It is a popular alternative to Certbot, especially for wildcard certificates and minimal servers. This guide shows how to use acme.sh.
Before you start
- A Linux server with
curlorwget,cronandsocat(for standalone mode). - DNS pointing to the server, or an API token for your DNS provider for DNS validation.
Install acme.sh
curl https://get.acme.sh | sh -s email=admin@example.comIt installs into ~/.acme.sh/ and adds a daily cron job for renewals. Reload your shell (source ~/.bashrc) to use the acme.sh command. Read the installer script first if you prefer, or clone the official repository.
Choose a certificate authority
acme.sh's default CA has changed over time. To use Let's Encrypt explicitly:
acme.sh --set-default-ca --server letsencryptIssue a certificate
- Webroot (a web server is already serving the domain):
acme.sh --issue -d example.com -d www.example.com -w /var/www/example.com/public - Standalone (nothing on port 80):
acme.sh --issue --standalone -d mail.example.com - DNS API (wildcards, servers without port 80) – example with Cloudflare:
export CF_Token="your-api-token" acme.sh --issue --dns dns_cf -d example.com -d '*.example.com'acme.sh saves the credentials for renewals. Use a token limited to DNS edits on that zone.
ECDSA keys are the default in current versions; add --keylength 2048 for RSA.
Install the certificate into your web server
Never point servers at files inside ~/.acme.sh/ directly – copy them with --install-cert, which also sets the reload command used after each renewal:
acme.sh --install-cert -d example.com \
--key-file /etc/nginx/ssl/example.com.key \
--fullchain-file /etc/nginx/ssl/example.com.crt \
--reloadcmd "systemctl reload nginx"For HAProxy, which wants key and chain in one file, use a reload command that concatenates them first.
Renewal
- List certificates:
acme.sh --list - Force a renewal test:
acme.sh --renew -d example.com --force - Check the cron entry:
crontab -l | grep acme
Upgrade and remove
- Keep acme.sh updated:
acme.sh --upgrade --auto-upgrade - Stop renewing a certificate:
acme.sh --remove -d example.com(files stay; delete them yourself).
Troubleshooting
- Verify error / 404: wrong webroot path or a redirect blocks
/.well-known/acme-challenge/. - DNS validation fails: wrong API token permissions or slow DNS propagation – add
--dnssleep 120. - Permission denied writing to /etc: running as a normal user – use paths that user can write, or run as root.
- Debug output: add
--debug 2to any command.
FAQ: acme.sh
acme.sh or Certbot?
Both are solid. acme.sh is lighter and has more DNS API integrations; Certbot integrates with Nginx/Apache configuration automatically.
Can acme.sh and Certbot run on the same server?
Yes, but manage each certificate with only one client to avoid confusion.
Does acme.sh need root?
No, but it needs permission to write certificate files and reload services, which often means root or sudo.
