diff --git a/.env.sample b/.env.sample index aa68c748..cc05fc81 100644 --- a/.env.sample +++ b/.env.sample @@ -1,87 +1,146 @@ +#----------------------------------------------------------------------- # -# docker-compose-letsencrypt-nginx-proxy-companion +# https://github.com/evertramos/nginx-proxy-automation # -# A Web Proxy using docker with NGINX and Let's Encrypt -# Using the great community docker-gen, nginx-proxy and docker-letsencrypt-nginx-proxy-companion +# NGINX Proxy automation # -# This is the .env file to set up your webproxy enviornment - -# -# Your local containers NAME +# This is the .env file to set up nginx-proxy in your environment # -NGINX_WEB=nginx-web -DOCKER_GEN=nginx-gen -LETS_ENCRYPT=nginx-letsencrypt +#----------------------------------------------------------------------- +#----------------------------------------------------------------------- # -# Set the IP address of the external access Interface +# Script requirements # -IP=0.0.0.0 +# PID file the running script +PID_FILE=.fresh_start.pid + +# Allow run commands with sudo if needed +ALLOW_RUN_WITH_SUDO=false + +#----------------------------------------------------------------------- # -# Default Network +# NGINX-Proxy containers/service # -NETWORK=webproxy +# The variables below is used to set the containers name for the nginx-proxy +# and the image version for each service, please note that if you use our script +# we will replace the service name in docker-compose file with the container name +# +NGINX_WEB_SEVICE_NAME=proxy-web +NGINX_IMAGE_VERSION=stable-alpine + +DOCKER_GEN_SEVICE_NAME=docker-gen +DOCKER_GEN_IMAGE_VERSION=latest -# If you want to customize the created network, use the following variable -#NETWORK_OPTIONS="--opt encrypted=true" +LETS_ENCRYPT_SEVICE_NAME=letsencrypt-companion +NGINX_PROXY_COMPANION_IMAGE_VERSION=2.0 +#----------------------------------------------------------------------- # -# Service Network (Optional) +# IP address of the external interface # -# In case you decide to add a new network to your services containers you can set this -# network as a SERVICE_NETWORK +# The IP address below is used to bind your local services to the internet +# please make sure you use the correct address otherwise your proxy will not +# work properly, '0.0.0.0' will work, but we recommend to update this variable # -# [WARNING] This setting was built to use our `start.sh` script or in that special case -# you could use the docker-composer with our multiple network option, as of: -# `docker-compose -f docker-compose-multiple-networks.yml up -d` +IPv4=0.0.0.0 +IPv6=::0 + +#----------------------------------------------------------------------- # -#SERVICE_NETWORK=webservices +# Default network name +# +# The network name set below is used by the proxy to forward internet requests +# to the correct containers in your environment, so please make sure to add this +# network in all docker containers, otherwise it will break the proxy redirection +# +NETWORK=proxy -# If you want to customize the created network, use the following variable -#SERVICE_NETWORK_OPTIONS="--opt encrypted=true" +#----------------------------------------------------------------------- +# +# Data path for the nginx-proxy files +# +# The variable below will be used to place all files used by the nginx-proxy +# please consider including this folder to your backup services, once all config +# files, settings and certificates will be placed here in case you need to recover +# +NGINX_FILES_PATH=./data +#----------------------------------------------------------------------- +# +# Docker logging settings # -## NGINX file path (mount into the host) -# Here you can configure the path where nginx stores all the configurations and certificates. -# With the value ./nginx-data it creates a new sub-folder into your current path. +# Logs! Very important, right? But if you do not clean it up, it might causes you +# issues on disk space over time, so keep in mind to set this log options making sure +# you will have the least to audit, any further information on that please check the docs +# +# https://docs.docker.com/config/containers/logging/configure/ +# +NGINX_WEB_LOG_DRIVER=json-file +NGINX_WEB_LOG_MAX_SIZE=4m +NGINX_WEB_LOG_MAX_FILE=10 + +NGINX_GEN_LOG_DRIVER=json-file +NGINX_GEN_LOG_MAX_SIZE=2m +NGINX_GEN_LOG_MAX_FILE=10 -NGINX_FILES_PATH=./nginx-data +NGINX_LETSENCRYPT_LOG_DRIVER=json-file +NGINX_LETSENCRYPT_LOG_MAX_SIZE=2m +NGINX_LETSENCRYPT_LOG_MAX_FILE=10 +#----------------------------------------------------------------------- # -# NGINX use special conf files +# Docker ports that should be binded by the proxy # -# In case you want to add some special configuration to your NGINX Web Proxy you could -# add your files to ./conf.d/ folder as of sample file 'uploadsize.conf' +# This option were added by a contributor long ago, so might be a very specific case +# where you might need to change http and https port number, keep in mind that changes +# on that setting might will break the auto renewing Let's Encrypt certificate services # -# [WARNING] This setting was built to use our `start.sh`. +DOCKER_HTTP_=80 +DOCKER_HTTPS=443 + +#----------------------------------------------------------------------- # -# [WARNING] Once you set this options to true all your files will be copied to data -# folder (./data/conf.d). If you decide to remove this special configuration -# you must delete your files from data folder ./data/conf.d. +# SSL policy (defaults to Mozilla-Intermediate) # -#USE_NGINX_CONF_FILES=true - +# This also was added by a contributor which sets the default cipher configuration +# to the nginx-proxy container, which has the 'Mozilla-Intermediate' as default value +# plase make sure you take a good look at options in the url below before messing around +# +# https://github.com/nginx-proxy/nginx-proxy#how-ssl-support-works # -# Docker Logging Config +#SSL_POLICY=Mozilla-Modern + +#----------------------------------------------------------------------- # -# This section offers two options max-size and max-file, which follow the docker documentation -# as follow: +# Let's Encrypt default email # -# logging: -# driver: "json-file" -# options: -# max-size: "200k" -# max-file: "10" +# You might want to inform a default email to Let's Encrypt certificate once it is +# a required parameter in order to issue the new certificate. This information will be +# replaced by the LETSENCRYPT_EMAIL environment varibale present in your docker container # -#NGINX_WEB_LOG_DRIVER=json-file -#NGINX_WEB_LOG_MAX_SIZE=4m -#NGINX_WEB_LOG_MAX_FILE=10 +DEFAULT_EMAIL=mail@yourdomain.tld -#NGINX_GEN_LOG_DRIVER=json-file -#NGINX_GEN_LOG_MAX_SIZE=2m -#NGINX_GEN_LOG_MAX_FILE=10 +#----------------------------------------------------------------------- +# +# Default host +# +# Nginx-proxy will then redirect all requests to a container where you have set +# "VIRTUAL HOST" set to "DEFAULT HOST", if they don't match any (other) container +# You might want to check the link below for more information: +# https://github.com/nginx-proxy/nginx-proxy#default-host +# +DEFAULT_HOST= -#NGINX_LETSENCRYPT_LOG_DRIVER=json-file -#NGINX_LETSENCRYPT_LOG_MAX_SIZE=2m -#NGINX_LETSENCRYPT_LOG_MAX_FILE=10 +#----------------------------------------------------------------------- +# +# Docker Rootless +# +# In case you want to use this proxy on Docker Rootless (DR) and you also have followed +# the DR installation from the official documentation (https://docs.docker.com/engine/security/rootless/) +# Set the following value of the DOCKER_HOST variable that you got in the final info messages after executing +# the "$ dockerd-rootless-setuptool.sh install" command. +# For example DOCKER_HOST_PATH=$XDG_RUNTIME_DIR/docker.sock +# If you are not using Docker Rootless, leave this variable blank +DOCKER_HOST_ROOTLESS_PATH= \ No newline at end of file diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 02c29f97..3d96aaea 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,9 +1,16 @@ -### Contributions +## Contributions -All contributions regarding the `nginx.tmpl` should be suggested or implemented in the [nginx-proxy repository](https://raw.githubusercontent.com/jwilder/nginx-proxy). +### NGINX template file (nginx.tmpl) + +All contributions regarding the `nginx.tmpl` should be suggested or implemented in the [nginx-proxy repository](https://github.com/nginx-proxy/nginx-proxy). We always use the latest version of this file: [https://raw.githubusercontent.com/jwilder/nginx-proxy/master/nginx.tmpl](https://raw.githubusercontent.com/jwilder/nginx-proxy/master/nginx.tmpl) +### Pull requests + +Sometimes it's better to start a discussion or an issue to find out the best solution of suggestion before sending a pull request... and if you do so, please test it with the automation script before sending new code. + + Thanks! diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..298fd08e --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,13 @@ +# These are supported funding model platforms + +github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: evertramos +open_collective: # nginx-proxy-automation +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] + diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index d05935ae..00000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,15 +0,0 @@ -# Error description: - - -# Steps to reproduce - - -# Expected result - - -# Error result - - -# Comments - - diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..925b4449 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,39 @@ +--- +name: Bug report +about: Create a report to help us improve +title: "[BUG]" +labels: '' +assignees: evertramos + +--- + +**Check [Discussions](https://github.com/evertramos/nginx-proxy-automation/discussions) to see if there is an answer might help you before opening an issue** + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If the error is in one of the scripts, an screen show will help a lot to identify which part of the script the error occurred. + +**Server info (please complete the following information):** + - Linux release: [e.g. Ubuntu 20.10] + - Server type [e.g. vps, Raspberry Pi] + - Docker version [e.g. 20.10] + - docker-compose version [e.g. 1.27] + +**Logs (please send some logs):** + - nginx container + - letsencrypt container (if related to ssl) + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..6c0a675d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: evertramos + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/README.md b/.github/README.md index 96c91a5e..0d8daba8 100644 --- a/.github/README.md +++ b/.github/README.md @@ -1,256 +1,88 @@ -# Web Proxy using Docker, NGINX and Let's Encrypt -With this repo you will be able to set up your server with multiple sites using a single NGINX proxy to manage your connections, automating your apps container (port 80 and 443) to auto renew your ssl certificates with Let´s Encrypt. +# NGINX Proxy Automation 🔥 -Something like: +

+ + + +

+

+ +

