Files
2026-08-08 18:27:38 +08:00

173 lines
7.8 KiB
Bash
Raw Permalink 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
# 云创芯 Laravel12 + Vue3(CDN) 一键安装脚本
# 适用:宝塔 Nginx + PHP 8.3 + MySQL 5.7
# 设计:零 Node、零前端构建。支持两种分发包:
# - 完整包(含 vendor/):无需服务器安装 Composer,直接跑
# - 源码包(不含 vendor/):脚本自动调用 Composer 安装依赖
set -euo pipefail
export COMPOSER_ALLOW_SUPERUSER=1
# 颜色(ANSI 转义,非 HEX 色值)
if [ -t 1 ]; then
C_OK=$'\033[0;32m'; C_WARN=$'\033[0;33m'; C_ERR=$'\033[0;31m'; C_RESET=$'\033[0m'
else
C_OK=''; C_WARN=''; C_ERR=''; C_RESET=''
fi
step() { echo; echo "${C_OK}==>${C_RESET} $*"; }
ok() { echo " ${C_OK}[OK]${C_RESET} $*"; }
warn() { echo " ${C_WARN}[WARN]${C_RESET} $*"; }
err() { echo " ${C_ERR}[ERROR]${C_RESET} $*"; exit 1; }
ROOT="$(cd "$(dirname "$0")" && pwd)"
cd "$ROOT"
echo "Project root: $ROOT"
# ── PHP 版本检查 ────────────────────────────────────────────────
PHP_BIN="$(command -v php || true)"
[ -z "$PHP_BIN" ] && err "未找到 php,请先在宝塔安装 PHP 8.3 并加入命令行。"
PHP_VER="$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')"
PHP_MAJOR="$(php -r 'echo PHP_MAJOR_VERSION;')"
PHP_MINOR="$(php -r 'echo PHP_MINOR_VERSION;')"
if [ "$PHP_MAJOR" -lt 8 ] || { [ "$PHP_MAJOR" -eq 8 ] && [ "$PHP_MINOR" -lt 2 ]; }; then
err "PHP $PHP_VER 过低,本项目要求 PHP >= 8.2(推荐 8.3)。"
fi
ok "PHP version: $PHP_VER"
# ── 必要扩展检查(大小写不敏感,兼容 php -m 输出)─────────────
REQ_EXT=(ctype curl dom fileinfo json mbstring openssl pdo pdo_mysql tokenizer xml)
missing=()
for ext in "${REQ_EXT[@]}"; do
if ! php -m | grep -iqw "$ext"; then
missing+=("$ext")
fi
done
if [ ${#missing[@]} -gt 0 ]; then
err "缺少 PHP 扩展: ${missing[*]}。请在宝塔 PHP-8.3 设置中安装后重试。"
fi
ok "All required PHP extensions present"
# ── 依赖安装 ───────────────────────────────────────────────────
# 完整包已内置 vendor/,直接跳过;源码包才需要 Composer。
step "Checking PHP dependencies"
if [ -f vendor/autoload.php ]; then
ok "vendor/ 已内置,跳过 Composer 安装"
else
if ! command -v composer >/dev/null 2>&1; then
warn "Composer 未安装,正在尝试自动安装..."
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php --quiet
rm -f composer-setup.php
mv composer.phar /usr/local/bin/composer
fi
if ! composer --version >/dev/null 2>&1; then
err "Composer 不可用。宝塔 PHP 可能禁用了 putenv/proc_open/pcntl_signal,请在【软件商店 → PHP8.3 → 设置 → 禁用函数】中删除这些函数并重启 PHP-FPM;或改用内置 vendor 的完整包。"
fi
ok "Composer: $(composer --version | head -n1)"
composer install --no-dev --optimize-autoloader --no-interaction
ok "Dependencies installed"
fi
# ── 运行时目录(Laravel 启动即需 bootstrap/cache 可写)──────────
step "Ensuring runtime directories"
mkdir -p bootstrap/cache \
storage/app/public \
storage/framework/cache/data \
storage/framework/sessions \
storage/framework/views \
storage/framework/testing \
storage/logs
ok "Runtime directories ready"
# ── 环境配置 ────────────────────────────────────────────────────
if [ ! -f .env ]; then
step "Creating .env from .env.example"
cp .env.example .env
warn ".env 已从模板创建,但数据库配置仍是默认值。"
warn "请先编辑 .env,填写 DB_DATABASE / DB_USERNAME / DB_PASSWORD / APP_URL"
warn "保存后重新运行 ./install.sh 继续安装。"
exit 0
else
ok ".env already exists — 跳过覆盖(如需重置请手动删除 .env)"
fi
if grep -q '^DB_PASSWORD=$' .env; then
err ".env 中 DB_PASSWORD 为空,请先填写数据库密码后重新运行。"
fi
# APP_KEY 为空才生成,避免覆盖已加密数据的密钥
if grep -q '^APP_KEY=$' .env; then
php artisan key:generate --force
ok "APP_KEY generated"
else
ok "APP_KEY already set — 保留现有密钥(覆盖会导致已加密数据无法解密)"
fi
# ── 存储权限 + 软链 ────────────────────────────────────────────
step "Preparing storage"
chmod -R 775 storage bootstrap/cache 2>/dev/null || true
# 宝塔默认运行用户为 www
if id www >/dev/null 2>&1; then
chown -R www:www storage bootstrap/cache 2>/dev/null || true
ok "storage / bootstrap/cache 属主已设为 www"
fi
php artisan storage:link --force >/dev/null 2>&1 || true
ok "Storage ready"
# ── 数据库连通性 ───────────────────────────────────────────────
step "Testing database connection"
if ! php -r '
require "vendor/autoload.php";
$app = require "bootstrap/app.php";
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
try { Illuminate\Support\Facades\DB::connection()->getPdo(); echo "OK"; }
catch (Throwable $e) { fwrite(STDERR, $e->getMessage()); exit(1); }
' >/dev/null 2>&1; then
err "数据库连接失败。请检查 .env 中 DB_HOST / DB_DATABASE / DB_USERNAME / DB_PASSWORD,并确认 MySQL 已启动。"
fi
ok "Database reachable"
# ── 数据库迁移 ─────────────────────────────────────────────────
step "Running migrations"
php artisan migrate --force
ok "Migrations done"
# ── 填充种子数据(全部使用 firstOrCreate,重复执行安全)────────
step "Seeding database"
php artisan db:seed --force
ok "Seed data inserted (admin: admin@cloud-chip.cn / cloudchip2026)"
# ── 缓存优化(生产)────────────────────────────────────────────
step "Optimizing cache"
php artisan config:cache
php artisan route:cache
php artisan view:cache
ok "Config / route / view cache built"
# ── 健康检查 ───────────────────────────────────────────────────
step "Health check"
APP_URL_VAL="$(grep -E '^APP_URL=' .env | head -n1 | cut -d= -f2- | tr -d '"' | tr -d "'" || true)"
APP_URL_VAL="${APP_URL_VAL:-http://127.0.0.1}"
if command -v curl >/dev/null 2>&1; then
if curl -fsS --max-time 10 "${APP_URL_VAL%/}/api/health" >/dev/null 2>&1; then
ok "API health: OK ($APP_URL_VAL)"
else
warn "健康检查未通过——若站点尚未在宝塔绑定域名/配置伪静态,这是正常的。"
warn "完成站点配置后手动验证:curl -I ${APP_URL_VAL%/}/"
fi
else
warn "未找到 curl,跳过健康检查。"
fi
echo
echo "${C_OK}安装完成。${C_RESET}"
echo
echo "下一步:"
echo " 1. 宝塔添加站点,网站目录指向本目录下的 ${C_OK}public/${C_RESET}"
echo " 2. 站点设置 → 伪静态 → 选择 ${C_OK}laravel5${C_RESET}(或粘贴 DEPLOY.md 中的规则)"
echo " 3. 申请 SSL 证书并开启强制 HTTPS.env 中 SESSION_SECURE_COOKIE=true 依赖 HTTPS"
echo " 4. 访问 /admin 登录后台,先到【站点设置】核对 ICP 备案号与 SEO 信息"
echo
echo " 管理员账号:admin@cloud-chip.cn / cloudchip2026 ${C_WARN}(务必立即在 /settings 修改密码)${C_RESET}"