Skip to content
Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


Build Status Gem Version

Yet another ACME client (e.g. to use together with Letsencrypt CA to issue TLS certs) for command lines using Ruby.


  • This tool needs Ruby >= 2.1 (as the dependency acme-client needs that because of use of keyword arguments).
  • OpenSSL bindings
  • no sudo! (needs access to webserver-root /.well-known/acme-challenges alias for all domains - See later section for Nginx example)
# check your ruby version:
$ ruby --version
ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-linux]

$ gem install acme-cli

$ acme-cli --version

Troubleshooting Ruby version

Unfortunately, most Linux distributions does not ship a current Ruby version (Version 1.9.3 or 2.0). Check, if your ruby version is at least 2.2. Otherwise you need to update the Ruby.

If you are installing this as a non-root user, you might want to try RVM. Installation itself needs no root, but needs some packages:

sudo apt-get install curl bison build-essential zlib1g-dev libssl-dev libreadline6-dev libxml2-dev libgmp-dev git-core

To install RVM:

gpg --keyserver hkp:// --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
\curl -sSL | bash -s stable  --autolibs=disable --auto-dotfiles

rvm install 2.2
source ~/.bashrc # or ~/.profile RVM tells you to reload your shell

ruby --version

Notice: If you are using RVM, all your cronjobs must be run as a login shell, otherwise RVM does not work:

* * * * * /bin/bash -l -c "acme-cli manage ..."

Another way, e.g. on Ubuntu 14.04 might be to use the Brightbox ppa.


Specify -t to use Letsencrypt test server. Without it, all requests are called against the production server, that might have some more strict rate limiting. If you are just toying around, add the -t flag.

# show all commands

acme-cli help

# show options for an individual command
acme-cli help cert

# creates account_key.json in current_dir
acme-cli register -t

# authorize one or more domains/subdomains
acme-cli authorize -t --webroot-path /var/www/default

# experimental: authorize all server_names in /etc/nginx/sites-enabled/*
acme-cli authorize_all -t --webroot-path /var/www/default

# create a certificate for domains that are already authorized within the last minutes (1h-2h I think)
# the first domain will be the cn subject. All other are subjectAlternateName
# if cert.pem already exists, will only create a new one if the old is expired
# (30 days before expiration) -> see full help
acme-cli help cert

acme-cli cert -t
# will create key.pem fullchain.pem chain.pem and cert.pem in current directory

# checks validation date of given certificate.
# Exists non-zero if:
# * not exists (exit 1)
# * will expire in more than 30 days (exit code 2)
acme-cli check --days-valid 30 cert.pem

And last but not least, the meta command manage that integrated check + authorize + cert (intended to be run as cronjob):

$ acme-cli manage --days-valid 30 \
                       --account-key /home/acme/account_key.pem \
                       --webroot-path /home/acme/webroot/.well-known/acme-challenge \
                       --key-directory /home/acme/certs \

2015-12-05 23:40:04 +0100: Certificate /home/acme/certs/ does not exists
2015-12-05 23:40:04 +0100: Authorizing
2015-12-05 23:40:04 +0100: existing account key found
2015-12-05 23:40:06 +0100: Authorization successful for
2015-12-05 23:40:06 +0100: Authorizing
2015-12-05 23:40:08 +0100: Authorization successful for
2015-12-05 23:40:08 +0100: creating new private key to /home/acme/certs/
2015-12-05 23:40:09 +0100: Certificate successfully created to /home/acme/certs/ /home/acme/certs/ and /home/acme/certs/!
2015-12-05 23:40:09 +0100: Certificate valid until: 2016-03-04 21:40:00 UTC

# Run command again exits immediately:
$ acme-cli manage --days-valid 30 --account-key /home/acme/account_key.pem --webroot-path /home/acme/webroot/.wel
l-known/acme-challenge --key-directory /home/acme/certs \
2015-12-05 23:40:17 +0100: Certificate '/home/acme/certs/' valid until 2016-03-04.
$ echo $?

This had:

  1. check if /home/acme/certs/ exists and expires in less than 30 days (or exit 1 at this point)
  2. authorize all domains + subdomains
  3. issue one certificate with those domains and place it under /home/acme/certs/[key.pem,fullchain.pem,chain.pem,cert.pem]
  4. exit 0 -> so can be && with service nginx reload or mail deliver

For running as cron, reducing log level to fatal might be desirable: acme-cli manage --log-level fatal.

Example integration Nginx:

server {
  listen 80;
  location /.well-known/acme-challenge {
	  alias /home/acme/webroot/.well-known/acme-challenge;
	  default_type "text/plain";
	  try_files $uri =404;

notice the location - alias. Use this dir with --webroot-path for authorization.

Afterwards, use the fullchain.pem and key.pem:

server {
  listen 443 ssl;
  ssl on;
  ssl_certificate_key /home/acme/certs/;
  ssl_certificate /home/acme/certs/;

  # use the settings from:


After checking out the repo, run bin/setup to install dependencies. Then, run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release to create a git tag for the version, push git commits and tags, and push the .gem file to


  1. Fork it ( )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request


Letsencrypt CLI client as Ruby gem





No packages published