Last active
July 26, 2024 22:55
-
-
Save aaccioly/409205f5b87228cae7a69aafa31a0924 to your computer and use it in GitHub Desktop.
Script to deploy certificates generated with DNSroboCert to nginx-proxy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
######################################################################################### | |
# deploy_certificates.sh | |
# | |
# Copyright (c) 2023 Anthony Accioly <[email protected]> | |
# | |
# SPDX-License-Identifier: MIT | |
# | |
# Description: | |
# This Bash script is used to deploy HTTPS/TLS certificates from the DNSroboCert | |
# Let's Encrypt `live` folder to Docker's `nginx-proxy` `nginx/certs` folder, | |
# following specific naming conventions for the output files. After deploying | |
# the certificates, it restarts Nginx to apply the changes. | |
# | |
# Usage: | |
# ./deploy_certificates.sh [-v|--verbose] [<input_directory>] [<output_directory>] | |
# | |
# Arguments: | |
# - -v, --verbose: Optional flag to enable verbose mode for detailed logging. | |
# - <input_directory>: Cerbot's style directory containing subfolders with | |
# certificate files. By default, it is '/etc/letsencrypt/live'. | |
# - <output_directory>: The nginx-proxy container certs folder, where | |
# certificate files will be copied. By default, it is '/etc/nginx/certs'. | |
# | |
# Example: | |
# ./deploy_certificates.sh -v /etc/letsencrypt/live /etc/nginx/certs | |
# | |
# Notes: | |
# - The script assumes the following naming conventions for certificate files: | |
# - privkey.pem -> [name of the domain].key | |
# - fullchain.pem -> [name of the domain].crt | |
# - chain.pem -> [name of the domain].chain.pem | |
# | |
# - The script will overwrite existing files in the output directory if they have | |
# the same names as the destination files. | |
# | |
# - When verbose mode is enabled, the script provides detailed logging of actions. | |
# | |
# Last Revised: 25 September 2023 | |
######################################################################################### | |
# Define colors for printing messages | |
GREEN="\e[32m" | |
RED="\e[31m" | |
RESET="\e[0m" | |
# Function to display an error message, print usage, and exit with a non-zero status code | |
die() { | |
echo -e "${RED}Error: $1${RESET}" >&2 | |
if [[ "$2" == "usage" ]]; then | |
print_usage | |
fi | |
exit 1 | |
} | |
# Function to display the script's usage message | |
print_usage() { | |
echo "Usage: $0 [-v|--verbose] [<input_directory>] [<output_directory>]" | |
echo "Arguments:" | |
echo " - -v, --verbose: Optional flag to enable verbose mode for detailed logging." | |
echo " - <input_directory>: Cerbot's style directory containing subfolders with" | |
echo " certificate files. By default, it is '/etc/letsencrypt/live'." | |
echo " - <output_directory>: The nginx-proxy container certs folder, where" | |
echo " certificate files will be copied. By default, it is '/etc/nginx/certs'." | |
echo "Example:" | |
echo " $0 -v /etc/letsencrypt/live /etc/nginx/certs" | |
} | |
# Function to display a success message | |
success() { | |
echo -e "${GREEN}$1${RESET}" | |
} | |
# Function to display verbose output | |
verbose() { | |
if [[ "$verbose_mode" == true ]]; then | |
echo -e "$1" | |
fi | |
} | |
# Function to copy a file and log the action | |
copy_file() { | |
local src_file="$1" | |
local dest_file="$2" | |
local file_description="$3" | |
verbose "Copying $file_description from '$src_file' to '$dest_file'." | |
cp -f "$src_file" "$dest_file" || die "Failed to copy $file_description from '$src_file' to '$dest_file'." | |
verbose "Copied $file_description to '$dest_file'." | |
} | |
# Restart Nginx | |
restart_nginx() { | |
verbose "Restarting Nginx..." | |
nginx -s reload || die "Failed to restart Nginx." | |
verbose "Nginx has been restarted." | |
} | |
# Initialize variables with default values | |
verbose_mode=false | |
input_dir="" | |
output_dir="" | |
# Process command line arguments | |
while [[ $# -gt 0 ]]; do | |
case "$1" in | |
-v|--verbose) | |
verbose_mode=true | |
shift | |
;; | |
-*) | |
die "Invalid flag: $1" usage | |
;; | |
*) | |
if [ -z "$input_dir" ]; then | |
input_dir="$1" | |
elif [ -z "$output_dir" ]; then | |
output_dir="$1" | |
else | |
die "Invalid argument: $1" usage | |
fi | |
shift | |
;; | |
esac | |
done | |
# Use default values if input directory is not provided | |
if [ -z "$input_dir" ]; then | |
input_dir="/etc/letsencrypt/live" | |
fi | |
# Use default values if output directory is not provided | |
if [ -z "$output_dir" ]; then | |
output_dir="/etc/nginx/certs" | |
fi | |
# Check if the input directory exists | |
if [ ! -d "$input_dir" ]; then | |
die "Input directory '$input_dir' does not exist." usage | |
fi | |
# Check if the output directory exists, if not, create it | |
if [ ! -d "$output_dir" ]; then | |
mkdir -p "$output_dir" || die "Failed to create output directory '$output_dir'." usage | |
fi | |
verbose "Verbose mode is enabled." | |
# Loop through subfolders in the input directory | |
for subfolder in "$input_dir"/*; do | |
if [ -d "$subfolder" ]; then | |
domain_name=$(basename "$subfolder") | |
verbose "Deploying HTTPS/TLS certificates for '$domain_name'." | |
# Copy privkey.pem to [name of subfolder].key | |
copy_file "$subfolder/privkey.pem" "$output_dir/$domain_name.key" "privkey.pem" | |
# Copy fullchain.pem to [name of subfolder].crt | |
copy_file "$subfolder/fullchain.pem" "$output_dir/$domain_name.crt" "fullchain.pem" | |
# Copy chain.pem to [name of subfolder].chain.pem | |
copy_file "$subfolder/chain.pem" "$output_dir/$domain_name.chain.pem" "chain.pem" | |
success "HTTPS/TLS certificates deployed for '$domain_name'." | |
fi | |
done | |
success "Deployment completed." | |
# Restart Nginx after deploying certificates | |
restart_nginx | |
success "Nginx restarted after certificate deployment." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is a script meant to deploy Let's encrypt TLS certificates generated by @adferrand's DNSroboCert to nginx-proxy
docker-compose.yml
And here is an sample DNSRoboCert's configuration that triggers the above script:
dnsrobocert/config.yml
This is a brilliant way to generate and keep wildcard certificates up to date (functionality not yet available in acme-companion). And in its own way it address the underlying asks of nginx-proxy/acme-companion#319, adferrand/dnsrobocert#669 and adferrand/dnsrobocert#764.
I'm open sourcing this under MIT License, feel free to use in as you see fit.