docker-entrypoint.sh
Rama main · réplica de lectura del repositorio original.
#!/bin/bash
# =============================================================================
# ZhikunCode — Container Entrypoint
# Starts Java backend (which internally manages the Python subprocess)
# =============================================================================
set -e
# ---- Resolve Python virtual environment ----
export PATH="/app/python-service/.venv/bin:${PATH}"
export PYTHONPATH="/app/python-service/src"
# ---- Ensure data directories exist ----
# Explicitly pass the log directory to Log4j2 (container convention: /app/log);
# an externally provided LOG_DIR always takes precedence.
export LOG_DIR="${LOG_DIR:-/app/log}"
mkdir -p /app/data /app/workspace "$LOG_DIR"
# ============================================================
# Pre-flight checks
# ============================================================
# 1. Validate LLM configuration (multi-provider or legacy single-provider)
HAS_PROVIDER_KEY=false
if [ -n "${LLM_PROVIDER_OPENAI_API_KEY//[[:space:]]/}" ]; then
HAS_PROVIDER_KEY=true
fi
if [ -n "$LLM_PROVIDER_DASHSCOPE_API_KEY" ] && [ "$LLM_PROVIDER_DASHSCOPE_API_KEY" != "your-dashscope-api-key-here" ]; then
HAS_PROVIDER_KEY=true
fi
if [ -n "$LLM_PROVIDER_DASHSCOPE_TOKEN_PLAN_API_KEY" ] && [ "$LLM_PROVIDER_DASHSCOPE_TOKEN_PLAN_API_KEY" != "your-token-plan-api-key-here" ]; then
HAS_PROVIDER_KEY=true
fi
if [ -n "$LLM_PROVIDER_DEEPSEEK_API_KEY" ] && [ "$LLM_PROVIDER_DEEPSEEK_API_KEY" != "your-deepseek-api-key-here" ]; then
HAS_PROVIDER_KEY=true
fi
if [ -n "$LLM_PROVIDER_MOONSHOT_API_KEY" ] && [ "$LLM_PROVIDER_MOONSHOT_API_KEY" != "your-moonshot-api-key-here" ]; then
HAS_PROVIDER_KEY=true
fi
if [ -n "$LLM_PROVIDER_ZHIPU_API_KEY" ] && [ "$LLM_PROVIDER_ZHIPU_API_KEY" != "your-zhipu-api-key-here" ]; then
HAS_PROVIDER_KEY=true
fi
if [ -n "$LLM_PROVIDER_ZENMUX_API_KEY" ] && [ "$LLM_PROVIDER_ZENMUX_API_KEY" != "your-zenmux-api-key-here" ]; then
HAS_PROVIDER_KEY=true
fi
HAS_LEGACY_KEY=false
if [ -n "$LLM_API_KEY" ] && [ "$LLM_API_KEY" != "your-api-key-here" ]; then
HAS_LEGACY_KEY=true
fi
if [ "$HAS_PROVIDER_KEY" = false ] && [ "$HAS_LEGACY_KEY" = false ]; then
echo "============================================================"
echo " ERROR: No LLM API Key configured!"
echo ""
echo " Option 1 (Recommended): Set provider-specific keys:"
echo " LLM_PROVIDER_OPENAI_API_KEY=your-key"
echo " LLM_PROVIDER_DASHSCOPE_API_KEY=your-key"
echo " LLM_PROVIDER_DASHSCOPE_TOKEN_PLAN_API_KEY=your-key"
echo " LLM_PROVIDER_DEEPSEEK_API_KEY=your-key"
echo " LLM_PROVIDER_ZHIPU_API_KEY=your-key"
echo " LLM_PROVIDER_ZENMUX_API_KEY=your-key"
echo ""
echo " Option 2 (Legacy): Set a single key:"
echo " LLM_API_KEY=your-key"
echo ""
echo " See .env.example for configuration details."
echo "============================================================"
exit 1
fi
# 2. Print configuration summary
echo "============================================================"
echo " ZhikunCode — Starting"
echo "============================================================"
if [ -n "$LLM_PROVIDER_DASHSCOPE_API_KEY" ] && [ "$LLM_PROVIDER_DASHSCOPE_API_KEY" != "your-dashscope-api-key-here" ]; then
MASKED="${LLM_PROVIDER_DASHSCOPE_API_KEY:0:6}****${LLM_PROVIDER_DASHSCOPE_API_KEY: -4}"
echo " DashScope Key: $MASKED"
fi
if [ -n "$LLM_PROVIDER_DASHSCOPE_TOKEN_PLAN_API_KEY" ] && [ "$LLM_PROVIDER_DASHSCOPE_TOKEN_PLAN_API_KEY" != "your-token-plan-api-key-here" ]; then
MASKED="${LLM_PROVIDER_DASHSCOPE_TOKEN_PLAN_API_KEY:0:6}****${LLM_PROVIDER_DASHSCOPE_TOKEN_PLAN_API_KEY: -4}"
echo " Bailian Key: $MASKED"
fi
if [ -n "$LLM_PROVIDER_DEEPSEEK_API_KEY" ] && [ "$LLM_PROVIDER_DEEPSEEK_API_KEY" != "your-deepseek-api-key-here" ]; then
MASKED="${LLM_PROVIDER_DEEPSEEK_API_KEY:0:6}****${LLM_PROVIDER_DEEPSEEK_API_KEY: -4}"
echo " DeepSeek Key: $MASKED"
fi
if [ -n "$LLM_PROVIDER_MOONSHOT_API_KEY" ] && [ "$LLM_PROVIDER_MOONSHOT_API_KEY" != "your-moonshot-api-key-here" ]; then
MASKED="${LLM_PROVIDER_MOONSHOT_API_KEY:0:6}****${LLM_PROVIDER_MOONSHOT_API_KEY: -4}"
echo " Moonshot Key: $MASKED"
fi
if [ -n "$LLM_PROVIDER_ZHIPU_API_KEY" ] && [ "$LLM_PROVIDER_ZHIPU_API_KEY" != "your-zhipu-api-key-here" ]; then
MASKED="${LLM_PROVIDER_ZHIPU_API_KEY:0:6}****${LLM_PROVIDER_ZHIPU_API_KEY: -4}"
echo " Zhipu Key: $MASKED"
fi
if [ -n "$LLM_PROVIDER_ZENMUX_API_KEY" ] && [ "$LLM_PROVIDER_ZENMUX_API_KEY" != "your-zenmux-api-key-here" ]; then
MASKED="${LLM_PROVIDER_ZENMUX_API_KEY:0:6}****${LLM_PROVIDER_ZENMUX_API_KEY: -4}"
echo " ZenMux Key: $MASKED"
fi
if [ "$HAS_LEGACY_KEY" = true ]; then
MASKED="${LLM_API_KEY:0:6}****${LLM_API_KEY: -4}"
echo " Legacy API Key: $MASKED"
echo " LLM Base URL: ${LLM_BASE_URL:-default (DashScope)}"
fi
echo " Default Model: ${LLM_DEFAULT_MODEL:-default}"
echo " Log Directory: ${LOG_DIR:-/app/log}"
echo " Private Network: ${ALLOW_PRIVATE_NETWORK:-false}"
echo "============================================================"
# 3. Check writable directories
for dir in "${LOG_DIR:-/app/log}" /app/data; do
if [ -d "$dir" ] && [ ! -w "$dir" ]; then
echo "WARNING: Directory $dir is not writable by user $(whoami)"
fi
done
# ---- Startup banner ----
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo " ZhikunCode — Starting..."
echo " Java: $(java --version 2>&1 | head -1)"
echo " Python: $(python --version 2>&1)"
echo " Profile: ${SPRING_PROFILES_ACTIVE:-default}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# ---- Launch Java application ----
# PythonProcessManager inside Spring Boot starts Python only when explicitly enabled.
exec java \
${JAVA_OPTS} \
-Djava.security.egd=file:/dev/./urandom \
-Dspring.profiles.active="${SPRING_PROFILES_ACTIVE:-production}" \
-jar /app/app.jar \
"$@"