#!/bin/bash ################################################################################ # n8n PostgreSQL Permission Fix Script - C.utf8 Locale Version (TEMPLATE) # # Purpose: Fix PostgreSQL 15+ permission issues for n8n database # Root Cause: 1) PostgreSQL 15+ removed default CREATE permission from PUBLIC # 2) Debian 12 minimal system only has C.utf8 locale available # Solution: Create database with C.utf8 locale and proper ownership # # Environment: Debian 12, PostgreSQL 16, n8n LXC Container (CT 113) # # USAGE: # 1. Copy this template: cp fix_n8n_db_c_locale.sh.template fix_n8n_db_c_locale.sh # 2. Set environment variable: export N8N_DB_PASSWORD="your_secure_password" # 3. Run the script: bash fix_n8n_db_c_locale.sh # 4. Delete the script after use: shred -u fix_n8n_db_c_locale.sh # # SECURITY NOTE: This template uses environment variables to avoid hardcoding # credentials in the repository. The actual script with embedded # credentials is excluded from git via .gitignore ################################################################################ set -euo pipefail DB_NAME="n8n_db" DB_USER="n8n_user" # IMPORTANT: Set this environment variable before running the script # Example: export N8N_DB_PASSWORD="your_secure_password_here" DB_PASSWORD="${N8N_DB_PASSWORD:-}" if [[ -z "$DB_PASSWORD" ]]; then echo "ERROR: N8N_DB_PASSWORD environment variable is not set" echo "Please set it before running this script:" echo " export N8N_DB_PASSWORD='your_secure_password'" exit 1 fi TIMESTAMP=$(date +%Y%m%d_%H%M%S) LOG_FILE="/var/log/n8n_db_fix_${TIMESTAMP}.log" # Color codes RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' log() { echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1" | tee -a "$LOG_FILE" } log_success() { echo -e "${GREEN}[✓]${NC} $1" | tee -a "$LOG_FILE" } log_error() { echo -e "${RED}[✗]${NC} $1" | tee -a "$LOG_FILE" } echo "================================================================================" echo "n8n PostgreSQL Permission Fix - C.utf8 Locale Version" echo "================================================================================" echo "" log "Stopping n8n service..." systemctl stop n8n || true sleep 3 log_success "n8n service stopped" log "Dropping existing database (if any) and recreating with C.UTF-8 locale..." sudo -u postgres psql <&1 | tee -a "$LOG_FILE" -- Terminate any existing connections SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = '$DB_NAME' AND pid <> pg_backend_pid(); -- Drop database if exists DROP DATABASE IF EXISTS $DB_NAME; -- Create database with C.utf8 locale (Debian 12 system locale) CREATE DATABASE $DB_NAME OWNER $DB_USER ENCODING 'UTF8' LC_COLLATE = 'C.utf8' LC_CTYPE = 'C.utf8' TEMPLATE template0; -- Connect to the database \c $DB_NAME -- Grant all privileges on the public schema (PostgreSQL 15+ fix) GRANT ALL ON SCHEMA public TO $DB_USER; -- Grant all privileges on all current and future objects GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO $DB_USER; GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO $DB_USER; GRANT ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public TO $DB_USER; -- Set default privileges for future objects ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO $DB_USER; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO $DB_USER; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON FUNCTIONS TO $DB_USER; -- Verify database settings SELECT datname, datcollate, datctype, pg_get_userbyid(datdba) as owner FROM pg_database WHERE datname = '$DB_NAME'; SQL log_success "Database recreated with C.utf8 locale and proper permissions" log "Testing database permissions..." PGPASSWORD="$DB_PASSWORD" psql -h localhost -U $DB_USER -d $DB_NAME <&1 | tee -a "$LOG_FILE" -- Test table creation (this is what was failing before) CREATE TABLE test_table (id SERIAL PRIMARY KEY, test_data VARCHAR(100)); INSERT INTO test_table (test_data) VALUES ('Permission test successful'); SELECT * FROM test_table; DROP TABLE test_table; -- Display current user and database SELECT current_user, current_database(); SQL if [[ $? -eq 0 ]]; then log_success "Permission test PASSED - n8n_user can create tables" else log_error "Permission test FAILED" exit 1 fi log "Starting n8n service..." systemctl start n8n sleep 10 if systemctl is-active --quiet n8n; then log_success "n8n service started successfully" else log_error "n8n service failed to start - check logs" journalctl -u n8n -n 30 exit 1 fi echo "" echo "================================================================================" log_success "n8n DATABASE FIX COMPLETED SUCCESSFULLY" echo "================================================================================" echo "" echo "✅ Database created with:" echo " - Locale: C.utf8 (Debian 12 system locale)" echo " - Owner: n8n_user" echo " - Permissions: Full CREATE access on public schema" echo "" echo "📋 Next Steps:" echo " 1. Monitor service: systemctl status n8n" echo " 2. Watch logs: journalctl -u n8n -f" echo " 3. Test access: https://n8n.apophisnetworking.net" echo "" echo "📄 Log file: $LOG_FILE" echo "" echo "🔒 SECURITY: Remember to delete this script after use:" echo " shred -u $(readlink -f "$0")" echo "================================================================================"