2019-11-30 16:52:16 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# Migrating Guide
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Greenlock v4 is the current version.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# v3 to v4
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								v4 is a very minor, but breaking, change from v3
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								### `configFile` is replaced with `configDir`
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								The default config file `./greenlock.json`  is now `./greenlock.d/config.json` .
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								This was change was mode to eliminate unnecessary configuration that was inadvertantly introduced in v3.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								### `.greenlockrc` is auto-generated
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								`.greenlockrc`  exists for the sake of tooling - so that the CLI, Web API, and your code naturally stay in sync. 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								It looks like this:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```json
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    "manager": {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        "module": "@greenlock/manager "
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    },
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    "configDir": "./greenlock.d"
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								If you deploy to a read-only filesystem, it is best that you create the `.greenlockrc`  file as part
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								of your image and use that rather than including any configuration in your code.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# v2 to v4
  
						 
					
						
							
								
									
										
										
										
											2019-10-29 03:20:10 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								**Greenlock Express** uses Greenlock directly, the same as before.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								All options described for `Greenlock.create({...})`  also apply to the Greenlock Express `init()`  callback.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# Overview of Major Differences
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 04:05:54 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								-    Reduced API 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    No code in the config 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    -    (config is completely serializable)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    Manager callbacks replace `approveDomains`  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    Greenlock Express does more, with less config 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    -    cluster is supported out-of-the-box
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    -    high-performance
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    -    scalable
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    ACME challenges are simplified 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    -    init
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    -    zones (dns-01)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    -    set
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    -    get
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    -    remove
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    Store callbacks are simplified 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    -    accounts
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        -    checkKeypairs
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    -    certificates
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        -    checkKeypairs
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        -    check
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        -    set
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# Greenlock JavaScript API greatly reduced
  
						 
					
						
							
								
									
										
										
										
											2019-10-29 03:20:10 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Whereas before there were many different methods with nuance differences,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								now there's just `create` , `get` , `renew` , and sometimes `add`  ().
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 04:05:54 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								-    Greenlock.create({ maintainerEmail, packageAgent, notify }) 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    Greenlock.get({ servername, wildname, duplicate, force }) 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    -    (just a convenience wrapper around renew)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    Greenlock.renew({ subject, altnames, issuedBefore, expiresAfter }) 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    -    (retrieves, issues, renews, all-in-one)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    _optional_  Greenlock.add({ subject, altnames, subscriberEmail }) 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    -    (partially replaces `approveDomains` )
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Also, some disambiguation on terms:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    `domains`  was often ambiguous and confusing, it has been replaced by: 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    -    `subject`  refers to the subject of a certificate - the primary domain
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    -    `altnames`  refers to the domains in the SAN (Subject Alternative Names) section of the certificate
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    -    `servername`  refers to the TLS (SSL) SNI (Server Name Indication) request for a cetificate
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    -    `wildname`  refers to the wildcard version of the servername (ex: `www.example.com => *.example.com` )
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 03:20:10 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								When you create an instance of Greenlock, you only supply package and maintainer info.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								All other configuration is A) optional and B) handled by the _Manager_ .
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								'use strict';
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var pkg = require('./package.json');
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var Greenlock = require('greenlock');
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var greenlock = Greenlock.create({
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 04:05:54 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // used for the ACME client User-Agent string as per RFC 8555 and RFC 7231
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    packageAgent: pkg.name + '/' + pkg.version,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // used as the contact for critical bug and security notices
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // should be the same as pkg.author.email
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    maintainerEmail: 'jon@example .com',
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // used for logging background events and errors
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    notify: function(ev, args) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if ('error' === ev || 'warning' === ev) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            console.error(ev, args);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        console.info(ev, args);
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 03:20:10 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								});
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								By default **no certificates will be issued** . See the _manager_  section.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								When you want to get a single certificate, you use `get` , which will:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    will return null if neither the `servername`  or its `wildname`  (wildcard) variant can be found 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    retrieve a non-expired certificate, if possible 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    will renew the certificate in the background, if stale 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    will wait for the certificate to be issued if new 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								greenlock
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 04:05:54 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    .get({ servername: 'www.example.com' })
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .then(function(result) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if (!result) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // certificate is not on the approved list
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return null;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        var fullchain = result.pems.cert + '\n' + result.pems.chain + '\n';
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        var privkey = result.pems.privkey;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            fullchain: fullchain,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            privkey: privkey
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        };
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    })
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .catch(function(e) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // something went wrong in the renew process
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        console.error(e);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    });
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 03:20:10 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								By default **no certificates will be issued** . See the _manager_  section.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								When you want to renew certificates, _en masse_ , you use `renew` , which will:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    check all certificates matching the given criteria 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    only renew stale certificates by default 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    return error objects (will NOT throw exception for failed renewals) 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								greenlock
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 04:05:54 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    .renew({})
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .then(function(results) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if (!result.length) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // no certificates found
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return null;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // [{ site, error }]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return results;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    })
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .catch(function(e) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // an unexpected error, not related to renewal
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        console.error(e);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    });
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 03:20:10 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Options:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								| Option        | Description                                                                |
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								| ------------- | -------------------------------------------------------------------------- |
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 04:40:59 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								| `altnames`     | only check and renew certs matching these altnames (including wildcards)   |
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 03:20:10 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								| `renewBefore`  | only check and renew certs marked for renewal before the given date, in ms |
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								| `duplicate`    | renew certificates regardless of timing                                    |
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								| `force`        | allow silly things, like tiny `renewOffset` s                               |
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								By default **no certificates will be issued** . See the _manager_  section.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# Greenlock Express Example
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								The options that must be returned from `init()`  are the same that are used in `Greenlock.create()` ,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								with a few extra that are specific to Greenlock Express:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								require('@root/greenlock -express')
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 04:05:54 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    .init(function() {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // This object will be passed to Greenlock.create()
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        var options = {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // some options, like cluster, are special to Greenlock Express
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            cluster: false,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // The rest are the same as for Greenlock
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            packageAgent: pkg.name + '/' + pkg.version,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            maintainerEmail: 'jon@example .com',
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            notify: function(ev, args) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                console.info(ev, args);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        };
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return options;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    })
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    .serve(function(glx) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // will start servers on port 80 and 443
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        glx.serveApp(function(req, res) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            res.end('Hello, Encrypted World!');
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        });
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // you can get access to the raw server (i.e. for websockets)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        glx.httpsServer(); // returns raw server object
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    });
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 03:20:10 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 04:05:54 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# _Manager_ replaces `approveDomains`
  
						 
					
						
							
								
									
										
										
										
											2019-10-29 03:20:10 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								`approveDomains`  was always a little confusing. Most people didn't need it. 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Instead, now there is a simple config file that will work for most people,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								as well as a set of callbacks for easy configurability.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								### Default Manager
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-30 16:52:16 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								The default manager is `@greenlock/manager`  and the default `configDir`  is `./.greenlock.d` .
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 03:20:10 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								The config file should look something like this:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-30 16:52:16 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								`./greenlock.d/config.json` : 
						 
					
						
							
								
									
										
										
										
											2019-10-29 03:20:10 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```json
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 04:05:54 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    "subscriberEmail": "jon@example .com",
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    "agreeToTerms": true,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    "sites": {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        "example.com": {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            "subject": "example.com",
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            "altnames": ["example.com", "www.example.com"]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 03:20:10 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 04:05:54 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								You can specify a `acme-dns-01-*`  or `acme-http-01-*`  challenge plugin globally, or per-site.
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 03:20:10 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```json
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 04:05:54 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    "subscriberEmail": "jon@example .com",
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    "agreeToTerms": true,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    "sites": {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        "example.com": {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            "subject": "example.com",
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            "altnames": ["example.com", "www.example.com"],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            "challenges": {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                "dns-01": {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    "module": "acme-dns-01-digitalocean",
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    "token": "apikey-xxxxx"
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 03:20:10 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 04:05:54 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								The same is true with `greenlock-store-*`  plugins:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 03:20:10 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								```json
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 04:05:54 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    "subscriberEmail": "jon@example .com",
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    "agreeToTerms": true,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    "sites": {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        "example.com": {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            "subject": "example.com",
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            "altnames": ["example.com", "www.example.com"]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    },
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    "store": {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        "module": "greenlock-store-fs",
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        "basePath": "~/.config/greenlock"
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 03:20:10 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 04:05:54 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								### Customer Manager, the lazy way
  
						 
					
						
							
								
									
										
										
										
											2019-10-29 03:20:10 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-30 16:52:16 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								At the very least you have to implement `get({ servername, wildname })` .
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 03:20:10 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var greenlock = Greenlock.create({
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 04:05:54 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    packageAgent: pkg.name + '/' + pkg.version,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    maintainerEmail: 'jon@example .com',
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    notify: notify,
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 03:20:10 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-30 16:52:16 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    packageRoot: __dirname,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    manager: {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        module: './manager.js'
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								});
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 03:20:10 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								function notify(ev, args) {
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 04:05:54 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if ('error' === ev || 'warning' === ev) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        console.error(ev, args);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    console.info(ev, args);
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 03:20:10 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-30 16:52:16 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								In the simplest case you can ignore all incoming options
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								and return a single site config in the same format as the config file
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 04:05:54 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-30 16:52:16 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								`./manager.js` : 
						 
					
						
							
								
									
										
										
										
											2019-10-29 04:05:54 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								'use strict';
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								module.exports.create = function() {
							 
						 
					
						
							
								
									
										
										
										
											2019-11-30 16:52:16 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        get: async function({ servername }) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // do something to fetch the site
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            var site = {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                subject: 'example.com',
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                altnames: ['example.com', 'www.example.com']
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            };
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 04:05:54 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-30 16:52:16 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return site;
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 04:05:54 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    };
							 
						 
					
						
							
								
									
										
										
										
											2019-11-30 16:52:16 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								};
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 04:05:54 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-30 16:52:16 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								If you want to use wildcards or local domains for a specific domain, you must specify the `dns-01`  challenge plugin to use:
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 04:05:54 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-30 16:52:16 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								'use strict';
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 04:05:54 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-30 16:52:16 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								module.exports.create = function() {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        get: async function({ servername }) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // do something to fetch the site
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            var site = {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                subject: 'example.com',
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                altnames: ['example.com', 'www.example.com'],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // dns-01 challenge
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                challenges: {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    'dns-01': {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        module: 'acme-dns-01-namedotcom',
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        apikey: 'xxxx'
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            };
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 04:05:54 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-30 16:52:16 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return site;
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 04:05:54 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    };
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								};
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-30 16:52:16 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								### Customer Manager, Complete
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								See < https: // git . rootprojects . org / root / greenlock-manager-test . js #quick -start > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-29 03:20:10 -06:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# ACME Challenge Plugins
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								The ACME challenge plugins are just a few simple callbacks:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    `init`  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    `zones`  (dns-01 only) 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    `set`  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    `get`  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    `remove`  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								They are described here:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    [dns-01 documentation ](https://git.rootprojects.org/root/acme-dns-01-test.js ) 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    [http-01 documentation ](https://git.rootprojects.org/root/acme-http-01-test.js ) 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# Key and Cert Store Plugins
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Again, these are just a few simple callbacks:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    `certificates.checkKeypair`  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    `certificates.check`  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    `certificates.setKeypair`  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    `certificates.set`  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    `accounts.checkKeypair`  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    `accounts.check`  (optional) 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    `accounts.setKeypair`  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    `accounts.set`  (optional) 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								The name `check`  is used instead of `get`  because they only need to return something if it exists. They do not need to fail, nor do they need to generate anything.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								They are described here:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-    [greenlock store documentation ](https://git.rootprojects.org/root/greenlock-store-test.js ) 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								If you are just implenting in-house and are not going to publish a module, you can also do some hack things like this: