add database to immich

This commit is contained in:
Morten Olsen
2026-01-03 12:29:44 +01:00
parent c1c0ae8707
commit 71feab50b1
9 changed files with 394 additions and 205 deletions

View File

@@ -0,0 +1,100 @@
#!/bin/bash
set -e
NAMESPACE="shared"
RELEASE_NAME="immich"
echo "=== Complete immich database password fix ==="
echo ""
# Step 1: Get PostgreSQL pod name
echo "Step 1: Finding PostgreSQL pod..."
POSTGRES_POD=$(kubectl get pods -n "$NAMESPACE" -l app="${RELEASE_NAME}-postgres" -o jsonpath='{.items[0].metadata.name}' 2>&1)
if [ -z "$POSTGRES_POD" ] || [[ "$POSTGRES_POD" == *"Error"* ]]; then
echo "ERROR: Could not find PostgreSQL pod"
echo "Output: $POSTGRES_POD"
exit 1
fi
echo "✓ Found PostgreSQL pod: $POSTGRES_POD"
# Step 2: Get the password from secret
echo "Step 2: Getting password from secret..."
SECRET_B64=$(kubectl get secret "${RELEASE_NAME}-postgres-secret" -n "$NAMESPACE" -o jsonpath='{.data.password}' 2>&1)
if [ -z "$SECRET_B64" ] || [[ "$SECRET_B64" == *"Error"* ]] || [[ "$SECRET_B64" == *"NotFound"* ]]; then
echo "ERROR: Could not find secret ${RELEASE_NAME}-postgres-secret"
echo "Output: $SECRET_B64"
exit 1
fi
# Decode password (double base64 decode)
EXTERNAL_SECRETS_B64=$(echo "$SECRET_B64" | base64 -d 2>&1)
PASSWORD=$(echo "$EXTERNAL_SECRETS_B64" | base64 -d 2>&1)
if [ -z "$PASSWORD" ]; then
echo "ERROR: Failed to decode password"
exit 1
fi
echo "✓ Password retrieved and decoded"
# Step 3: Update PostgreSQL database password
echo "Step 3: Updating PostgreSQL password in database..."
# Escape single quotes in password for SQL
ESCAPED_PASSWORD=$(echo "$PASSWORD" | sed "s/'/''/g")
kubectl exec "$POSTGRES_POD" -n "$NAMESPACE" -- psql -U immich -d immich -c "ALTER USER immich WITH PASSWORD '${ESCAPED_PASSWORD}';" 2>&1
if [ $? -eq 0 ]; then
echo "✓ PostgreSQL password updated"
else
echo "WARNING: Failed to update PostgreSQL password (might already be correct)"
fi
# Step 4: URL encode the password for ConfigMap
echo "Step 4: URL encoding password for ConfigMap..."
ENCODED_PASSWORD=$(python3 -c "import urllib.parse; import sys; print(urllib.parse.quote(sys.stdin.read().strip(), safe=''))" <<< "$PASSWORD" 2>&1)
if [ $? -ne 0 ] || [ -z "$ENCODED_PASSWORD" ]; then
echo "ERROR: Failed to URL encode password"
exit 1
fi
echo "✓ Password URL encoded"
# Step 5: Create DB URL and update ConfigMap
echo "Step 5: Updating ConfigMap..."
DB_URL="postgresql://immich:${ENCODED_PASSWORD}@${RELEASE_NAME}-postgres.${NAMESPACE}.svc.cluster.local:5432/immich"
kubectl create configmap "${RELEASE_NAME}-db-config" \
--from-literal=url="${DB_URL}" \
--namespace="$NAMESPACE" \
--dry-run=client -o yaml 2>&1 | kubectl apply -f - 2>&1
if [ $? -eq 0 ]; then
echo "✓ ConfigMap updated successfully"
else
echo "ERROR: Failed to update ConfigMap"
exit 1
fi
# Step 6: Verify ConfigMap
echo "Step 6: Verifying ConfigMap..."
CM_URL=$(kubectl get configmap "${RELEASE_NAME}-db-config" -n "$NAMESPACE" -o jsonpath='{.data.url}' 2>&1)
if [[ "$CM_URL" == postgresql://immich:* ]]; then
echo "✓ ConfigMap verified: URL starts with postgresql://immich:"
else
echo "WARNING: ConfigMap URL doesn't look correct: $CM_URL"
fi
# Step 7: Restart deployment
echo "Step 7: Restarting immich-server deployment..."
kubectl rollout restart deployment "${RELEASE_NAME}-server" -n "$NAMESPACE" 2>&1
if [ $? -eq 0 ]; then
echo "✓ Deployment restart initiated"
else
echo "ERROR: Failed to restart deployment"
exit 1
fi
echo ""
echo "=== Fix completed ==="
echo "Waiting for pod to restart..."
sleep 5
echo ""
echo "Current pod status:"
kubectl get pods -n "$NAMESPACE" | grep "${RELEASE_NAME}-server" || true
echo ""
echo "Check logs with: kubectl logs -n $NAMESPACE -l app=${RELEASE_NAME}-server --tail=50"

View File

@@ -0,0 +1,79 @@
#!/bin/bash
set -e
RELEASE_NAME="immich"
NAMESPACE=""
# Try to find the namespace
for ns in immich default apps; do
if kubectl get configmap "${RELEASE_NAME}-db-config" -n "$ns" &>/dev/null; then
NAMESPACE="$ns"
break
fi
done
if [ -z "$NAMESPACE" ]; then
# Try to find from pod
POD_NAME="immich-server-6759ddb46c-c2cmq"
for ns in immich default apps; do
if kubectl get pod "$POD_NAME" -n "$ns" &>/dev/null; then
NAMESPACE="$ns"
break
fi
done
fi
if [ -z "$NAMESPACE" ]; then
echo "Error: Could not find immich resources. Please specify namespace manually."
echo "Usage: $0 <namespace>"
exit 1
fi
# Allow manual namespace override
if [ -n "$1" ]; then
NAMESPACE="$1"
fi
echo "Using namespace: $NAMESPACE"
# Get the password from the secret (double base64 decode)
echo "Getting password from secret..."
SECRET_B64=$(kubectl get secret "${RELEASE_NAME}-postgres-secret" -n "$NAMESPACE" -o jsonpath='{.data.password}')
if [ -z "$SECRET_B64" ]; then
echo "Error: Could not find secret ${RELEASE_NAME}-postgres-secret in namespace $NAMESPACE"
exit 1
fi
# Decode twice: Kubernetes base64 -> External Secrets base64 -> actual password
EXTERNAL_SECRETS_B64=$(echo "$SECRET_B64" | base64 -d)
PASSWORD=$(echo "$EXTERNAL_SECRETS_B64" | base64 -d)
if [ -z "$PASSWORD" ]; then
echo "Error: Failed to decode password"
exit 1
fi
echo "Password retrieved successfully"
# URL encode the password using Python (same as the Helm hook job does)
ENCODED_PASSWORD=$(python3 -c "import urllib.parse; import sys; print(urllib.parse.quote(sys.stdin.read().strip(), safe=''))" <<< "$PASSWORD")
# Construct the DB URL
DB_URL="postgresql://immich:${ENCODED_PASSWORD}@${RELEASE_NAME}-postgres.${NAMESPACE}.svc.cluster.local:5432/immich"
echo "Updating ConfigMap ${RELEASE_NAME}-db-config..."
# Update the ConfigMap
kubectl create configmap "${RELEASE_NAME}-db-config" \
--from-literal=url="${DB_URL}" \
--namespace="$NAMESPACE" \
--dry-run=client -o yaml | kubectl apply -f -
echo "ConfigMap updated successfully!"
# Restart the immich-server deployment to pick up the new ConfigMap
echo "Restarting immich-server deployment..."
kubectl rollout restart deployment "${RELEASE_NAME}-server" -n "$NAMESPACE"
echo "Done! The immich-server pod will restart with the correct database password."

View File

@@ -0,0 +1,88 @@
#!/bin/bash
set -e
NAMESPACE="shared"
RELEASE_NAME="immich"
echo "=== Fixing immich database password issue ==="
echo "Namespace: $NAMESPACE"
echo ""
# Step 1: Get the password from secret
echo "Step 1: Getting password from secret..."
SECRET_B64=$(kubectl get secret "${RELEASE_NAME}-postgres-secret" -n "$NAMESPACE" -o jsonpath='{.data.password}' 2>&1)
if [ -z "$SECRET_B64" ] || [[ "$SECRET_B64" == *"Error"* ]] || [[ "$SECRET_B64" == *"NotFound"* ]]; then
echo "ERROR: Could not find secret ${RELEASE_NAME}-postgres-secret"
echo "Secret output: $SECRET_B64"
exit 1
fi
echo "✓ Secret found"
# Step 2: Decode password (double base64 decode)
echo "Step 2: Decoding password..."
EXTERNAL_SECRETS_B64=$(echo "$SECRET_B64" | base64 -d 2>&1)
if [ $? -ne 0 ]; then
echo "ERROR: Failed to decode secret (first level)"
exit 1
fi
PASSWORD=$(echo "$EXTERNAL_SECRETS_B64" | base64 -d 2>&1)
if [ $? -ne 0 ]; then
echo "ERROR: Failed to decode secret (second level)"
exit 1
fi
if [ -z "$PASSWORD" ]; then
echo "ERROR: Password is empty after decoding"
exit 1
fi
echo "✓ Password decoded successfully"
# Step 3: URL encode the password
echo "Step 3: URL encoding password..."
ENCODED_PASSWORD=$(python3 -c "import urllib.parse; import sys; print(urllib.parse.quote(sys.stdin.read().strip(), safe=''))" <<< "$PASSWORD" 2>&1)
if [ $? -ne 0 ] || [ -z "$ENCODED_PASSWORD" ]; then
echo "ERROR: Failed to URL encode password"
echo "Python output: $ENCODED_PASSWORD"
exit 1
fi
echo "✓ Password URL encoded"
# Step 4: Create DB URL
echo "Step 4: Creating database URL..."
DB_URL="postgresql://immich:${ENCODED_PASSWORD}@${RELEASE_NAME}-postgres.${NAMESPACE}.svc.cluster.local:5432/immich"
echo "✓ Database URL created"
# Step 5: Update ConfigMap
echo "Step 5: Updating ConfigMap..."
kubectl create configmap "${RELEASE_NAME}-db-config" \
--from-literal=url="${DB_URL}" \
--namespace="$NAMESPACE" \
--dry-run=client -o yaml 2>&1 | kubectl apply -f - 2>&1
if [ $? -eq 0 ]; then
echo "✓ ConfigMap updated successfully"
else
echo "ERROR: Failed to update ConfigMap"
exit 1
fi
# Step 6: Restart deployment
echo "Step 6: Restarting immich-server deployment..."
kubectl rollout restart deployment "${RELEASE_NAME}-server" -n "$NAMESPACE" 2>&1
if [ $? -eq 0 ]; then
echo "✓ Deployment restart initiated"
else
echo "ERROR: Failed to restart deployment"
exit 1
fi
echo ""
echo "=== Done ==="
echo "The immich-server pod should restart with the correct database password."
echo "Check status with: kubectl get pods -n $NAMESPACE | grep immich-server"

View File

@@ -0,0 +1,58 @@
#!/bin/bash
set -e
RELEASE_NAME="immich"
NAMESPACE="${1:-immich}" # Default to immich namespace, or pass as first argument
echo "Triggering db-config job in namespace: $NAMESPACE"
# Create a temporary job based on the Helm hook job
kubectl create job --from=cronjob/immich-db-config-generator "${RELEASE_NAME}-db-config-manual-$(date +%s)" -n "$NAMESPACE" 2>/dev/null || \
kubectl create job "${RELEASE_NAME}-db-config-manual-$(date +%s)" \
--image=python:3.11-slim \
-n "$NAMESPACE" \
-- /bin/bash -c "
set -e
apt-get update -qq && apt-get install -y -qq curl > /dev/null 2>&1 && \
curl -sSL \"https://dl.k8s.io/release/\$(curl -sL https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl\" -o /tmp/kubectl && \
chmod +x /tmp/kubectl && mv /tmp/kubectl /usr/local/bin/kubectl
PASSWORD_B64=\$(cat /secrets/password)
PASSWORD=\$(python3 -c \"import base64; import sys; print(base64.b64decode(sys.stdin.read().strip()).decode('utf-8'))\" <<< \"\$PASSWORD_B64\")
ENCODED_PASSWORD=\$(python3 -c \"import urllib.parse; import sys; print(urllib.parse.quote(sys.stdin.read().strip(), safe=''))\" <<< \"\$PASSWORD\")
DB_URL=\"postgresql://immich:\${ENCODED_PASSWORD}@${RELEASE_NAME}-postgres.${NAMESPACE}.svc.cluster.local:5432/immich\"
kubectl create configmap ${RELEASE_NAME}-db-config --from-literal=url=\"\${DB_URL}\" --dry-run=client -o yaml | kubectl apply -f -
echo \"ConfigMap ${RELEASE_NAME}-db-config updated successfully\"
" \
--overrides='
{
"spec": {
"serviceAccountName": "'"${RELEASE_NAME}"'-db-config-sa",
"volumes": [
{
"name": "postgres-secret",
"secret": {
"secretName": "'"${RELEASE_NAME}"'-postgres-secret"
}
}
],
"containers": [{
"name": "generator",
"volumeMounts": [
{
"name": "postgres-secret",
"mountPath": "/secrets",
"readOnly": true
}
]
}]
}
}'
echo "Job created. Waiting for completion..."
kubectl wait --for=condition=complete --timeout=60s job -l job-name="${RELEASE_NAME}-db-config-manual" -n "$NAMESPACE" || true
echo "Restarting immich-server..."
kubectl rollout restart deployment "${RELEASE_NAME}-server" -n "$NAMESPACE"
echo "Done!"

View File

@@ -0,0 +1,61 @@
#!/bin/bash
set -e
# Find the pod namespace
POD_NAME="immich-postgres-544f467fd8-2k84c"
NAMESPACE=""
# Try to find the namespace
for ns in immich default apps; do
if kubectl get pod "$POD_NAME" -n "$ns" &>/dev/null; then
NAMESPACE="$ns"
break
fi
done
if [ -z "$NAMESPACE" ]; then
# Try without namespace specification
if kubectl get pod "$POD_NAME" -A &>/dev/null; then
NAMESPACE=$(kubectl get pod "$POD_NAME" -A -o jsonpath='{.items[0].metadata.namespace}' 2>/dev/null || \
kubectl get pod "$POD_NAME" -A -o jsonpath='{.metadata.namespace}' 2>/dev/null)
fi
fi
if [ -z "$NAMESPACE" ]; then
echo "Error: Could not find pod $POD_NAME in any namespace"
exit 1
fi
echo "Found pod in namespace: $NAMESPACE"
# Get the password from the secret
# The secret is stored as base64 in Kubernetes, and External Secrets uses base64 encoding
# So we need to decode twice: Kubernetes base64 -> External Secrets base64 -> actual password
SECRET_B64=$(kubectl get secret "immich-postgres-secret" -n "$NAMESPACE" -o jsonpath='{.data.password}')
if [ -z "$SECRET_B64" ]; then
echo "Error: Could not find secret immich-postgres-secret in namespace $NAMESPACE"
exit 1
fi
# Decode the password (double base64 decode: Kubernetes -> External Secrets -> actual password)
# First decode: Kubernetes base64 to get External Secrets base64 value
EXTERNAL_SECRETS_B64=$(echo "$SECRET_B64" | base64 -d)
# Second decode: External Secrets base64 to get actual password
PASSWORD=$(echo "$EXTERNAL_SECRETS_B64" | base64 -d)
if [ -z "$PASSWORD" ]; then
echo "Error: Failed to decode password"
exit 1
fi
echo "Updating PostgreSQL password for user 'immich'..."
# Update the password in PostgreSQL
# Escape single quotes in password for SQL by doubling them
ESCAPED_PASSWORD=$(echo "$PASSWORD" | sed "s/'/''/g")
# Use psql to update the password
kubectl exec "$POD_NAME" -n "$NAMESPACE" -- psql -U immich -d immich -c "ALTER USER immich WITH PASSWORD '${ESCAPED_PASSWORD}';"
echo "Password updated successfully!"