|
| 1 | +#!/bin/bash |
| 2 | +# ============================================================================= |
| 3 | +# Database Password Synchronization Script |
| 4 | +# ============================================================================= |
| 5 | +# This script ensures the PostgreSQL password matches the environment variable |
| 6 | +# by updating it on each startup. This fixes the password mismatch issue that |
| 7 | +# occurs when: |
| 8 | +# - Coder workspace is rebuilt (new random password generated) |
| 9 | +# - Local devcontainer is recreated but postgres volume persists |
| 10 | +# |
| 11 | +# The script uses pg_isready to detect if PostgreSQL is available, then |
| 12 | +# attempts to connect and update the application user's password. |
| 13 | +# ============================================================================= |
| 14 | + |
| 15 | +set -e |
| 16 | + |
| 17 | +# Colors for output |
| 18 | +RED='\033[0;31m' |
| 19 | +GREEN='\033[0;32m' |
| 20 | +YELLOW='\033[1;33m' |
| 21 | +BLUE='\033[0;34m' |
| 22 | +NC='\033[0m' # No Color |
| 23 | + |
| 24 | +# Detect environment and set hostname |
| 25 | +if [ -n "$CODER_AGENT_TOKEN" ]; then |
| 26 | + DB_HOST="${POSTGRES_HOST:-db}" |
| 27 | + echo -e "${BLUE}ℹ${NC} Detected Coder environment (using '$DB_HOST' hostname)" |
| 28 | +else |
| 29 | + DB_HOST="${SIMPLEACCOUNTS_DB_HOST:-localhost}" |
| 30 | + echo -e "${BLUE}ℹ${NC} Detected local devcontainer (using '$DB_HOST' hostname)" |
| 31 | +fi |
| 32 | + |
| 33 | +DB_PORT="${SIMPLEACCOUNTS_DB_PORT:-5432}" |
| 34 | +DB_USER="${SIMPLEACCOUNTS_DB_USER:-simpleaccounts}" |
| 35 | +DB_PASSWORD="${SIMPLEACCOUNTS_DB_PASSWORD:-simpleaccounts_dev}" |
| 36 | +DB_NAME="${SIMPLEACCOUNTS_DB:-simpleaccounts}" |
| 37 | +POSTGRES_USER_ENV="${POSTGRES_USER:-simpleaccounts}" |
| 38 | +POSTGRES_PASSWORD_ENV="${POSTGRES_PASSWORD:-$DB_PASSWORD}" |
| 39 | + |
| 40 | +echo -e "${BLUE}🔄 Synchronizing database password...${NC}" |
| 41 | +echo " Host: $DB_HOST:$DB_PORT" |
| 42 | +echo " User: $DB_USER" |
| 43 | +echo " Database: $DB_NAME" |
| 44 | + |
| 45 | +# Function to try connecting with a password |
| 46 | +try_connection() { |
| 47 | + local password="$1" |
| 48 | + local user="$2" |
| 49 | + PGPASSWORD="$password" psql -h "$DB_HOST" -p "$DB_PORT" -U "$user" -d "$DB_NAME" -c "SELECT 1" > /dev/null 2>&1 |
| 50 | + return $? |
| 51 | +} |
| 52 | + |
| 53 | +# Function to update user password |
| 54 | +update_password() { |
| 55 | + local admin_password="$1" |
| 56 | + local admin_user="$2" |
| 57 | + local target_user="$3" |
| 58 | + local new_password="$4" |
| 59 | + |
| 60 | + PGPASSWORD="$admin_password" psql -h "$DB_HOST" -p "$DB_PORT" -U "$admin_user" -d "$DB_NAME" -c "ALTER USER $target_user WITH PASSWORD '$new_password';" > /dev/null 2>&1 |
| 61 | + return $? |
| 62 | +} |
| 63 | + |
| 64 | +# Wait for PostgreSQL to be ready |
| 65 | +echo -e "${BLUE}⏳ Waiting for PostgreSQL...${NC}" |
| 66 | +TIMEOUT=30 |
| 67 | +ELAPSED=0 |
| 68 | +until pg_isready -h "$DB_HOST" -p "$DB_PORT" -q; do |
| 69 | + sleep 1 |
| 70 | + ELAPSED=$((ELAPSED + 1)) |
| 71 | + if [ $ELAPSED -ge $TIMEOUT ]; then |
| 72 | + echo -e "${YELLOW}⚠${NC} PostgreSQL not ready after ${TIMEOUT}s" |
| 73 | + exit 0 # Don't fail, let other scripts continue |
| 74 | + fi |
| 75 | +done |
| 76 | +echo -e "${GREEN}✓${NC} PostgreSQL is accepting connections" |
| 77 | + |
| 78 | +# Test connection with current environment password |
| 79 | +if try_connection "$DB_PASSWORD" "$DB_USER"; then |
| 80 | + echo -e "${GREEN}✓${NC} Password is already synchronized" |
| 81 | + exit 0 |
| 82 | +fi |
| 83 | + |
| 84 | +echo -e "${YELLOW}⚠${NC} Password mismatch detected, attempting to synchronize..." |
| 85 | + |
| 86 | +# List of passwords to try for admin access |
| 87 | +# Order matters: try most likely passwords first |
| 88 | +ADMIN_PASSWORDS=( |
| 89 | + "$POSTGRES_PASSWORD_ENV" |
| 90 | + "$DB_PASSWORD" |
| 91 | + "simpleaccounts_dev" |
| 92 | + "postgres" |
| 93 | + "" |
| 94 | +) |
| 95 | + |
| 96 | +# List of admin users to try |
| 97 | +ADMIN_USERS=( |
| 98 | + "$POSTGRES_USER_ENV" |
| 99 | + "postgres" |
| 100 | + "simpleaccounts" |
| 101 | +) |
| 102 | + |
| 103 | +PASSWORD_SYNCED=false |
| 104 | + |
| 105 | +for admin_user in "${ADMIN_USERS[@]}"; do |
| 106 | + for admin_password in "${ADMIN_PASSWORDS[@]}"; do |
| 107 | + # Try connecting as admin |
| 108 | + if try_connection "$admin_password" "$admin_user"; then |
| 109 | + echo -e "${BLUE}ℹ${NC} Connected as '$admin_user'" |
| 110 | + |
| 111 | + # Update the application user password |
| 112 | + if update_password "$admin_password" "$admin_user" "$DB_USER" "$DB_PASSWORD"; then |
| 113 | + echo -e "${GREEN}✓${NC} Updated password for user '$DB_USER'" |
| 114 | + |
| 115 | + # Also update postgres user if different |
| 116 | + if [ "$admin_user" != "postgres" ] && [ "$DB_USER" != "postgres" ]; then |
| 117 | + update_password "$admin_password" "$admin_user" "postgres" "$POSTGRES_PASSWORD_ENV" 2>/dev/null || true |
| 118 | + fi |
| 119 | + |
| 120 | + PASSWORD_SYNCED=true |
| 121 | + break 2 |
| 122 | + else |
| 123 | + echo -e "${YELLOW}⚠${NC} Failed to update password (may lack permissions)" |
| 124 | + fi |
| 125 | + fi |
| 126 | + done |
| 127 | +done |
| 128 | + |
| 129 | +if [ "$PASSWORD_SYNCED" = true ]; then |
| 130 | + # Verify the new password works |
| 131 | + if try_connection "$DB_PASSWORD" "$DB_USER"; then |
| 132 | + echo -e "${GREEN}✓${NC} Password synchronization complete" |
| 133 | + exit 0 |
| 134 | + else |
| 135 | + echo -e "${RED}✗${NC} Password update succeeded but verification failed" |
| 136 | + exit 1 |
| 137 | + fi |
| 138 | +else |
| 139 | + echo -e "${RED}✗${NC} Could not synchronize password" |
| 140 | + echo "" |
| 141 | + echo "This usually means the PostgreSQL volume was initialized with a different password." |
| 142 | + echo "To fix this, you need to:" |
| 143 | + echo "" |
| 144 | + echo " Option 1: Delete the PostgreSQL volume and let it reinitialize" |
| 145 | + echo " - Coder: coder restart --build" |
| 146 | + echo " - Local: docker compose down -v && docker compose up -d" |
| 147 | + echo "" |
| 148 | + echo " Option 2: Manually reset the password" |
| 149 | + echo " - Connect to PostgreSQL as superuser" |
| 150 | + echo " - Run: ALTER USER $DB_USER WITH PASSWORD 'your-password';" |
| 151 | + echo "" |
| 152 | + exit 1 |
| 153 | +fi |
0 commit comments