Files
CoinOX/deploy/setup_env.sh
T
dekun 135cdc13ba Fix hedge market quotes via public HTTP and default cloud-server deploy settings.
Avoid load_markets hangs on weak networks; enable login-required sim defaults and document Baota Nginx reverse proxy.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-14 10:13:39 +08:00

215 lines
5.7 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# coinox 一键环境部署(Ubuntu / root /opt/coinox)
#
# 用法:
# bash deploy/setup_env.sh
# bash deploy/setup_env.sh --skip-pm2
# bash deploy/setup_env.sh --recreate-venv
# bash deploy/setup_env.sh --install-system-deps
#
set -e
set -u
if [ -n "${BASH_VERSION:-}" ]; then
set -o pipefail
fi
DEPLOY_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${DEPLOY_DIR}/.." && pwd)"
REQ_FILE="${REPO_ROOT}/requirements.txt"
# shellcheck source=lib/common.sh
source "${DEPLOY_DIR}/lib/common.sh"
SKIP_PM2=0
SKIP_ENV_COPY=0
RECREATE_VENV=0
INSTALL_APT_DEPS=0
PY=""
usage() {
sed -n '2,10p' "$0" | sed 's/^# \?//'
exit "${1:-0}"
}
while [[ $# -gt 0 ]]; do
case "$1" in
--skip-pm2) SKIP_PM2=1; shift ;;
--skip-env-copy) SKIP_ENV_COPY=1; shift ;;
--recreate-venv) RECREATE_VENV=1; shift ;;
--install-system-deps) INSTALL_APT_DEPS=1; shift ;;
-h|--help) usage 0 ;;
*) echo "未知参数: $1" >&2; usage 1 ;;
esac
done
find_python() {
if command -v python3 >/dev/null 2>&1; then
echo python3
return
fi
if command -v python >/dev/null 2>&1; then
echo python
return
fi
echo "未找到 python3/python,请先安装 Python 3.10+" >&2
exit 1
}
check_python_version() {
local py="$1"
local ver
ver="$("${py}" -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')"
local major minor
major="${ver%%.*}"
minor="${ver#*.}"
if [[ "${major}" -lt 3 ]] || [[ "${major}" -eq 3 && "${minor}" -lt 10 ]]; then
echo "需要 Python 3.10+,当前: ${ver}" >&2
exit 1
fi
echo "Python: $("${py}" --version 2>&1)"
}
python_minor_version() {
local py="$1"
"${py}" -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")'
}
check_venv_available() {
local py="$1"
local tmp
tmp="$(mktemp -d 2>/dev/null || mktemp -d -t cmvenv)"
if "${py}" -m venv "${tmp}" >/dev/null 2>&1 && [[ -x "${tmp}/bin/python" ]]; then
rm -rf "${tmp}"
return 0
fi
rm -rf "${tmp}" 2>/dev/null || true
return 1
}
install_debian_venv_packages() {
local py="$1"
local ver
ver="$(python_minor_version "${py}")"
if ! command -v apt-get >/dev/null 2>&1; then
echo " 未检测到 apt-get,请手动安装 python${ver}-venv 与 python3-pip" >&2
return 1
fi
if [[ "$(id -u)" -ne 0 ]]; then
echo " 需要 root 安装系统包,请执行:" >&2
echo " sudo apt update && sudo apt install -y python${ver}-venv python3-pip curl" >&2
echo " 或: sudo bash deploy/setup_env.sh --install-system-deps" >&2
return 1
fi
step "安装系统依赖 (python${ver}-venv) ..."
export DEBIAN_FRONTEND=noninteractive
apt-get update -qq
if ! apt-get install -y "python${ver}-venv" python3-pip curl ca-certificates git; then
apt-get install -y python3-venv python3-pip curl ca-certificates git
fi
}
ensure_venv_prereqs() {
local py="$1"
if check_venv_available "${py}"; then
return 0
fi
echo " 当前 Python 无法创建 venv(缺少 ensurepip,常见于未安装 python*-venv)" >&2
if [[ "${INSTALL_APT_DEPS}" -eq 1 ]] || [[ "$(id -u)" -eq 0 ]]; then
install_debian_venv_packages "${py}" || exit 1
if check_venv_available "${py}"; then
return 0
fi
fi
local ver
ver="$(python_minor_version "${py}")"
echo "请安装后重试:" >&2
echo " apt update && apt install -y python${ver}-venv python3-pip" >&2
echo " bash deploy/setup_env.sh" >&2
exit 1
}
create_project_venv() {
local py="$1"
if [[ "${RECREATE_VENV}" -eq 1 && -d .venv ]]; then
echo " 删除旧 venv ..."
rm -rf .venv
fi
if [[ -d .venv && ! -x .venv/bin/python ]]; then
echo " 清理未完成的 venv ..."
rm -rf .venv
fi
if [[ -x .venv/bin/python ]]; then
return 0
fi
echo " 创建 venv ..."
if ! "${py}" -m venv .venv; then
rm -rf .venv 2>/dev/null || true
echo " venv 创建失败" >&2
exit 1
fi
}
setup_app() {
step "CoinOX"
cd "${REPO_ROOT}"
create_project_venv "${PY}"
pip_upgrade_tools ".venv/bin/pip"
pip_install_requirements ".venv/bin/pip" "${REQ_FILE}" "CoinOX 依赖"
if [[ "${SKIP_ENV_COPY}" -eq 0 ]]; then
if [[ -f .env.example && ! -f .env ]]; then
cp -n .env.example .env 2>/dev/null || cp .env.example .env
echo " 已复制 .env.example -> .env"
elif [[ -f .env ]]; then
echo " 保留已有 .env"
else
echo " 无 .env.example,请手动配置 .env"
fi
fi
mkdir -p static/images/order_charts
echo " 完成: ${REPO_ROOT}/.venv/bin/python"
}
install_pm2_optional() {
if [[ "${SKIP_PM2}" -eq 1 ]]; then
return
fi
step "PM2(可选)"
if ! command -v node >/dev/null 2>&1; then
echo " 未检测到 Node.js,跳过.安装后执行: npm install -g pm2"
return
fi
if command -v pm2 >/dev/null 2>&1; then
echo " PM2 已安装: $(pm2 -v)"
return
fi
echo " 正在安装 pm2 ..."
npm install -g pm2
}
echo "CoinOX 环境部署"
echo "仓库根目录: ${REPO_ROOT}"
echo "远端仓库: ${GIT_URL}"
[[ -f "${REQ_FILE}" ]] || { echo "缺少 ${REQ_FILE}" >&2; exit 1; }
PY="$(find_python)"
check_python_version "${PY}"
ensure_venv_prereqs "${PY}"
setup_app
install_pm2_optional
step "部署密钥(首次自动生成,不覆盖已有)"
if command -v python3 >/dev/null 2>&1; then
python3 "${REPO_ROOT}/scripts/bootstrap_deploy_secrets.py" || true
else
echo " 跳过 bootstrap_deploy_secrets(未找到 python3)"
fi
echo ""
echo "部署完成.下一步:"
echo " 1. 编辑 ${REPO_ROOT}/.env(云上默认: 模拟盘 sim + 必须登录 + 无代理;改 APP_PASSWORD)"
echo " 2. pm2 start ecosystem.config.cjs"
echo " 3. 可选: 宝塔 Nginx 反代到 http://127.0.0.1:5010(详见 部署文档.md)"
echo " 或: bash deploy/manage.sh # 选 1"
echo ""