fix: 修复部署镜像与生产环境配置
- 固定 easyflow-backend 运行镜像为 linux/amd64 并接入新的容器入口脚本 - 支持外挂 jar 的运行目录权限修正、日志管理与热更新监听 - 调整 admin 生产环境基础路径与接口前缀用于部署
This commit is contained in:
16
Dockerfile
16
Dockerfile
@@ -1,25 +1,27 @@
|
|||||||
FROM eclipse-temurin:17-jre
|
FROM --platform=linux/amd64 swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/eclipse-temurin:17-jre
|
||||||
|
|
||||||
ENV LANG=C.UTF-8
|
ENV LANG=C.UTF-8
|
||||||
ENV LC_ALL=C.UTF-8
|
ENV LC_ALL=C.UTF-8
|
||||||
ENV TZ=Asia/Shanghai
|
ENV TZ=Asia/Shanghai
|
||||||
ENV JAVA_OPTS=""
|
ENV JAVA_OPTS=""
|
||||||
ENV EASYFLOW_JAR_PATH=/app/easyflow.jar
|
ENV EASYFLOW_JAR_PATH=/app/artifacts/easyflow.jar
|
||||||
ENV EASYFLOW_CONFIG_PATH=file:/app/application.yml
|
ENV EASYFLOW_CONFIG_PATH=file:/app/application.yml
|
||||||
ENV EASYFLOW_LOG_FILE=/app/logs/app.log
|
ENV EASYFLOW_LOG_FILE=/app/logs/app.log
|
||||||
|
ENV EASYFLOW_JAR_RESTART_GRACE_SECONDS=30
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
RUN useradd --system --create-home easyflow && \
|
RUN useradd --system --create-home easyflow && \
|
||||||
apt-get update && \
|
apt-get update && \
|
||||||
apt-get install -y --no-install-recommends python3 && \
|
apt-get install -y --no-install-recommends python3 inotify-tools tini && \
|
||||||
rm -rf /var/lib/apt/lists/* && \
|
rm -rf /var/lib/apt/lists/* && \
|
||||||
mkdir -p /app/logs && \
|
mkdir -p /app/logs /app/artifacts /app/data && \
|
||||||
chown -R easyflow:easyflow /app
|
chown -R easyflow:easyflow /app
|
||||||
|
|
||||||
USER easyflow
|
COPY docker-entrypoint.sh /usr/local/bin/easyflow-entrypoint.sh
|
||||||
|
RUN chmod 755 /usr/local/bin/easyflow-entrypoint.sh
|
||||||
|
|
||||||
VOLUME ["/app/logs"]
|
VOLUME ["/app/logs", "/app/data"]
|
||||||
EXPOSE 8111
|
EXPOSE 8111
|
||||||
|
|
||||||
ENTRYPOINT ["sh", "-c", "if [ ! -f \"${EASYFLOW_JAR_PATH}\" ]; then echo \"ERROR: easyflow jar not found: ${EASYFLOW_JAR_PATH}\"; exit 1; fi; java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar \"${EASYFLOW_JAR_PATH}\" --spring.config.location=\"${EASYFLOW_CONFIG_PATH}\" --logging.file.name=\"${EASYFLOW_LOG_FILE}\""]
|
ENTRYPOINT ["/usr/bin/tini", "--", "/usr/local/bin/easyflow-entrypoint.sh"]
|
||||||
|
|||||||
175
docker-entrypoint.sh
Normal file
175
docker-entrypoint.sh
Normal 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 "$@"
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
VITE_BASE=/
|
VITE_BASE=/flow/
|
||||||
|
|
||||||
# 接口地址
|
# 接口地址
|
||||||
VITE_GLOB_API_URL=
|
VITE_GLOB_API_URL=/flow
|
||||||
|
|
||||||
# 是否开启压缩,可以设置为 none, brotli, gzip
|
# 是否开启压缩,可以设置为 none, brotli, gzip
|
||||||
VITE_COMPRESS=none
|
VITE_COMPRESS=none
|
||||||
|
|||||||
Reference in New Issue
Block a user