fix: 修复部署镜像与生产环境配置

- 固定 easyflow-backend 运行镜像为 linux/amd64 并接入新的容器入口脚本

- 支持外挂 jar 的运行目录权限修正、日志管理与热更新监听

- 调整 admin 生产环境基础路径与接口前缀用于部署
This commit is contained in:
2026-03-14 14:58:39 +08:00
parent b5ba6912eb
commit 14c78d54f5
3 changed files with 186 additions and 9 deletions

175
docker-entrypoint.sh Normal file
View File

@@ -0,0 +1,175 @@
#!/usr/bin/env sh
set -eu
JAR_PATH="${EASYFLOW_JAR_PATH:-/app/artifacts/easyflow.jar}"
CONFIG_PATH="${EASYFLOW_CONFIG_PATH:-file:/app/application.yml}"
LOG_FILE="${EASYFLOW_LOG_FILE:-/app/logs/app.log}"
RESTART_GRACE_SECONDS="${EASYFLOW_JAR_RESTART_GRACE_SECONDS:-30}"
ENTRYPOINT_PRIVS_DROPPED="${EASYFLOW_ENTRYPOINT_PRIVS_DROPPED:-0}"
JAVA_PID=""
WATCHER_PID=""
STOP_REQUESTED=0
RESTART_REASON_FILE="/tmp/easyflow-restart-reason"
log() {
printf '%s %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*"
}
ensure_runtime_permissions() {
for path in /app/logs /app/data; do
mkdir -p "$path"
chown -R easyflow:easyflow "$path"
done
}
drop_privileges_if_needed() {
if [ "$(id -u)" -ne 0 ] || [ "$ENTRYPOINT_PRIVS_DROPPED" = "1" ]; then
return
fi
ensure_runtime_permissions
export EASYFLOW_ENTRYPOINT_PRIVS_DROPPED=1
exec setpriv --reuid=easyflow --regid=easyflow --init-groups "$0" "$@"
}
ensure_prerequisites() {
if ! command -v inotifywait >/dev/null 2>&1; then
log "ERROR: inotifywait not found"
exit 1
fi
if [ ! -f "$JAR_PATH" ]; then
log "ERROR: easyflow jar not found: $JAR_PATH"
exit 1
fi
mkdir -p "$(dirname "$LOG_FILE")"
}
compute_jar_digest() {
sha256sum "$JAR_PATH" | awk '{print $1}'
}
stop_watcher() {
if [ -n "$WATCHER_PID" ] && kill -0 "$WATCHER_PID" 2>/dev/null; then
kill "$WATCHER_PID" 2>/dev/null || true
wait "$WATCHER_PID" 2>/dev/null || true
fi
WATCHER_PID=""
}
stop_java_process() {
if [ -z "$JAVA_PID" ] || ! kill -0 "$JAVA_PID" 2>/dev/null; then
return
fi
kill -TERM "$JAVA_PID" 2>/dev/null || true
remaining="$RESTART_GRACE_SECONDS"
while kill -0 "$JAVA_PID" 2>/dev/null; do
if [ "$remaining" -le 0 ]; then
log "java process did not stop within ${RESTART_GRACE_SECONDS}s, forcing shutdown"
kill -KILL "$JAVA_PID" 2>/dev/null || true
break
fi
sleep 1
remaining=$((remaining - 1))
done
}
handle_shutdown() {
STOP_REQUESTED=1
printf '%s' "shutdown" >"$RESTART_REASON_FILE"
stop_watcher
stop_java_process
}
trap 'handle_shutdown' TERM INT
start_java() {
log "starting jar: $JAR_PATH"
# JAVA_OPTS needs shell word splitting to preserve user-provided JVM args.
# shellcheck disable=SC2086
java ${JAVA_OPTS:-} -Djava.security.egd=file:/dev/./urandom -jar "$JAR_PATH" \
--spring.config.location="$CONFIG_PATH" \
--logging.file.name="$LOG_FILE" &
JAVA_PID=$!
}
start_watcher() {
jar_digest="$1"
jar_dir="$(dirname "$JAR_PATH")"
jar_name="$(basename "$JAR_PATH")"
(
while true; do
event_line="$(inotifywait --quiet --event close_write,moved_to --format '%e %f' "$jar_dir")" || exit 0
event_name="${event_line%% *}"
event_file="${event_line#* }"
if [ "$event_file" != "$jar_name" ]; then
continue
fi
if [ ! -f "$JAR_PATH" ]; then
continue
fi
new_digest="$(compute_jar_digest)"
if [ "$new_digest" = "$jar_digest" ]; then
continue
fi
log "detected jar update (${event_name}), restarting java process"
printf '%s' "jar_changed" >"$RESTART_REASON_FILE"
stop_java_process
exit 0
done
) &
WATCHER_PID=$!
}
main() {
drop_privileges_if_needed "$@"
ensure_prerequisites
current_digest="$(compute_jar_digest)"
while true; do
rm -f "$RESTART_REASON_FILE"
start_java
start_watcher "$current_digest"
set +e
wait "$JAVA_PID"
java_status=$?
set -e
stop_watcher
JAVA_PID=""
restart_reason=""
if [ -f "$RESTART_REASON_FILE" ]; then
restart_reason="$(cat "$RESTART_REASON_FILE")"
rm -f "$RESTART_REASON_FILE"
fi
if [ "$STOP_REQUESTED" -eq 1 ] || [ "$restart_reason" = "shutdown" ]; then
exit 0
fi
if [ "$restart_reason" = "jar_changed" ]; then
ensure_prerequisites
current_digest="$(compute_jar_digest)"
log "restarting java with updated jar"
continue
fi
log "java process exited unexpectedly with code $java_status"
exit "$java_status"
done
}
main "$@"