# Overview

Nginx-LE provides a docker container and tools to create an Nginx web server that automatically acquires and renews HTTPS certificates.

## Nginx-LE

Nginx-LE provides a docker container and tools to create an Nginx web server that automatically acquires and renews HTTPS certificates.

Nginx-LE uses the LetsEncrypt CLi tool, Certbot, to acquire and renew certificates.

Nginx-LE ships as a Docker image which you can use with Docker or Docker Compose.

You can optionally use Nginx-LE CLi tooling which allows you to configure and build Nginx-LE containers in a couple of seconds.

Nginx-LE is suitable for production systems, internal infrastructure and even when a developer needs a web server on their local machine.

This documentation tends to use the terms LetsEncrypt and Certbot somewhat interchangeably.

## Sponsored by OnePub

Help support Nginx-LE by supporting [OnePub](https://onepub.dev/drive/12368288-d545-4889-9c40-c0c1466d7073), the private Dart repository.&#x20;

OnePub allows you to privately share Dart packages across your Team and with your customers.

Try it for free and publish your first private package in seconds.

| ![](/files/fopu3C1In2oklc72uDal) | <p>Publish a private package in five commands:</p><p><mark style="color:green;"><code>dart pub global activate onepub</code></mark></p><p><mark style="color:green;"><code>onepub login</code></mark></p><p><mark style="color:green;"><code>cd \<my package></code></mark></p><p><mark style="color:green;"><code>onepub pub private</code></mark> </p><p><mark style="color:green;"><code>dart pub publish</code></mark></p> |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |

Nginx-LE supports both public-facing web servers and private (internal) web servers such as those used by individual developers.

The key advantages of Nginx-LE are:

* automatic certificate acquisition and renewal
* no down time when renewing certificates
* for Public facing servers, works with any DNS server
* support for wildcard certificates
* makes it easy for a developer to acquire a live certificate.

### Automatic renewal

Nginx-LE supports the automatic renewal of both Public and Private Web Servers.

### No downtime.

Nginx-LE is able to renew a certificate WITHOUT taking your web server offline.

Nginx-LE leaves your web server fully operational whilst it acquires or renews a certificate. After acquiring or renewing a certificate Nginx-LE performs an Nginx `reload` command which is close to instantaneous.


# Prerequisites

To obtain a Lets Encrypt certificate you must have a public DNS record for your host.

To obtain a Lets Encrypt certificate you must have a public DNS record for your host.

For a production web server this isn't a problem as it will already meet the prerequisites.

For an internal private web server such as those used for running internal infrastructure or an individual developers PC this can be a little tricker.

For a private web server you will still need to create a public DNS A record.

For a private web server we need to do DNS authentication which means that you need to be using a DNS provider from list of DNS providers that Nginx-LE supports.

The simplest way to do this is to acquire the cheapest domain name that you can find. Host the domain name with Cloudflare (host is free for the volumes involved).

For each developer or internal web server create a DNS A record. The IP address you use in the DNS A record does NOT have to be a public IP address. You can just use any private IP address. I would suggest that you don't use any of your real internal ip addresses to avoid exposing information about your internal network.

Now that you have a DNS A record are ready to acquire live certificates.


# Cli commands

## Nginx-LE cli tooling

Nginx-LE provides optional cli tooling to manage your Nginx-LE instance.

The cli tooling is based on dart and the DCli library.

To install the cli tooling:

(If you already have dart installed you can go straight to step 3.)

1. Install dcli [install guide](https://github.com/bsutton/dcli/wiki/Installing-DCli)
2. Restart your terminal
3. Activate Nginx-LE

`pub global activate nginx_le`

On linux this amounts to:

```
sudo apt-get update
sudo apt-get install --no-install-recommends -y wget ca-certificates gnupg2
wget https://github.com/noojee/dcli/releases/download/latest-linux/dcli_install -O dcli_install
chmod +x dcli_install
export PATH="$PATH":"$HOME/.pub-cache/bin":"$HOME/.dcli/bin"
./dcli_install
pub global activate nginx_le
```

The DCli installer also installs dart (if its not already installed).

The Nginx-LE cli exposes the following commands:

| Command | Description                                           | Comment                                                                                                                                                                                        |
| ------- | ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| build   | Builds the docker image.                              | Only required if you need to customise the code the image runs on.                                                                                                                             |
| config  | Configures nginx-le and creates the docker container. | You must run config before you can run any other commands (except build).                                                                                                                      |
| start   | Starts nginx-le                                       | Starts the nginx-le docker container                                                                                                                                                           |
| restart | Restarts nginx-le                                     | Restarts the docker container                                                                                                                                                                  |
| stop    | Stops nginx-le                                        | Stops the docker container.                                                                                                                                                                    |
| acquire | Acquires or renews a Lets Encrypt certificate         | The method used to acquire a certificate depends on the Auth Provider selected when you ran `nginx-le config`. If you are using the AUTO\_ACQUIRE mode then this action happens automatically. |
| revoke  | Revokes the current Lets Encrypt certificate          | Full certificate revocation. You need to run revoke/acquire if you change the type of certificate between production and staging.                                                              |
| cli     | Attaches you to the Docker container in a bash shell. | Play inside the nginx-le docker container.                                                                                                                                                     |
| logs    | Tails various logs in the container                   |                                                                                                                                                                                                |

Example of running Nginx-LE command

```
nginx-le config
```


# build

## Building Nginx-LE

Most users of Nginx-LE will never need to run a build. The build tooling is primarily used by the Nginx-LE development team and if you need to customize the code that underpins the Nginx-LE docker image.

When do you need to use the build command?

| Method                               | Build Required | Usage                                                                                                                                                    |
| ------------------------------------ | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Customise nginx or the Nginx-LE code | Yes            | Get your hands dirty and modify the core of Nginx-LE.                                                                                                    |
| Extend the Image                     | Maybe          | Create your own Dockerfile based on Nginx-LE. You can use the standard docker tools to build the image if you aren't modifying any of the Nginx-LE code. |
| Serve static content                 | No             | Mount a volume with your static content into /opt/nginx/wwwroot                                                                                          |
| Configure your own Location(s)       | No             | Add nginx compatible `.location` files under /opt/nginx/include                                                                                          |
| Configure as Proxy                   | No             | Add nginx compatible `.location` and `.upstream` files under /opt/nginx/include                                                                          |
| Docker-compose                       | No             | Add Nginx-LE as a service in a docker-compose.yaml file.                                                                                                 |

For details on creating or modifying the docker file see [Create aDockerfile](https://github.com/bsutton/nginx-le#create-a-dockerfile)

To build the Nginx-LE image run:

```
git clone https://github.com/bsutton/nginx-le.git
nginx-le build --image=<repo/image:version>
```

### Switches

The build command takes a number of switches.

#### image

The required `--image` switch sets the docker image/tag name (repo/image:version) for the image.

e.g. --image=noojee/nginx-le:1.0.0

The switch can be abbreviated to `-i`.

#### update-dcli

The optional flag `--update-dcli` causes the build to pull the latest version of dart/dcli rather than using the docker cache instance.

You only need to add this switch if you have an existing build and you need to update the dcli/dart version.

#### debug

The optional flag `--debug` outputs additional build information.

The flag can be abbreviated to `-d`.

##


# config

## Configure Nginx-LE

Use the `nginx-le config` command to configure you Nginx-LE container.

When you run config, Nginx-LE will destroy and create a new container with the new settings.

When running `nginx-le config` you will prompted to answer a no. of questions

### FQDN

Enter the fully qualified domain name of your nginx-le host.

e.g. [www.noojee.com.au](http://www.noojee.com.au)

### TLD

Enter the top level domain (TLD) for your nginx-le host.

Examples

| FQDN                                          | TLD    |
| --------------------------------------------- | ------ |
| [www.noojee.com.au](http://www.noojee.com.au) | com.au |
| [www.noojee.org](http://www.noojee.org)       | org    |

### Mode

Enter the web servers mode. This is either public or private.

A public web server is one that can be reached (directly or via NAT etc) via a public ip address.&#x20;

A private web server is one that can only be reached via a private ip address.

### Wildcard or FQDN

Nginx-le allows you to acquire a wild card certificate (\*.noojee.com.au) or a FQDN certificate ([www.noojee.com.au).\&#x20](http://www.noojee.com.au\).\&#x20);

You should only use a wild card certificates if you have multiple web servers running of the same domain.&#x20;

{% hint style="info" %}
Certbot normally expects you to manually distribute wildcard certificates within your own organisations so the wild card option is only usable with nginx-le in limited circumstances.
{% endhint %}

### Production/Staging

Lets you choose the type of certificate to acquire.

Select production to get a production certificate.

Select staging to get a staging/test certificate.&#x20;

Use this staging option if you are destroying/recreating your web server during testing. Certbot has hard limits on the no. of production certificates you can acquire per day (5 per day) where you can get a far larger no. of staging certificates.

### Auth Providers

To acquire a LetsEncrypt certificate you must be able to prove that you own the domain for which the certificate is being issued.

Nginx-LE supports a number of Certbot Authentication methods (Auth Providers).

| Auth Provider | Usage Case                                                                   | Description                                                                                                                                                 |
| ------------- | ---------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| HTTP01Auth    | For a public web server using a FQDN certificate.                            | Your web server must be accessible on a public ip address. This is the simplest form of validation as it works with any DNS provider. Port 80 must be open. |
| cloudflare    | For public and private web servers. Supports FQDN and wildcard certificates. | The most flexible auth provider, your DNS must be hosted with Cloudflare.                                                                                   |
| namecheap     | For public and private web servers. Supports FQDN and wildcard certificates. | Not recommended. The namecheap api is dangerous and currently limited to domains that have no more than 10 A records.                                       |

### Content Provider

The configure command lets you set how the content is to be served.

Nginx-LE supports four types of Content Providers

| Provider      | Description                                                                                                                                                                       |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Static        | Serve static web content from a local folder.                                                                                                                                     |
| Generic Proxy | Pass requests through to a Web Application server that can respond to HTTP requests. This is normally on the same host as the Nginx-LE server as the connection is not encrypted. |
| Tomcat Proxy  | Pass requests to a local Tomcat web application server on port 8080.                                                                                                              |
| Custom        | Allows you to configure your own Nginx location and upstream settings.                                                                                                            |

#### Static Content Provider

The static Content Provider allows you to serve static content from a local directory (e.g. index.html)

The Static Content Provider will request the path to your static content and the default html file.

#### Generic Proxy Content Provider

The Generic proxy Content Provider allows you to proxy requests through to a web application server.

The Nginx-LE container exposes the secure HTTPS connection and then passes all requests through to your web application server via HTTP.

Please note that normally you need to select a port other than 80 as Nginx-LE needs to accept requests on port 80 for certificate acquisition and renewals.

#### Tomcat Proxy Content Provider

Designed to work with the java based Tomcat Web application Server.

The Tomcat proxy allows you to configure the port and context the Tomcat server operates on.

#### Custom Content Provider

The [Custom Content Provider](/custom-content-providers) allows you to configure your own Location and Upstream files.

### Location of nginx include files

By default nginx-le configures nginx to look for files in `/opt/nginx/include` on the host system. Change the path to have nginx-le load the include files from a different directory.

### Paused Mode

The start paused option is mainly used by the Nginx-LE team for diagnosing startup issues.

When you place Nginx-LE into start paused mode it will not start the nginx server nor attempt to acquire a certificate.

Once you start Nginx-LE in paused mode you can attach to the Nginx-LE docker container and explore its configuration.

You can connect to the Nginx-LE container (even when not in paused mode) by running `nginx-le cli`.

### Errors are notified via email

Enter an email address where errors are emailed to.

### SMTP Server

The FQDN of your SMTP Server which will be used to notify errors.

### SMTP Server Port

The Port of your SMTP Server which will be used to notify errors.

### Start Method

Select the method by which you are going to start Nginx-LE

| Method           | Description                                                                                                                           |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| nginx-le start   | The simplest method. `nginx-le config` will create a container. Use `nginx-le start` and `nginx-le stop` to start/stop the container. |
| docker start/run | nginx-le config will create a container. Use docker start and docker stop to start/stop the container.                                |
| docker-compose   | `docker-compose up` will create and start the container. See the section on [docker-compose](/docker-compose) for details             |

The `config` command saves each of the entered settings so that you don't have to pass them when running other commands.

### Select the nginx-le image

Allows you to choose which version of nginx-le docker image to run. Mostly you should choose 'latest'.

###

###


# start

## Starting Nginx-LE

If you are using the Nginx-LE cli tools then before starting Nginx-LE you must first run `nginx-le config`.

If you are not using the Nginx-LE cli tools then follow the standard docker, docker-compose processes.

To start the Nginx-LE container run:

```
nginx-le start
```

However you start Nginx-LE, when you first start the Nginx-LE container it won't have a certificate.

If you have set AUTO\_ACQUIRE=true then Nginx-Le will automatically acquire a certificate.

If you have set AUTO\_ACQUIRE=false then when Nginx-LE detects that it doesn't have a valid certificate it will enter certificate acquisition mode.

In this mode it will display a default 'Certificate Acquisition Required' home page with instructions on obtaining a certificate.

You then need to run the `nginx-le acquire` command.


# acquire

The acquire command allows you to acquire a certificate.

The acquire command is mainly used by the nginx-le team, you should normally configure nginx-le to auto acquire certificates.

Possible usages:

* you have had to revoke a certificate and need to force a new certificate to be acquired. In this case use the `nginx-le revoke` command followed by then `nginx-le acquire` command.
* an error occurred during auto acquisition and acquisitions have been blocked by nginx-le for 15 minutes. Running `nginx-le acquire` clears the block flag.

To acquire a certificate use `nginx-le acquire` command:

e.g.

`nginx-le acquire`

Note: The `acquire` command can take upto 5 minutes + to acquire a certificate due to delays in DNS propagation but is normally much quicker.

If you have rolled your own Docker or docker-compose configuration then you can still use the cli tools if you first run `nginx-le config`.

If you can't use the Nginx-LE cli tools then you can still use the 'in-container' tools.

To manually run the internal acquire command first attached to the Nginx-LE container and then run `acquire`.

```
nginx-le cli
acquire
```

Once you have run `acquire` Nginx-LE will automatically renew certificates.


# certificates

The certificates command displays the list of certificates and their current status.


# cli

The cli command attaches you to the nginx-le docker container's cli. You can then explore the container and run any of the internal nginx-le commands.


# doctor

Display details about the current nginx-le environment.

When reporting a bug you should include the output of `nginx-le doctor`.


# logs

The logs command lets you tail one or more of the nginx-le logs.


# renew

Runs a renew on the certificate. This should normally be unnecessary as renewal checks are schedule every 13 hours.


# restart

Restarts the nginx-le container.


# revoke

Revokes the active Lets Encrypt certificate and places the server into manual acquire mode.

The revoke command should rarely be needed an is used in the event that a certificate has been hacked.

After running revoke you should run acquire to acquire a new certificate.


# stop

Stops the nginx-le container.


# docker-compose

## Start with docker-compose

May users deploy their docker containers using docker-compose. In these circumstances using the Nginx-LE cli tools may not be appropriate.

This is the case for most production systems, in which case you will just use the standard docker management tools.

Whilst it can be useful to run `nginx-le config,` it is not required and for most users won't be needed.

If you want to use any of the nginx-le commands you MUST first run:

* `docker-compose up` at least once
* `nginx-le config`.

Note: If you do use `nginx-le config` then if you change your dock-compose configuration, docker-compose will recreate the container. When this occurs you MUST re-run `nginx-le config` and select the new container.

To start Nginx-LE with docker-compose you must provide a number of configuration settings:

The following is a sample configuration:

```
version: '3.3'
volumes:
  certificates:

services:   
  nginx-le:
    container_name: nginx-le
    image: noojee/nginx-le:latest
    restart: on-failure
    ports:
      - "80:80"
      - "443:443"
    network_mode: "host"
    environment: 
      HOSTNAME: www
      DOMAIN: example.com.au
      TLD: com.au
      DOMAIN_WILD_CARD: "false"
      PRODUCTION: "true"
      EMAIL_ADDRESS: support@example.com
      AUTO_ACQUIRE: "true"
      DEBUG: "true"
      AUTH_PROVIDER: cloudflare
      AUTH_PROVIDER_TOKEN: XXXXXXX
      AUTH_PROVIDER_EMAIL_ADDRESS: XXX@XXXXX
      SMTP_SERVER: smtp.someserver.com
      SMTP_SERVER_PORT: 25
    volumes:
      - certificates:/etc/letsencrypt
      - /opt/nginx/include:/etc/nginx/include
    logging:
      driver: "journald"
```

The environment variables for the Auth Provider will change based on which Auth Provider you have selected.

### Volumes

The `certificates` volume is used to store the certbot certificates between restarts. The `/opt/nginx/include` host path is where you place the nginx `.location` and `.upstream` includes.

#### Acquire a certificate

If you set the environment variable AUTO\_ACQUIRE=true then Nginx-LE will automatically acquire and renew certificates as required.

If you don't pass the AUTO\_ACQUIRE environment variable or set it to false than you must manually acquire a certificate (using nginx-le acquire).

{% hint style="info" %}
We strongly recommend using AUTO\_ACQUIRE and don't know of any valid reason why you would not.
{% endhint %}


# Certificate management

Nginx-le automates the acquisition and renewal of certificates. However we also provide cli tooling to let you directly control certificate acquisition. The cli commands are primarily used by the nginx-le team to test nginx-le.

When configuring nginx-le you need to select the correct Certbot Auth provider based on:

1\) public or private web server

2\) your dns provider (for a private web server)

A public web server is one that is accessible on the web with a public ip address.

A private web server is one that is only visible on your internal private network.

## Acquiring/Renewing certificates

### Public Mode

Public mode is only suitable for web servers which are directly accessible on the internet.

To be considered directly accessible it MUST:

* Be able to accept requests on a public IP address.
* Both port 80 and 443 must be exposed on the above public IP address.

The public access can be via a NAT, proxy or other suitable mechanism.

If your Nginx-LE web server is in public mode then you can use the HTTP01Auth Auth Provider method unless you need a wildcard.

If you need to acquire a wild card certificate (\*.nginx.com) then you must use one of the DNS auth methods.

There is no specific setting required on the Nginx-LE container for public mode, it simply limits which Auth Providers you can choose from.

### Private Mode

Private mode is only suitable for any web servers but some Auth Providers don't support Private Mode servers.

A Private mode web server is one that doesn't isn't accessible from the public internet. A development, test or internal web server will typically be private.

A Private web server must still have port 443 open (but only visible locally -be that your dev PC or your office network) however port 80 is not required.

If your Nginx-LE web server is in private mode then you can NOT use the HTTP01Auth method. You must use one of the DNS Auth Providers.

You will still need to have a valid DNS entry for your web server on a public DNS provider that is supported by one of Nginx-LE's DNS Auth Providers.

The IP address of the DNS A record does not need to be valid and can be a private IP address. The IP address is not used.


# Staging (test) certificates

Lets Encrypt puts fairly tight constraints on the number of times you can request a certificate for a given domain (5 per day).

During testing we recommend that you use a Lets Encrypt staging certificate as the limits are much higher.

You can select a staging certificate via the `nginx-le config` command or setting the `PRODUCTION` environment variable to false when creating your docker container.


# Certificate volume

Nginx-LE stores certificates on a persistent volume which by convention is called `certificates`.

The `certificates` folder is mounted into the container at `/etc/letsencrypt/`.

It is critical that this is a persistent volume otherwise Nginx-LE will need to acquire a new certificate every time it starts.

`nginx-le config` will automatically create the volume but if you are using docker-compose or creating your own docker container you must create a persistent volume called `certificates`.

Lets Encrypt have hard limits (5 per day) on the no. of certificates you can acquire so if you don't have a persistent volume you will very quickly breach this limit.


# Customise Nginx-le container

In some circumstances it may be required that you modify the standard Nginx-LE docker container.

This section details the internal structure of the docker image and what the hard requirements are.

By default the Nginx-LE ships with the following configuration files:

The base nginx configuration is defined by:

* /etc/nginx/nginx.conf
* /etc/nginx/custom/defaults.conf

The `nginx.conf` is the first configuration file that nginx loads which then chain loads the `default.conf` file which in turn loads our standard `.location` and `.upstream` files.

If you are happy with the standard configuration you can simply add `.location` and `.upstream`files under `/opt/nginx/include` which is normally done via a persistent volume but you could directly include these files in your own custom nginx-le container.

You can also replace the `/etc/nginx/custom/default.conf` with your own customised defaults.

NOTE: if you replace `default.conf` you MUST include a `./well-known` location for lets-encrypt to work:

```
  # lets encrypt renewal path
    location ^~ /.well-known {
      allow all;
      root  /opt/letsencrypt/wwwroot;
    }
```

The nginx-le container REQUIRES that you have a default.conf file in:

* /etc/nginx/custom/default.conf

If you need complete control over nginx then you can also replace the `/etc/nginx/nginx.conf` file.

If you modify the `/etc/nginx/nginx.conf` it must include the following lines:

* daemon off;
* user nginx;
* include /etc/nginx/live/default.conf

Changing any of the above settings will cause nginx-le to fail.

### What's with this 'live' directory

The `nginx.conf` loads its configuration from the `/etc/nginx/live/defaults.conf` file.

However the above instructions dictate that you put your `default.conf` in `/etc/nginx/operating/defaults.conf`

Note: the difference `operating` vs `live`.

At runtime Nginx-LE pulls its configuration from the `live` directory.

On startup, if you have a valid certificate,  the `live` directory is symlinked to your `/etc/nginx/custom` directory.

If you don't have a valid certificate, the `live` directory is symlinked to the `/etc/nginx/acquire` folder and Nginx-LE is placed into acquisition mode.

The `acquire` path contains a single `index.html` page informing users that a certificate needs to be acquired. In this mode no other content will be served and only requests from certbot will be processed.

Normally nginx-le will initially start in the acquire mode whilst it acquires a certificate for the first time. Once it has acquired a certificate then transitions to its standard operating mode.

If you have configured nginx-le to not auto acquire a certificate it stays in this mode until you run `nginx-le acquire`.

It's important to note here that we do this because when nginx has been configured to start an HTTPS service, `nginx` will not start if you don't have a valid certificate.  The acquisition mode starts `nginx` as  an HTTP only service to avoid nginx shutting down.

Once a valid certificate has been acquired `nginx-le` switches the `live` symlink back to `/etc/nginx/custom` and does a `nginx` reload and your site is online.


# Diagnosing problems

If you are having problems with nginx-le we provide some hints and solutions to common problems.

## Welcome to nginx!

When you connect to nginx-le you get the nginx welcome page rather than your actual web site.

Nginx-le typically uses two configuration files that tell nginx-le how to connect to your web server.


# Environment variables

Nginx-le uses environment variables to configure your docker container when it is created.

#### nginx-le config

When using `nginx-le config` it will automatically create the required environment variables when creating a container for you. As such you don't need to set any of these variables.

#### docker-compose

When using docker-compose you need to configure each environment variable in your docker-compose file. See the [docker-compose](/docker-compose) section for more details.

#### docker

If you are manually creating your docker container then you will need to set each environment variable before you create your docker container.&#x20;

{% hint style="info" %}
These environment variables are only needed when your container is being created. You do not need to set them when running an existing container.
{% endhint %}

Nginx-LE uses the following environment variables to control the operation of the container:

<table data-header-hidden><thead><tr><th width="196.81767180925667">Name</th><th width="150">Type</th><th width="163">Domain</th><th>Description</th></tr></thead><tbody><tr><td>Name</td><td>Type</td><td>Domain</td><td>Description</td></tr><tr><td>DEBUG</td><td>bool</td><td>true|false</td><td>Controls the logging level of Nginx-LE.</td></tr><tr><td>HOSTNAME</td><td>String</td><td>A valid host name</td><td>The host name of the web server. e.g. www</td></tr><tr><td>DOMAIN</td><td>String</td><td>A valid domain name</td><td>The domain name of the web server. e.g. microsoft.com.au</td></tr><tr><td>TLD</td><td>String</td><td>Top level domain name</td><td>The top level domain name of the web server. e.g. com.au</td></tr><tr><td>EMAIL_ADDRESS</td><td>String</td><td>valid email address</td><td>The email address that errors are sent to and also passed to Certbot which will use the email address to send renewal reminders to.</td></tr><tr><td>PRODUCTION</td><td>bool</td><td>true|false</td><td>True to use a 'production' certbot certificate. False will acquire a Staging (test) certificate. We recommend that you set this to false during testing.</td></tr><tr><td>DOMAIN_WILDCARD</td><td>bool</td><td>true |false</td><td>Controls whether we acquire a single FQDN certificate or a domain wildcard certificate. Set to true to obtain a wild card domain. If you use this option on a number of servers which use the same domain then you will quickly hit the Certbot rate limits.</td></tr><tr><td>AUTO_ACQUIRE</td><td>bool</td><td>true|false</td><td>Defaults to true. If true Nginx-LE will automatically acquire a certificate.</td></tr><tr><td>AUTH_PROVIDER</td><td>String</td><td>HTTP01Auth | cloudflare | namecheap</td><td>Select the Certbot Authentication method.</td></tr><tr><td>SMTP_SERVER</td><td>String</td><td>FQDN or IP</td><td>The FQDN or IP of the SMTP server Nginx-LE is to use to send error emails via. Currently we only support email servers that don't require authentication.</td></tr><tr><td>SMTP_SERVER_PORT</td><td>int</td><td>Port no.</td><td>Defaults to 25, The tcp port no.of the SMTP server Nginx-LE is to use to send error emails via.</td></tr><tr><td>START_PAUSED</td><td>bool</td><td>true |false</td><td>If true then the docker container will start but it won't try to start nginx or acquire a certificate. This mode is intended to help diagnose startup problems. Use nginx-le cli to attach to the container.</td></tr><tr><td>AUTH_PROVIDER_TOKEN</td><td>String</td><td>Auth Provider token</td><td>If the Auth Provider requires a TOKEN then this will be used to hold it.</td></tr><tr><td>AUTH_PROVIDER_USERNAME</td><td>String</td><td>Auth Provider username</td><td>If the Auth Provider requires a username then this will be used to hold it.</td></tr><tr><td>AUTH_PROVIDER_PASSWORD</td><td>String</td><td>Auth Provider password</td><td>If the Auth Provider requires a password then this will be used to hold it.</td></tr><tr><td>AUTH_PROVIDER_EMAIL_ADDRESS</td><td>String</td><td>Auth Provider Email Address</td><td>If the Auth Provider requires an email address that differs from <code>EMAIL_ADDRESS</code> then this will be used to hold it. If not passed the value contained in EMAIL_ADDRESS will be used.</td></tr><tr><td>CERTBOT_IGNORE_BLOCK</td><td>bool</td><td>true|false</td><td>If an error occurs when attempting to acquire a certificate, a flag file (block_acquisitions.flag<strong>)</strong> is written into /etc/letsencrypt to stop further auto acquisition attempts. This is done to avoid hitting Certbot rate limits which can occur if we keep retrying due to a permanent failure. If you are are sure you deployments never fail and don't want temporary errors to stop auto acquisition then you can pass this environment variable (with a value of true) in which case the normal auto acquisition will occur regardless of the existence of the flag. The block flag file automatically times out after 15 minutes. Running 'nginx-le acquire' also clears the block flag.</td></tr></tbody></table>


# Internal Environment Variables

Nginx-LE uses a no. of internal environment variables primarily to communicate with Auth providers. You do not normally need to worry about these as the Nginx-LE sets these as necessary based on the selected Auth Provider.

| Name                           | Type   | Domain                                                                                                                                                                                                          | Description                                                                                                                                                        |
| ------------------------------ | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| LOG\_FILE                      | String | Path                                                                                                                                                                                                            | The name of the logfile that certbot writes to. We also redirect the auth providers to write to this log file.                                                     |
| CERTBOT\_ROOT\_PATH            | String | Path                                                                                                                                                                                                            | Path to the letsencrypt root directory which defaults to: `/etc/letsencrypt`. You don't normally need to alter this. Its primary purpose is for Unit Testing.      |
| CERTBOT\_VERBOSE               | String | true \| false                                                                                                                                                                                                   | Used by the `acquire` command to control the log level of the Certbot Auth and Cleanup hooks.                                                                      |
| CERTBOT\_AUTH\_HOOK\_PATH      | String | Path                                                                                                                                                                                                            | Path to the auth\_hook script provided as part of nginx-le. The auth hook is called by certbot at the start of an attempt to acquire or renew a certificate.       |
| CERTBOT\_CLEANUP\_HOOK\_PATH   | String | Path                                                                                                                                                                                                            | Path to the cleanup\_hook script provided as part of nginx-le. The cleanup hook is called by certbot when completing an attempt to acquire or renew a certificate. |
| CERTBOT\_DEPLOY\_HOOK          | String | Path to the deploy\_hook script provided as part of nginx-le. The deploy hook is called by certbot to deploy certificates into nginx. Its is only called when a certificate is sucessfully renewed or acquired. |                                                                                                                                                                    |
| DNS\_RETRIES                   | int    | Integer                                                                                                                                                                                                         | The number of times the DNS Auth Hook will check the DNS for the required TXT record.                                                                              |
| NGINX\_CERT\_ROOT\_OVERWRITE   | String | Path                                                                                                                                                                                                            | Only used for Unit Testing. Sets the path where certbot saves certificates to.                                                                                     |
| NGINX\_ACCESS\_LOG\_PATH       | String | Path                                                                                                                                                                                                            | Path to the Nginx access.log file in the container.                                                                                                                |
| NGINX\_ERROR\_LOG\_PATH        | String | Path                                                                                                                                                                                                            | Path to the Nginx error.log file in the container                                                                                                                  |
| NGINX\_LOCATION\_INCLUDE\_PATH | String | Path                                                                                                                                                                                                            | Path of the .location and .upstream files.                                                                                                                         |

### Certbot environment variables.

Certbot sets a number of environment variables during the auth process to communicate to the Auth and Cleanup hooks. You don't need to set this but if you are writing a custom auth or cleanup hook they are available to the hook.

| Name                | Type   | Domain               | Description                                                                                                                                                                                                                  |
| ------------------- | ------ | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| CERTBOT\_TOKEN      | String | Filename             | Used only by HTTP01Auth. This is the name of the file that the CERTBOT\_VALIDATION string must be written into e.g. .well-known/acme-challenge/$CERTBOT\_TOKEN                                                               |
| CERTBOT\_VALIDATION | String | Generated by Certbot | This is the validation string Certbot generates to verify ownership of your domain. For DNS Auth Providers this is written into a TXT record on your DNS server. For HTTP01Auth this is written int the CERTBOT\_TOKEN file. |
| CERTBOT\_DOMAIN     | String | Domain name          | Will be the same as DOMAIN but required by Certbot                                                                                                                                                                           |


# Auth Providers

Nginx-LE supports a number of auth providers. Each auth provider has its on method of configuration.

### HTTP01 Auth

This is the default Certbot authentication method and only works if your web server is exposed on a public IP address with ports 80 and 443 open.

HTTP01 Auth does not support wildcard certificates.

Set the following environment variables:

AUTH\_PROVIDER=HTTP01Auth

DOMAIN\_WILDCARD=false

### Namecheap

We don't recommend using this provider.

The Namecheap API is very crappy and requires that we update EVERY dns record to just modify a single record.

It is also currently limited to domains that have no more than 10 A records. This could be fixed by changing the request from a HTTP GET to a POST but unfortunately Namecheap hasn't documented the POST method.

AUTH\_PROVIDER=namecheap

AUTH\_PROVIDER\_TOKEN=name cheap Api Key

AUTH\_PROVIDER\_USERNAME=name cheap username

DOMAIN\_WILDCARD=true|false

### Cloudflare

This is the most versatile auth provider as it supports public and private websites as well as Wildcard and single FQDN certificates.

NOTE: currently we only support using a cloudflare global access token. A restricted API token will NOT WORK. This is due to ubuntu 20.04 using an old version of certbot. When a newer version is available we will upgrade to support the restricted access token.

AUTH\_PROVIDER=cloudflare

AUTH\_PROVIDER\_TOKEN=api token for cloudflare

AUTH\_PROVIDER\_EMAIL\_ADDRESS=email address used to acquire api token

DOMAIN\_WILDCARD=true|false

##


# Contributing


# Testing

Nginx-LE uses the [critical\_test](https://pub.dev/packages/critical_test) and [DCli](https://pub.dev/packages/dcli) package to run unit tests.

You should have both of these installed before you start testing.

```dart
pub global activate critical_test
pub global activate dcli
dcli install
```

Critical tests provides the ability to setup a no. of pre and post test hooks.

Nginx-LE relies on these hooks to correctly configure the test environment.

In particular the pre test setup hook compiles and installs the auth, deploy and cleanup hooks onto your path (using the DCli path \~/.dcli/bin) before running the tests.

If you can't use critical\_test for some reason then you can directly run the setup script:

```bash
container\tool\critical_test\pre_hook\setup.dart
```

To run the unit tests:

```bash
cd shared
critical_test
cd ../container
critical_test
cd ../cli
critical_test
```


# Releasing nginx-le

## Releasing Nginx-le

If you are involved in developing Nginx-LE you will get to the point where you need to make a release.

Nginx-LE uses the pub\_release package to do simultaneous releases. Pub Release in turn uses the critical\_test package to run the unit tests as part of the release process.

```
pub global activate pub_release
pub global activate critical_test
cd cli

pub_release multi
```

Select the appropriate version no. when prompted and pub\_release will do the rest.

The cli/tool/pubrelease\_multi.yaml file controls the order the packages are published in.

Pub Release will release each of the three packages and also push the docker container.

### release details

The above noted pub\_release process automates each of the below processes.

## Manual Release process

If you want to manually release the packages (not recommended).

There are four components that need to be released

The three dart components:&#x20;

* nginx-le/cli
* nginx-le/container
* &#x20;nginx-le/shared

You must also publish nginx-le/shared first as the other two packages can't be published until the `shared` package is released.

Finally you need to publish the Nginx-LE docker image using:

```
docker push
```


# Custom Content Providers

A Content Provider provides the actual web content (html pages) that nginx-le is to serve.

Nginx-le ship with a number of standard content providers:

* static - serve static HTML content from a local directory.
* generic - proxy a generic HTTP application server.
* tomcat - proxy the tomcat web application server.

If none of the above methods suite your model then you can create your own custom content provider.

{% hint style="info" %}
In most cases you can use the generic option. For example, if you have a PHP or a Ruby web server then simply use one of the standard nginx docker containers for PHP or Ruby and then use the nginx-le 'generic' Content Provider to have nginx-le proxy your docker container.
{% endhint %}

If you select any of the three built in Content Providers nginx-le automatically generates the location and upstream files required by nginx.

A custom Content Provider is simply one that provides its own location and upstream files for nginx.

**Location file**

By default Nginx-le:

* configures Nginx to look for the location files (within the container) in: `/etc/nginx/include/*.location`.
* mounts the host path `/opt/nginx/include` into the container path `/etc/nginx/include`.

When you select Custom Content Provider you need to provide your own location file in `/opt/nginx/include`.

{% hint style="info" %}
location files must be named with a '.location' extension.
{% endhint %}

You can place any number of nginx location files in the `/opt/nginx/include/`host directory and all `*.location` files be mounted the next time that the Nginx-LE container is started or nginx is reloaded.

This is an example location file for proxying the java Tomcat server.

This location file requires an upstream file (see the example below) to be functional.

```
location / {
        #try_files $uri $uri/ =404;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_redirect off;
        proxy_max_temp_file_size 0;
        proxy_pass http://tomcat/mycontext/;
        proxy_read_timeout 300;
}

location /mycontext {
        #try_files $uri $uri/ =404;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_redirect off;
        proxy_max_temp_file_size 0;
        proxy_pass http://tomcat/mycontext/;
        proxy_read_timeout 300;
}
```

**Upstream servers**

If you Nginx-LE needs to proxy your web application server then you will need to provide one or more `.upstream` files to configure the connection to those servers.

{% hint style="info" %}
upstream files must be named with a '.upstream' extension.
{% endhint %}

By default Nginx-LE:

* mounts the host path `/opt/nginx/include` into the container path `/etc/nginx/include`.
* configures Nginx to look for the upstream files (within the container) in: `/etc/nginx/include/*.upstream`.

When you select Custom Content Provider you need to provide your own upstream file in `/opt/nginx/include`.

Nginx-LE will load any `/opt/nginx/include/*.upstream` files from the host system.

You can place any number of nginx upstream files in this directory and they will be mounted the next time that the Nginx-LE container is started or nginx is reloaded.

This is an example upstream file for proxying the java Tomcat server

```
upstream tomcat {
    server 127.0.0.1:8080 fail_timeout=0;
}
```

###


# Custom docker file

In some circumstances it may be required that you modify the standard Dockerfile that Nginx-LE ships with.

This section details the internal structure of the docker image and what the hard requirements are.

By default the Nginx-LE ships with the following configuration files:

The base nginx configuration is defined by:

* /etc/nginx/nginx.conf
* /etc/nginx/operating/defaults.conf

The `nginx.conf` is the first configuration file that nginx loads which then chains the `default.conf` file which in turn loads our standard `.location` and `.upstream` files.

If you are happy with the standard configuration you can simply add `.location` and `.upstream`files under `/opt/nginx/include`.

Otherwise you can replace the `/etc/nginx/operating/default.conf` with your own customised defaults.

NOTE: if you replace `default.conf` you MUST include a `./well-known` location for lets-encrypt to work:

```
  # lets encrypt renewal path
    location ^~ /.well-known {
      allow all;
      root  /opt/letsencrypt/wwwroot;
    }
```

The nginx-le container REQUIRES that you have a default.conf file in:

* /etc/nginx/operating/default.conf

If you need complete control over nginx then you can also replace the `nginx-conf` file.

If you modify the `nginx.conf` it must include the following lines:

* daemon off;
* user nginx;
* include /etc/nginx/live/default.conf

Changing any of the above settings will cause nginx-le to fail.

### What's with this 'live' directory

The `nginx.conf` loads its configuration from the `/etc/nginx/live/defaults.conf` file.

However the above instructions dictate that you put your `default.conf` in `/etc/nginx/operating/defaults.conf`

Note: the difference `operating` vs `live`.

At runtime Nginx-LE pulls its configuration from the `live` directory.

On startup, if you have a valid certificate, the `live` directory is symlinked to your `/etc/nginx/operating` directory.

If you don't have a valid certificate, the `live` directory is symlinked to the `acquire` folder and Nginx-LE is placed into acquisition mode.

The `acquire` path contains a single `index.html` page informing you that a certificate needs to be acquired. In this mode no other content will be served and only requests from certbot will be processed.

This allows `nginx` to start and then `nginx-le` can then you can run the `acquire` command to obtain a valid certificate.

Its important to note here that we do this because `nginx` will not start if you don't have a valid certificate and it has been configured to start a HTTPS service.

Once a valid certificate has been acquired `nginx-le` switches the `live` symlink back to `/etc/nginx/operating` and does a `nginx` reload and your site is online.

##


# Auth Providers

Nginx-LE supports a number of auth providers. Each auth provider has its on method of configuration.

If your web server is public accessible then you should use the [HTTP01 Auth](/auth-providers/http-auth) provider.

###


# HTTP Auth

### HTTP01 Auth

This is the default Certbot authentication method and only works if your web server is exposed on a public IP address with ports 80 and 443 open.

This is the simplest auth provider and requires no configuration. If you are running a public web server then you should use this version.

HTTP01 Auth does not support wildcard certificates.

If you are using docker-compose or creating your own container then you need to set the following environment variable when you are creating the container.

Set the following environment variables:

AUTH\_PROVIDER=HTTP01Auth

DOMAIN\_WILDCARD=false

###


# Cloudflare

This is the most versatile auth provider as it supports public and private websites as well as Wildcard and single FQDN certificates.

NOTE: currently we only support using a cloudflare global access token. A restricted API token will NOT WORK. This is due to ubuntu 20.04 using an old version of certbot. When a newer version is available we will upgrade to support the restricted access token.

Use the following guide to Generate API token:

<https://support.cloudflare.com/hc/en-us/articles/200167836-Managing-API-Tokens-and-Keys#12345680>

If you are using docker-compose or creating your own container then you need to set the following environment variable when you are creating the container.

AUTH\_PROVIDER=cloudflare

AUTH\_PROVIDER\_TOKEN=api token for cloudflare

AUTH\_PROVIDER\_EMAIL\_ADDRESS=email address used to acquire api token

DOMAIN\_WILDCARD=true|false


# Name cheap

We don't recommend using this provider.

The Namecheap API is very crappy and requires that we update EVERY dns record to just modify a single record.

It is also currently limited to domains that have no more than 10 A records. This could be fixed by changing the request from a HTTP GET to a POST but unfortunately Namecheap hasn't documented the POST method.

If you are using docker-compose or creating your own container then you need to set the following environment variable when you are creating the container.

AUTH\_PROVIDER=namecheap

AUTH\_PROVIDER\_TOKEN=name cheap Api Key

AUTH\_PROVIDER\_USERNAME=name cheap username

DOMAIN\_WILDCARD=true|false

###


# Implement an Auth Provider

Certbot requires an Auth Provider to validate the owner of a domain when allocating certificates.

Generally there are two types of auth providers.

1\) the standard http auth mechanism

2\) dns based authentication.

The http auth mechanism is built into nginx-le and is suitable for all public facing websites.

The dns based authentication mechanism is required for private web servers (no public ip address).

For dns authentication you need to be able to create a special dns record for your domain during the certificate acquisition and renewal phases.  This means that you need to use your DNS providers API to create the required DNS entry.&#x20;

Certbot supports a large number of DNS providers:

<https://certbot.eff.org/docs/using.html#dns-plugins>

The problem is that currently nginx-le only supports a limited no. of Certbot Auth Providers.

This guide provide details on implementing additional Certbot Auth Providers (or even full custom providers) into nginx-le.

We would welcome contributions of additional Auth Providers.

You can add a Certbot supported DNS Auth Providers to Nginx-LE with a fairly low effort.

To add a new Auth Providers the following changes would need to be made:

### 1. Update Dockerfile

Modify the Nginx-LE docker file by changing the `apt install` command to include the additional packages required to support the selected Certbot Auth provider.

Find the following section.

```
RUN apt  update && apt install --no-install-recommends -y \
    ca-certificates \
    certbot \
    dnsutils \
    gnupg \
    nginx \
    openssl \
    python3-certbot-dns-cloudflare \
    python3-certbot-nginx \
    software-properties-common \
    tzdata \
    vim
```

Additional packages as required.

### 2. Implement an Auth Provider

We provide a base class AuthProvider. Your new Auth Provider should be derived from this class.

```
shared/lib/src/auth_provider.dart
```

The shared/lib/src/auth\_providers/dns\_auth\_providers/cloudlfare/cloudflare\_provider.dart provider should be a good example to work from.

### 3. Register your new Auth Provider

Add you new auth provider to the AuthProviders class:

shared/lib/src/auth\_providers/auth\_providers.dart

Find this section:

```
  /// Add new auth providers to this list.
  var providers = <AuthProvider>[
    HTTPAuthProvider(),
    NameCheapAuthProvider(),
    CloudFlareProvider()
  ];
```

### 4. Build Nginx-LE

`nginx-le build --image=repo/image:version`

### 5. Run config

Run `nginx-le config` to confirm that you new provider is listed.

### 6. Raise a PR on our github page.

job done.


