2026-06-03 00:58:46 +08:00
|
|
|
#!/bin/sh
|
|
|
|
|
# Nexus Docker entrypoint — wait for deps, sync .env with persistent volume, exec uvicorn.
|
|
|
|
|
set -eu
|
|
|
|
|
|
|
|
|
|
PERSIST_DIR="${NEXUS_PERSIST_DIR:-/var/lib/nexus}"
|
|
|
|
|
PERSIST_ENV="${PERSIST_DIR}/.env"
|
|
|
|
|
|
|
|
|
|
wait_tcp() {
|
|
|
|
|
host="$1"
|
|
|
|
|
port="$2"
|
|
|
|
|
echo "entrypoint: waiting for ${host}:${port}..."
|
|
|
|
|
until python3 -c "
|
|
|
|
|
import socket
|
|
|
|
|
s = socket.socket()
|
|
|
|
|
s.settimeout(2)
|
|
|
|
|
s.connect(('${host}', ${port}))
|
|
|
|
|
s.close()
|
|
|
|
|
" 2>/dev/null; do
|
|
|
|
|
sleep 2
|
|
|
|
|
done
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-06 02:48:00 +08:00
|
|
|
wait_tcp_optional() {
|
|
|
|
|
host="$1"
|
|
|
|
|
port="$2"
|
|
|
|
|
tries="${3:-15}"
|
|
|
|
|
echo "entrypoint: waiting for external Redis ${host}:${port} (max ${tries} tries)..."
|
|
|
|
|
n=0
|
|
|
|
|
while [ "$n" -lt "$tries" ]; do
|
|
|
|
|
if python3 -c "
|
|
|
|
|
import socket
|
|
|
|
|
s = socket.socket()
|
|
|
|
|
s.settimeout(2)
|
|
|
|
|
s.connect(('${host}', ${port}))
|
|
|
|
|
s.close()
|
|
|
|
|
" 2>/dev/null; then
|
|
|
|
|
echo "entrypoint: Redis ready at ${host}:${port}"
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
n=$((n + 1))
|
|
|
|
|
sleep 2
|
|
|
|
|
done
|
|
|
|
|
echo "entrypoint: warn — Redis not reachable at ${host}:${port}; install on host or set NEXUS_REDIS_URL"
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-03 00:58:46 +08:00
|
|
|
restore_persisted_env() {
|
|
|
|
|
if [ -f "${PERSIST_ENV}" ]; then
|
|
|
|
|
cp "${PERSIST_ENV}" /app/.env
|
|
|
|
|
chmod 600 /app/.env
|
|
|
|
|
echo "entrypoint: restored .env from ${PERSIST_ENV}"
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
write_env_from_environment() {
|
|
|
|
|
if [ -f /app/.env ]; then
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
if [ "${NEXUS_DOCKER_WRITE_ENV:-}" != "1" ]; then
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
if [ -z "${NEXUS_SECRET_KEY:-}" ]; then
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
2026-06-06 00:25:57 +08:00
|
|
|
if [ "${NEXUS_INSTALL_WIZARD_PENDING:-}" = "1" ]; then
|
|
|
|
|
echo "entrypoint: install wizard pending — skip writing /app/.env"
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
2026-06-03 00:58:46 +08:00
|
|
|
mkdir -p "${PERSIST_DIR}"
|
|
|
|
|
{
|
|
|
|
|
echo "# Generated by docker/entrypoint.sh — do not commit"
|
|
|
|
|
env | grep '^NEXUS_' | sort
|
|
|
|
|
} > /app/.env
|
|
|
|
|
chmod 600 /app/.env
|
|
|
|
|
cp /app/.env "${PERSIST_ENV}"
|
|
|
|
|
echo "entrypoint: wrote .env from container environment"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
persist_env_on_exit() {
|
|
|
|
|
if [ -f /app/.env ]; then
|
|
|
|
|
mkdir -p "${PERSIST_DIR}"
|
|
|
|
|
cp /app/.env "${PERSIST_ENV}"
|
|
|
|
|
chmod 600 "${PERSIST_ENV}" 2>/dev/null || true
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
trap persist_env_on_exit EXIT INT TERM
|
|
|
|
|
|
2026-06-06 03:27:57 +08:00
|
|
|
# MySQL / Redis 均由用户自行安装在宿主机;安装向导阶段不阻塞启动
|
|
|
|
|
if [ "${NEXUS_INSTALL_WIZARD_PENDING:-0}" != "1" ] && [ "${NEXUS_SKIP_MYSQL_WAIT:-0}" != "1" ]; then
|
2026-06-06 05:35:04 +08:00
|
|
|
MYSQL_HOST="${NEXUS_1PANEL_DB_HOST:-${MYSQL_HOST:-host.docker.internal}}"
|
2026-06-06 03:27:57 +08:00
|
|
|
MYSQL_PORT="${MYSQL_PORT:-3306}"
|
|
|
|
|
wait_tcp_optional "${MYSQL_HOST}" "${MYSQL_PORT}" 30
|
|
|
|
|
fi
|
2026-06-06 02:48:00 +08:00
|
|
|
|
|
|
|
|
if [ "${NEXUS_INSTALL_WIZARD_PENDING:-0}" != "1" ] && [ "${NEXUS_SKIP_REDIS_WAIT:-0}" != "1" ]; then
|
2026-06-06 05:35:04 +08:00
|
|
|
REDIS_HOST="${NEXUS_1PANEL_REDIS_HOST:-${REDIS_HOST:-host.docker.internal}}"
|
2026-06-06 02:48:00 +08:00
|
|
|
REDIS_PORT="${REDIS_PORT:-6379}"
|
|
|
|
|
wait_tcp_optional "${REDIS_HOST}" "${REDIS_PORT}" 15
|
|
|
|
|
fi
|
2026-06-03 00:58:46 +08:00
|
|
|
|
|
|
|
|
restore_persisted_env
|
|
|
|
|
write_env_from_environment
|
|
|
|
|
|
|
|
|
|
exec "$@"
|