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.

Related services

KVM VPS hosting

NVMe SSD and full root access, with Free Basic Managed Support.

Unmanaged dedicated servers

full root access and free IPMI KVM, with Free Basic Managed Support.

Managed dedicated servers

our engineers look after the server for you, from $135 a month.

Was this answer helpful?

Still stuck? Open a ticket