Add monitored npm install with timeout and fallback registry.
Improve container startup by printing periodic install heartbeat logs, enforcing npm install timeout, and retrying with a fallback registry to avoid silent hangs. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -83,6 +83,7 @@ DOCKER_BUILDKIT=1 docker build --network=host \
|
||||
docker run --rm -it \
|
||||
-p 14620:14620 \
|
||||
-p 14621:14621 \
|
||||
-v media_crawler_runtime:/app/runtime \
|
||||
--env-file backend/.env \
|
||||
-e GIT_REPO_URL=https://git.rc707blog.top/rose_cat707/media_crawler.git \
|
||||
-e GIT_BRANCH=main \
|
||||
@@ -95,4 +96,8 @@ docker run --rm -it \
|
||||
- `GIT_BRANCH`:拉取分支(默认 `main`)
|
||||
- `WORKTREE_DIR`:容器内代码目录(默认 `/app/runtime`)
|
||||
- `NPM_REGISTRY`:前端依赖安装镜像源(默认 `https://registry.npmmirror.com`)
|
||||
- `NPM_FALLBACK_REGISTRY`:`NPM_REGISTRY` 失败时回退源(默认 `https://registry.npmjs.org`)
|
||||
- `FORCE_FRONTEND_REBUILD`:强制每次重装前端依赖并重建(默认 `0`,仅 lockfile 变更时才安装构建)
|
||||
- `NPM_INSTALL_TIMEOUT_SEC`:前端依赖安装超时秒数(默认 `900`)
|
||||
- `NPM_PROGRESS_INTERVAL_SEC`:安装过程心跳日志间隔秒数(默认 `15`)
|
||||
|
||||
|
||||
@@ -7,6 +7,32 @@ WORKTREE_DIR="${WORKTREE_DIR:-/app/runtime}"
|
||||
BACKEND_PORT="${FLASK_RUN_PORT:-14620}"
|
||||
FRONTEND_PORT="${FRONTEND_PORT:-14621}"
|
||||
NPM_REGISTRY="${NPM_REGISTRY:-https://registry.npmmirror.com}"
|
||||
FORCE_FRONTEND_REBUILD="${FORCE_FRONTEND_REBUILD:-0}"
|
||||
NPM_FALLBACK_REGISTRY="${NPM_FALLBACK_REGISTRY:-https://registry.npmjs.org}"
|
||||
NPM_INSTALL_TIMEOUT_SEC="${NPM_INSTALL_TIMEOUT_SEC:-900}"
|
||||
NPM_PROGRESS_INTERVAL_SEC="${NPM_PROGRESS_INTERVAL_SEC:-15}"
|
||||
|
||||
run_npm_install_with_monitor() {
|
||||
INSTALL_CMD="$1"
|
||||
START_TS="$(date +%s)"
|
||||
sh -c "${INSTALL_CMD}" &
|
||||
INSTALL_PID=$!
|
||||
|
||||
while kill -0 "${INSTALL_PID}" 2>/dev/null; do
|
||||
NOW_TS="$(date +%s)"
|
||||
ELAPSED="$((NOW_TS - START_TS))"
|
||||
if [ "${ELAPSED}" -ge "${NPM_INSTALL_TIMEOUT_SEC}" ]; then
|
||||
echo "[start] npm install timeout after ${ELAPSED}s, killing process"
|
||||
kill "${INSTALL_PID}" 2>/dev/null || true
|
||||
wait "${INSTALL_PID}" 2>/dev/null || true
|
||||
return 124
|
||||
fi
|
||||
echo "[start] npm install running... elapsed=${ELAPSED}s"
|
||||
sleep "${NPM_PROGRESS_INTERVAL_SEC}"
|
||||
done
|
||||
|
||||
wait "${INSTALL_PID}"
|
||||
}
|
||||
|
||||
echo "[start] syncing source from ${GIT_REPO_URL} (${GIT_BRANCH})"
|
||||
if [ ! -d "${WORKTREE_DIR}/.git" ]; then
|
||||
@@ -27,11 +53,52 @@ fi
|
||||
|
||||
echo "[start] installing frontend dependencies and building"
|
||||
cd "${WORKTREE_DIR}/frontend"
|
||||
echo "[start] npm registry: ${NPM_REGISTRY}"
|
||||
npm config set registry "${NPM_REGISTRY}"
|
||||
npm ci --no-audit --no-fund
|
||||
echo "[start] building frontend assets"
|
||||
npm run build
|
||||
LOCKFILE_PATH="${WORKTREE_DIR}/frontend/package-lock.json"
|
||||
LOCKFILE_HASH_PATH="${WORKTREE_DIR}/.cache/frontend_lock.sha256"
|
||||
mkdir -p "${WORKTREE_DIR}/.cache"
|
||||
|
||||
if command -v sha256sum >/dev/null 2>&1; then
|
||||
CURRENT_LOCK_HASH="$(sha256sum "${LOCKFILE_PATH}" | awk '{print $1}')"
|
||||
else
|
||||
CURRENT_LOCK_HASH="$(shasum -a 256 "${LOCKFILE_PATH}" | awk '{print $1}')"
|
||||
fi
|
||||
|
||||
LAST_LOCK_HASH=""
|
||||
if [ -f "${LOCKFILE_HASH_PATH}" ]; then
|
||||
LAST_LOCK_HASH="$(cat "${LOCKFILE_HASH_PATH}")"
|
||||
fi
|
||||
|
||||
NEED_FRONTEND_BUILD=0
|
||||
if [ "${FORCE_FRONTEND_REBUILD}" = "1" ]; then
|
||||
NEED_FRONTEND_BUILD=1
|
||||
elif [ ! -d "${WORKTREE_DIR}/frontend/node_modules" ]; then
|
||||
NEED_FRONTEND_BUILD=1
|
||||
elif [ ! -d "${WORKTREE_DIR}/frontend/dist" ]; then
|
||||
NEED_FRONTEND_BUILD=1
|
||||
elif [ "${CURRENT_LOCK_HASH}" != "${LAST_LOCK_HASH}" ]; then
|
||||
NEED_FRONTEND_BUILD=1
|
||||
fi
|
||||
|
||||
if [ "${NEED_FRONTEND_BUILD}" = "1" ]; then
|
||||
echo "[start] npm registry: ${NPM_REGISTRY}"
|
||||
npm config set registry "${NPM_REGISTRY}"
|
||||
npm config set fetch-retries 2
|
||||
npm config set fetch-retry-mintimeout 20000
|
||||
npm config set fetch-retry-maxtimeout 120000
|
||||
npm config set fetch-timeout 120000
|
||||
npm config set progress false
|
||||
echo "[start] installing frontend dependencies (timeout=${NPM_INSTALL_TIMEOUT_SEC}s)"
|
||||
if ! run_npm_install_with_monitor "npm install --prefer-offline --no-audit --no-fund --loglevel=info"; then
|
||||
echo "[start] npm install failed with ${NPM_REGISTRY}, fallback to ${NPM_FALLBACK_REGISTRY}"
|
||||
npm config set registry "${NPM_FALLBACK_REGISTRY}"
|
||||
run_npm_install_with_monitor "npm install --prefer-offline --no-audit --no-fund --loglevel=info"
|
||||
fi
|
||||
echo "[start] building frontend assets"
|
||||
npm run build
|
||||
echo "${CURRENT_LOCK_HASH}" > "${LOCKFILE_HASH_PATH}"
|
||||
else
|
||||
echo "[start] skip frontend install/build (lockfile unchanged)"
|
||||
fi
|
||||
|
||||
echo "[start] launching backend:${BACKEND_PORT} and frontend:${FRONTEND_PORT}"
|
||||
cd "${WORKTREE_DIR}/backend"
|
||||
|
||||
Reference in New Issue
Block a user