SSL Front-End Proxy With Automatic Free Certificate Management
Zero configuration required - set up SSL in 30 seconds. Out of the box A rating at SSL labs. HTTP/2 enabled for increased performance.
This image contains nginx along with some glue code to automatically obtain and renew a free DV SSL certificate from Let's Encrypt.
It is configured by setting two environment variables:
UPSTREAM- The IP address or hostname (and optional port) of the upstream server to proxy requests towards.
SERVERNAME- The hostname to listen to. The system will automatically obtain an SSL certificate for this hostname.
EXTRANAMES variable can be provided with a list of additional domains to request as subject-alternative-names for the certificate.
Certificates from Let's Encrypt are issued with a 90 day expiration. This image will automatically renew the certificate when it is 60 days old.
Prior versions of this image used simp_le. It has been changed to use certbot due to reliability issues with simp_le.
WARNING - HSTS Strict-Transport-Security Header
This image's default configuration includes a
Strict-Transport-Security header with expiry set to 1 year. Visitors' browsers will cache this header and will refuse to connect except over SSL. Eventually, you may wish to have your domain included in browser HSTS Preload lists.
This header can be customized with the
HSTS_HEADER variable. If set to
skip, no HSTS header will be used. If set to any other value, the value of the
HSTS_HEADER variable will be used as the header's value. e.g. to prepare for HSTS preload, you could set
max-age=31536000; includeSubDomains; preload.
Example Use (via docker-compose)
Create a docker-compose.yml file as follows:
nginx-ssl-proxy: image: danieldent/nginx-ssl-proxy restart: always environment: UPSTREAM: 127.0.0.1:8080 SERVERNAME: test.example.com EXTRANAMES: www.test.example.com,test2.example.com ports: - "80:80" - "443:443" volumes: - "/etc/letsencrypt"
Optional: Enable Simple Authentication
DO_AUTH environment variable is set to
required, the proxy implements a simple authentication system.
A user meeting any of these three criteria will be allowed access to the proxied service:
- Users coming from an IP or CIDR range listed in the space-separated
- Users presenting a cookie named
magic_ssl_proxy_authset to the value of the
- Users providing HTTP Basic Authentication credentials, username
adminwith a password matching the
A user that correctly authenticates with HTTP Basic Authentication will have their
magic_ssl_proxy_auth cookie set so that they are not required to re-authenticate.
By default, no IPs are whitelisted. When authentication is enabled, the
PROXY_PASSWORD values will be chosen randomly if they are not provided. If randomly chosen, the randomly chosen values will be output to the console during container startup. The
PROXY_PASSWORD value will also be available in the
/tmp/proxy_password file within the container, while the chosen
COOKIE_VALUE will be available in the
Nginx limits the length of your
COOKIE_VALUE for performance reasons. If your
COOKIE_VALUE is too long, nginx will refuse to start and will display errors relating to
server_names_hash_max_size. If you have difficulties, try decreasing the legnth of your cookie or add directives to your Nginx configuration to increase the maximum size.
Optional: Use upstream
When configuring IP based authentication, be mindful that upstream reverse proxies and your Docker configuration may result in an apparent source IP that does not match the client's true IP address. Directly exposing this image to the internet (e.g. via the
ports directive as in the above example) will remove one source of potential problems with IP based authentication.
REAL_IP_RECURSIVE environment variable to
on to cause Nginx to parse & use upstream
The list of IPs or CIDR ranges from which Nginx will trust the
X-Forwarded-For variable can be specified in the
As a convenience, setting
yes will cause Cloudflare's reverse proxy source IP addresses to be appended to the provided
Optional: Adjust request size limits & buffer size
NGINX_CLIENT_BODY_BUFFER_SIZE variables can be used to set nginx's
client_body_buffer_size directives. This is most commonly required when users are uploading files to the proxied service.
NGINX_CLIENT_MAX_BODY_SIZE set to
100m, nginx will allow a maximum body size of 100 megabytes. When requests are larger than
client_body_buffer_size, nginx buffers the request using a temporary file. A larger
client_body_buffer_size will use more memory, but will also reduce disk I/O. In many scenarios, a larger buffer size will result in increased performance. Different tradeoffs will be appropriate for different environments and use cases.
Optional: Add Arbitrary Nginx Config
/etc/nginx/main_location.conf file provides a place to add arbitrary Nginx configuration directives to the main location block in the Nginx configuration file. The file is empty and can be safely overwritten in a downstream image or using a Docker volume.
/etc/letsencrypt volume is used to maintain certificate data. An
account_key.json file holds the key to your Let's Encrypt account - which provides a convenient way to revoke a certificate.
Nginx configuration can be customized by editing proxy.conf and placing a new copy of it at
FROM danieldent/nginx-ssl-proxy COPY proxy.conf /etc/nginx/conf.d/default.conf
Reasonable defaults have been chosen for SSL cipher suites using Mozilla's Recommendations. Very old browsers (such as IE6) will be unable to connect with the default settings.
Reasonable defaults have been chosen with an eye towards a configuration which is more secure by default. See https://www.owasp.org/index.php/List_of_useful_HTTP_headers for more information on the headers used. These headers can be disabled by setting the
SECURITY_HEADERS variable to
skip. If your upstream server is itself sending these headers, setting the
SECURITY_HEADERS variable will avoid the presence of multiple instances of these headers in responses.
- nginx - proxy server
- certbot - for handling certificate creation & validation (+ some wrappers in this image)
- envplate - for allowing use of environment variables in Nginx configuration
- s6-overlay - for PID 1, process supervision, zombie reaping
If you run into any problems with this image, please check for issues on GitHub. Please file a pull request or create a new issue for problems or potential improvements.
Copyright 2015-2018 Daniel Dent.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use these files except in compliance with the License. You may obtain a copy of the License at
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Third-party contents included in builds of the image are licensed separately.