diff --git a/dashcaddy-api/scripts/build-release.sh b/dashcaddy-api/scripts/build-release.sh index e80818c..1c0eda3 100644 --- a/dashcaddy-api/scripts/build-release.sh +++ b/dashcaddy-api/scripts/build-release.sh @@ -5,7 +5,7 @@ set -euo pipefail -readonly REPO_URL="http://100.98.123.59:3000/sami7777/dashcaddy.git" +readonly REPO_URL="http://sami7777:2728bb667201841b08cb35ac101ffe52838f7d11@100.98.123.59:3000/sami7777/dashcaddy.git" readonly RELEASE_DIR="/var/www/get.dashcaddy.net/release" readonly BUILD_DIR="/tmp/dashcaddy-build-$$" readonly MIRROR_HOST="root@100.98.123.59" # Contabo DE diff --git a/dashcaddy-api/scripts/dashcaddy-update.sh b/dashcaddy-api/scripts/dashcaddy-update.sh index 712a809..29ab64f 100644 --- a/dashcaddy-api/scripts/dashcaddy-update.sh +++ b/dashcaddy-api/scripts/dashcaddy-update.sh @@ -162,7 +162,7 @@ main() { # Step 3: Rebuild container log "Step 3: Building new container image" cd "$compose_dir" - if ! DASHCADDY_COMMIT="$commit" docker compose build --quiet 2>&1; then + if ! docker compose build --build-arg DASHCADDY_COMMIT="$commit" --quiet 2>&1; then log "ERROR: docker compose build failed, rolling back" restore_backup "$api_dir" "$from_version" local elapsed=$(( $(date +%s) - start_time )) diff --git a/dashcaddy-api/scripts/dashcaddy-updater.path b/dashcaddy-api/scripts/dashcaddy-updater.path index 7f10547..e65498b 100644 --- a/dashcaddy-api/scripts/dashcaddy-updater.path +++ b/dashcaddy-api/scripts/dashcaddy-updater.path @@ -4,7 +4,6 @@ Documentation=https://dashcaddy.net [Path] PathChanged=/opt/dashcaddy/updates/trigger.json -MakeDirectory=yes [Install] WantedBy=multi-user.target diff --git a/dashcaddy-api/self-updater.js b/dashcaddy-api/self-updater.js index d4b6377..d57ae46 100644 --- a/dashcaddy-api/self-updater.js +++ b/dashcaddy-api/self-updater.js @@ -42,6 +42,9 @@ class SelfUpdater extends EventEmitter { updateUrl: options.updateUrl || DEFAULTS.UPDATE_URL, mirrorUrl: options.mirrorUrl || DEFAULTS.MIRROR_URL, updatesDir: options.updatesDir || DEFAULTS.UPDATES_DIR, + // hostUpdatesDir is the HOST path that maps to updatesDir inside the container. + // Used when writing trigger.json so the host-side script can find staging files. + hostUpdatesDir: options.hostUpdatesDir || (isWindows ? options.updatesDir || DEFAULTS.UPDATES_DIR : '/opt/dashcaddy/updates'), apiSourceDir: options.apiSourceDir || DEFAULTS.API_SOURCE_DIR, frontendDir: options.frontendDir || DEFAULTS.FRONTEND_DIR, maxBackups: parseInt(options.maxBackups || DEFAULTS.MAX_BACKUPS, 10), @@ -102,12 +105,14 @@ class SelfUpdater extends EventEmitter { this.status = 'checking'; try { let remote; + let sourceUrl = this.config.updateUrl; try { remote = await this._fetchJson(`${this.config.updateUrl}/version.json`); } catch (primaryErr) { console.warn('[SelfUpdater] Primary server failed:', primaryErr.message, '— trying mirror'); try { remote = await this._fetchJson(`${this.config.mirrorUrl}/version.json`); + sourceUrl = this.config.mirrorUrl; } catch (mirrorErr) { this.status = 'idle'; this.lastCheckTime = Date.now(); @@ -120,7 +125,7 @@ class SelfUpdater extends EventEmitter { const available = this._isNewer(local, remote); this.lastCheckTime = Date.now(); - this.lastCheckResult = { available, local, remote }; + this.lastCheckResult = { available, local, remote, sourceUrl }; this.status = 'idle'; if (available) { @@ -147,13 +152,21 @@ class SelfUpdater extends EventEmitter { const stagingDir = path.join(this.config.updatesDir, 'staging'); try { - // 1. Download + // 1. Download (try primary, fallback to mirror) this.status = 'downloading'; this.emit('update-progress', { step: 'downloading', version: remoteInfo.version }); - const tarballUrl = `${this.config.updateUrl}/${remoteInfo.tarball}`; const tarballPath = path.join(this.config.updatesDir, remoteInfo.tarball); - await this._downloadFile(tarballUrl, tarballPath); + const primaryUrl = `${this.config.updateUrl}/${remoteInfo.tarball}`; + const mirrorUrl = `${this.config.mirrorUrl}/${remoteInfo.tarball}`; + try { + await this._downloadFile(primaryUrl, tarballPath); + } catch (dlErr) { + console.warn('[SelfUpdater] Primary download failed:', dlErr.message, '— trying mirror'); + // Ensure file is fully cleaned up before mirror attempt + try { fs.unlinkSync(tarballPath); } catch (_) {} + await this._downloadFile(mirrorUrl, tarballPath); + } // 2. Verify SHA-256 const hash = await this._computeSha256(tarballPath); @@ -184,12 +197,14 @@ class SelfUpdater extends EventEmitter { this.status = 'waiting'; this.emit('update-progress', { step: 'triggering-rebuild', version: remoteInfo.version }); + // Convert container path to host path for trigger.json + const hostApiSrc = apiSrc.replace(this.config.updatesDir, this.config.hostUpdatesDir); const trigger = { action: 'update', version: remoteInfo.version, commit: remoteInfo.commit, fromVersion: local.version, - stagingDir: apiSrc, + stagingDir: hostApiSrc, apiSourceDir: this.config.apiSourceDir, timestamp: new Date().toISOString(), }; @@ -285,11 +300,12 @@ class SelfUpdater extends EventEmitter { } const local = this.getLocalVersion(); + const hostBackupDir = backupDir.replace(this.config.updatesDir, this.config.hostUpdatesDir); const trigger = { action: 'rollback', version: version, fromVersion: local.version, - stagingDir: backupDir, + stagingDir: hostBackupDir, apiSourceDir: this.config.apiSourceDir, timestamp: new Date().toISOString(), }; @@ -508,6 +524,7 @@ const selfUpdater = new SelfUpdater({ updateUrl: process.env.DASHCADDY_UPDATE_URL, mirrorUrl: process.env.DASHCADDY_MIRROR_URL, updatesDir: process.env.DASHCADDY_UPDATES_DIR, + hostUpdatesDir: process.env.DASHCADDY_HOST_UPDATES_DIR, apiSourceDir: process.env.DASHCADDY_API_SOURCE_DIR, frontendDir: process.env.DASHCADDY_FRONTEND_DIR, });