Changes from old deployment system to new dynamic one

This commit is contained in:
2026-07-28 22:09:40 +02:00
parent a1c5a78b20
commit 6f50fb2263
4 changed files with 42 additions and 272 deletions
+31 -151
View File
@@ -2,7 +2,7 @@
set -euo pipefail
# Release-only updater for Docker deployment.
# Updates are pulled exclusively from Gitea Releases assets.
# Updates pull the deployment bundle from Gitea and the Docker Image via 'docker pull'.
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LOG_DIR="$PROJECT_DIR/logs"
@@ -11,13 +11,10 @@ STATE_FILE="$PROJECT_DIR/.release-version"
REPO_SLUG="Invario/Inventarsystem"
API_URL="https://git.invario-software.eu/api/v1/repos/$REPO_SLUG/releases/latest"
BUNDLE_ASSET="inventarsystem-docker-bundle.tar.gz"
APP_IMAGE_ASSET_PREFIX="inventarsystem-image-"
ENV_FILE="$PROJECT_DIR/.docker-build.env"
APP_IMAGE_REPO="git.invario-software.eu/invario/inventarsystem"
DIST_DIR="$PROJECT_DIR/dist"
COMPOSE_FILE="docker-compose-multitenant.yml"
MIN_ROOT_FREE_MB="${INVENTAR_MIN_ROOT_FREE_MB:-2048}"
DIST_KEEP_COUNT="${INVENTAR_DIST_KEEP_COUNT:-2}"
MODE="release"
mkdir -p "$LOG_DIR"
@@ -109,36 +106,6 @@ ensure_min_root_disk_space() {
fi
}
cleanup_old_dist_artifacts() {
local keep_count
keep_count="$DIST_KEEP_COUNT"
if [ ! -d "$DIST_DIR" ]; then
return 0
fi
if ! [[ "$keep_count" =~ ^[0-9]+$ ]]; then
keep_count=2
fi
mapfile -t archives < <(find "$DIST_DIR" -maxdepth 1 -type f \( -name 'inventarsystem-image-*.tar.gz' -o -name 'inventarsystem-image-*.tar' \) -printf '%T@ %p\n' | sort -nr | awk '{print $2}')
if [ "${#archives[@]}" -le "$keep_count" ]; then
return 0
fi
local index old_archive deleted=0
for (( index=keep_count; index<${#archives[@]}; index++ )); do
old_archive="${archives[$index]}"
if rm -f "$old_archive"; then
deleted=$((deleted + 1))
fi
done
if [ "$deleted" -gt 0 ]; then
log_message "Cleaned up $deleted old dist image archive(s)"
fi
}
cleanup_docker_dangling_images() {
if docker image prune -f >> "$LOG_FILE" 2>&1; then
log_message "Cleaned up dangling Docker images"
@@ -153,7 +120,6 @@ Usage: $0 [options]
Options:
--multitenant Use docker-compose-multitenant.yml (default)
development Install development build from Gitea Registry or local dist
-h, --help Show this help message
EOF
}
@@ -165,10 +131,6 @@ parse_args() {
COMPOSE_FILE="docker-compose-multitenant.yml"
shift
;;
development|dev)
MODE="development"
shift
;;
-h|--help)
usage
exit 0
@@ -216,14 +178,12 @@ create_backup() {
}
fetch_release_metadata() {
local meta_file
meta_file="$1"
local meta_file="$1"
curl -fsSL "$API_URL" -o "$meta_file"
}
parse_latest_tag() {
local meta_file
meta_file="$1"
local meta_file="$1"
python3 - <<'PY' "$meta_file"
import json, sys
with open(sys.argv[1], 'r', encoding='utf-8') as f:
@@ -233,9 +193,8 @@ PY
}
parse_asset_url() {
local meta_file asset_name
meta_file="$1"
asset_name="$2"
local meta_file="$1"
local asset_name="$2"
python3 - <<'PY' "$meta_file" "$asset_name"
import json, sys
meta_file, asset_name = sys.argv[1], sys.argv[2]
@@ -248,31 +207,6 @@ for asset in data.get('assets', []):
PY
}
load_release_image() {
local meta_file tag image_asset image_url tmp_dir archive
meta_file="$1"
tag="$2"
image_asset="${APP_IMAGE_ASSET_PREFIX}${tag}.tar.gz"
image_url="$(parse_asset_url "$meta_file" "$image_asset")"
if [ -z "$image_url" ]; then
log_message "ERROR: Release image asset not found: $image_asset"
return 1
fi
tmp_dir="$(mktemp -d)"
archive="$tmp_dir/$image_asset"
trap 'rm -rf "${tmp_dir:-}"' RETURN
log_message "Loading app image from release asset $image_asset"
curl -fL "$image_url" -o "$archive"
docker load -i "$archive" >> "$LOG_FILE" 2>&1
docker tag "$APP_IMAGE_REPO:$tag" "$APP_IMAGE_REPO:latest" >> "$LOG_FILE" 2>&1 || true
trap - RETURN
}
refresh_runtime_scripts_from_main() {
local start_url stop_url restart_url update_url
start_url="https://git.invario-software.eu/$REPO_SLUG/raw/branch/main/start.sh"
@@ -285,61 +219,13 @@ refresh_runtime_scripts_from_main() {
curl -fsSL "$restart_url" -o "$PROJECT_DIR/restart.sh" || log_message "WARNING: Could not refresh restart.sh from main"
curl -fsSL "$update_url" -o "$PROJECT_DIR/update.sh" || log_message "WARNING: Could not refresh update.sh from main"
chmod +x "$PROJECT_DIR/start.sh" "$PROJECT_DIR/stop.sh" "$PROJECT_DIR/restart.sh" "$PROJECT_DIR/update.sh"
}
find_local_dist_image_archive() {
local tag="$1"
local archive
if [ ! -d "$DIST_DIR" ]; then
return 1
fi
for archive in \
"$DIST_DIR/inventarsystem-image-$tag.tar.gz" \
"$DIST_DIR/inventarsystem-image-$tag.tar" \
"$DIST_DIR/inventarsystem-image.tar.gz" \
"$DIST_DIR/inventarsystem-image.tar"; do
if [ -f "$archive" ]; then
echo "$archive"
return 0
fi
done
archive="$(find "$DIST_DIR" -maxdepth 1 -type f \( -name 'inventarsystem-image-*.tar.gz' -o -name 'inventarsystem-image-*.tar' \) | sort | tail -n1)"
if [ -n "$archive" ]; then
echo "$archive"
return 0
fi
return 1
}
load_local_dist_image() {
local tag="$1"
local archive
archive="$(find_local_dist_image_archive "$tag" || true)"
if [ -z "$archive" ]; then
return 1
fi
log_message "Loading app image from local dist artifact: $archive"
if docker load -i "$archive" >> "$LOG_FILE" 2>&1; then
docker tag "$APP_IMAGE_REPO:$tag" "$APP_IMAGE_REPO:latest" >> "$LOG_FILE" 2>&1 || true
return 0
fi
log_message "WARNING: Failed to load local dist artifact: $archive"
return 1
chmod +x "$PROJECT_DIR/start.sh" "$PROJECT_DIR/stop.sh" "$PROJECT_DIR/restart.sh" "$PROJECT_DIR/update.sh" 2>/dev/null || true
}
download_and_extract_bundle() {
local url tmp_dir archive
url="$1"
tmp_dir="$2"
archive="$tmp_dir/$BUNDLE_ASSET"
local url="$1"
local tmp_dir="$2"
local archive="$tmp_dir/$BUNDLE_ASSET"
curl -fL "$url" -o "$archive"
tar -xzf "$archive" -C "$tmp_dir"
@@ -375,19 +261,15 @@ download_and_extract_bundle() {
# Ensure executable permissions on all copied scripts
chmod +x "$PROJECT_DIR/start.sh" "$PROJECT_DIR/stop.sh" "$PROJECT_DIR/restart.sh" "$PROJECT_DIR/update.sh" "$PROJECT_DIR/backup.sh" "$PROJECT_DIR/manage-tenant.sh" "$PROJECT_DIR/run-tenant-cmd.sh" 2>/dev/null || true
chmod +x "$PROJECT_DIR"/manage-tenant.sh "$PROJECT_DIR"/run-tenant-cmd.sh 2>/dev/null || true
if [ ! -f "$PROJECT_DIR/config.json" ] && [ -f "$tmp_dir/config.json" ]; then
cp -f "$tmp_dir/config.json" "$PROJECT_DIR/config.json"
log_message "Installed default config.json from release bundle"
fi
chmod +x "$PROJECT_DIR/start.sh" "$PROJECT_DIR/stop.sh" "$PROJECT_DIR/restart.sh" "$PROJECT_DIR/update.sh" "$PROJECT_DIR/backup.sh" "$PROJECT_DIR/manage-tenant.sh" "$PROJECT_DIR/run-tenant-cmd.sh" 2>/dev/null || true
}
deploy() {
local tag="$1"
local meta_file="$2"
local app_image="${APP_IMAGE_REPO}:${tag}"
local compose_path
@@ -410,17 +292,14 @@ EOF
printf '\nINVENTAR_APP_IMAGE=%s\n' "$app_image" >> "$ENV_FILE"
fi
if ! load_local_dist_image "$tag"; then
if ! load_release_image "$meta_file" "$tag"; then
log_message "Falling back to tagged Gitea Registry image $app_image"
if ! docker pull "$app_image" >> "$LOG_FILE" 2>&1; then
log_message "Falling back to local Docker build for $app_image"
docker build -t "$app_image" "$PROJECT_DIR" >> "$LOG_FILE" 2>&1
fi
fi
log_message "Pulling Gitea Registry image $app_image"
if ! docker pull "$app_image" >> "$LOG_FILE" 2>&1; then
log_message "Falling back to local Docker build for $app_image"
docker build -t "$app_image" "$PROJECT_DIR" >> "$LOG_FILE" 2>&1
fi
docker compose -f "$compose_path" --env-file "$ENV_FILE" pull app mongodb >> "$LOG_FILE" 2>&1
# Image wurde oben gepullt, Stack hochfahren
docker compose -f "$compose_path" --env-file "$ENV_FILE" pull mongodb redis >> "$LOG_FILE" 2>&1 || true
docker compose -f "$compose_path" --env-file "$ENV_FILE" up -d --remove-orphans >> "$LOG_FILE" 2>&1
docker tag "$app_image" "$APP_IMAGE_REPO:latest" >> "$LOG_FILE" 2>&1 || true
}
@@ -460,9 +339,12 @@ cleanup_server_space() {
else
log_message "WARNING: Docker system prune failed"
fi
# Clean up old dist artifacts
cleanup_old_dist_artifacts
# Clean up log files older than 7 days
# Delete legacy dist folder if it exists
if [ -d "$PROJECT_DIR/dist" ]; then
rm -rf "$PROJECT_DIR/dist" || true
log_message "Legacy dist folder removed"
fi
# Clean up old log files older than 7 days
if find "$LOG_DIR" -type f -name '*.log' -mtime +7 -exec rm -f {} +; then
log_message "Old log files (older than 7 days) cleaned up"
else
@@ -511,17 +393,14 @@ EOF
printf '\nINVENTAR_APP_IMAGE=%s\n' "$app_image" >> "$ENV_FILE"
fi
# Try local dist first, then pull from Gitea Registry
if ! load_local_dist_image "$tag"; then
log_message "Attempting to pull development image $app_image"
if ! docker pull "$app_image" >> "$LOG_FILE" 2>&1; then
log_message "ERROR: Could not obtain development image $app_image"
exit 1
fi
log_message "Attempting to pull development image $app_image"
if ! docker pull "$app_image" >> "$LOG_FILE" 2>&1; then
log_message "ERROR: Could not obtain development image $app_image"
exit 1
fi
# Bring up stack
docker compose -f "$compose_path" --env-file "$ENV_FILE" pull app mongodb >> "$LOG_FILE" 2>&1 || true
docker compose -f "$compose_path" --env-file "$ENV_FILE" pull mongodb redis >> "$LOG_FILE" 2>&1 || true
docker compose -f "$compose_path" --env-file "$ENV_FILE" up -d --remove-orphans >> "$LOG_FILE" 2>&1
if ! verify_stack_health; then
@@ -581,7 +460,7 @@ EOF
if [ "$current_tag" = "$latest_tag" ]; then
log_message "Already on latest release ($latest_tag). Refreshing containers from prebuilt image."
deploy "$latest_tag" "$meta_file"
deploy "$latest_tag"
if verify_stack_health; then
log_message "Container refresh completed"
else
@@ -611,18 +490,19 @@ EOF
log_message "Updating from release $latest_tag"
download_and_extract_bundle "$bundle_url" "$tmp_dir"
refresh_runtime_scripts_from_main
deploy "$latest_tag" "$meta_file"
deploy "$latest_tag"
if ! verify_stack_health; then
log_message "ERROR: Updated stack failed health check"
exit 1
fi
echo "$latest_tag" > "$STATE_FILE"
cleanup_old_dist_artifacts
cleanup_docker_dangling_images
log_message "Update completed successfully to release $latest_tag"
sudo ./opt/Inventarsystem/restart.sh
if [ -x "./opt/Inventarsystem/restart.sh" ]; then
sudo ./opt/Inventarsystem/restart.sh
fi
echo "Restart of the Server Completed"
}