mirror of
https://github.com/okxlin/appstore.git
synced 2026-09-22 16:00:58 +00:00
Migrate legacy ServerKit volume during upgrade
Run the target version upgrade hook to move the SQLite database and its SQLite sidecars from the previously published serverkit-data volume into the new app-local bind directory. Keep the migration scoped to installs whose old Compose still used the named volume and retain the legacy volume for rollback.
This commit is contained in:
Executable
+90
@@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
export PATH
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
|
||||
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd -P)"
|
||||
DATA_DIR="$ROOT_DIR/data"
|
||||
COMPOSE_FILE="$ROOT_DIR/docker-compose.yml"
|
||||
LEGACY_VOLUME="serverkit-data"
|
||||
MIGRATION_IMAGE="jhd3197/serverkit:1.11.4"
|
||||
|
||||
fail() {
|
||||
printf '%s\n' "$1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
has_data_files() {
|
||||
local entry
|
||||
for entry in "$DATA_DIR"/* "$DATA_DIR"/.[!.]* "$DATA_DIR"/..?*; do
|
||||
if [[ -e "$entry" || -L "$entry" ]]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
bash "$SCRIPT_DIR/init.sh"
|
||||
|
||||
if ! grep -Fq 'serverkit-data:/app/instance' "$COMPOSE_FILE"; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ -f "$DATA_DIR/serverkit.db" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if has_data_files; then
|
||||
fail "ServerKit data directory is non-empty but serverkit.db is missing; refusing legacy-volume migration"
|
||||
fi
|
||||
|
||||
command -v docker >/dev/null 2>&1 || fail "docker is required for legacy ServerKit volume migration"
|
||||
if ! docker volume inspect "$LEGACY_VOLUME" >/dev/null 2>&1; then
|
||||
exit 0
|
||||
fi
|
||||
docker image inspect "$MIGRATION_IMAGE" >/dev/null 2>&1 || fail "migration image is unavailable: $MIGRATION_IMAGE"
|
||||
|
||||
docker run --rm --network none --user 0 --entrypoint /bin/sh \
|
||||
--volume "$LEGACY_VOLUME:/legacy:ro" \
|
||||
--volume "$DATA_DIR:/target:rw" \
|
||||
"$MIGRATION_IMAGE" \
|
||||
-c '
|
||||
set -eu
|
||||
stage=/target/.serverkit-data-migration
|
||||
[ ! -e "$stage" ] && [ ! -L "$stage" ] || { echo "migration staging path already exists" >&2; exit 1; }
|
||||
mkdir "$stage"
|
||||
cleanup() {
|
||||
rm -rf -- "$stage"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
found=0
|
||||
found_db=0
|
||||
for item in /legacy/* /legacy/.[!.]* /legacy/..?*; do
|
||||
[ -e "$item" ] || [ -L "$item" ] || continue
|
||||
[ -f "$item" ] && [ ! -L "$item" ] || { echo "legacy volume contains an unsupported non-regular file" >&2; exit 1; }
|
||||
name=${item##*/}
|
||||
case "$name" in
|
||||
serverkit.db|serverkit.db-wal|serverkit.db-shm) ;;
|
||||
*) echo "legacy volume contains an unexpected file" >&2; exit 1 ;;
|
||||
esac
|
||||
cp -p -- "$item" "$stage/$name"
|
||||
found=1
|
||||
[ "$name" = serverkit.db ] && found_db=1
|
||||
done
|
||||
|
||||
[ "$found" = 0 ] && exit 0
|
||||
[ "$found_db" = 1 ] || { echo "legacy volume does not contain serverkit.db" >&2; exit 1; }
|
||||
|
||||
for name in serverkit.db-wal serverkit.db-shm serverkit.db; do
|
||||
if [ -e "$stage/$name" ]; then
|
||||
[ ! -e "/target/$name" ] && [ ! -L "/target/$name" ] || { echo "target data file already exists" >&2; exit 1; }
|
||||
chown 999:999 "$stage/$name"
|
||||
chmod 0640 "$stage/$name"
|
||||
mv -- "$stage/$name" "/target/$name"
|
||||
fi
|
||||
done
|
||||
'
|
||||
|
||||
bash "$SCRIPT_DIR/init.sh"
|
||||
@@ -29,7 +29,7 @@ ServerKit 是一个自托管的远程服务器管理与运维面板,提供服
|
||||
3. 通过安装时配置的 HTTP 端口打开 ServerKit。首次打开时使用注册页面创建第一个用户;第一个用户会被授予管理员角色。
|
||||
4. 如果使用反向代理,请填写 `SERVERKIT_PUBLIC_URL`,并仅在请求一定经过可信反向代理时将 `TRUST_PROXY_HEADERS` 设为 `true`。需要同时允许多个浏览器来源时,在 `CORS_ORIGINS` 中用逗号分隔填写。
|
||||
|
||||
SQLite 数据库持久化在应用安装目录的 `data/serverkit.db`,并以 bind mount 映射到容器内的 `/app/instance`。该目录位于 1Panel 应用目录中,便于随应用数据一起备份。不要删除该目录,否则会丢失 ServerKit 数据。
|
||||
SQLite 数据库持久化在应用安装目录的 `data/serverkit.db`,并以 bind mount 映射到容器内的 `/app/instance`。该目录位于 1Panel 应用目录中,便于随应用数据一起备份。不要删除该目录,否则会丢失 ServerKit 数据。由旧版 `serverkit-data` 卷升级时,目标版本会在新目录为空时自动迁移 SQLite 文件;旧卷会保留,不会自动删除。
|
||||
|
||||
## 版本
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ This is ServerKit's containerized deployment. The package does not mount the Doc
|
||||
3. Open ServerKit on the configured HTTP port. On the first visit, use the registration page to create the first user; the first user is given the administrator role.
|
||||
4. When using a reverse proxy, set `SERVERKIT_PUBLIC_URL`. Set `TRUST_PROXY_HEADERS` to `true` only when every request is guaranteed to pass through a trusted proxy. Add multiple browser origins as a comma-separated `CORS_ORIGINS` value.
|
||||
|
||||
The SQLite database is persisted at `data/serverkit.db` in the application install directory and bind-mounted to `/app/instance`. This keeps the data under the 1Panel application directory for application backups. Do not remove this directory unless the ServerKit data can be discarded.
|
||||
The SQLite database is persisted at `data/serverkit.db` in the application install directory and bind-mounted to `/app/instance`. This keeps the data under the 1Panel application directory for application backups. Do not remove this directory unless the ServerKit data can be discarded. When upgrading from the legacy `serverkit-data` volume, the target version migrates the SQLite files when the new directory is empty; the legacy volume is retained and is not deleted automatically.
|
||||
|
||||
## Versions
|
||||
|
||||
|
||||
Executable
+90
@@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
export PATH
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
|
||||
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd -P)"
|
||||
DATA_DIR="$ROOT_DIR/data"
|
||||
COMPOSE_FILE="$ROOT_DIR/docker-compose.yml"
|
||||
LEGACY_VOLUME="serverkit-data"
|
||||
MIGRATION_IMAGE="jhd3197/serverkit:latest"
|
||||
|
||||
fail() {
|
||||
printf '%s\n' "$1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
has_data_files() {
|
||||
local entry
|
||||
for entry in "$DATA_DIR"/* "$DATA_DIR"/.[!.]* "$DATA_DIR"/..?*; do
|
||||
if [[ -e "$entry" || -L "$entry" ]]; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
bash "$SCRIPT_DIR/init.sh"
|
||||
|
||||
if ! grep -Fq 'serverkit-data:/app/instance' "$COMPOSE_FILE"; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ -f "$DATA_DIR/serverkit.db" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if has_data_files; then
|
||||
fail "ServerKit data directory is non-empty but serverkit.db is missing; refusing legacy-volume migration"
|
||||
fi
|
||||
|
||||
command -v docker >/dev/null 2>&1 || fail "docker is required for legacy ServerKit volume migration"
|
||||
if ! docker volume inspect "$LEGACY_VOLUME" >/dev/null 2>&1; then
|
||||
exit 0
|
||||
fi
|
||||
docker image inspect "$MIGRATION_IMAGE" >/dev/null 2>&1 || fail "migration image is unavailable: $MIGRATION_IMAGE"
|
||||
|
||||
docker run --rm --network none --user 0 --entrypoint /bin/sh \
|
||||
--volume "$LEGACY_VOLUME:/legacy:ro" \
|
||||
--volume "$DATA_DIR:/target:rw" \
|
||||
"$MIGRATION_IMAGE" \
|
||||
-c '
|
||||
set -eu
|
||||
stage=/target/.serverkit-data-migration
|
||||
[ ! -e "$stage" ] && [ ! -L "$stage" ] || { echo "migration staging path already exists" >&2; exit 1; }
|
||||
mkdir "$stage"
|
||||
cleanup() {
|
||||
rm -rf -- "$stage"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
found=0
|
||||
found_db=0
|
||||
for item in /legacy/* /legacy/.[!.]* /legacy/..?*; do
|
||||
[ -e "$item" ] || [ -L "$item" ] || continue
|
||||
[ -f "$item" ] && [ ! -L "$item" ] || { echo "legacy volume contains an unsupported non-regular file" >&2; exit 1; }
|
||||
name=${item##*/}
|
||||
case "$name" in
|
||||
serverkit.db|serverkit.db-wal|serverkit.db-shm) ;;
|
||||
*) echo "legacy volume contains an unexpected file" >&2; exit 1 ;;
|
||||
esac
|
||||
cp -p -- "$item" "$stage/$name"
|
||||
found=1
|
||||
[ "$name" = serverkit.db ] && found_db=1
|
||||
done
|
||||
|
||||
[ "$found" = 0 ] && exit 0
|
||||
[ "$found_db" = 1 ] || { echo "legacy volume does not contain serverkit.db" >&2; exit 1; }
|
||||
|
||||
for name in serverkit.db-wal serverkit.db-shm serverkit.db; do
|
||||
if [ -e "$stage/$name" ]; then
|
||||
[ ! -e "/target/$name" ] && [ ! -L "/target/$name" ] || { echo "target data file already exists" >&2; exit 1; }
|
||||
chown 999:999 "$stage/$name"
|
||||
chmod 0640 "$stage/$name"
|
||||
mv -- "$stage/$name" "/target/$name"
|
||||
fi
|
||||
done
|
||||
'
|
||||
|
||||
bash "$SCRIPT_DIR/init.sh"
|
||||
Reference in New Issue
Block a user