Merge remote-tracking branch 'origin/main' into release/v4.5

This commit is contained in:
Andras Bacsai
2026-10-21 16:49:31 +02:00
15 changed files with 1082 additions and 7 deletions
+115
View File
@@ -0,0 +1,115 @@
#!/usr/bin/env bash
# Patches Coolify 4.0 to 4.4 to the security fix release of its own line.
# Only the coolify container is recreated, the compose files and the other containers stay as they are.
# Usage: curl -fsSL https://cdn.coollabs.io/coolify/patch.sh | sudo bash
set -euo pipefail
SOURCE_DIR=/data/coolify/source
ENV_FILE="$SOURCE_DIR/.env"
TIMESTAMP="$(date +%Y-%m-%d-%H-%M-%S)"
LOG_FILE="$SOURCE_DIR/patch-$TIMESTAMP.log"
BACKUP_FILE="$ENV_FILE-$TIMESTAMP"
PATCH_VERSIONS=(4.0.1 4.1.3 4.2.1 4.3.24 4.4.7)
BOLD=$'\033[1m' GREEN=$'\033[32m' BLUE=$'\033[34m' RED=$'\033[31m' RESET=$'\033[0m'
heading() { printf '\n %s%s%s\n' "$BOLD" "$*" "$RESET"; }
info() { printf ' %sℹ%s %s\n' "$BLUE" "$RESET" "$*"; }
ok() { printf ' %s✔%s %s\n' "$GREEN" "$RESET" "$*"; }
die() {
printf ' %s✖%s %s\n' "$RED" "$RESET" "$*" >&2
exit 1
}
main() {
check_installation
read_version
select_patch_version
check_compose_files
heading "Patching Coolify $current_version to $patch_version"
pull_image
update_env_file
restart_coolify
wait_for_coolify
}
check_installation() {
heading "Checking the installation"
[ "$EUID" = 0 ] || die "run this script as root, for example with sudo"
[ -f "$ENV_FILE" ] && [ -f "$SOURCE_DIR/docker-compose.prod.yml" ] || die "Coolify is not installed in $SOURCE_DIR"
docker compose version > /dev/null 2>&1 || die "the Docker Compose plugin is not installed"
compose=(docker compose --env-file "$ENV_FILE" -f "$SOURCE_DIR/docker-compose.yml" -f "$SOURCE_DIR/docker-compose.prod.yml")
if [ -f "$SOURCE_DIR/docker-compose.custom.yml" ]; then
compose+=(-f "$SOURCE_DIR/docker-compose.custom.yml")
fi
if [ -f "$SOURCE_DIR/docker-compose.postgres-upgrade.yml" ]; then
compose+=(-f "$SOURCE_DIR/docker-compose.postgres-upgrade.yml")
fi
ok "Coolify is installed in $SOURCE_DIR"
}
read_version() {
current_version="$(docker exec -w /var/www/html coolify php bootstrap/getVersion.php 2> /dev/null)" || die "the coolify container is not running"
ok "Coolify $BOLD$current_version$RESET is running"
}
select_patch_version() {
[[ "$current_version" =~ ^4\.([0-4])\.([0-9]+)$ ]] || die "Coolify $current_version has no security fix release, upgrade to the latest version from the dashboard instead"
patch_version="${PATCH_VERSIONS[${BASH_REMATCH[1]}]}"
if [ "${BASH_REMATCH[2]}" -ge "${patch_version##*.}" ]; then
ok "Coolify $current_version already includes the security fixes"
exit 0
fi
}
check_compose_files() {
local has_realtime=false needs_realtime=true
if grep -q 'coollabsio/coolify-realtime:' "$SOURCE_DIR/docker-compose.prod.yml"; then
has_realtime=true
fi
if [[ "$patch_version" == 4.4.* ]]; then
needs_realtime=false
fi
[ "$has_realtime" = "$needs_realtime" ] || die "the compose files in $SOURCE_DIR do not belong to Coolify $current_version, upgrade to the latest version from the dashboard instead"
ok "the compose files belong to Coolify $current_version"
}
pull_image() {
LATEST_IMAGE="$patch_version" "${compose[@]}" pull coolify < /dev/null >> "$LOG_FILE" 2>&1 || die "could not pull Coolify $patch_version, nothing was changed (log: $LOG_FILE)"
ok "pulled Coolify $patch_version"
}
update_env_file() {
local key updated
cp "$ENV_FILE" "$BACKUP_FILE"
for key in LATEST_IMAGE COOLIFY_VERSION; do
if grep -q "^$key=" "$ENV_FILE"; then
updated="$(sed "s|^$key=.*|$key=$patch_version|" "$ENV_FILE")"
printf '%s\n' "$updated" > "$ENV_FILE"
fi
done
ok "backed up .env to $BACKUP_FILE"
}
restart_coolify() {
# Detached, because the Coolify 4.4 terminal runs inside the coolify container and closes when it stops
LATEST_IMAGE="$patch_version" nohup "${compose[@]}" up -d --no-deps coolify < /dev/null >> "$LOG_FILE" 2>&1 &
wait $! || die "could not restart the coolify container (log: $LOG_FILE)"
ok "restarted the coolify container"
}
wait_for_coolify() {
local status
for _ in $(seq 60); do
status="$(docker inspect --format '{{.State.Health.Status}}' coolify 2> /dev/null || true)"
if [ "$status" = healthy ]; then
ok "Coolify $BOLD$patch_version$RESET is healthy and runs PHP $(docker exec coolify php -r 'echo PHP_VERSION;')"
return
fi
sleep 5
done
info "roll back with: cp $BACKUP_FILE $ENV_FILE && LATEST_IMAGE=$current_version ${compose[*]} up -d --no-deps coolify"
die "Coolify $patch_version is not healthy after 5 minutes, check it with: docker logs coolify"
}
main