From 55fbb1aadf884ab5fce4e2bcfe7a6ebe2022fae3 Mon Sep 17 00:00:00 2001 From: codesterribly Date: Thu, 18 Dec 2025 13:21:59 -0500 Subject: [PATCH] fix(install): preserve existing .env, portable sed, mac-safe password, compose check --- install.sh | 69 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 7 deletions(-) diff --git a/install.sh b/install.sh index ccefe4e894..1887dd0331 100755 --- a/install.sh +++ b/install.sh @@ -2,6 +2,21 @@ set -o nounset set -o pipefail +# Portable in-place sed: +# - GNU sed: sed -i -e 's/.../.../' file +# - BSD/macOS sed: sed -i '' -e 's/.../.../' file +sed_in_place() { + local expr="$1" + local file="$2" + + # GNU sed supports `--version`; BSD/macOS sed does not. + if sed --version >/dev/null 2>&1; then + sed -i -e "$expr" "$file" + else + sed -i '' -e "$expr" "$file" + fi +} + create_immich_directory() { local -r Tgt='./immich-app' echo "Creating Immich directory..." @@ -20,23 +35,63 @@ download_docker_compose_file() { download_dot_env_file() { echo "Downloading .env file..." + # If there is already a pre-existing .env, do not overwrite it. + # This makes reruns safe for users who have customized settings. + if [[ -f ./.env ]]; then + echo "Found existing .env, leaving it unchanged" + return 0 + fi "${Curl[@]}" "$RepoUrl"/example.env -o ./.env } +# Safer, Mac-safe +gen_password() { + # Generate exactly 10 alphanumeric characters for DB_PASSWORD. + # Preference order: + # 1) openssl: available on most systems, good entropy + # 2) shasum: macOS-friendly fallback + # 3) sha256sum: common on Linux + # + # Notes: + # - We strip to [A-Za-z0-9] to avoid quoting/escaping surprises in .env. + # - We ensure the function always outputs 10 chars, or fails. + + local pw + + if command -v openssl >/dev/null 2>&1; then + pw="$(openssl rand -base64 24 | tr -dc 'A-Za-z0-9' | head -c 10)" + elif command -v shasum >/dev/null 2>&1; then + pw="$(printf '%s' "$RANDOM$(date)$RANDOM" | shasum -a 256 | awk '{print $1}' | tr -dc 'A-Za-z0-9' | head -c 10)" + elif command -v sha256sum >/dev/null 2>&1; then + pw="$(printf '%s' "$RANDOM$(date)$RANDOM" | sha256sum | awk '{print $1}' | tr -dc 'A-Za-z0-9' | head -c 10)" + else + # Very last-resort fallback. Not cryptographically strong, but better than failing installs. + pw="postgres${RANDOM}${RANDOM}" + pw="$(printf '%s' "$pw" | tr -dc 'A-Za-z0-9' | head -c 10)" + fi + + # If something went wrong, fail fast so the caller can handle it. + if [[ -z "${pw}" || "${#pw}" -ne 10 ]]; then + return 1 + fi + + printf '%s' "$pw" +} + generate_random_password() { echo "Generate random password for .env file..." - rand_pass=$(echo "$RANDOM$(date)$RANDOM" | sha256sum | base64 | head -c10) - if [ -z "$rand_pass" ]; then - sed -i -e "s/DB_PASSWORD=postgres/DB_PASSWORD=postgres${RANDOM}${RANDOM}/" ./.env - else - sed -i -e "s/DB_PASSWORD=postgres/DB_PASSWORD=${rand_pass}/" ./.env + local rand_pass + rand_pass="$(gen_password)" || return 1 + if ! grep -q '^DB_PASSWORD=postgres$' "./.env"; then + echo "DB_PASSWORD already set, leaving it unchanged" + return 0 fi + sed_in_place "s/^DB_PASSWORD=postgres$/DB_PASSWORD=${rand_pass}/" "./.env" } start_docker_compose() { echo "Starting Immich's docker containers" - - if ! docker compose >/dev/null 2>&1; then + if ! docker compose version >/dev/null 2>&1; then echo "failed to find 'docker compose'" return 1 fi