Created
          October 26, 2025 19:24 
        
      - 
      
- 
        Save SpotlightForBugs/a8fa9e2f7ded0c717f47ec0b7718efd1 to your computer and use it in GitHub Desktop. 
    Automates most of adding Cloudflare Origin Certificates to Coolify (Traefic required)
  
        
  
    
      This file contains hidden or 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
    
  
  
    
  | #!/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