Skip to content

Instantly share code, notes, and snippets.

@SpotlightForBugs
Created October 26, 2025 19:24
Show Gist options
  • Save SpotlightForBugs/a8fa9e2f7ded0c717f47ec0b7718efd1 to your computer and use it in GitHub Desktop.
Save SpotlightForBugs/a8fa9e2f7ded0c717f47ec0b7718efd1 to your computer and use it in GitHub Desktop.
Automates most of adding Cloudflare Origin Certificates to Coolify (Traefic required)
#!/bin/bash
# --- Configuration ---
# Set the base directory for the Coolify proxy
PROXY_DIR="/data/coolify/proxy"
CERT_DIR="$PROXY_DIR/certs"
DYNAMIC_CONF_DIR="$PROXY_DIR/dynamic"
DYNAMIC_CONF_FILE="$DYNAMIC_CONF_DIR/custom-certs.yaml"
# --- Helper Functions ---
# Function to add a certificate entry to the dynamic YAML configuration
add_to_config() {
local domain_name=$1
echo "⚙️ Updating dynamic configuration for '$domain_name'..."
# Ensure the dynamic config directory exists
mkdir -p "$DYNAMIC_CONF_DIR"
# If the config file is new or empty, add the required TLS header
if ! grep -q "tls:" "$DYNAMIC_CONF_FILE" 2>/dev/null; then
echo "tls:" > "$DYNAMIC_CONF_FILE"
echo " certificates:" >> "$DYNAMIC_CONF_FILE"
fi
# Check if the entry already exists to prevent duplicates
if grep -q "certs/${domain_name}.crt" "$DYNAMIC_CONF_FILE"; then
echo "⚠️ Configuration for '$domain_name' already exists. Skipping."
return
fi
# Append the new certificate details.
# The paths MUST start with /traefik/ as this is the path inside the container.
{
echo " - certFile: /traefik/certs/${domain_name}.crt"
echo " keyFile: /traefik/certs/${domain_name}.key"
} >> "$DYNAMIC_CONF_FILE"
echo "✅ Dynamic configuration updated."
}
# Function to detect unconfigured certificate files
detect_unconfigured_certs() {
echo "🔎 Searching for unconfigured certificate files..."
shopt -s nullglob # Prevent errors if no files are found
local unconfigured_certs=()
for cert_path in "$CERT_DIR"/*.crt; do
local domain_name
domain_name=$(basename "$cert_path" .crt)
local key_path="$CERT_DIR/${domain_name}.key"
# Check if a matching key file exists
if [[ -f "$key_path" ]]; then
# Check if it's already in the config file
if ! grep -q "certs/${domain_name}.crt" "$DYNAMIC_CONF_FILE" 2>/dev/null; then
unconfigured_certs+=("$domain_name")
fi
fi
done
if [ ${#unconfigured_certs[@]} -gt 0 ]; then
echo "💡 Found unconfigured certificate pairs:"
for domain in "${unconfigured_certs[@]}"; do
echo " - $domain"
done
echo ""
read -p "Do you want to add them to the configuration now? (y/n): " choice
if [[ "$choice" == "y" || "$choice" == "Y" ]]; then
for domain in "${unconfigured_certs[@]}"; do
add_to_config "$domain"
done
fi
else
echo "👍 All existing certificate files seem to be configured."
fi
}
# --- Main Script Logic ---
# Ensure we're running with root privileges
if [ "$EUID" -ne 0 ]; then
echo "❌ Please run this script with sudo."
exit 1
fi
# Ensure the main certificate directory exists
mkdir -p "$CERT_DIR"
if [ $? -ne 0 ]; then
echo "❌ Error: Could not create directory '$CERT_DIR'. Please check permissions."
exit 1
fi
# Clean up temporary files on exit
trap 'rm -f cert.tmp key.tmp' EXIT
clear
echo "--- SSL Certificate & Config Manager ---"
echo "Manages certificates and Traefik dynamic configuration."
echo
# Run the auto-discovery feature first
detect_unconfigured_certs
echo "----------------------------------------"
while true; do
echo
read -p "Enter the domain name to add (e.g., my-app.com) or press Enter to quit: " DOMAIN
if [[ -z "$DOMAIN" ]]; then
echo "Exiting."
break
fi
echo -e "\n➡️ Opening nano for the CERTIFICATE for '$DOMAIN'."
echo " Paste the full certificate chain, then press Ctrl+O, Enter (save), and Ctrl+X (exit)."
nano cert.tmp
if [[ ! -s "cert.tmp" ]]; then
echo "⚠️ Certificate file is empty. Aborting for this domain."
continue
fi
echo -e "\n➡️ Opening nano for the PRIVATE KEY for '$DOMAIN'."
echo " Paste the private key, then press Ctrl+O, Enter (save), and Ctrl+X (exit)."
nano key.tmp
if [[ ! -s "key.tmp" ]]; then
echo "⚠️ Private key file is empty. Aborting for this domain."
rm -f cert.tmp
continue
fi
CERT_FILE="$CERT_DIR/${DOMAIN}.crt"
KEY_FILE="$CERT_DIR/${DOMAIN}.key"
mv cert.tmp "$CERT_FILE"
mv key.tmp "$KEY_FILE"
# Set secure permissions
chmod 644 "$CERT_FILE"
chmod 600 "$KEY_FILE" # CRITICAL: Private key should not be world-readable
echo -e "\n✅ Certificate files for '$DOMAIN' saved successfully."
echo " - Cert: $CERT_FILE"
echo " - Key: $KEY_FILE (Permissions set to 600)"
# Now, add the new entry to the dynamic configuration
add_to_config "$DOMAIN"
echo "----------------------------------------"
done
echo
echo "All done. Remember to redeploy your Coolify proxy to apply the changes!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment