Updated: 3 November 2026 · Applies to: acme.sh, Let's Encrypt
acme.sh is a free, zero-dependency ACME protocol client written entirely in shell, used to request, install and automatically renew SSL certificates from Let's Encrypt or any other ACME-compatible certificate authority. Unlike certbot, it needs nothing beyond a POSIX shell, no Python runtime or system packages to install first.
What Let's Encrypt provides
Let's Encrypt is a certificate authority that issues free, automated SSL/TLS certificates. A single certificate can cover up to 100 hostnames (a SAN certificate) or a wildcard domain, and every certificate it issues is valid for 90 days, which is exactly why an automated renewal tool like acme.sh is worth using instead of renewing by hand.
Install acme.sh
The simplest method, via curl:
curl https://get.acme.sh | sh -s email=you@example.com
Or via wget:
wget -O - https://get.acme.sh | sh -s email=you@example.com
Or clone and install it directly from its official repository (the project moved from its original author's personal GitHub account to the acmesh-official organization; old links to the previous address still redirect, but the current one is the correct reference):
git clone https://github.com/acmesh-official/acme.sh.git cd acme.sh ./acme.sh --install -m you@example.com
After any of these, reload your shell so the acme.sh alias is available:
source ~/.bashrc
The installer creates ~/.acme.sh/ (where acme.sh itself and your certificates live), adds the acme.sh command as an alias to it, and sets up a daily cron job that checks whether any certificate needs renewing.
Confirm it installed correctly
acme.sh --version
Issue a certificate using webroot mode
If you already have a web server running and can write to its web root, webroot mode is the simplest validation method; acme.sh places a verification file there temporarily to prove you control the domain.
Single domain:
acme.sh --issue -d example.com --webroot /var/www/example.com
Multiple domains on one certificate:
acme.sh --issue -d example.com -d www.example.com --webroot /var/www/example.com
An ECC certificate instead of RSA, generally smaller and faster to negotiate:
acme.sh --issue -d example.com --webroot /var/www/example.com --keylength ec-256
Issue a certificate using standalone mode
If there is no web server running yet, or port 80 is free, acme.sh can run its own temporary web server just to complete validation:
acme.sh --issue -d example.com --standalone
Automatic validation through your DNS provider's API
If your DNS provider has an API, acme.sh can add the required TXT record for you automatically, which also makes renewal fully unattended, since nothing manual is needed each time. acme.sh supports roughly 150 DNS providers natively today; check its wiki for your specific provider's exact flag. As an example, for Cloudflare:
export CF_Token="your-cloudflare-api-token" acme.sh --issue -d example.com --dns dns_cf
A token scoped to a single zone is enough for one domain; if your token covers multiple domains in the same Cloudflare account, also set CF_Account_ID. acme.sh's own documentation still shows an older method using a Global API Key (CF_Key and CF_Email) as an alternative, but it explicitly recommends the token method above instead.
For a wildcard certificate, add the wildcard as a second -d:
acme.sh --issue -d example.com -d '*.example.com' --dns dns_cf
If your provider has no supported API, acme.sh falls back to manual DNS mode, printing the TXT record for you to add by hand, but that means renewal is manual too, since nothing can re-add the record automatically.
Install the issued certificate where your web server needs it
Never point your web server directly at files inside ~/.acme.sh/; that folder's layout is for acme.sh's own internal use and can change. Use --install-cert to copy the certificate to a real, stable location and reload your web server automatically whenever it renews:
acme.sh --install-cert -d example.com \
--cert-file /etc/nginx/ssl/example.com/cert.pem \
--key-file /etc/nginx/ssl/example.com/key.pem \
--fullchain-file /etc/nginx/ssl/example.com/fullchain.pem \
--reloadcmd "systemctl reload nginx"
Renewing certificates
The daily cron job the installer created handles renewal automatically; you do not need to do anything for a certificate to renew on time. To force a renewal immediately, for testing or because something changed:
acme.sh --renew -d example.com --force
Keeping acme.sh itself up to date
acme.sh --upgrade
Or let it keep itself updated automatically from then on:
acme.sh --upgrade --auto-upgrade
For the full list of commands, options and every supported DNS provider, see the official acme.sh wiki.