-![Web Proxy environment](https://github.com/evertramos/images/raw/master/webproxy.jpg) +

+ +

+## How to start 🔰 +[![shell script](https://img.shields.io/badge/Shell_Script-121011?style=for-the-badge&logo=gnu-bash&logoColor=white)](https://github.com/evertramos) -## Why use it? -Using this set up you will be able start a production environment in a few seconds. For each new web project simply start the containers with the option `-e VIRTUAL_HOST=your.domain.com` and you will be ready to go. If you want to use SSL (Let's Encrypt) just add the tag `-e LETSENCRYPT_HOST=your.domain.com`. Done! - -Easy and trustworthy! - - -## Prerequisites - -In order to use this compose file (docker-compose.yml) you must have: - -1. docker (https://docs.docker.com/engine/installation/) -2. docker-compose (https://docs.docker.com/compose/install/) - - -## How to use it - -1. Clone this repository: - -```bash -git clone https://github.com/evertramos/docker-compose-letsencrypt-nginx-proxy-companion.git -``` - -2. Make a copy of our `.env.sample` and rename it to `.env`: - -Update this file with your preferences. - -``` -# -# docker-compose-letsencrypt-nginx-proxy-companion -# -# A Web Proxy using docker with NGINX and Let's Encrypt -# Using the great community docker-gen, nginx-proxy and docker-letsencrypt-nginx-proxy-companion -# -# This is the .env file to set up your webproxy enviornment - -# -# Your local containers NAME -# -NGINX_WEB=nginx-web -DOCKER_GEN=nginx-gen -LETS_ENCRYPT=nginx-letsencrypt - -# -# Set the IP address of the external access Interface -# -IP=0.0.0.0 - -# -# Default Network -# -NETWORK=webproxy - -# If you want to customize the created network, use the following variable -#NETWORK_OPTIONS="--opt encrypted=true" - -# -# Service Network (Optional) -# -# In case you decide to add a new network to your services containers you can set this -# network as a SERVICE_NETWORK -# -# [WARNING] This setting was built to use our `start.sh` script or in that special case -# you could use the docker-composer with our multiple network option, as of: -# `docker-compose -f docker-compose-multiple-networks.yml up -d` -# -#SERVICE_NETWORK=webservices - -# If you want to customize the created network, use the following variable -#SERVICE_NETWORK_OPTIONS="--opt encrypted=true" - -# -## NGINX file path (mount into the host) -# Here you can configure the path where nginx stores all the configurations and certificates. -# With the value ./nginx-data it creates a new sub-folder into your current path. - -NGINX_FILES_PATH=./nginx-data - -# -# NGINX use special conf files -# -# In case you want to add some special configuration to your NGINX Web Proxy you could -# add your files to ./conf.d/ folder as of sample file 'uploadsize.conf' -# -# [WARNING] This setting was built to use our `start.sh`. -# -# [WARNING] Once you set this options to true all your files will be copied to data -# folder (./data/conf.d). If you decide to remove this special configuration -# you must delete your files from data folder ./data/conf.d. -# -#USE_NGINX_CONF_FILES=true - -# -# Docker Logging Config -# -# This section offers two options max-size and max-file, which follow the docker documentation -# as follow: -# -# logging: -# driver: "json-file" -# options: -# max-size: "200k" -# max-file: "10" -# -#NGINX_WEB_LOG_DRIVER=json-file -#NGINX_WEB_LOG_MAX_SIZE=4m -#NGINX_WEB_LOG_MAX_FILE=10 - -#NGINX_GEN_LOG_DRIVER=json-file -#NGINX_GEN_LOG_MAX_SIZE=2m -#NGINX_GEN_LOG_MAX_FILE=10 - -#NGINX_LETSENCRYPT_LOG_DRIVER=json-file -#NGINX_LETSENCRYPT_LOG_MAX_SIZE=2m -#NGINX_LETSENCRYPT_LOG_MAX_FILE=10 -``` - -3. Run our start script - -```bash -./start.sh -``` - -Your proxy is ready to go! - -## Starting your web containers - -After following the steps above you can start new web containers with port 80 open and add the option `-e VIRTUAL_HOST=your.domain.com` so proxy will automatically generate the reverse script in NGINX Proxy to forward new connections to your web/app container, as of: +1. Clone this repository using the option **_--recurse-submodules_** ⚠️ ```bash -docker run -d -e VIRTUAL_HOST=your.domain.com \ - --network=webproxy \ - --name my_app \ - httpd:alpine +git clone --recurse-submodules https://github.com/evertramos/nginx-proxy-automation.git proxy ``` -To have SSL in your web/app you just add the option `-e LETSENCRYPT_HOST=your.domain.com`, as follow: - -```bash -docker run -d -e VIRTUAL_HOST=your.domain.com \ - -e LETSENCRYPT_HOST=your.domain.com \ - -e LETSENCRYPT_EMAIL=your.email@your.domain.com \ - --network=webproxy \ - --name my_app \ - httpd:alpine -``` - -> You don´t need to open port *443* in your container, the certificate validation is managed by the web proxy. - - -> Please note that when running a new container to generate certificates with LetsEncrypt (`-e LETSENCRYPT_HOST=your.domain.com`), it may take a few minutes, depending on multiples circumstances. - -## Further Options - -1. Basic Authentication Support - -In order to be able to secure your virtual host with basic authentication, you must create a htpasswd file within `${NGINX_FILES_PATH}/htpasswd/${VIRTUAL_HOST}` via: - -```bash -sudo sh -c "echo -n '[username]:' >> ${NGINX_FILES_PATH}/htpasswd/${VIRTUAL_HOST}" -sudo sh -c "openssl passwd -apr1 >> ${NGINX_FILES_PATH}/htpasswd/${VIRTUAL_HOST}" -``` - -> Please substitute the `${NGINX_FILES_PATH}` with your path information, replace `[username]` with your username and `${VIRTUAL_HOST}` with your host's domain. You will be prompted for a password. - -2. Using multiple networks - -If you want to use more than one network to better organize your environment you could set the option `SERVICE_NETWORK` in our `.env.sample` or you can just create your own network and attach all your containers as of: +We use submodule for [basescript](https://github.com/evertramos/basescript) +2. 🚀 Run the script 'fresh_start.sh' from the _./proxy/bin_ folder + ```bash -docker network create myownnetwork -docker network connect myownnetwork nginx-web -docker network connect myownnetwork nginx-gen -docker network connect myownnetwork nginx-letsencrypt +cd proxy/bin && ./fresh-start.sh --yes -e your_email@domain --skip-docker-image-check ``` -3. Using different ports to be proxied +Update the email above with your real e-mail address -If your service container runs on port 8545 you probably will need to add the `VIRTUAL_PORT` environment variable to your container, in the `docker-compose.yml`, as of: +3. 🧪 Test the proxy ```bash -parity - image: parity/parity:v1.8.9 - [...] - environment: - [...] - VIRTUAL_PORT: 8545 +docker run -dit -e VIRTUAL_HOST=your.domain.com --network=proxy --name test-web httpd:alpine ``` - -Or as of below: - -```bash -docker run [...] -e VIRTUAL_PORT=8545 [...] -``` - -## Testing your proxy with scripts preconfigured - -1. Run the script `test.sh` informing your domain already configured in your DNS to point out to your server as follow: - -```bash -./test_start_ssl.sh your.domain.com -``` - or simply run: - ```bash -docker run -dit -e VIRTUAL_HOST=your.domain.com --network=webproxy --name test-web httpd:alpine +./test.sh your.domain.com ``` -Access your browser with your domain! +Use your own domain name when testing this proxy and make sure your DNS is correctly configured. -To stop and remove your test container run our `stop_test.sh` script: +## Video Tutorial 🎥 -```bash -./test_stop.sh -``` +I made a tutorial video to walk you through this project: -Or simply run: +[![youtube](https://img.shields.io/badge/YouTube-FF0000?style=for-the-badge&logo=youtube&logoColor=white)](https://www.youtube.com/channel/UCN5wb0eA3ZLlvJNYo23qBRQ) -```bash -docker stop test-web && docker rm test-web -``` +### AWS EC2 +

+ +

+ +### Digital Ocean Droplet +

+ +

-## Production Environment using Web Proxy and Wordpress +### OVH +

+ +

-1. [docker-wordpress-letsencrypt](https://github.com/evertramos/docker-wordpress-letsencrypt) -2. [docker-portainer-letsencrypt](https://github.com/evertramos/docker-portainer-letsencrypt) -3. [docker-nextcloud-letsencrypt](https://github.com/evertramos/docker-nextcloud-letsencrypt) +## Server Automation 🚀 -In this repo you will find a docker-compose file to start a production environment for a new wordpress site. +Make user you try our [Server Automation](https://github.com/evertramos/server-automation) -## Credits +[https://github.com/evertramos/server-automation](https://github.com/evertramos/server-automation) -Without the repositories below this webproxy wouldn´t be possible. +## Further information 📓 -Credits goes to: -- nginx-proxy [@jwilder](https://github.com/jwilder/nginx-proxy) -- docker-gen [@jwilder](https://github.com/jwilder/docker-gen) -- docker-letsencrypt-nginx-proxy-companion [@JrCs](https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion) +For more installation details please [click here](/docs/). +## Supporting ♥️ +[![Patreon](https://img.shields.io/badge/Patreon-F96854?style=for-the-badge&logo=patreon&logoColor=white)](https://www.patreon.com/evertramos) +[![image](https://img.shields.io/badge/picpay-21C25E?style=for-the-badge&logo=picpay&logoColor=white)](https://picpay.me/evert.ramos) -### Special thanks to: +[List of all supporters](https://github.com/evertramos/evertramos/blob/main/pages/supporters.md). -- [@j7an](https://github.com/j7an) - Many contributions and the ipv6 branch! -- [@buchdag](https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion/pull/226#event-1145800062) -- [@fracz](https://github.com/fracz) - Many contributions! +## Code Contributors +[](https://opencollective.com/nginx-proxy-automation) diff --git a/.gitignore b/.gitignore index 9b5908d6..6a749cb5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ data .env* !.env.sample .DS_Store +.idea/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..d68568a7 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "basescript"] + path = basescript + url = https://github.com/evertramos/basescript.git diff --git a/LICENSE b/LICENSE index 54376ba9..5248c724 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2017 Evert Ramos +Copyright (c) Evert Ramos Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/basescript b/basescript new file mode 160000 index 00000000..d223a5f4 --- /dev/null +++ b/basescript @@ -0,0 +1 @@ +Subproject commit d223a5f41324f163baa793de6b8b221cdad84b58 diff --git a/bin/.env b/bin/.env new file mode 100644 index 00000000..3438caf5 --- /dev/null +++ b/bin/.env @@ -0,0 +1,60 @@ +#----------------------------------------------------------------------- +# +# https://github.com/evertramos/nginx-proxy-automation +# +# NGINX Proxy automation +# +# This is the .env file with default values for the nginx-proxy-automation script +# +#----------------------------------------------------------------------- + +#----------------------------------------------------------------------- +# +# NGINX-Proxy default image, version and service name +# +DEFAULT_NGINX_PROXY_SERVICE_NAME=proxy-web +DEFAULT_NGINX_PROXY_IMAGE_NAME="nginx" +DEFAULT_NGINX_PROXY_IMAGE_VERSION="stable-alpine" + +#----------------------------------------------------------------------- +# +# Docker-gen default image, version and service name +# +DEFAULT_DOCKER_GEN_SERVICE_NAME=docker-gen +DEFAULT_DOCKER_GEN_IMAGE_NAME="nginxproxy/docker-gen" +DEFAULT_DOCKER_GEN_IMAGE_VERSION="0.9" + +#----------------------------------------------------------------------- +# +# Letsencrypt-nginx-proxy-companion default image, version and service name +# +DEFAULT_LETSENCRYPT_SERVICE_NAME=letsencrypt-companion +DEFAULT_LETSENCRYPT_IMAGE_NAME="nginxproxy/acme-companion" +DEFAULT_LETSENCRYPT_IMAGE_VERSION="2.2" + +#----------------------------------------------------------------------- +# +# Network default name for the nginx-proxy +# +DEFAULT_DOCKER_NETWORK_NAME=proxy + +#----------------------------------------------------------------------- +# +# Data path for the nginx-proxy files +# +#DEFAULT_DATA_LOCATION="./data" + +#----------------------------------------------------------------------- +# +# Default servies name in docker-compose.yml +# +REPLACE_NGINX_PROXY_SERVICE_NAME="nginx-proxy-automation-web" +REPLACE_DOCKER_GEN_SERVICE_NAME="nginx-proxy-automation-gen" +REPLACE_LETSENCRYPT_SERVICE_NAME="nginx-proxy-automation-letsencrypt" + +#----------------------------------------------------------------------- +# +# md5 checksum for .env and docker-compose.yml files +# +MD5_SUM_DOCKER_COMPOSE=54590c26c4f3d0ce52ef9ea4268d1408 +MD5_SUM_ENV_SAMPLE=c790c227c850cd2be25d1b071f31f6b3 diff --git a/bin/fresh-start.sh b/bin/fresh-start.sh new file mode 100755 index 00000000..e2410b51 --- /dev/null +++ b/bin/fresh-start.sh @@ -0,0 +1,1326 @@ +#!/bin/bash + +#----------------------------------------------------------------------- +# +# Fresh Start script - set up nginx-proxy in a fresh installed server +# +# https://github.com/evertramos/nginx-proxy-automation +# +# Script developed by +# Evert Ramos +# +# Copyright Evert Ramos +# +#----------------------------------------------------------------------- + +# Bash settings (do not mess with it) +shopt -s nullglob globstar + +# Get the script name and its file real path +SCRIPT_PATH="$(dirname "$(readlink -f "$0")")" +SCRIPT_NAME="${0##*/}" + +# Source basescript functions +source $SCRIPT_PATH"/../basescript/bootstrap.sh" + +# Source localscripts +source $SCRIPT_PATH"/localscript/bootstrap.sh" + +# Log +printf "${energy} Start execution '${SCRIPT_PATH}/${SCRIPT_NAME} " +log "Start execution" +log "$@" + +#----------------------------------------------------------------------- +# Process arguments +#----------------------------------------------------------------------- +while [[ $# -gt 0 ]]; do + case "$1" in + -d) + ARG_DATA_LOCATION="${2}" + if [[ $ARG_DATA_LOCATION == "" ]]; then + echoerror "Invalid option for -d" + break + fi + shift 2 + ;; + --data-files-location=*) + ARG_DATA_LOCATION="${1#*=}" + if [[ $ARG_DATA_LOCATION == "" ]]; then + echoerror "Invalid option for --data-files-location=''" + break + fi + shift 1 + ;; + -e) + ARG_DEFAULT_EMAIL="${2}" + if [[ $ARG_DEFAULT_EMAIL == "" ]]; then + echoerror "Invalid option for -e" + break + fi + shift 2 + ;; + --default-email=*) + ARG_DEFAULT_EMAIL="${1#*=}" + if [[ $ARG_DEFAULT_EMAIL == "" ]]; then + echoerror "Invalid option for --default-email=''" + break + fi + shift 1 + ;; + -pn) + ARG_NGINX_PROXY_SERVICE_NAME="${2}" + if [[ $ARG_NGINX_PROXY_SERVICE_NAME == "" ]]; then + echoerror "Invalid option for -pn" + break + fi + shift 2 + ;; + --proxy-name=*) + ARG_NGINX_PROXY_SERVICE_NAME="${1#*=}" + if [[ $ARG_NGINX_PROXY_SERVICE_NAME == "" ]]; then + echoerror "Invalid option for --proxy-name=''" + break + fi + shift 1 + ;; + -ln) + ARG_LETSENCRYPT_SERVICE_NAME="${2}" + if [[ $ARG_LETSENCRYPT_SERVICE_NAME == "" ]]; then + echoerror "Invalid option for -ln" + break + fi + shift 2 + ;; + --letsencrypt-name=*) + ARG_LETSENCRYPT_SERVICE_NAME="${1#*=}" + if [[ $ARG_LETSENCRYPT_SERVICE_NAME == "" ]]; then + echoerror "Invalid option for --letsencrypt-name=''" + break + fi + shift 1 + ;; + -gn) + ARG_DOCKER_GEN_SERVICE_NAME="${2}" + if [[ $ARG_DOCKER_GEN_SERVICE_NAME == "" ]]; then + echoerror "Invalid option for -gn" + break + fi + shift 2 + ;; + --docker-gen-name=*) + ARG_DOCKER_GEN_SERVICE_NAME="${1#*=}" + if [[ $ARG_DOCKER_GEN_SERVICE_NAME == "" ]]; then + echoerror "Invalid option for --docker-gen-name=''" + break + fi + shift 1 + ;; + -piv) + ARG_NGINX_PROXY_IMAGE_VERSION="${2}" + if [[ $ARG_NGINX_PROXY_IMAGE_VERSION == "" ]]; then + echoerror "Invalid option for -pversion" + break + fi + shift 2 + ;; + --proxy-image-version=*) + ARG_NGINX_PROXY_IMAGE_VERSION="${1#*=}" + if [[ $ARG_NGINX_PROXY_IMAGE_VERSION == "" ]]; then + echoerror "Invalid option for --proxy-image-version=''" + break + fi + shift 1 + ;; + -liv) + ARG_LETSENCRYPT_IMAGE_VERSION="${2}" + if [[ $ARG_LETSENCRYPT_IMAGE_VERSION == "" ]]; then + echoerror "Invalid option for -liv" + break + fi + shift 2 + ;; + --letsencrypt-image-version=*) + ARG_LETSENCRYPT_IMAGE_VERSION="${1#*=}" + if [[ $ARG_LETSENCRYPT_IMAGE_VERSION == "" ]]; then + echoerror "Invalid option for --letsencrypt-image-version=''" + break + fi + shift 1 + ;; + -giv) + ARG_DOCKER_GEN_IMAGE_VERSION="${2}" + if [[ $ARG_DOCKER_GEN_IMAGE_VERSION == "" ]]; then + echoerror "Invalid option for -giv" + break + fi + shift 2 + ;; + --docker-gen-image-version=*) + ARG_DOCKER_GEN_IMAGE_VERSION="${1#*=}" + if [[ $ARG_DOCKER_GEN_IMAGE_VERSION == "" ]]; then + echoerror "Invalid option for --docker-gen-image-version=''" + break + fi + shift 1 + ;; + + # Network options + -ip) + ARG_IP_ADDRESS="${2}" + if [[ $ARG_IP_ADDRESS == "" ]]; then + echoerror "Invalid option for -ip" + break + fi + shift 2 + ;; + --ip-address=*) + ARG_IP_ADDRESS="${1#*=}" + if [[ $ARG_IP_ADDRESS == "" ]]; then + echoerror "Invalid option for --ip-address" + break + fi + shift 1 + ;; + -ipv6) + ARG_IPv6_ADDRESS="${2}" + if [[ $ARG_IPv6_ADDRESS == "" ]]; then + echoerror "Invalid option for -ipv6" + break + fi + shift 2 + ;; + --ipv6-address=*) + ARG_IPv6_ADDRESS="${1#*=}" + if [[ $ARG_IPv6_ADDRESS == "" ]]; then + echoerror "Invalid option for --ipv6-address" + break + fi + shift 1 + ;; + -net) + ARG_NETWORK_NAME="${2}" + if [[ $ARG_NETWORK_NAME == "" ]]; then + echoerror "Invalid option for -net" + break + fi + shift 2 + ;; + --network-name=*) + ARG_NETWORK_NAME="${1#*=}" + if [[ $ARG_NETWORK_NAME == "" ]]; then + echoerror "Invalid option for --network-name" + break + fi + shift 1 + ;; + -netopt) + NETWORK_OPTION="${2}" + if [[ $NETWORK_OPTION == "" ]]; then + echoerror "Invalid option for -netopt" + break + fi + shift 2 + ;; + --network-option=*) + NETWORK_OPTION="${1#*=}" + if [[ $NETWORK_OPTION == "" ]]; then + echoerror "Invalid option for --network-option" + break + fi + shift 1 + ;; + + # Log settings + -lpd) + ARG_NGINX_PROXY_LOG_DRIVER="${2}" + if [[ $ARG_NGINX_PROXY_LOG_DRIVER == "" ]]; then + echoerror "Invalid option for -lpd" + break + fi + shift 2 + ;; + --log-nginx-proxy-driver=*) + ARG_NGINX_PROXY_LOG_DRIVER="${1#*=}" + if [[ $ARG_NGINX_PROXY_LOG_DRIVER == "" ]]; then + echoerror "Invalid option for --log-nginx-proxy-driver" + break + fi + shift 1 + ;; + -lpms) + ARG_NGINX_PROXY_LOG_MAX_SIZE="${2}" + if [[ $ARG_NGINX_PROXY_LOG_MAX_SIZE == "" ]]; then + echoerror "Invalid option for -lpms" + break + fi + shift 2 + ;; + --log-nginx-proxy-max_size=*) + ARG_NGINX_PROXY_LOG_MAX_SIZE="${1#*=}" + if [[ $ARG_NGINX_PROXY_LOG_MAX_SIZE == "" ]]; then + echoerror "Invalid option for --log-nginx-proxy-max_size" + break + fi + shift 1 + ;; + -lpmf) + ARG_NGINX_PROXY_LOG_MAX_FILE="${2}" + if [[ $ARG_NGINX_PROXY_LOG_MAX_FILE == "" ]]; then + echoerror "Invalid option for -lpmf" + break + fi + shift 2 + ;; + --log-nginx-proxy-max_file=*) + ARG_NGINX_PROXY_LOG_MAX_FILE="${1#*=}" + if [[ $ARG_NGINX_PROXY_LOG_MAX_FILE == "" ]]; then + echoerror "Invalid option for --log-nginx-proxy-max_file" + break + fi + shift 1 + ;; + -lgd) + ARG_DOCKER_GEN_LOG_DRIVER="${2}" + if [[ $ARG_DOCKER_GEN_LOG_DRIVER == "" ]]; then + echoerror "Invalid option for -lgd" + break + fi + shift 2 + ;; + --log-docker-gen-driver=*) + ARG_DOCKER_GEN_LOG_DRIVER="${1#*=}" + if [[ $ARG_DOCKER_GEN_LOG_DRIVER == "" ]]; then + echoerror "Invalid option for --log-docker-gen-driver" + break + fi + shift 1 + ;; + -lgms) + ARG_DOCKER_GEN_LOG_MAX_SIZE="${2}" + if [[ $ARG_DOCKER_GEN_LOG_MAX_SIZE == "" ]]; then + echoerror "Invalid option for -lgms" + break + fi + shift 2 + ;; + --log-docker-gen-max_size=*) + ARG_DOCKER_GEN_LOG_MAX_SIZE="${1#*=}" + if [[ $ARG_DOCKER_GEN_LOG_MAX_SIZE == "" ]]; then + echoerror "Invalid option for --log-docker-gen-max_size" + break + fi + shift 1 + ;; + -lgmf) + ARG_DOCKER_GEN_LOG_MAX_FILE="${2}" + if [[ $ARG_DOCKER_GEN_LOG_MAX_FILE == "" ]]; then + echoerror "Invalid option for -lgmf" + break + fi + shift 2 + ;; + --log-docker-gen-max_file=*) + ARG_DOCKER_GEN_LOG_MAX_FILE="${1#*=}" + if [[ $ARG_DOCKER_GEN_LOG_MAX_FILE == "" ]]; then + echoerror "Invalid option for --log-docker-gen-max_file" + break + fi + shift 1 + ;; + -lld) + ARG_LETSENCRYPT_LOG_DRIVER="${2}" + if [[ $ARG_LETSENCRYPT_LOG_DRIVER == "" ]]; then + echoerror "Invalid option for -lld" + break + fi + shift 2 + ;; + --log-letsencrypt-driver=*) + ARG_LETSENCRYPT_LOG_DRIVER="${1#*=}" + if [[ $ARG_LETSENCRYPT_LOG_DRIVER == "" ]]; then + echoerror "Invalid option for --log-letsencrypt-driver" + break + fi + shift 1 + ;; + -llms) + ARG_LETSENCRYPT_LOG_MAX_SIZE="${2}" + if [[ $ARG_LETSENCRYPT_LOG_MAX_SIZE == "" ]]; then + echoerror "Invalid option for -llms" + break + fi + shift 2 + ;; + --log-letsencrypt-max_size=*) + ARG_LETSENCRYPT_LOG_MAX_SIZE="${1#*=}" + if [[ $ARG_LETSENCRYPT_LOG_MAX_SIZE == "" ]]; then + echoerror "Invalid option for --log-letsencrypt-max_size" + break + fi + shift 1 + ;; + -llmf) + ARG_LETSENCRYPT_LOG_MAX_FILE="${2}" + if [[ $ARG_LETSENCRYPT_LOG_MAX_FILE == "" ]]; then + echoerror "Invalid option for -llmf" + break + fi + shift 2 + ;; + --log-letsencrypt-max_file=*) + ARG_LETSENCRYPT_LOG_MAX_FILE="${1#*=}" + if [[ $ARG_LETSENCRYPT_LOG_MAX_FILE == "" ]]; then + echoerror "Invalid option for --log-letsencrypt-max_file" + break + fi + shift 1 + ;; + + # Port binginds + -phttp) + ARG_DOCKER_HTTP="${2}" + if [[ $ARG_DOCKER_HTTP == "" ]]; then + echoerror "Invalid option for -phttp" + break + fi + shift 2 + ;; + --port-http=*) + ARG_DOCKER_HTTP="${1#*=}" + if [[ $ARG_DOCKER_HTTP == "" ]]; then + echoerror "Invalid option for --port-http" + break + fi + shift 1 + ;; + -phttps) + ARG_DOCKER_HTTPS="${2}" + if [[ $ARG_DOCKER_HTTPS == "" ]]; then + echoerror "Invalid option for -phttps" + break + fi + shift 2 + ;; + --port-https=*) + ARG_DOCKER_HTTPS="${1#*=}" + if [[ $ARG_DOCKER_HTTPS == "" ]]; then + echoerror "Invalid option for --port-https" + break + fi + shift 1 + ;; + + # SSL Policy + -sp) + ARG_SSL_POLICY="${2}" + if [[ $ARG_SSL_POLICY == "" ]]; then + echoerror "Invalid option for -sp" + break + fi + shift 2 + ;; + --ssl-policy=*) + ARG_SSL_POLICY="${1#*=}" + if [[ $ARG_SSL_POLICY == "" ]]; then + echoerror "Invalid option for --ssl-policy" + break + fi + shift 1 + ;; + + # Docker rootless support + -dr) + USE_DOCKER_ROOTLESS=true + shift 1 + ;; + --docker-rootless) + USE_DOCKER_ROOTLESS=true + shift 1 + ;; + + # IPv4 options + --ipv4-subnet=*) + ARG_IPv4_SUBNET="${1#*=}" + if [[ $ARG_IPv4_SUBNET == "" ]]; then + echoerror "Invalid option for --ipv4-subnet" + break + fi + shift 1 + ;; + # IPv6 options + --ipv6-subnet=*) + ARG_IPv6_SUBNET="${1#*=}" + if [[ $ARG_IPv6_SUBNET == "" ]]; then + echoerror "Invalid option for --ipv6-subnet" + break + fi + shift 1 + ;; + --activate-ipv6) + ACTIVATE_IPV6=true + shift 1 + ;; + + # Default host + -dh) + ARG_DEFAULT_HOST="${2}" + if [[ $ARG_DEFAULT_HOST == "" ]]; then + echoerror "Invalid option for -dh" + break + fi + shift 2 + ;; + --default-host=*) + ARG_DEFAULT_HOST="${1#*=}" + if [[ $ARG_DEFAULT_HOST == "" ]]; then + echoerror "Invalid option for --default-host" + break + fi + shift 1 + ;; + + # Other options + --update-nginx-template) + UPDATE_NGINX_TEMPLATE=true + shift 1 + ;; + --skip-docker-image-check) + SKIP_DOCKER_IMAGE_CHECK=true + shift 1 + ;; + --use-nginx-conf-files) + USE_NGINX_CONF_FILES=true + shift 1 + ;; + --yes) + REPLY_YES=true + shift 1 + ;; + --debug) + DEBUG=true + shift 1 + ;; + --silent) + SILENT=true + shift 1 + ;; + -h | --help) + usage + exit 0 + ;; + *) + echoerror "Unknown argument: $1" false + usage + exit 0 + ;; + esac +done + +#----------------------------------------------------------------------- +# Initial check - DO NOT CHANGE SETTINGS BELOW +#----------------------------------------------------------------------- + +# Check if there is an .env file in local folder +run_function check_local_env_file + +# Specific PID File if needs to run multiple scripts +NEW_PID_FILE=${PID_FILE_FRESH_INSTALL:-".fresh_start.pid"} + +# Run initial check function +run_function starts_initial_check $NEW_PID_FILE + +# Save PID +system_save_pid $NEW_PID_FILE + +# DO NOT CHANGE ANY OPTIONS ABOVE THIS LINE! + +#----------------------------------------------------------------------- +# [function] Undo script actions +#----------------------------------------------------------------------- +local_undo_restore() { + local LOCAL_KEEP_RESTORE_FILES + + LOCAL_KEEP_RESTORE_FILES=${1:-$KEEP_RESTORE_FILES} + + echoerror \ + "It seems something went wrong! \ + \nRunning '${FUNCNAME[0]} to try to UNDO all actions done by this script. \ + \nPlease make sure everything was put it back in place." false + + # If docker network was created + if [[ "$ACTION_DOCKER_NETWORK_CREATED" == true ]]; then + [[ "$SILENT" != true ]] && echowarning "[undo] Deleting created docker network '$DOCKER_NETWORK_NAME'." + run_function docker_network_remove $DOCKER_NETWORK_NAME + ACTION_DOCKER_NETWORK_CREATED=false + fi + + # If docker-compose file was renamed (backup) + if [[ "$ACTION_DOCKER_COMPOSE_FILE_RENAMED" == true ]]; then + [[ "$SILENT" != true ]] && echowarning "[undo] Renaming docker-compose.yml file '$LOCAL_BACKUP_DOCKER_COMPOSE_FILE'." + mv $LOCAL_BACKUP_DOCKER_COMPOSE_FILE "$SCRIPT_PATH/../docker-compose.yml" + ACTION_DOCKER_COMPOSE_FILE_RENAMED=false + fi + + # If .env file was renamed (backup) + if [[ "$ACTION_ENV_FILE_RENAMED" == true ]]; then + [[ "$SILENT" != true ]] && echowarning "[undo] Renaming .env file '$LOCAL_BACKUP_ENV_FILE'." + mv $LOCAL_BACKUP_ENV_FILE "$SCRIPT_PATH/../.env" + ACTION_ENV_FILE_RENAMED=false + fi + + # If docker-compose file was renamed (backup) + if [[ "$ACTION_DOCKER_COMPOSE_FILE_RENAMED" == true ]]; then + [[ "$SILENT" != true ]] && echowarning "[undo] Renaming docker-compose file '$LOCAL_BACKUP_DOCKER_COMPOSE_FILE'." + mv $LOCAL_BACKUP_DOCKER_COMPOSE_FILE "$SCRIPT_PATH/../docker-compose.yml" + ACTION_DOCKER_COMPOSE_FILE_RENAMED=false + fi + + # If the service was stopped try to restart it + if [[ "$ACTION_DOCKER_COMPOSE_STOPPED" == true ]]; then + [[ "$SILENT" != true ]] && echowarning "[undo] Stopping docker-compose service '$SCRIPT_PATH/../'." + run_function docker_compose_start "$SCRIPT_PATH/../" + ACTION_DOCKER_COMPOSE_STOPPED=false + fi + + exit 0 +} + +#----------------------------------------------------------------------- +# [function] Docker images and version check +#----------------------------------------------------------------------- +local_check_docker_hub_image_version() { + local LOCAL_DOCKER_IMAGE_NAME LOCAL_DOCKER_IMAGE_VERSION + + LOCAL_DOCKER_IMAGE_NAME=${1:-null} + LOCAL_DOCKER_IMAGE_VERSION=${2:-null} + + # Check image exists + run_function dockerhub_check_image_exists $LOCAL_DOCKER_IMAGE_NAME + + if [[ "$DOCKERHUB_IMAGE_EXISTS" != true ]]; then + echoerror "It seems the image '$LOCAL_DOCKER_IMAGE_NAME' does not exist in docker hub (https://hub.docker.com) or the site is down. Wait a few minutes and try again." false + local_undo_restore + fi + + # Check if image and version exists in docker hub + run_function dockerhub_check_image_exists $LOCAL_DOCKER_IMAGE_NAME $LOCAL_DOCKER_IMAGE_VERSION + + if [[ "$DOCKERHUB_IMAGE_EXISTS" != true ]]; then + echoerror "It seems the image '$LOCAL_DOCKER_IMAGE_NAME:$LOCAL_DOCKER_IMAGE_VERSION' does not exist in docker hub (https://hub.docker.com) or the site is down. Wait a few minutes and try again." false + local_undo_restore + fi +} + +#----------------------------------------------------------------------- +# Check if the docker compose is already running +#----------------------------------------------------------------------- +LOCAL_DOCKER_COMPOSE_FILE_FULL_PATH="$SCRIPT_PATH/../ " +run_function docker_compose_check_service_exists $LOCAL_DOCKER_COMPOSE_FILE_FULL_PATH + +if [[ "$DOCKER_COMPOSE_SERVICE_EXISTS" == true ]]; then + [[ "$SILENT" != true ]] && echowarning \ + "The services in the docker compose file below is already running: \ + \n'$LOCAL_DOCKER_COMPOSE_FILE_FULL_PATH' \ + \nIf you continue, the services will be stopped and all settings replaced \ + \nif you are uncertain, check your current files settings before continue." + + if [[ "$REPLY_YES" == true ]]; then + LOCAL_STOP_CURRENT_NGINX_PROXY_SERVICES=true + LOCAL_BACKUP_OLD_DOCKER_COMPOSE_FILE=true + else + run_function confirm_user_action "Your services for this project are already running, \ + \nare you sure you want to continue?" + + [[ "$USER_ACTION_RESPONSE" == true ]] && LOCAL_STOP_CURRENT_NGINX_PROXY_SERVICES=true && LOCAL_BACKUP_OLD_DOCKER_COMPOSE_FILE=true + fi +fi + +#----------------------------------------------------------------------- +# Check if the .env file was already configured +#----------------------------------------------------------------------- +run_function check_docker_nginx_proxy_automation_env_file_exits + +# Result from function above +if [[ "$DOCKER_NGINX_PROXY_AUTOMATION_ENV_FILE_EXISTS" == true ]]; then + [[ "$SILENT" != true ]] && echowarning \ + "There is an '.env' file already set to your project, if you continue \ + \nall settings will be replaced, there is no turn back on that, ok?." + + if [[ "$REPLY_YES" == true ]]; then + LOCAL_BACKUP_OLD_ENV_FILE=true + LOCAL_BACKUP_OLD_DOCKER_COMPOSE_FILE=true + else + run_function confirm_user_action "There is an .env file at your proxy folder, \ + \nall settings at will be replaced with new values, \ + \nare you sure you want to continue?" + [[ "$USER_ACTION_RESPONSE" == true ]] && LOCAL_BACKUP_OLD_ENV_FILE=true && LOCAL_BACKUP_OLD_DOCKER_COMPOSE_FILE=true + fi +fi + +#----------------------------------------------------------------------- +# Arguments validation and variables fulfillment +#----------------------------------------------------------------------- + +#----------------------------------------------------------------------- +# NGINX-proxy service/container name +# +# Parameters: -pn | --proxy-name +# +# Final result: +# - NGINX_PROXY_SERVICE_NAME +# +# Further action: +# - LOCAL_STOP_AND_REMOVE_NGINX_PROXY_SERVICE_CONTAINER +#----------------------------------------------------------------------- +LOCAL_DEFAULT_NGINX_PROXY_SERVICE_NAME="proxy-web-auto" +if [[ $ARG_NGINX_PROXY_SERVICE_NAME == "" ]] && [[ ! "$REPLY_YES" == true ]]; then + + # Get user's response + run_function common_read_user_input "Please enter the nginx-proxy service name (default: $LOCAL_DEFAULT_NGINX_PROXY_SERVICE_NAME):" + + LOCAL_NGINX_PROXY_SERVICE_NAME=${USER_INPUT_RESPONSE:-$LOCAL_DEFAULT_NGINX_PROXY_SERVICE_NAME} +else + LOCAL_NGINX_PROXY_SERVICE_NAME=${ARG_NGINX_PROXY_SERVICE_NAME:-$LOCAL_DEFAULT_NGINX_PROXY_SERVICE_NAME} +fi + +# Validate the name +run_function string_remove_all_special_char_string $LOCAL_NGINX_PROXY_SERVICE_NAME "-_" +NGINX_PROXY_SERVICE_NAME=${STRING_REMOVE_ALL_SPECIAL_CHAR_STRING_RESPONSE:-null} +[[ $NGINX_PROXY_SERVICE_NAME == null ]] && echoerror "The service name can not contain special chars, neither be empty" + +# Check exists a container with this name +run_function docker_check_container_exists $NGINX_PROXY_SERVICE_NAME + +if [[ "$DOCKER_CONTAINER_EXISTS" == true ]]; then + # Check if there is a container running with this name + run_function docker_check_container_is_running $NGINX_PROXY_SERVICE_NAME + + if [[ "$DOCKER_CONTAINER_IS_RUNNING" == true ]]; then + [[ "$SILENT" != true ]] && echowarning \ + "The container '$NGINX_PROXY_SERVICE_NAME' is running in this server \ + \nmake sure you have unique names for each container. This script \ + \nmight stop and remove the container if you set '--yes' or reply \ + \n'yes' on the line below, but, there is no turn back on this action!" + + if [[ "$REPLY_YES" == true ]]; then + LOCAL_STOP_AND_REMOVE_NGINX_PROXY_SERVICE_CONTAINER=true + else + run_function confirm_user_action \ + "The container '$NGINX_PROXY_SERVICE_NAME' is running in this server. We will \ + \nstop and REMOVE it, do you want to continue?" + + [[ "$USER_ACTION_RESPONSE" == true ]] && LOCAL_STOP_AND_REMOVE_NGINX_PROXY_SERVICE_CONTAINER=true + fi + else + [[ "$SILENT" != true ]] && echowarning \ + "The container '$NGINX_PROXY_SERVICE_NAME' is exist in this server, but it is not running \ + \nmake sure you have unique names for each container. This script \ + \nmight stop and remove the container if you set '--yes' or reply \ + \n'yes' on the line below, but, there is no turn back on this action!" + + if [[ "$REPLY_YES" == true ]]; then + LOCAL_STOP_AND_REMOVE_NGINX_PROXY_SERVICE_CONTAINER=true + else + run_function confirm_user_action \ + "The container '$NGINX_PROXY_SERVICE_NAME' exist in this server. We will \ + \nREMOVE it, do you want to continue?" + + [[ "$USER_ACTION_RESPONSE" == true ]] && LOCAL_STOP_AND_REMOVE_NGINX_PROXY_SERVICE_CONTAINER=true + fi + # We kept STOP and REMOVE because the stop function will not break the script even if the container isn't running + fi +fi + +#----------------------------------------------------------------------- +# Let's Encrypt service/container name +# +# Parameters: -ln | --letsencrypt-name +# +# Final result: +# - LETSENCRYPT_SERVICE_NAME +# +# Further action: +# - LOCAL_STOP_AND_REMOVE_LETSENCRYPT_SERVICE_CONTAINER +#----------------------------------------------------------------------- +LOCAL_DEFAULT_LETSENCRYPT_SERVICE_NAME="letsencrypt-auto" +if [[ $ARG_LETSENCRYPT_SERVICE_NAME == "" ]] && [[ ! "$REPLY_YES" == true ]]; then + + # Get user's response + run_function common_read_user_input "Please enter the letsencrypt service name (default: $LOCAL_DEFAULT_LETSENCRYPT_SERVICE_NAME):" + + LOCAL_LETSENCRYPT_SERVICE_NAME=${USER_INPUT_RESPONSE:-$LOCAL_DEFAULT_LETSENCRYPT_SERVICE_NAME} +else + LOCAL_LETSENCRYPT_SERVICE_NAME=${ARG_LETSENCRYPT_SERVICE_NAME:-$LOCAL_DEFAULT_LETSENCRYPT_SERVICE_NAME} +fi + +# Validate the name +run_function string_remove_all_special_char_string $LOCAL_LETSENCRYPT_SERVICE_NAME "-_" +LETSENCRYPT_SERVICE_NAME=${STRING_REMOVE_ALL_SPECIAL_CHAR_STRING_RESPONSE:-null} +[[ $LETSENCRYPT_SERVICE_NAME == null ]] && echoerror "The service name can not contain special chars, neither be empty" + +# Check exists a container with this name +run_function docker_check_container_exists $LETSENCRYPT_SERVICE_NAME + +if [[ "$DOCKER_CONTAINER_EXISTS" == true ]]; then + # Check if there is a container running with this name + run_function docker_check_container_is_running $LETSENCRYPT_SERVICE_NAME + + if [[ "$DOCKER_CONTAINER_IS_RUNNING" == true ]]; then + [[ "$SILENT" != true ]] && echowarning \ + "The container '$LETSENCRYPT_SERVICE_NAME' is running in this server \ + \nmake sure you have unique names for each container. This script \ + \nmight stop and remove the container if you set '--yes' or reply \ + \n'yes' on the line below, but, there is no turn back on this action!" + + if [[ "$REPLY_YES" == true ]]; then + LOCAL_STOP_AND_REMOVE_LETSENCRYPT_SERVICE_CONTAINER=true + else + run_function confirm_user_action \ + "The container '$LETSENCRYPT_SERVICE_NAME' is running in this server. We will \ + \nstop and REMOVE it, do you want to continue?" + + [[ "$USER_ACTION_RESPONSE" == true ]] && LOCAL_STOP_AND_REMOVE_LETSENCRYPT_SERVICE_CONTAINER=true + fi + else + [[ "$SILENT" != true ]] && echowarning \ + "The container '$LETSENCRYPT_SERVICE_NAME' is exist in this server, but it is not running \ + \nmake sure you have unique names for each container. This script \ + \nmight stop and remove the container if you set '--yes' or reply \ + \n'yes' on the line below, but, there is no turn back on this action!" + + if [[ "$REPLY_YES" == true ]]; then + LOCAL_STOP_AND_REMOVE_LETSENCRYPT_SERVICE_CONTAINER=true + else + run_function confirm_user_action \ + "The container '$LETSENCRYPT_SERVICE_NAME' exist in this server. We will \ + \nREMOVE it, do you want to continue?" + + [[ "$USER_ACTION_RESPONSE" == true ]] && LOCAL_STOP_AND_REMOVE_LETSENCRYPT_SERVICE_CONTAINER=true + fi + # We kept STOP and REMOVE because the stop function will not break the script even if the container isn't running + fi +fi + +#----------------------------------------------------------------------- +# Docker-gen service/container name +# +# Parameters: -gn | --docker-gen-name +# +# Final result: +# - DOCKER_GEN_SERVICE_NAME +# +# Further action: +# - LOCAL_STOP_AND_REMOVE_DOCKER_GEN_SERVICE_CONTAINER +#----------------------------------------------------------------------- +LOCAL_DEFAULT_DOCKER_GEN_SERVICE_NAME="docker-gen-auto" +if [[ $ARG_DOCKER_GEN_SERVICE_NAME == "" ]] && [[ ! "$REPLY_YES" == true ]]; then + + # Get user's response + run_function common_read_user_input "Please enter the docker-gen service name (default: $LOCAL_DEFAULT_DOCKER_GEN_SERVICE_NAME):" + + LOCAL_DOCKER_GEN_SERVICE_NAME=${USER_INPUT_RESPONSE:-$LOCAL_DEFAULT_DOCKER_GEN_SERVICE_NAME} +else + LOCAL_DOCKER_GEN_SERVICE_NAME=${ARG_DOCKER_GEN_SERVICE_NAME:-$LOCAL_DEFAULT_DOCKER_GEN_SERVICE_NAME} +fi + +# Validate the name +run_function string_remove_all_special_char_string $LOCAL_DOCKER_GEN_SERVICE_NAME "-_" +DOCKER_GEN_SERVICE_NAME=${STRING_REMOVE_ALL_SPECIAL_CHAR_STRING_RESPONSE:-null} +[[ $DOCKER_GEN_SERVICE_NAME == null ]] && echoerror "The service name can not contain special chars, neither be empty" + +# Check exists a container with this name +run_function docker_check_container_exists $DOCKER_GEN_SERVICE_NAME + +if [[ "$DOCKER_CONTAINER_EXISTS" == true ]]; then + # Check if there is a container running with this name + run_function docker_check_container_is_running $DOCKER_GEN_SERVICE_NAME + + if [[ "$DOCKER_CONTAINER_IS_RUNNING" == true ]]; then + [[ "$SILENT" != true ]] && echowarning \ + "The container '$DOCKER_GEN_SERVICE_NAME' is running in this server \ + \nmake sure you have unique names for each container. This script \ + \nmight stop and remove the container if you set '--yes' or reply \ + \n'yes' on the line below, but, there is no turn back on this action!" + + if [[ "$REPLY_YES" == true ]]; then + LOCAL_STOP_AND_REMOVE_DOCKER_GEN_SERVICE_CONTAINER=true + else + run_function confirm_user_action \ + "The container '$DOCKER_GEN_SERVICE_NAME' is running in this server. We will \ + \nstop and REMOVE it, do you want to continue?" + + [[ "$USER_ACTION_RESPONSE" == true ]] && LOCAL_STOP_AND_REMOVE_DOCKER_GEN_SERVICE_CONTAINER=true + fi + else + [[ "$SILENT" != true ]] && echowarning \ + "The container '$DOCKER_GEN_SERVICE_NAME' is exist in this server, but it is not running \ + \nmake sure you have unique names for each container. This script \ + \nmight stop and remove the container if you set '--yes' or reply \ + \n'yes' on the line below, but, there is no turn back on this action!" + + if [[ "$REPLY_YES" == true ]]; then + LOCAL_STOP_AND_REMOVE_DOCKER_GEN_SERVICE_CONTAINER=true + else + run_function confirm_user_action \ + "The container '$DOCKER_GEN_SERVICE_NAME' exist in this server. We will \ + \nREMOVE it, do you want to continue?" + + [[ "$USER_ACTION_RESPONSE" == true ]] && LOCAL_STOP_AND_REMOVE_DOCKER_GEN_SERVICE_CONTAINER=true + fi + # We kept STOP and REMOVE because the stop function will not break the script even if the container isn't running + fi +fi + +#----------------------------------------------------------------------- +# nginx-proxy image version +# +# Parameters: -piv | --proxy-image-version +# +# Final result: +# - NGINX_PROXY_IMAGE_VERSION +#----------------------------------------------------------------------- +LOCAL_DEFAULT_NGINX_PROXY_IMAGE_NAME=${DEFAULT_NGINX_PROXY_IMAGE_NAME:-nginx} +LOCAL_DEFAULT_NGINX_PROXY_IMAGE_VERSION=${DEFAULT_NGINX_PROXY_IMAGE_VERSION:-latest} +# We have commented the lines below once the proxy will use a regular nginx container and it's not optional today +#if [[ $ARG_NGINX_PROXY_IMAGE_VERSION == "" ]] && [[ ! "$REPLY_YES" == true ]]; then +# # Get user's response +# run_function dockerhub_list_tags $LOCAL_DEFAULT_NGINX_PROXY_IMAGE_NAME +# run_function select_one_option "${DOCKERHUB_LIST_TAGS[*]}" "Please select a tag for the image '$LOCAL_DEFAULT_NGINX_PROXY_IMAGE_NAME' (the list below comes from https://hub.docker.com):" +# +# [[ $SELECT_ONE_OPTION_NAME == "" ]] && echowarning "Once you did not select any option, '$LOCAL_DEFAULT_NGINX_PROXY_IMAGE_VERSION' will be used." +# NGINX_PROXY_IMAGE_VERSION=${SELECT_ONE_OPTION_NAME:-$LOCAL_DEFAULT_NGINX_PROXY_IMAGE_VERSION} +#else +NGINX_PROXY_IMAGE_VERSION=${ARG_NGINX_PROXY_IMAGE_VERSION:-$LOCAL_DEFAULT_NGINX_PROXY_IMAGE_VERSION} +#fi +# +#if [[ "$NGINX_PROXY_IMAGE_VERSION" == null ]] || [[ "$LOCAL_DEFAULT_NGINX_PROXY_IMAGE_NAME" == null ]]; then +# echoerror "It seems there is no default image or version, please check the .env file at '$SCRIPT_PATH'" +#fi + +# Final check image a version with dockerhub +#[[ "$SKIP_DOCKER_IMAGE_CHECK" != true ]] && [[ ! "$REPLY_YES" == true ]] && local_check_docker_hub_image_version $LOCAL_DEFAULT_NGINX_PROXY_IMAGE_NAME $NGINX_PROXY_IMAGE_VERSION + +#----------------------------------------------------------------------- +# Let's Encrypt image version +# +# Parameters: -liv | --letsencrypt-image-version +# +# Final result: +# - LETSENCRYPT_IMAGE_VERSION +#----------------------------------------------------------------------- +LOCAL_DEFAULT_LETSENCRYPT_IMAGE_NAME=${DEFAULT_LETSENCRYPT_IMAGE_NAME:-null} +LOCAL_DEFAULT_LETSENCRYPT_IMAGE_VERSION=${DEFAULT_LETSENCRYPT_IMAGE_VERSION:-null} +if [[ $ARG_LETSENCRYPT_IMAGE_VERSION == "" ]] && [[ ! "$REPLY_YES" == true ]]; then + + # ------- + # docker hub api v2 does not allow to get tags from personal repos without login + # @todo - fix this with user login + # ------- + + LETSENCRYPT_IMAGE_VERSION=${LOCAL_DEFAULT_LETSENCRYPT_IMAGE_VERSION} + + + # Get user's response (COMMENTED - TO BE FIXED) +# run_function dockerhub_list_tags $LOCAL_DEFAULT_LETSENCRYPT_IMAGE_NAME +# run_function select_one_option "${DOCKERHUB_LIST_TAGS[*]}" "Please select a tag for the image '$LOCAL_DEFAULT_LETSENCRYPT_IMAGE_NAME' (the list below comes from https://hub.docker.com):" +# +# [[ $SELECT_ONE_OPTION_NAME == "" ]] && echowarning "Once you did not select any option, '$LOCAL_DEFAULT_LETSENCRYPT_IMAGE_VERSION' will be used." +# LETSENCRYPT_IMAGE_VERSION=${SELECT_ONE_OPTION_NAME:-$LOCAL_DEFAULT_LETSENCRYPT_IMAGE_VERSION} +else + LETSENCRYPT_IMAGE_VERSION=${ARG_LETSENCRYPT_IMAGE_VERSION:-$LOCAL_DEFAULT_LETSENCRYPT_IMAGE_VERSION} +fi + +if [[ "$LETSENCRYPT_IMAGE_VERSION" == null ]] || [[ "$LOCAL_DEFAULT_LETSENCRYPT_IMAGE_VERSION" == null ]]; then + echoerror "It seems there is no default image or version, please check the .env file at '$SCRIPT_PATH'" +fi + +# ------- +# docker hub api v2 does not allow to get tags from personal repos without login +# @todo - fix this with user login +# ------- + +# Final check image a version with dockerhub (COMMENTED - TO BE FIXED) +#[[ "$SKIP_DOCKER_IMAGE_CHECK" != true ]] && [[ ! "$REPLY_YES" == true ]] && local_check_docker_hub_image_version $LOCAL_DEFAULT_LETSENCRYPT_IMAGE_NAME $LETSENCRYPT_IMAGE_VERSION + +#----------------------------------------------------------------------- +# docker-gen image version +# +# Parameters: -giv | --docker-gen-image-versio +# +# Final result: +# - DOCKER_GEN_IMAGE_VERSION +#----------------------------------------------------------------------- +LOCAL_DEFAULT_DOCKER_GEN_IMAGE_NAME=${DEFAULT_DOCKER_GEN_IMAGE_NAME:-null} +LOCAL_DEFAULT_DOCKER_GEN_IMAGE_VERSION=${DEFAULT_DOCKER_GEN_IMAGE_VERSION:-null} +if [[ $ARG_DOCKER_GEN_IMAGE_VERSION == "" ]] && [[ ! "$REPLY_YES" == true ]]; then + # ------- + # docker hub api v2 does not allow to get tags from personal repos without login + # @todo - fix this with user login + # ------- + +# # Get user's response (COMMENTED - TO BE FIXED) +# run_function dockerhub_list_tags $LOCAL_DEFAULT_DOCKER_GEN_IMAGE_NAME false +# run_function select_one_option "${DOCKERHUB_LIST_TAGS[*]}" "Please select a tag for the image '$LOCAL_DEFAULT_DOCKER_GEN_IMAGE_NAME' (the list below comes from https://hub.docker.com):" +# +# [[ $SELECT_ONE_OPTION_NAME == "" ]] && echowarning "Once you did not select any option, '$LOCAL_DEFAULT_DOCKER_GEN_IMAGE_VERSION' will be used." +# DOCKER_GEN_IMAGE_VERSION=${SELECT_ONE_OPTION_NAME:-$LOCAL_DEFAULT_DOCKER_GEN_IMAGE_VERSION} + DOCKER_GEN_IMAGE_VERSION=${ARG_DOCKER_GEN_IMAGE_VERSION:-$LOCAL_DEFAULT_DOCKER_GEN_IMAGE_VERSION} +else + DOCKER_GEN_IMAGE_VERSION=${ARG_DOCKER_GEN_IMAGE_VERSION:-$LOCAL_DEFAULT_DOCKER_GEN_IMAGE_VERSION} +fi + +if [[ "$DOCKER_GEN_IMAGE_VERSION" == null ]] || [[ "$LOCAL_DEFAULT_DOCKER_GEN_IMAGE_VERSION" == null ]]; then + echoerror "It seems there is no default image or version, please check the .env file at '$SCRIPT_PATH'" +fi + +# ------- +# docker hub api v2 does not allow to get tags from personal repos without login +# @todo - fix this with user login +# ------- + +# Final check image a version with dockerhub (COMMENTED - TO BE FIXED) +#[[ "$SKIP_DOCKER_IMAGE_CHECK" != true ]] && [[ ! "$REPLY_YES" == true ]] && local_check_docker_hub_image_version $LOCAL_DEFAULT_DOCKER_GEN_IMAGE_NAME $DOCKER_GEN_IMAGE_VERSION + +#----------------------------------------------------------------------- +# IP address (IPv4) +# +# Parameters: -ip | --ip-address +# +# Final result: +# - IP_ADDRESS +#----------------------------------------------------------------------- +if [[ $ARG_IP_ADDRESS == "" ]] && [[ ! "$REPLY_YES" == true ]]; then + + run_function ip_get_external_ipv4 + + # Get user's response + run_function common_read_user_input \ + "Please enter the IP address (ipv4) that your server uses to connect to the internet. \ + \nYou might try the following '$IP_EXTERNAL_IPV4' (default: 0.0.0.0):" + + LOCAL_IP_ADDRESS=${USER_INPUT_RESPONSE:-"0.0.0.0"} +else + LOCAL_IP_ADDRESS=${ARG_IP_ADDRESS:-"0.0.0.0"} +fi + +# Check the IP address +run_function ip_check_ipv4 $LOCAL_IP_ADDRESS + +if [[ ! "$IP_IPV4" == true ]]; then + echoerror "The IP address '$LOCAL_IP_ADDRESS' seems to be in wrong format. Please try again or keep the default value." + local_undo_restore +else + IP_ADDRESS=${LOCAL_IP_ADDRESS:-"0.0.0.0"} +fi + +#----------------------------------------------------------------------- +# IP address (IPv6) +# +# Parameters: -ipv6 | --ipv6-address +# +# Final result: +# - IPv6_ADDRESS +#----------------------------------------------------------------------- +if [[ "$ACTIVATE_IPV6" == true ]]; then + + # Check the ipv6 + if [[ $ARG_IPv6_ADDRESS == "" ]] && [[ ! "$REPLY_YES" == true ]]; then + + run_function ip_get_external_ipv6 + + # Get user's response + run_function common_read_user_input \ + "Please enter the IP address (ipv6) that your server uses to connect to the internet. \ + \nYou might try the following '$IP_EXTERNAL_IPV6' (default: ::0):" + + LOCAL_IPv6_ADDRESS=${USER_INPUT_RESPONSE:-"::0"} + else + LOCAL_IPv6_ADDRESS=${ARG_IPv6_ADDRESS:-"::0"} + fi + + # Check the IP address + run_function ip_check_ipv6 $LOCAL_IPv6_ADDRESS + + if [[ ! "$IP_IPV6" == true ]]; then + echoerror "The IP address '$LOCAL_IPv6_ADDRESS' seems to be in wrong format. Please try again or keep the default value." + local_undo_restore + else + IPv6_ADDRESS=${LOCAL_IPv6_ADDRESS:-"::0"} + fi +fi + +#----------------------------------------------------------------------- +# Docker network for the nginx-proxy +# +# Parameters: -net | --network-name +# +# Final result: +# - DOCKER_NETWORK_NAME +#----------------------------------------------------------------------- +LOCAL_DEFAULT_DOCKER_NETWORK_NAME=${DEFAULT_DOCKER_NETWORK_NAME:-"proxy"} +if [[ $ARG_NETWORK_NAME == "" ]] && [[ ! "$REPLY_YES" == true ]]; then + + # Get user's response + run_function common_read_user_input "Please enter the network name for your nginx-proxy (default: $LOCAL_DEFAULT_DOCKER_NETWORK_NAME):" + + LOCAL_DOCKER_NETWORK_NAME=${USER_INPUT_RESPONSE:-$LOCAL_DEFAULT_DOCKER_NETWORK_NAME} +else + LOCAL_DOCKER_NETWORK_NAME=${ARG_NETWORK_NAME:-$LOCAL_DEFAULT_DOCKER_NETWORK_NAME} +fi + +# Validate the name +run_function string_remove_all_special_char_string $LOCAL_DOCKER_NETWORK_NAME "-_" +DOCKER_NETWORK_NAME=${STRING_REMOVE_ALL_SPECIAL_CHAR_STRING_RESPONSE:-null} +[[ $DOCKER_NETWORK_NAME == null ]] && echoerror "The network name can not contain special chars, neither be empty" + +#----------------------------------------------------------------------- +# Data location for nginx-proxy files +# +# Parameters: -d | --data-files-location +# +# Final result: +# - DATA_LOCATION +#----------------------------------------------------------------------- +LOCAL_DEFAULT_DATA_LOCATION=${DEFAULT_DATA_LOCATION:-"$SCRIPT_PATH/../data"} +if [[ $ARG_DATA_LOCATION == "" ]] && [[ ! "$REPLY_YES" == true ]]; then + + # Get user's response + run_function common_read_user_input "Please enter the path location where you wish to place your nginx-proxy files (default: $LOCAL_DEFAULT_DATA_LOCATION):" + + DATA_LOCATION=${USER_INPUT_RESPONSE:-$LOCAL_DEFAULT_DATA_LOCATION} +else + DATA_LOCATION=${ARG_DATA_LOCATION:-$LOCAL_DEFAULT_DATA_LOCATION} +fi + +# Create folder if it does not exist +run_function common_create_folder $DATA_LOCATION + +#----------------------------------------------------------------------- +# Default email address for the Lets Encrypt certificates +# +# Parameters: -e | --default-email +# +# Final result: +# - DEFAULT_EMAIL +#----------------------------------------------------------------------- +if [[ $ARG_DEFAULT_EMAIL == "" ]]; then + + # Get user's response + run_function common_read_user_input "You must inform a valid email address in order to continue. Please check the docs:" + + DEFAULT_EMAIL=${USER_INPUT_RESPONSE} +else + DEFAULT_EMAIL=${ARG_DEFAULT_EMAIL} +fi + +# Check if email is valid +run_function email_check_is_valid $DEFAULT_EMAIL + +[[ ! "$EMAIL_IS_VALID" == true ]] && echoerror "You must inform a valid email address in order to continue. Please try again." + +#----------------------------------------------------------------------- +# Log settings for nginx-proxy +# +# We would like to comment that this is a very specific configuration +# that, once we will not offer the available options we decided to +# simplify these options once was not a common issue setting up +#----------------------------------------------------------------------- +NGINX_PROXY_LOG_DRIVER=${ARG_NGINX_PROXY_LOG_DRIVER:-"json-file"} +NGINX_PROXY_LOG_MAX_SIZE=${ARG_NGINX_PROXY_LOG_MAX_SIZE:-"4m"} +NGINX_PROXY_LOG_MAX_FILE=${ARG_NGINX_PROXY_LOG_MAX_FILE:-"10"} + +DOCKER_GEN_LOG_DRIVER=${ARG_DOCKER_GEN_LOG_DRIVER:-"json-file"} +DOCKER_GEN_LOG_MAX_SIZE=${ARG_DOCKER_GEN_LOG_MAX_SIZE:-"2m"} +DOCKER_GEN_LOG_MAX_FILE=${ARG_DOCKER_GEN_LOG_MAX_FILE:-"10"} + +LETSENCRYPT_LOG_DRIVER=${ARG_LETSENCRYPT_LOG_DRIVER:-"json-file"} +LETSENCRYPT_LOG_MAX_SIZE=${ARG_LETSENCRYPT_LOG_MAX_SIZE:-"2m"} +LETSENCRYPT_LOG_MAX_FILE=${ARG_LETSENCRYPT_LOG_MAX_FILE:-"10"} + +#----------------------------------------------------------------------- +# Port binding +# +# We would like to comment out that the settings below seems to be +# rearly changes by the users, so we kept that pretty simple in +# this script, if that is all right with you! Thank you! +#----------------------------------------------------------------------- +DOCKER_HTTP=${ARG_DOCKER_HTTP:-"80"} +DOCKER_HTTPS=${ARG_DOCKER_HTTPS:-"443"} + +#----------------------------------------------------------------------- +# SSL policy (set to Mozilla-Intermediate) +# +# Please read the options at the url below: +# https://github.com/nginx-proxy/nginx-proxy#how-ssl-support-works +#----------------------------------------------------------------------- +SSL_POLICY=${ARG_SSL_POLICY:-"Mozilla-Intermediate"} + +#----------------------------------------------------------------------- +# Docker rootless support. Add the current user's docker.sock path (default: blank) +# Please read the official documentation of installing Docker Rootless: +# https://docs.docker.com/engine/security/rootless/ +#----------------------------------------------------------------------- +if [[ "$USE_DOCKER_ROOTLESS" == true ]]; then + # Get the current user's $XDG_RUNTIME_DIR and concat with the '/docker.sock' + DOCKER_HOST_ROOTLESS_PATH=`echo ${XDG_RUNTIME_DIR}/docker.sock` +fi + +#----------------------------------------------------------------------- +# Start actions! +#----------------------------------------------------------------------- + +#----------------------------------------------------------------------- +# Verify checksum of docker-compose.yml and .env.sample files +#----------------------------------------------------------------------- +run_function md5_check_checksum "$SCRIPT_PATH/../" "docker-compose.yml" $MD5_SUM_DOCKER_COMPOSE +if [[ ! "$MD5_CHECKSUM" == true ]] && [[ ! "$REPLY_YES" == true ]]; then + + run_function confirm_user_action \ + "We could not verify the checksum (md5) for the docker-compose.yml \ + \n are you sure you want to continue?" +fi + +run_function md5_check_checksum "$SCRIPT_PATH/../" ".env.sample" $MD5_SUM_ENV_SAMPLE +if [[ ! "$MD5_CHECKSUM" == true ]] && [[ ! "$REPLY_YES" == true ]]; then + + run_function confirm_user_action \ + "We could not verify the checksum (md5) for the .env \ + \n are you sure you want to continue?" +fi + +#----------------------------------------------------------------------- +# Stop services (docker-compose) if they are running +#----------------------------------------------------------------------- +if [[ "$LOCAL_STOP_CURRENT_NGINX_PROXY_SERVICES" == true ]]; then + run_function docker_compose_stop "$SCRIPT_PATH/../" + + ACTION_DOCKER_COMPOSE_STOPPED=true + + [[ "$ERROR_DOCKER_COMPOSE_START" == true ]] && local_undo_restore + + # If there is no error when stopping container backup docker-compose file + run_function backup_file "$SCRIPT_PATH/../docker-compose.yml" + ACTION_DOCKER_COMPOSE_FILE_RENAMED=true + LOCAL_BACKUP_DOCKER_COMPOSE_FILE=$BACKUP_FILE +fi + +#----------------------------------------------------------------------- +# Add nginx config folder (conf.d) +#----------------------------------------------------------------------- +if [[ "$USE_NGINX_CONF_FILES" == true ]]; then + # Create the conf folder if it does not exists + run_function common_create_folder "$DATA_LOCATION/conf.d" + + # Copy the special configurations to the nginx conf folder + cp -R $SCRIPT_PATH/../conf.d/* $DATA_LOCATION/conf.d/ + + # Check if there was an error and try with sudo + if [ $? -ne 0 ]; then + echo "sudo cp -R $SCRIPT_PATH/../conf.d/* $DATA_LOCATION/conf.d/" + exit 0 + sudo cp -R $SCRIPT_PATH/../conf.d/* $DATA_LOCATION/conf.d/ + fi + + # If there was any errors inform the user + if [ $? -ne 0 ]; then + echoerror "There was an error trying to copy the nginx conf files. \ + \nThe proxy will still work with default options, but \ + \nthe custom settings might not be loaded." + fi +fi + +#----------------------------------------------------------------------- +# Update the nginx.template with the latest version +#----------------------------------------------------------------------- +DEFAULT_NGINX_TEMPLATE_URL="https://raw.githubusercontent.com/nginx-proxy/nginx-proxy/master/nginx.tmpl" +if [[ "$UPDATE_NGINX_TEMPLATE" == true ]]; then + cd "$SCRIPT_PATH/../" + curl -L $DEFAULT_NGINX_TEMPLATE_URL -o nginx.tmpl + cd - > /dev/null 2>&1 +fi + +#----------------------------------------------------------------------- +# Backup .env file if exists +#----------------------------------------------------------------------- +if [[ "$LOCAL_BACKUP_OLD_ENV_FILE" == true ]]; then + run_function backup_file "$SCRIPT_PATH/../.env" + ACTION_ENV_FILE_RENAMED=true + LOCAL_BACKUP_ENV_FILE=$BACKUP_FILE +fi + +#----------------------------------------------------------------------- +# Backup docker-compose.yml file if exists +#----------------------------------------------------------------------- +if [[ "$LOCAL_BACKUP_OLD_DOCKER_COMPOSE_FILE" == true ]]; then + run_function backup_file "$SCRIPT_PATH/../docker-compose.yml" + ACTION_DOCKER_COMPOSE_FILE_RENAMED=true + LOCAL_BACKUP_DOCKER_COMPOSE_FILE=$BACKUP_FILE +fi + +#----------------------------------------------------------------------- +# Create and update .env file for nginx-proxy +#----------------------------------------------------------------------- +cp "$SCRIPT_PATH/../.env.sample" "$SCRIPT_PATH/../.env" + +run_function local_update_env_new_site_variables "$SCRIPT_PATH/../" + +#----------------------------------------------------------------------- +# Create docker network if it does not exist +#----------------------------------------------------------------------- +run_function docker_check_network_exists $DOCKER_NETWORK_NAME + +if [[ ! "$DOCKER_NETWORK_EXISTS" == true ]]; then + + run_function docker_network_create $DOCKER_NETWORK_NAME ${ARG_IPv4_SUBNET:-null} $ACTIVATE_IPV6 $ARG_IPv6_SUBNET + + if [[ "$ERROR_DOCKER_NETWORK_CREATE" == true ]]; then + echoerror \ + "There was an error when creating the docker network $DOCKER_NETWORK_NAME [IPv6 enabled: ${ACTIVATE_IPV6:-'false'} ] \ + \nPlease try to create the network by yourself using the appropriate options described below and try again: \ + \nhttps://docs.docker.com/engine/reference/commandline/network_create/" \ + false + local_undo_restore + else + ACTION_DOCKER_NETWORK_CREATED=true + fi +fi + +#----------------------------------------------------------------------- +# Update docker-compose file +#----------------------------------------------------------------------- +run_function local_update_docker_compose_file "$SCRIPT_PATH/../" + +#----------------------------------------------------------------------- +# Start proxy +#----------------------------------------------------------------------- +run_function docker_compose_start "$SCRIPT_PATH/../" + +if [[ "$ERROR_DOCKER_COMPOSE_START" == true ]]; then + echoerror "There was an error starting the service at '$SCRIPT_PATH/../'" + local_undo_restore +fi + +#----------------------------------------------------------------------- +# Show data for the user to take notes +#----------------------------------------------------------------------- +echosuccess "Your proxy was started successfully!" + +# @todo - testing the proxy +# +# attention: +# 1. if yes don't ask for testing unless splicit +# 2. timeout optional yes|no as default? +# 3. url for testing - test dns first +# 4. option for ssl testing as well +# +# without ssl +# docker run -d -e VIRTUAL_HOST=$DOMAIN --network=$NETWORK --name test-web httpd:alpine +# +# with ss +# docker run -d -e VIRTUAL_HOST=$DOMAIN -e LETSENCRYPT_HOST=$DOMAIN --network=$NETWORK --name $NAME httpd:alpine +# +# stop testint - timeout?! +# docker stop test-web && docker rm test-web + +exit 0 diff --git a/bin/localscript/bootstrap.sh b/bin/localscript/bootstrap.sh new file mode 100755 index 00000000..6a0c23ce --- /dev/null +++ b/bin/localscript/bootstrap.sh @@ -0,0 +1,44 @@ +#----------------------------------------------------------------------- +# +# Server Automation - https://github.com/evertramos/server-automation +# +# Developed by +# Evert Ramos +# +# Copyright Evert Ramos +# +#----------------------------------------------------------------------- +# +# Be careful when editing this file, it is part of a bigger script! +# +#----------------------------------------------------------------------- + +#----------------------------------------------------------------------- +# This script has one main objective: +# 1. Load all functions in local folder +#----------------------------------------------------------------------- + +#----------------------------------------------------------------------- +# Fill out local variables +#----------------------------------------------------------------------- +# Get Current directory +LOCAL_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd)" + +# Bootstrap file name +BOOTSTRAP_FILE_NAME="bootstrap.sh" + +#----------------------------------------------------------------------- +# Debug message +#----------------------------------------------------------------------- +[[ "$DEBUG" == true ]] && "Reading base script files... [bootstrap.sh]" + +#----------------------------------------------------------------------- +# Read files with extension '.sh' +#----------------------------------------------------------------------- +# Loop the base folder and source all files in root folder +for file in $LOCAL_PATH/*.sh +do + [[ $file != $LOCAL_PATH/$BOOTSTRAP_FILE_NAME ]] && source $file +done + +return 0 diff --git a/bin/localscript/check-docker-nginx-proxy-automation-env-file.sh b/bin/localscript/check-docker-nginx-proxy-automation-env-file.sh new file mode 100755 index 00000000..e0f4afcc --- /dev/null +++ b/bin/localscript/check-docker-nginx-proxy-automation-env-file.sh @@ -0,0 +1,29 @@ +#----------------------------------------------------------------------- +# +# Server Automation - https://github.com/evertramos/server-automation +# +# Developed by +# Evert Ramos +# +# Copyright Evert Ramos +# +#----------------------------------------------------------------------- +# +# Be careful when editing this file, it is part of a bigger script! +# +#----------------------------------------------------------------------- + +#----------------------------------------------------------------------- +# This script has one main objective: +# 1. Check if the .env file already exists for the +# docker-nginx-proxy-automation +#----------------------------------------------------------------------- + +check_docker_nginx_proxy_automation_env_file_exits() +{ + [[ "$DEBUG" == true ]] && echo "Check if '.env' file exists for the nginx-proxy." + + if [[ -e ./../.env ]]; then + DOCKER_NGINX_PROXY_AUTOMATION_ENV_FILE_EXISTS=true + fi +} diff --git a/bin/localscript/check-local-env-file.sh b/bin/localscript/check-local-env-file.sh new file mode 100755 index 00000000..d583bdc6 --- /dev/null +++ b/bin/localscript/check-local-env-file.sh @@ -0,0 +1,31 @@ +#----------------------------------------------------------------------- +# +# Server Automation - https://github.com/evertramos/server-automation +# +# Developed by +# Evert Ramos +# +# Copyright Evert Ramos +# +#----------------------------------------------------------------------- +# +# Be careful when editing this file, it is part of a bigger script! +# +#----------------------------------------------------------------------- + +#----------------------------------------------------------------------- +# This script has one main objective: +# 1. Check if the .env file exists in the current folder +#----------------------------------------------------------------------- + +check_local_env_file() +{ + [[ "$DEBUG" == true ]] && echo "Check if local '.env' file is set." + + if [[ -e .env ]]; then + source .env + else + MESSAGE="'.env' file not found! \n Cheers!" + return 1 + fi +} diff --git a/bin/localscript/update-docker-compose-file.sh b/bin/localscript/update-docker-compose-file.sh new file mode 100755 index 00000000..c2fe4abf --- /dev/null +++ b/bin/localscript/update-docker-compose-file.sh @@ -0,0 +1,50 @@ +#----------------------------------------------------------------------- +# +# Server Automation - https://github.com/evertramos/server-automation +# +# Developed by +# Evert Ramos +# +# Copyright Evert Ramos +# +#----------------------------------------------------------------------- +# +# Be careful when editing this file, it is part of a bigger script! +# +#----------------------------------------------------------------------- + +# ---------------------------------------------------------------------- +# This function has one main objective: +# 1. Update all variables in docker-compose file +# +# You must/might inform the parameters below: +# 1. Path where docker-compose.yml file is located +# 2. [optional] (default: ) +# +# ---------------------------------------------------------------------- + +local_update_docker_compose_file() +{ + local LOCAL_FULL_PATH + + LOCAL_FULL_PATH=${1} + + [[ $LOCAL_FULL_PATH == "" || $LOCAL_FULL_PATH == null ]] && echoerror "You must inform the required argument(s) to the function: '${FUNCNAME[0]}'" + + [[ "$DEBUG" == true ]] && echo "Updating all variables in docker-compose.yml file for nginx-proxy (file: ${LOCAL_FULL_PATH})" + + # Services name + run_function docker_compose_replace_string $LOCAL_FULL_PATH "$REPLACE_NGINX_PROXY_SERVICE_NAME" "$NGINX_PROXY_SERVICE_NAME" + run_function docker_compose_replace_string $LOCAL_FULL_PATH "$REPLACE_DOCKER_GEN_SERVICE_NAME" "$DOCKER_GEN_SERVICE_NAME" + run_function docker_compose_replace_string $LOCAL_FULL_PATH "$REPLACE_LETSENCRYPT_SERVICE_NAME" "$LETSENCRYPT_SERVICE_NAME" + + # Uncomment in case of IPv6 activation or comment + [[ "$ACTIVATE_IPV6" == true ]] && run_function file_uncomment_line_with_string ${LOCAL_FULL_PATH%/}"/docker-compose.yml" "IPv6" && run_function file_uncomment_line_with_string ${LOCAL_FULL_PATH%/}"/docker-compose.yml" "IPV6" + [[ ! "$ACTIVATE_IPV6" == true ]] && run_function file_comment_line_with_string ${LOCAL_FULL_PATH%/}"/docker-compose.yml" "IPv6" && run_function file_comment_line_with_string ${LOCAL_FULL_PATH%/}"/docker-compose.yml" "IPV6" + # We are aware that it will set two '#' if the IPv6 is already commented + + # Uncomment in case of Default Host activation + [[ ! $ARG_DEFAULT_HOST == "" ]] && run_function file_uncomment_line_with_string ${LOCAL_FULL_PATH%/}"/docker-compose.yml" "DEFAULT_HOST" + + return 0 +} diff --git a/bin/localscript/update-env-new-site-variables.sh b/bin/localscript/update-env-new-site-variables.sh new file mode 100755 index 00000000..26336db6 --- /dev/null +++ b/bin/localscript/update-env-new-site-variables.sh @@ -0,0 +1,85 @@ +#----------------------------------------------------------------------- +# +# Server Automation - https://github.com/evertramos/server-automation +# +# Developed by +# Evert Ramos +# +# Copyright Evert Ramos +# +#----------------------------------------------------------------------- +# +# Be careful when editing this file, it is part of a bigger script! +# +#----------------------------------------------------------------------- + +#----------------------------------------------------------------------- +# This function has one main objective: +# 1. Update all variables in .env file for fresh start script +# +# You must/might inform the parameters below: +# 1. Path where .env is located +# 2. [optional] (default: ) n/a +# +#----------------------------------------------------------------------- + +local_update_env_new_site_variables() +{ + local LOCAL_FILE_PATH + + LOCAL_FILE_PATH=${1:-null} + + [[ $LOCAL_FILE_PATH == "" || $LOCAL_FILE_PATH == null ]] && echoerror "You must inform the required argument(s) to the function: '${FUNCNAME[0]}'" + + [[ "$DEBUG" == true ]] && echo "Updating all variables in .env file for nginx-proxy (file: ${LOCAL_FILE_PATH})" + + # Docker servides and image versions + run_function env_update_variable $LOCAL_FILE_PATH "NGINX_WEB_SEVICE_NAME" "$NGINX_PROXY_SERVICE_NAME" + run_function env_update_variable $LOCAL_FILE_PATH "NGINX_IMAGE_VERSION" "$NGINX_PROXY_IMAGE_VERSION" + run_function env_update_variable $LOCAL_FILE_PATH "DOCKER_GEN_SEVICE_NAME" "$DOCKER_GEN_SERVICE_NAME" + run_function env_update_variable $LOCAL_FILE_PATH "DOCKER_GEN_IMAGE_VERSION" "$DOCKER_GEN_IMAGE_VERSION" + run_function env_update_variable $LOCAL_FILE_PATH "LETS_ENCRYPT_SEVICE_NAME" "$LETSENCRYPT_SERVICE_NAME" + run_function env_update_variable $LOCAL_FILE_PATH "NGINX_PROXY_COMPANION_IMAGE_VERSION" "$LETSENCRYPT_IMAGE_VERSION" + + # IPs + run_function env_update_variable $LOCAL_FILE_PATH "IPv4" "$IP_ADDRESS" + [[ "$ACTIVATE_IPV6" == true ]] && run_function env_update_variable $LOCAL_FILE_PATH "IPv6" "$IPv6_ADDRESS" + + # Network + run_function env_update_variable $LOCAL_FILE_PATH "NETWORK" "$DOCKER_NETWORK_NAME" + + # Data files path + run_function env_update_variable $LOCAL_FILE_PATH "NGINX_FILES_PATH" "$DATA_LOCATION" + + # Log variables + # proxy + run_function env_update_variable $LOCAL_FILE_PATH "NGINX_WEB_LOG_DRIVER" "$NGINX_PROXY_LOG_DRIVER" + run_function env_update_variable $LOCAL_FILE_PATH "NGINX_WEB_LOG_MAX_SIZE" "$NGINX_PROXY_LOG_MAX_SIZE" + run_function env_update_variable $LOCAL_FILE_PATH "NGINX_WEB_LOG_MAX_FILE" "$NGINX_PROXY_LOG_MAX_FILE" + # docker-gen + run_function env_update_variable $LOCAL_FILE_PATH "NGINX_GEN_LOG_DRIVER" "$DOCKER_GEN_LOG_DRIVER" + run_function env_update_variable $LOCAL_FILE_PATH "NGINX_GEN_LOG_MAX_SIZE" "$DOCKER_GEN_LOG_MAX_SIZE" + run_function env_update_variable $LOCAL_FILE_PATH "NGINX_GEN_LOG_MAX_FILE" "$DOCKER_GEN_LOG_MAX_FILE" + # Lets Encrypt + run_function env_update_variable $LOCAL_FILE_PATH "NGINX_LETSENCRYPT_LOG_DRIVER" "$LETSENCRYPT_LOG_DRIVER" + run_function env_update_variable $LOCAL_FILE_PATH "NGINX_LETSENCRYPT_LOG_MAX_SIZE" "$LETSENCRYPT_LOG_MAX_SIZE" + run_function env_update_variable $LOCAL_FILE_PATH "NGINX_LETSENCRYPT_LOG_MAX_FILE" "$LETSENCRYPT_LOG_MAX_FILE" + + # Port bindings + run_function env_update_variable $LOCAL_FILE_PATH "DOCKER_HTTP_" "$DOCKER_HTTP" + run_function env_update_variable $LOCAL_FILE_PATH "DOCKER_HTTPS" "$DOCKER_HTTPS" + + # SSL Policy + run_function env_update_variable $LOCAL_FILE_PATH "SSL_POLICY" "$SSL_POLICY" + + # Default email address + run_function env_update_variable $LOCAL_FILE_PATH "DEFAULT_EMAIL" "$DEFAULT_EMAIL" + + # Default host + [[ ! $ARG_DEFAULT_HOST == "" ]] && run_function env_update_variable $LOCAL_FILE_PATH "DEFAULT_HOST" "${ARG_DEFAULT_HOST}" + + # Docker rootless support + [[ "$USE_DOCKER_ROOTLESS" == true ]] && run_function env_update_variable $LOCAL_FILE_PATH "DOCKER_HOST_ROOTLESS_PATH" "$DOCKER_HOST_ROOTLESS_PATH" + + return 0 +} diff --git a/bin/localscript/usage-fresh-start.sh b/bin/localscript/usage-fresh-start.sh new file mode 100755 index 00000000..9496cb90 --- /dev/null +++ b/bin/localscript/usage-fresh-start.sh @@ -0,0 +1,144 @@ +#----------------------------------------------------------------------- +# +# Server Automation - https://github.com/evertramos/server-automation +# +# Developed by +# Evert Ramos +# +# Copyright Evert Ramos +# +#----------------------------------------------------------------------- +# +# Be careful when editing this file, it is part of a bigger script! +# +#----------------------------------------------------------------------- + +#----------------------------------------------------------------------- +# This script has one main objective: +# 1. Show the script usage (helper) +#----------------------------------------------------------------------- + +# +# NGINX use special conf files +# +# In case you want to add some special configuration to your NGINX Web Proxy you could +# add your files to ./conf.d/ folder as of sample file 'uploadsize.conf' +# +# [WARNING] This setting was built to use our `start.sh`. +# +# [WARNING] Once you set this options to true all your files will be copied to data +# folder (./data/conf.d). If you decide to remove this special configuration +# you must delete your files from data folder ./data/conf.d. +# +# USE_NGINX_CONF_FILES=true + +#----------------------------------------------------------------------- +# +# Docker network options +# +# The docker network has many options when creating a new network, you can +# check the url below for more information about the docker network creation +# in our 'fresh_start.sh' script you can enable the network encryption option +# +# https://docs.docker.com/engine/reference/commandline/network_create/ +# +# NETWORK_OPTIONS="--opt encrypted=true" + +usage() +{ + cat << USAGE >&2 +${purple} +============================================================================= +| _____ _____ _ _ _ | +| | __|___ ___ _ _ ___ ___ ___| _ |_ _| |_ ___ _____ ___| |_|_|___ ___ | +| |__ | -_| _| | | -_| _|___| | | | _| . | | .'| _| | . | | | +| |_____|___|_| \_/|___|_| |__|__|___|_| |___|_|_|_|__,|_| |_|___|_|_| | +| | +============================================================================= +${reset}${blue} +Usage: + $SCRIPT_NAME -e "john.doe@example.com" + [-d "/server/proxy/data"] + [-pn "proxy"] [-ln "letsencrypt"] [-gn "docker-gen"] + [-net "proxy"] + [--use-nginx-conf-files] [--update-nginx-template] + [--yes] + [--debug] + [--docker-rootless] + + Required + -e | --default-email Default email address require to issue ssl + certificates with Let's Encrypt service + + Basic options + -d | --data-files-location Proxy files location + -pn | --proxy-name Proxy service and container name + -ln | --letsencrypt-name Let's Encrypt service & container name + -gn | --docker-gen-name Docker-gen service and container name + -net | --network-name Docker network name for proxy services + -ip | --ip-address IP address for external connectivity + + Proxy config + --use-nginx-conf-files Add basic config folder to the Proxy + --update-nginx-template Download the latest nginx.tmpl + + Network + -netopt | --network-option Network options please check the docs + --ipv4-subnet You may inform IPv4 subnet to create + a docker network + (default: 172.17.0.0/16) + + Docker image + -piv | --proxy-image-version Proxy image version + -liv | --letsencrypt-image-version Let's Encrypt image version + -giv | --docker-gen-image-version Docker-gen image version + + --skip-docker-image-check Use this option to skip docker image + verification which might takes a few + seconds to check if images exists in + docker hub api + + Docker log + -lpd | --log-nginx-proxy-driver Proxy service log driver + -lpms | --log-nginx-proxy-max_size Proxy service log max file size + -lpmf | --log-nginx-proxy-max_file Proxy service log max files + -lgd | --log-docker-gen-driver Docker-gen service log driver + -lgms | --log-docker-gen-max_size Docker-gen service log max file size + -lgmf | --log-docker-gen-max_file Docker-gen service log max files + -lld | --log-letsencrypt-driver Let's Encrypt service log driver + -llms | --log-letsencrypt-max_size Let's Encrypt service log max size + -llmf | --log-letsencrypt-max_file Let's Encrypt service log max files + + Proxy port binding + -phttp | --port-http Proxy http port (default: 80) + -phttps | --port-https Proxy https port (default: 443) + + Proxy SSL policy + -sp | --ssl-policy Proxy SSL suport + (default: Mozilla-Intermediate) + + Default Host + -df | --default-host The default host where nginx-proxy will redirect all requests to + the container that matches the VIRTUAL_HOST + + IPv6 support + --activate-ipv6 Use to activate IPv6 support + -ipv6 | --ipv6-address IPv6 address for external connectivity + --ipv6-subnet You must inform IPv6 subnet to create + a docker network + (default: 2001:db8:1:1::/112) + + Other options + --yes Set "yes" to all, use it with caution + --debug Show script debug options + --silent Hide all script message + -dr | --docker-rootless Add Docker rootless support by adding the + the current user's $XDG_RUNTIME_DIR and + concat with the '/docker.sock' in the + DOCKER_HOST_ROOTLESS_PATH .env file. + -h | --help Display this help + +${reset} +USAGE + exit 1 +} diff --git a/bin/ssl_test.sh b/bin/ssl_test.sh new file mode 100755 index 00000000..31d8acec --- /dev/null +++ b/bin/ssl_test.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +#----------------------------------------------------------------------- +# +# test-proxy script - testing nginx-proxy +# +# https://github.com/evertramos/nginx-proxy-automation +# +# Script developed by +# Evert Ramos +# +# Copyright Evert Ramos +# +#----------------------------------------------------------------------- + +# Set up your DOMAIN +if [ $# -eq 0 ]; then + echo "Please inform your domain name to test your proxy." + echo "./test.sh $1" + exit 1 +else + DOMAIN=$1 +fi + +# Read your .env file +source ./../.env + +# Testing your proxy +docker run -d -e VIRTUAL_HOST=$DOMAIN -e LETSENCRYPT_HOST=$DOMAIN --network=$NETWORK --rm --name test-web httpd:alpine + +exit 0 diff --git a/bin/stop.sh b/bin/stop.sh new file mode 100755 index 00000000..e66055fd --- /dev/null +++ b/bin/stop.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +#----------------------------------------------------------------------- +# +# test-proxy script - testing nginx-proxy +# +# https://github.com/evertramos/nginx-proxy-automation +# +# Script developed by +# Evert Ramos +# +# Copyright Evert Ramos +# +#----------------------------------------------------------------------- + +# Stop if test is running +docker stop test-web + +exit 0 diff --git a/bin/test.sh b/bin/test.sh new file mode 100755 index 00000000..61d94827 --- /dev/null +++ b/bin/test.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +#----------------------------------------------------------------------- +# +# test-proxy script - testing nginx-proxy +# +# https://github.com/evertramos/nginx-proxy-automation +# +# Script developed by +# Evert Ramos +# +# Copyright Evert Ramos +# +#----------------------------------------------------------------------- + +# Set up your DOMAIN +if [ $# -eq 0 ]; then + echo "Please inform your domain name to test your proxy." + echo "./test.sh $1" + exit 1 +else + DOMAIN=$1 +fi + +# Read your .env file +source ./../.env + +# Testing your proxy +docker run -d -e VIRTUAL_HOST=$DOMAIN --network=$NETWORK --rm --name test-web httpd:alpine + +exit 0 diff --git a/bin/update-checksum.sh b/bin/update-checksum.sh new file mode 100755 index 00000000..af67e498 --- /dev/null +++ b/bin/update-checksum.sh @@ -0,0 +1,96 @@ +#!/bin/bash + +#----------------------------------------------------------------------- +# +# Update checksum in .env files +# +# Part of https://github.com/evertramos/nginx-proxy-automation +# +# Script written by +# Evert Ramos +# +# Copyright Evert Ramos +# +#----------------------------------------------------------------------- + +# Bash settings (do not mess with it) +shopt -s nullglob globstar + +# Get the script name and its file real path +SCRIPT_PATH="$(dirname "$(readlink -f "$0")")" +SCRIPT_NAME="${0##*/}" + +# Source basescript functions +source $SCRIPT_PATH"/../basescript/bootstrap.sh" + +# Source localscripts +source $SCRIPT_PATH"/localscript/bootstrap.sh" + +# Log +printf "${energy} Start execution '${SCRIPT_PATH}/${SCRIPT_NAME} " +log "Start execution" +log "$@" + +#----------------------------------------------------------------------- +# Initial check - DO NOT CHANGE SETTINGS BELOW +#----------------------------------------------------------------------- + +# Check if there is an .env file in local folder +run_function check_local_env_file + +# Specific PID File if needs to run multiple scripts +NEW_PID_FILE=${PID_FILE_FRESH_INSTALL:-".update_checksum"} + +# Run initial check function +run_function starts_initial_check $NEW_PID_FILE + +# Save PID +system_save_pid $NEW_PID_FILE + +# DO NOT CHANGE ANY OPTIONS ABOVE THIS LINE! + +#----------------------------------------------------------------------- +# [function] Undo script actions +#----------------------------------------------------------------------- +local_undo_restore() { +# local LOCAL_KEEP_RESTORE_FILES +# +# LOCAL_KEEP_RESTORE_FILES=${1:-$KEEP_RESTORE_FILES} + + echoerror \ + "It seems something went wrong! \ + \nRunning '${FUNCNAME[0]} to try to UNDO all actions done by this script. \ + \nPlease make sure everything was put it back in place." false + + # If docker network was created +# if [[ "$ACTION_DOCKER_NETWORK_CREATED" == true ]]; then +# [[ "$SILENT" != true ]] && echowarning "[undo] Deleting created docker network '$DOCKER_NETWORK_NAME'." +# run_function docker_network_remove $DOCKER_NETWORK_NAME +# ACTION_DOCKER_NETWORK_CREATED=false +# fi + + exit 0 +} + +#----------------------------------------------------------------------- +# Verify checksum of docker-compose.yml and .env.sample files +#----------------------------------------------------------------------- +run_function md5_check_checksum "$SCRIPT_PATH/../" "docker-compose.yml" $MD5_SUM_DOCKER_COMPOSE +if [[ ! "$MD5_CHECKSUM" == true ]]; then + DOCKER_COMPOSE_CHECKSUM=$(md5sum "$SCRIPT_PATH/../docker-compose.yml" | awk '{print $1}') + echowarning "Updating the checksum for 'MD5_SUM_DOCKER_COMPOSE'" + run_function env_update_variable "$SCRIPT_PATH" "MD5_SUM_DOCKER_COMPOSE" "$DOCKER_COMPOSE_CHECKSUM" +else + echosuccess "Checksum for 'MD5_SUM_DOCKER_COMPOSE' is just fine!" +fi + +run_function md5_check_checksum "$SCRIPT_PATH/../" ".env.sample" $MD5_SUM_ENV_SAMPLE +if [[ ! "$MD5_CHECKSUM" == true ]]; then + ENV_CHECKSUM=$(md5sum "$SCRIPT_PATH/../.env.sample" | awk '{print $1}') + echowarning "Updating the checksum for 'MD5_SUM_ENV_SAMPLE'" + run_function env_update_variable "$SCRIPT_PATH" "MD5_SUM_ENV_SAMPLE" "$ENV_CHECKSUM" +else + echosuccess "Checksum for 'MD5_SUM_ENV_SAMPLE' is just fine!" +fi + +exit 0 diff --git a/conf.d/realip.conf b/conf.d/realip.conf index 04d8ae33..5dfb8a0a 100644 --- a/conf.d/realip.conf +++ b/conf.d/realip.conf @@ -15,9 +15,9 @@ # # The option 'set_real_ip_from' # must correspont to your docker network address -set_real_ip_from 172.18.0.0/32; -real_ip_header X-Real-IP; -real_ip_recursive on; +set_real_ip_from 172.16.0.0/12; +set_real_ip_from 10.0.0.0/8; +set_real_ip_from 192.168.0.0/16; # # CloudFlare settings @@ -26,25 +26,32 @@ real_ip_recursive on; # user's real IP to your app services you # must uncomment all lines below and be sure # to comment the lines of the "Basic settings" -#set_real_ip_from 103.21.244.0/22; -#set_real_ip_from 103.22.200.0/22; -#set_real_ip_from 103.31.4.0/22; -#set_real_ip_from 104.16.0.0/12; -#set_real_ip_from 108.162.192.0/18; -#set_real_ip_from 131.0.72.0/22; -#set_real_ip_from 141.101.64.0/18; -#set_real_ip_from 162.158.0.0/15; -#set_real_ip_from 172.64.0.0/13; -#set_real_ip_from 173.245.48.0/20; -#set_real_ip_from 188.114.96.0/20; -#set_real_ip_from 190.93.240.0/20; -#set_real_ip_from 197.234.240.0/22; -#set_real_ip_from 198.41.128.0/17; -#set_real_ip_from 2400:cb00::/32; -#set_real_ip_from 2606:4700::/32; -#set_real_ip_from 2803:f800::/32; -#set_real_ip_from 2405:b500::/32; -#set_real_ip_from 2405:8100::/32; -#set_real_ip_from 2c0f:f248::/32; -#set_real_ip_from 2a06:98c0::/29; -#real_ip_header X-Forwarded-For; +set_real_ip_from 103.21.244.0/22; +set_real_ip_from 103.22.200.0/22; +set_real_ip_from 103.31.4.0/22; +set_real_ip_from 104.16.0.0/12; +set_real_ip_from 108.162.192.0/18; +set_real_ip_from 131.0.72.0/22; +set_real_ip_from 141.101.64.0/18; +set_real_ip_from 162.158.0.0/15; +set_real_ip_from 172.64.0.0/13; +set_real_ip_from 173.245.48.0/20; +set_real_ip_from 188.114.96.0/20; +set_real_ip_from 190.93.240.0/20; +set_real_ip_from 197.234.240.0/22; +set_real_ip_from 198.41.128.0/17; +set_real_ip_from 2400:cb00::/32; +set_real_ip_from 2606:4700::/32; +set_real_ip_from 2803:f800::/32; +set_real_ip_from 2405:b500::/32; +set_real_ip_from 2405:8100::/32; +set_real_ip_from 2c0f:f248::/32; +set_real_ip_from 2a06:98c0::/29; + +# +# Header for Real IP Address +# +real_ip_header X-Forwarded-For; +#real_ip_header X-Real-IP; +real_ip_recursive on; + diff --git a/conf.d/uploadsize.conf b/conf.d/uploadsize.conf index ed6efd1a..4dcdc1d0 100644 --- a/conf.d/uploadsize.conf +++ b/conf.d/uploadsize.conf @@ -1,7 +1,5 @@ # -# [WARNING] To enable this files you need to uncomment USE_NGINX_CONF_FILES=true in .env file -# -# [WARNING] Also, read all the comments in .env about NGINX use special conf files +# [WARNING] In order to enable this option in the proxy you must run the fresh start script with the option `--use-nginx-conf-files` # client_max_body_size 100m; diff --git a/docker-compose-multiple-networks.yml b/docker-compose-multiple-networks.yml deleted file mode 100644 index 09141f2c..00000000 --- a/docker-compose-multiple-networks.yml +++ /dev/null @@ -1,77 +0,0 @@ -version: '3' -services: - nginx-web: - image: nginx - labels: - com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy: "true" - container_name: ${NGINX_WEB:-nginx-web} - restart: always - ports: - - "${IP:-0.0.0.0}:80:80" - - "${IP:-0.0.0.0}:443:443" - volumes: - - ${NGINX_FILES_PATH:-./data}/conf.d:/etc/nginx/conf.d - - ${NGINX_FILES_PATH:-./data}/vhost.d:/etc/nginx/vhost.d - - ${NGINX_FILES_PATH:-./data}/html:/usr/share/nginx/html - - ${NGINX_FILES_PATH:-./data}/certs:/etc/nginx/certs:ro - - ${NGINX_FILES_PATH:-./data}/htpasswd:/etc/nginx/htpasswd:ro - networks: - - default - - outside - logging: - driver: ${NGINX_WEB_LOG_DRIVER:-json-file} - options: - max-size: ${NGINX_WEB_LOG_MAX_SIZE:-4m} - max-file: ${NGINX_WEB_LOG_MAX_FILE:-10} - - nginx-gen: - image: jwilder/docker-gen - command: -notify-sighup ${NGINX_WEB:-nginx-web} -watch -wait 5s:30s /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf - container_name: ${DOCKER_GEN:-nginx-gen} - restart: always - volumes: - - ${NGINX_FILES_PATH:-./data}/conf.d:/etc/nginx/conf.d - - ${NGINX_FILES_PATH:-./data}/vhost.d:/etc/nginx/vhost.d - - ${NGINX_FILES_PATH:-./data}/html:/usr/share/nginx/html - - ${NGINX_FILES_PATH:-./data}/certs:/etc/nginx/certs:ro - - ${NGINX_FILES_PATH:-./data}/htpasswd:/etc/nginx/htpasswd:ro - - /var/run/docker.sock:/tmp/docker.sock:ro - - ./nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro - networks: - - default - - outside - logging: - driver: ${NGINX_GEN_LOG_DRIVER:-json-file} - options: - max-size: ${NGINX_GEN_LOG_MAX_SIZE:-2m} - max-file: ${NGINX_GEN_LOG_MAX_FILE:-10} - - nginx-letsencrypt: - image: jrcs/letsencrypt-nginx-proxy-companion - container_name: ${LETS_ENCRYPT:-nginx-letsencrypt} - restart: always - volumes: - - ${NGINX_FILES_PATH:-./data}/conf.d:/etc/nginx/conf.d - - ${NGINX_FILES_PATH:-./data}/vhost.d:/etc/nginx/vhost.d - - ${NGINX_FILES_PATH:-./data}/html:/usr/share/nginx/html - - ${NGINX_FILES_PATH:-./data}/certs:/etc/nginx/certs:rw - - /var/run/docker.sock:/var/run/docker.sock:ro - environment: - NGINX_DOCKER_GEN_CONTAINER: ${DOCKER_GEN:-nginx-gen} - NGINX_PROXY_CONTAINER: ${NGINX_WEB:-nginx-web} - networks: - - default - - outside - logging: - driver: ${NGINX_LETSENCRYPT_LOG_DRIVER:-json-file} - options: - max-size: ${NGINX_LETSENCRYPT_LOG_MAX_SIZE:-2m} - max-file: ${NGINX_LETSENCRYPT_LOG_MAX_FILE:-10} - -networks: - default: - external: - name: ${NETWORK:-webproxy} - outside: - external: - name: ${SERVICE_NETWORK:-webservices} diff --git a/docker-compose.yml b/docker-compose.yml index 230146ee..bc7fb1c9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,14 +1,21 @@ -version: '3' +version: '3.5' + services: - nginx-web: - image: nginx + nginx-proxy-automation-web: + image: nginx:${NGINX_IMAGE_VERSION:-stable-alpine} labels: - com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy: "true" - container_name: ${NGINX_WEB:-nginx-web} + com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy: "true" + container_name: ${NGINX_WEB_SEVICE_NAME:-nginx-proxy-automation-web} restart: always ports: - - "${IP:-0.0.0.0}:80:80" - - "${IP:-0.0.0.0}:443:443" + - "${IPv4:-0.0.0.0}:${DOCKER_HTTP_:-80}:80" + - "${IPv4:-0.0.0.0}:${DOCKER_HTTPS:-443}:443" +# - "${IPv6:-::0}:${DOCKER_HTTP_:-80}:80" +# - "${IPv6:-::0}:${DOCKER_HTTPS:-443}:443" + environment: + SSL_POLICY: ${SSL_POLICY:-Mozilla-Intermediate} +# DEFAULT_HOST: ${DEFAULT_HOST} +# ENABLE_IPV6: "true" volumes: - ${NGINX_FILES_PATH:-./data}/conf.d:/etc/nginx/conf.d - ${NGINX_FILES_PATH:-./data}/vhost.d:/etc/nginx/vhost.d @@ -21,10 +28,10 @@ services: max-size: ${NGINX_WEB_LOG_MAX_SIZE:-4m} max-file: ${NGINX_WEB_LOG_MAX_FILE:-10} - nginx-gen: - image: jwilder/docker-gen - command: -notify-sighup ${NGINX_WEB:-nginx-web} -watch -wait 5s:30s /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf - container_name: ${DOCKER_GEN:-nginx-gen} + nginx-proxy-automation-gen: + image: nginxproxy/docker-gen:${DOCKER_GEN_IMAGE_VERSION:-0.7.7} + command: -notify-sighup ${NGINX_WEB_SEVICE_NAME:-nginx-proxy-automation-web} -watch -wait 5s:30s /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf + container_name: ${DOCKER_GEN_SEVICE_NAME:-nginx-proxy-automation-gen} restart: always volumes: - ${NGINX_FILES_PATH:-./data}/conf.d:/etc/nginx/conf.d @@ -32,7 +39,7 @@ services: - ${NGINX_FILES_PATH:-./data}/html:/usr/share/nginx/html - ${NGINX_FILES_PATH:-./data}/certs:/etc/nginx/certs:ro - ${NGINX_FILES_PATH:-./data}/htpasswd:/etc/nginx/htpasswd:ro - - /var/run/docker.sock:/tmp/docker.sock:ro + - ${DOCKER_HOST_ROOTLESS_PATH:-/var/run/docker.sock}:/tmp/docker.sock:ro - ./nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro logging: driver: ${NGINX_GEN_LOG_DRIVER:-json-file} @@ -40,19 +47,21 @@ services: max-size: ${NGINX_GEN_LOG_MAX_SIZE:-2m} max-file: ${NGINX_GEN_LOG_MAX_FILE:-10} - nginx-letsencrypt: - image: jrcs/letsencrypt-nginx-proxy-companion - container_name: ${LETS_ENCRYPT:-nginx-letsencrypt} + nginx-proxy-automation-letsencrypt: + image: nginxproxy/acme-companion:${NGINX_PROXY_COMPANION_IMAGE_VERSION:-2.1} + container_name: ${LETS_ENCRYPT_SEVICE_NAME:-nginx-proxy-automation-letsencrypt} restart: always volumes: - ${NGINX_FILES_PATH:-./data}/conf.d:/etc/nginx/conf.d - ${NGINX_FILES_PATH:-./data}/vhost.d:/etc/nginx/vhost.d - ${NGINX_FILES_PATH:-./data}/html:/usr/share/nginx/html - ${NGINX_FILES_PATH:-./data}/certs:/etc/nginx/certs:rw - - /var/run/docker.sock:/var/run/docker.sock:ro + - ${NGINX_FILES_PATH:-./data}/acme.sh:/etc/acme.sh + - ${DOCKER_HOST_ROOTLESS_PATH:-/var/run/docker.sock}:/var/run/docker.sock:ro environment: - NGINX_DOCKER_GEN_CONTAINER: ${DOCKER_GEN:-nginx-gen} - NGINX_PROXY_CONTAINER: ${NGINX_WEB:-nginx-web} + NGINX_DOCKER_GEN_CONTAINER: ${DOCKER_GEN_SEVICE_NAME:-nginx-proxy-automation-gen} + NGINX_PROXY_CONTAINER: ${NGINX_WEB_SEVICE_NAME:-nginx-proxy-automation-web} + DEFAULT_EMAIL: ${DEFAULT_EMAIL:-mail@yourdomain.tld} logging: driver: ${NGINX_LETSENCRYPT_LOG_DRIVER:-json-file} options: @@ -61,5 +70,6 @@ services: networks: default: - external: - name: ${NETWORK:-webproxy} + external: true + name: ${NETWORK:-proxy} + diff --git a/docs/HOWTO-Synlogy.md b/docs/HOWTO-Synlogy.md new file mode 100755 index 00000000..4c456f81 --- /dev/null +++ b/docs/HOWTO-Synlogy.md @@ -0,0 +1,27 @@ +## Port mapping +Synology default installs a web server on port 80 blocking certificate generation. + +To circumvent this - if you do not need external access to the default web server (and you should not expose it anyway) configure your .env to use alternative ports and your router to forward the external official port to the alternative internal ports: + +# +# Set the local exposed ports for http and https - this will allow you to run with a legacy web +# server already installed for local use +# +# NOTE: For this to function your internet router must forward the official ports to the mapped ports - +# in this example external port 80 to docker host 81 and external port 443 to docker host 444 +# +DOCKER_HTTP=81 +DOCKER_HTTPS=444 + +## File permissions +To setup the needed configuration directoties and proper permissions run the below commands (assuming default ./data is where you have your catalog for persistent files) + +mkdir -p data/certs +mkdir data/htpasswd +mkdir data/conf.d +mkdir data/vhost.d +mkdir data/html +chgrp -R 101 data +chmod -R g+rwx data + +Contributed by https://github.com/nicolailang/ diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..b7e449f7 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,219 @@ +# NGINX Proxy Automation 🔥 + +## What this project does + +This script will _power up_ your new server with the [*nginx-proxy*](https://github.com/nginx-proxy/nginx-proxy), where you will be able to host multiple sites, +auto renewing Let´s Encrypt certificates! ❤️ + +We strongly recommend you (please do! 🙏) to read all documentation before starting in production as well as the [nginx-proxy docs](https://github.com/nginx-proxy/nginx-proxy). + +> To access the previous version of this project please access [version 0.4](https://github.com/evertramos/nginx-proxy-automation/tree/v0.4). + +### Upgrading from previous version + +If you are upgrading from the previous version please follow the guide below carefully: + +https://github.com/evertramos/nginx-proxy-automation/blob/master/docs/upgrade-guide.md + +## Prerequisites + +1. 🐧 Linux! (just in case...) + +> Please check all requirements at [requirements](/docs/requirements.md). + +In order to use this compose file (docker-compose.yml) you must have: + +2. 🐋 Docker installed (https://docs.docker.com/engine/installation/) + +3. Docker-compose installed (https://docs.docker.com/compose/install/) + +> I have an [easy-server](https://github.com/evertramos/easy-server) for myself which I use to install +> docker and docker-compose in new servers and some aliases and other stuff. Feel free to use it, **but** +> it is not related to this repo and maintainance it's for my own use only. Check './install/docker' folder. + +Also, you will need to make sure you have: + +4. Port 80 and 443 available for binding - which means apache/nginx or other web services should not be + running in your server + +5. Server must be accessible by a public IP address + +## How to use it + +1. Clone this repository **using the option _--recurse-submodules_**: + +```bash +git clone --recurse-submodules https://github.com/evertramos/nginx-proxy-automation.git proxy +``` + +> Make sure you use the option '--recurse-submodules' once we use an external module in this project, please check +> [basescript](https://github.com/evertramos/basescript) + +> Please note we use 'proxy' as folder at the end. But you can change it to whatever fits you better + +2. 🚀 Run the script 'fresh_start.sh' + +```bash +cd proxy/bin +./fresh-start.sh +``` +This script will walk you through all config process. + +When it finishes you are good to go! :checkered_flag: + +> ✈️ If you are in a 'hurry' just run `$ ./fresh-start.sh --yes -e your_email@domain --skip-docker-image-check` + +> ⚠️ You can check all available options to run the script `$ ./fresh-start.sh --help` + +> 🗒️ From version _v0.3_ the script will output logs to _/var/log/basescript.log_ + +3. Fire your new site with the following options: + +```yaml + VIRTUAL_HOST=your.domain.com + LETSENCRYPT_HOST=your.domain.com + LETSENCRYPT_EMAIL=your.email@your.domain.com + NETWORK=proxy +``` + +The fresh start script asked you for the proxy network name if you changed set a name differente from +the default please update the option *'NETWORK'* in the examples below before running it. + +- Simple site without Let's Encrypt certificate +```bash +docker run -d -e VIRTUAL_HOST=your.domain.com \ + --network=proxy \ + --name my_app \ + httpd:alpine +``` + +- To have SSL in your web/app you must add the option `-e LETSENCRYPT_HOST=your.domain.com`, as follow: + +```bash +docker run -d -e VIRTUAL_HOST=your.domain.com \ + -e LETSENCRYPT_HOST=your.domain.com \ + -e LETSENCRYPT_EMAIL=your.email@your.domain.com \ + --network=proxy \ + --name my_app \ + httpd:alpine +``` + +> You don´t need to open port *443* in your container, the certificate validation is managed by the web proxy + +> Please note that when running a new container to generate certificates with Let's Encrypt +> (`-e LETSENCRYPT_HOST=your.domain.com`), it may take a few minutes + + +## Further Options + +1. Basic Authentication Support + +In order to be able to secure your virtual host with basic authentication, you must create a htpasswd file +within `${NGINX_FILES_PATH}/htpasswd/${VIRTUAL_HOST}` via: + +```bash +sudo sh -c "echo -n '[username]:' >> ${NGINX_FILES_PATH}/htpasswd/${VIRTUAL_HOST}" +sudo sh -c "openssl passwd -apr1 >> ${NGINX_FILES_PATH}/htpasswd/${VIRTUAL_HOST}" +``` + +> Please replace the `${NGINX_FILES_PATH}` with real path to information, replace `[username]` with your username and `${VIRTUAL_HOST}` with your host's domain. You will be prompted for a password. + +2. Using different networks + +If you want to use more than one network to better organize your environment you could set the option `SERVICE_NETWORK` in our `.env.sample` or you can just create your own network and attach all your containers as of: + +```bash +docker network create myownnetwork +docker network connect myownnetwork nginx-web +docker network connect myownnetwork nginx-gen +docker network connect myownnetwork nginx-letsencrypt +``` + +3. Ports + +If your service container runs on port 8545 you probably will need to add the `VIRTUAL_PORT` environment variable to your container, +in the `docker-compose.yml`, so it can be proxied, as of: + +```bash +parity + image: parity/parity:v1.8.9 + [...] + environment: + [...] + VIRTUAL_PORT: 8545 +``` + +Or as of below: + +```bash +docker run [...] -e VIRTUAL_PORT=8545 [...] +``` + +4. Restarting proxy container + +In some cases you will need to restart the proxy in order to read, as an example, the Basic Auth, if you set it after your service container is already up and running. So, the way I use to restart the proxy (NGINX) is as following, which has no downtime: + +```bash +docker exec -it ${NGINX_WEB} nginx -s reload +``` + +Where *${NGINX_WEB}* is your proxy container name, which in the original `.env` file is set as *nginx-web*. + +5. **sudo** options + +If you need to save the nginx-proxy data files in a folder which the user running 'fresh-start.sh' script does not have access, you might accomplish that using _sudo_. In order to allow the script to run some commands with _sudo_ you need to set _true_ to the variable ['ALLOW_RUN_WITH_SUDO'](https://github.com/evertramos/nginx-proxy-automation/blob/d48b2477ed28cbda37738046079e35df219ba3e9/.env.sample#L20) at '.env.sample' file **before** running fresh-start.sh script, as of: + +```bash +# Allow run commands with sudo if needed +ALLOW_RUN_WITH_SUDO=true +``` + +## Testing nginx-proxy + +1. Run the script `test.sh` informing your domain already configured in your DNS to point out to your server as follow: + +```bash +./test.sh your.domain.com +``` + +or simply run: + +```bash +docker run -dit -e VIRTUAL_HOST=your.domain.com --network=proxy --name test-web httpd:alpine +``` + +> If you want to test the Let's Encrypt certificate as well use `ssl_test.sh your.domain.com` + +Access your browser with your domain! + +To stop and remove your test container run our `stop.sh` script: + +```bash +./stop.sh +``` + +Or simply run: + +```bash +docker stop test-web && docker rm test-web +``` + +## **PRODUCTION** ⚠️ [IMPORTANT] + +If you are using this project in production enviroment, check all license involved and consider the following recomendation: + +- [rootless docker](https://docs.docker.com/engine/security/rootless/) +- [docker compose files](https://docs.docker.com/compose/production/) + +## Other projects using nginx-proxy +Following are links to docker containers using this web proxy: +1. [docker-wordpress-letsencrypt](https://github.com/evertramos/docker-wordpress-letsencrypt) +2. [docker-portainer-letsencrypt](https://github.com/evertramos/docker-portainer-letsencrypt) +3. [docker-nextcloud-letsencrypt](https://github.com/evertramos/docker-nextcloud-letsencrypt) +4. [docker-registry-letsencrypt](https://github.com/evertramos/docker-registry-letsencrypt) +5. [gitlab-docker-letsencrypt](https://github.com/steevepay/gitlab-docker-letsencrypt) +6. [docker-webtrees-letsencrypt](https://github.com/mstroppel/docker-webtrees-letsencrypt) + +## Running this Proxy on a Synology NAS +Please checkout this [howto](https://github.com/evertramos/nginx-proxy-automation/blob/master/docs/HOWTO-Synlogy.md). + diff --git a/docs/requirements.md b/docs/requirements.md new file mode 100644 index 00000000..292cb11a --- /dev/null +++ b/docs/requirements.md @@ -0,0 +1,46 @@ +# Requirements to run this automation script + + +## Environment +- Linux + +## Softwares +- Bash +- Docker +- Docker Compose +- Git +- Curl +- Dpkg +- Md5sum + +## Used functions +- sudo +- source +- cd +- cp +- mv +- dirname +- type +- command +- systemctl +- echo +- printf +- read +- sed +- awk +- wget +- cat +- cut +- head +- tr +- grep +- rm +- trap +- dpkg +- tput +- md5sum +- ip +- git +- docker +- docker-compose +- curl diff --git a/docs/upgrade-guide.md b/docs/upgrade-guide.md new file mode 100644 index 00000000..26498cec --- /dev/null +++ b/docs/upgrade-guide.md @@ -0,0 +1,133 @@ +# Upgrading guide + +Here we will try to cover all aspects we faced in a real production environment when migrating from the previous version of this project to the newst version. + +## From v0.4 to v0.5 + +The version v0.5 was a big step into automation. We 'conquer the world'! + +> I update one of the production server and got a _96 seconds_ of downtime, with no complaint from clients. +> Some of them did not even notice, but all were advised about the update and the possible downtime in case of failure. + +> If you can not afford this downtime there is a couple way around on this but you will need +a couple things... new server (temporary), set a dns rules to create the new certificates +copy all files to the new server and do the following, after all is ready, redirect the dns +to the new server and than copy the temp server to the production, fire all services, test +and redirect the dns to the new server. Be aware that changes made during this proccess might +need to be updated in the containers when syncing files from one server to another. + +So, let's go. First thing first! + +1. Backup EVERYTHING! I would suggest backup in the server and somewhere else (not in the server) + +2. Update the git repo with the new version (:warning:) + + 2.1 Copy _docker-compose.yml_ (or the _docker-compose-multiple-networks.yml_ if you used this option) and _.env_ file + + ```bash + $ cp docker-compose.yml docker-compose-old.yml + $ cp .env .env-old + ``` + + > We will use this do stop the current services + + 2.2 Reset all changes in the repo + + This is required to update to the latest version + + ```bash + $ git reset --hard + ``` + + 2.3 Pull and Checkout master + + ```bash + $ git pull origin master + $ git checkout master + ``` + + 2.4 Set the **basescript** submodule + + If you notice the submodule folder used in this project ([basescript](https://github.com/evertramos/basescript/)) + is present in the master branch we just checkout, but it is empty, so we need to fix it (init and update). + + ```bash + $ git submodule init + $ git submodule update + ``` + + > The _basescript_ folder should not be empty after the commands above + +3. Run the _fresh-start.sh_ script (:construction:) + + Here we will run the _fresh-start.sh_ script in order to create all new settings that we will use. + Please do it carefully. You might use different names for proxy services. + + ```bash + $ cd bin + $ ./fresh-start.sh + ``` + + In most cases you will get the following _'error'_, which is expected: + + ![fresh-start-expected-error](https://user-images.githubusercontent.com/905951/113016796-33aaa080-9155-11eb-845d-aa712294236d.png) + + The error above is related to port binding, once port 80 is already binded to the current nginx-proxy container. + + > [IMPORTANT] If you use the *same service name* for all containers and the same network name you might not receive the error above + > and you should be ready to go at this point. Check the your running sites at the browser to see if everything is up and running. + + ⚠️ if you do not get the error above and your sites are NOT working, you might checkthe network name and go for the next item. + +4. Adding the running containers to the new network + + If you keep the same network name you might skip this item, but if not, you must add all running containers to the new network + created by the _fresh-start.sh_ script. + + ```bash + $ docker network connect [YOUR_NEW_NETWORK_NAME] [CONTAINER_NAME] + ``` + + > Run the command above for all containers connected to the proxy and remember to update the network name in the docker-compose file + > for the all sites + +5. Restart proxy with new service + + At this point all sites should be still up and running, so keep it cool and let's see if all will work as expected. + + After all containers are connected to the new proxy network (if the case) you will stop the current proxy services and start the new one. + We did it in one command line to reduce the downtime. + + ```bash + $ docker-compose --file docker-compose-old.yml down && docker-compose up -d + ``` + + Check your sites to see if it is all running, if some of them are not working, you might check the letsencrypt container logs to see if + there was a problem issuing new certificates. + + If something else happen and you must reverse it quickly just follow the next step. But try to check the logs first, it might take a few + minutes to fire new certificates with Let's Encrypt so, depending on the quantity of sites you are running in your server it might take + some time to issue it all. + +6. Reverting to the old proxy + + You can retore backup files and start the same exact environmen you had previously this upgrade guide, but there is a quicker way to restore your sites. + Just run the following: + + ```bash + $ docker-compose down && docker-compose --file docker-compose-old.yml --env-file .env-old up -d + ``` + + > The command above will stop the new version and fire the previous version of your proxy, so, after this command evertyhing should 'be back to normal' + > as it was before the update, but keep in mind to find the errors if they occured and update it. + +7. Clean up + + After having all work done you might remove unused file such as: + + + ```bash + $ rm docker-compose-old.yml .env-old + ``` + +> If you get any erros when updating please post on the [**upgrade discussion**](https://github.com/evertramos/basescript/discussions/5) (avoid creating new issues). diff --git a/nginx.tmpl b/nginx.tmpl index d861050a..07e2b50e 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -1,5 +1,8 @@ {{ $CurrentContainer := where $ "ID" .Docker.CurrentContainerID | first }} +{{ $external_http_port := coalesce $.Env.HTTP_PORT "80" }} +{{ $external_https_port := coalesce $.Env.HTTPS_PORT "443" }} + {{ define "upstream" }} {{ if .Address }} {{/* If we got the containers from swarm and this container's port is published to host, use host IP:PORT */}} @@ -19,7 +22,50 @@ server 127.0.0.1 down; {{ end }} {{ end }} - + +{{ end }} + +{{ define "ssl_policy" }} + {{ if eq .ssl_policy "Mozilla-Modern" }} + ssl_protocols TLSv1.3; + {{/* nginx currently lacks ability to choose ciphers in TLS 1.3 in configuration, see https://trac.nginx.org/nginx/ticket/1529 /*}} + {{/* a possible workaround can be modify /etc/ssl/openssl.cnf to change it globally (see https://trac.nginx.org/nginx/ticket/1529#comment:12 ) /*}} + {{/* explicitly set ngnix default value in order to allow single servers to override the global http value */}} + ssl_ciphers HIGH:!aNULL:!MD5; + ssl_prefer_server_ciphers off; + {{ else if eq .ssl_policy "Mozilla-Intermediate" }} + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384'; + ssl_prefer_server_ciphers off; + {{ else if eq .ssl_policy "Mozilla-Old" }} + ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; + ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA'; + ssl_prefer_server_ciphers on; + {{ else if eq .ssl_policy "AWS-TLS-1-2-2017-01" }} + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:AES128-GCM-SHA256:AES128-SHA256:AES256-GCM-SHA384:AES256-SHA256'; + ssl_prefer_server_ciphers on; + {{ else if eq .ssl_policy "AWS-TLS-1-1-2017-01" }} + ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; + ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA'; + ssl_prefer_server_ciphers on; + {{ else if eq .ssl_policy "AWS-2016-08" }} + ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; + ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA'; + ssl_prefer_server_ciphers on; + {{ else if eq .ssl_policy "AWS-2015-05" }} + ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; + ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:DES-CBC3-SHA'; + ssl_prefer_server_ciphers on; + {{ else if eq .ssl_policy "AWS-2015-03" }} + ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; + ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:DHE-DSS-AES128-SHA:DES-CBC3-SHA'; + ssl_prefer_server_ciphers on; + {{ else if eq .ssl_policy "AWS-2015-02" }} + ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; + ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:DHE-DSS-AES128-SHA'; + ssl_prefer_server_ciphers on; + {{ end }} {{ end }} # If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the @@ -65,6 +111,10 @@ log_format vhost '$host $remote_addr - $remote_user [$time_local] ' access_log off; +{{/* Get the SSL_POLICY defined by this container, falling back to "Mozilla-Intermediate" */}} +{{ $ssl_policy := or ($.Env.SSL_POLICY) "Mozilla-Intermediate" }} +{{ template "ssl_policy" (dict "ssl_policy" $ssl_policy) }} + {{ if $.Env.RESOLVERS }} resolver {{ $.Env.RESOLVERS }}; {{ end }} @@ -88,27 +138,30 @@ proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port; proxy_set_header Proxy ""; {{ end }} +{{ $access_log := (or (and (not $.Env.DISABLE_ACCESS_LOGS) "access_log /var/log/nginx/access.log vhost;") "") }} + {{ $enable_ipv6 := eq (or ($.Env.ENABLE_IPV6) "") "true" }} server { server_name _; # This is just an invalid value which will never trigger on a real hostname. - listen 80; + listen {{ $external_http_port }}; {{ if $enable_ipv6 }} - listen [::]:80; + listen [::]:{{ $external_http_port }}; {{ end }} - access_log /var/log/nginx/access.log vhost; + {{ $access_log }} return 503; } {{ if (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }} server { server_name _; # This is just an invalid value which will never trigger on a real hostname. - listen 443 ssl http2; + listen {{ $external_https_port }} ssl http2; {{ if $enable_ipv6 }} - listen [::]:443 ssl http2; + listen [::]:{{ $external_https_port }} ssl http2; {{ end }} - access_log /var/log/nginx/access.log vhost; + {{ $access_log }} return 503; + ssl_session_cache shared:SSL:50m; ssl_session_tickets off; ssl_certificate /etc/nginx/certs/default.crt; ssl_certificate_key /etc/nginx/certs/default.key; @@ -161,13 +214,13 @@ upstream {{ $upstream_name }} { {{ $network_tag := or (first (groupByKeys $containers "Env.NETWORK_ACCESS")) "external" }} {{/* Get the HTTPS_METHOD defined by containers w/ the same vhost, falling back to "redirect" */}} -{{ $https_method := or (first (groupByKeys $containers "Env.HTTPS_METHOD")) "redirect" }} +{{ $https_method := or (first (groupByKeys $containers "Env.HTTPS_METHOD")) (or $.Env.HTTPS_METHOD "redirect") }} -{{/* Get the SSL_POLICY defined by containers w/ the same vhost, falling back to "Mozilla-Intermediate" */}} -{{ $ssl_policy := or (first (groupByKeys $containers "Env.SSL_POLICY")) "Mozilla-Intermediate" }} +{{/* Get the SSL_POLICY defined by containers w/ the same vhost, falling back to empty string (use default) */}} +{{ $ssl_policy := or (first (groupByKeys $containers "Env.SSL_POLICY")) "" }} {{/* Get the HSTS defined by containers w/ the same vhost, falling back to "max-age=31536000" */}} -{{ $hsts := or (first (groupByKeys $containers "Env.HSTS")) "max-age=31536000" }} +{{ $hsts := or (first (groupByKeys $containers "Env.HSTS")) (or $.Env.HSTS "max-age=31536000") }} {{/* Get the VIRTUAL_ROOT By containers w/ use fastcgi root */}} {{ $vhost_root := or (first (groupByKeys $containers "Env.VIRTUAL_ROOT")) "/var/www/public" }} @@ -193,58 +246,42 @@ upstream {{ $upstream_name }} { {{ if eq $https_method "redirect" }} server { server_name {{ $host }}; - listen 80 {{ $default_server }}; + listen {{ $external_http_port }} {{ $default_server }}; {{ if $enable_ipv6 }} - listen [::]:80 {{ $default_server }}; + listen [::]:{{ $external_http_port }} {{ $default_server }}; {{ end }} - access_log /var/log/nginx/access.log vhost; - return 301 https://$host$request_uri; + {{ $access_log }} + + # Do not HTTPS redirect Let'sEncrypt ACME challenge + location /.well-known/acme-challenge/ { + auth_basic off; + allow all; + root /usr/share/nginx/html; + try_files $uri =404; + break; + } + + location / { + return 301 https://$host$request_uri; + } } {{ end }} server { server_name {{ $host }}; - listen 443 ssl http2 {{ $default_server }}; + listen {{ $external_https_port }} ssl http2 {{ $default_server }}; {{ if $enable_ipv6 }} - listen [::]:443 ssl http2 {{ $default_server }}; + listen [::]:{{ $external_https_port }} ssl http2 {{ $default_server }}; {{ end }} - access_log /var/log/nginx/access.log vhost; + {{ $access_log }} {{ if eq $network_tag "internal" }} # Only allow traffic from internal clients include /etc/nginx/network_internal.conf; {{ end }} - {{ if eq $ssl_policy "Mozilla-Modern" }} - ssl_protocols TLSv1.2 TLSv1.3; - ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256'; - {{ else if eq $ssl_policy "Mozilla-Intermediate" }} - ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; - ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:!DSS'; - {{ else if eq $ssl_policy "Mozilla-Old" }} - ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; - ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:HIGH:SEED:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!RSAPSK:!aDH:!aECDH:!EDH-DSS-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!SRP'; - {{ else if eq $ssl_policy "AWS-TLS-1-2-2017-01" }} - ssl_protocols TLSv1.2 TLSv1.3; - ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:AES128-GCM-SHA256:AES128-SHA256:AES256-GCM-SHA384:AES256-SHA256'; - {{ else if eq $ssl_policy "AWS-TLS-1-1-2017-01" }} - ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; - ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA'; - {{ else if eq $ssl_policy "AWS-2016-08" }} - ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; - ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA'; - {{ else if eq $ssl_policy "AWS-2015-05" }} - ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; - ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:DES-CBC3-SHA'; - {{ else if eq $ssl_policy "AWS-2015-03" }} - ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; - ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:DHE-DSS-AES128-SHA:DES-CBC3-SHA'; - {{ else if eq $ssl_policy "AWS-2015-02" }} - ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; - ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:DHE-DSS-AES128-SHA'; - {{ end }} + {{ template "ssl_policy" (dict "ssl_policy" $ssl_policy) }} - ssl_prefer_server_ciphers on; ssl_session_timeout 5m; ssl_session_cache shared:SSL:50m; ssl_session_tickets off; @@ -262,7 +299,7 @@ server { ssl_trusted_certificate {{ printf "/etc/nginx/certs/%s.chain.pem" $cert }}; {{ end }} - {{ if (and (ne $https_method "noredirect") (ne $hsts "off")) }} + {{ if (not (or (eq $https_method "noredirect") (eq $hsts "off"))) }} add_header Strict-Transport-Security "{{ trim $hsts }}" always; {{ end }} @@ -278,8 +315,10 @@ server { uwsgi_pass {{ trim $proto }}://{{ trim $upstream_name }}; {{ else if eq $proto "fastcgi" }} root {{ trim $vhost_root }}; - include fastcgi.conf; + include fastcgi_params; fastcgi_pass {{ trim $upstream_name }}; + {{ else if eq $proto "grpc" }} + grpc_pass {{ trim $proto }}://{{ trim $upstream_name }}; {{ else }} proxy_pass {{ trim $proto }}://{{ trim $upstream_name }}; {{ end }} @@ -302,11 +341,11 @@ server { server { server_name {{ $host }}; - listen 80 {{ $default_server }}; + listen {{ $external_http_port }} {{ $default_server }}; {{ if $enable_ipv6 }} listen [::]:80 {{ $default_server }}; {{ end }} - access_log /var/log/nginx/access.log vhost; + {{ $access_log }} {{ if eq $network_tag "internal" }} # Only allow traffic from internal clients @@ -325,8 +364,10 @@ server { uwsgi_pass {{ trim $proto }}://{{ trim $upstream_name }}; {{ else if eq $proto "fastcgi" }} root {{ trim $vhost_root }}; - include fastcgi.conf; + include fastcgi_params; fastcgi_pass {{ trim $upstream_name }}; + {{ else if eq $proto "grpc" }} + grpc_pass {{ trim $proto }}://{{ trim $upstream_name }}; {{ else }} proxy_pass {{ trim $proto }}://{{ trim $upstream_name }}; {{ end }} @@ -345,11 +386,11 @@ server { {{ if (and (not $is_https) (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }} server { server_name {{ $host }}; - listen 443 ssl http2 {{ $default_server }}; + listen {{ $external_https_port }} ssl http2 {{ $default_server }}; {{ if $enable_ipv6 }} - listen [::]:443 ssl http2 {{ $default_server }}; + listen [::]:{{ $external_https_port }} ssl http2 {{ $default_server }}; {{ end }} - access_log /var/log/nginx/access.log vhost; + {{ $access_log }} return 500; ssl_certificate /etc/nginx/certs/default.crt; diff --git a/scripts/update.sh b/scripts/update.sh index 6f5c15f3..614811c4 100755 --- a/scripts/update.sh +++ b/scripts/update.sh @@ -3,7 +3,7 @@ # # This scrip update the web proxy without downtime # -# Source: https://github.com/evertramos/docker-compose-letsencrypt-nginx-proxy-companion +# Source: https://github.com/evertramos/nginx-proxy-automation # # 1. Check if .env file exists diff --git a/start.sh b/start.sh deleted file mode 100755 index b1fc35df..00000000 --- a/start.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/bin/bash - -# -# This file should be used to prepare and run your WebProxy after set up your .env file -# Source: https://github.com/evertramos/docker-compose-letsencrypt-nginx-proxy-companion -# - -# 1. Check if .env file exists -if [ -e .env ]; then - source .env -else - echo "Please set up your .env file before starting your environment." - exit 1 -fi - -# 2. Create docker network -docker network create $NETWORK $NETWORK_OPTIONS - -# 3. Verify if second network is configured -if [ ! -z ${SERVICE_NETWORK+X} ]; then - docker network create $SERVICE_NETWORK $SERVICE_NETWORK_OPTIONS -fi - -# 4. Download the latest version of nginx.tmpl -curl https://raw.githubusercontent.com/jwilder/nginx-proxy/master/nginx.tmpl > nginx.tmpl - -# 5. Update local images -docker-compose pull - -# 6. Add any special configuration if it's set in .env file - -# Check if user set to use Special Conf Files -if [ ! -z ${USE_NGINX_CONF_FILES+X} ] && [ "$USE_NGINX_CONF_FILES" = true ]; then - - # Create the conf folder if it does not exists - mkdir -p $NGINX_FILES_PATH/conf.d - - # Copy the special configurations to the nginx conf folder - cp -R ./conf.d/* $NGINX_FILES_PATH/conf.d - - # Check if there was an error and try with sudo - if [ $? -ne 0 ]; then - sudo cp -R ./conf.d/* $NGINX_FILES_PATH/conf.d - fi - - # If there was any errors inform the user - if [ $? -ne 0 ]; then - echo - echo "#######################################################" - echo - echo "There was an error trying to copy the nginx conf files." - echo "The webproxy will still work, your custom configuration" - echo "will not be loaded." - echo - echo "#######################################################" - fi -fi - -# 7. Start proxy - -# Check if you have multiple network -if [ -z ${SERVICE_NETWORK+X} ]; then - docker-compose up -d -else - docker-compose -f docker-compose-multiple-networks.yml up -d -fi - -exit 0 diff --git a/test_start.sh b/test_start.sh deleted file mode 100755 index 8fb1058a..00000000 --- a/test_start.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -# Set up your DOMAIN -if [ $# -eq 0 ]; then - echo "Please inform your domain name to test your proxy." - echo "./test_start.sh $1" - exit 1 -else - DOMAIN=$1 -fi - -# Read your .env file -source .env - -# Testing your proxy -if [ -z ${SERVICE_NETWORK+X} ]; then - docker run -d -e VIRTUAL_HOST=$DOMAIN --network=$NETWORK --name test-web httpd:alpine -else - docker run -d -e VIRTUAL_HOST=$DOMAIN --network=$SERVICE_NETWORK --name test-web httpd:alpine -fi - -exit 0 diff --git a/test_start_ssl.sh b/test_start_ssl.sh deleted file mode 100755 index a14bd3a5..00000000 --- a/test_start_ssl.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash - -NAME=test-web - - -# Set up your DOMAIN -if [ $# -eq 0 ]; then - echo "Please inform your domain name to test your proxy." - echo "./test_start_ssl.sh $1" - exit 1 -else - DOMAIN=$1 -fi - -# Read your .env file -source .env - -# Testing your proxy -if [ -z ${SERVICE_NETWORK+X} ]; then - docker run -d -e VIRTUAL_HOST=$DOMAIN -e LETSENCRYPT_HOST=$DOMAIN --network=$NETWORK --name $NAME httpd:alpine -else - docker run -d -e VIRTUAL_HOST=$DOMAIN -e LETSENCRYPT_HOST=$DOMAIN --network=$SERVICE_NETWORK --name $NAME httpd:alpine -fi - -exit 0 diff --git a/test_stop.sh b/test_stop.sh deleted file mode 100755 index 065392a0..00000000 --- a/test_stop.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -# Stop and remove test enviornment -docker stop test-web && docker rm test-web - -exit 0