feat: Phase 1 - PocketBase 迁移文件、种子数据、部署脚本
- apps/pb_migrations/1710000001_init_collections.js: 9个集合完整定义 - apps/pb_migrations/1710000002_seed_data.js: 默认管理员、分类、标签、页面、示例文章 - scripts/install.sh: Linux 一键部署脚本 (systemd, Nginx, SSL, 防火墙, Fail2Ban) - scripts/install.ps1: Windows 一键部署脚本 (NSSM服务, 计划任务, Certbot) - scripts/start.sh: 服务启动脚本 - scripts/backup.sh: 数据备份脚本 - scripts/update.sh: 代码更新部署脚本 - docs/DEPLOY.md: 详细部署教程文档
This commit is contained in:
@@ -0,0 +1,596 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# PocketBase 版本
|
||||
PB_VERSION="0.22.0"
|
||||
PB_DIR="/opt/pocketbase"
|
||||
PB_DATA_DIR="${PB_DIR}/pb_data"
|
||||
PB_MIGRATIONS_DIR="${PB_DIR}/pb_migrations"
|
||||
PB_PUBLIC_DIR="${PB_DIR}/pb_public"
|
||||
|
||||
# 颜色输出
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
log_info() { echo -e "${BLUE}[INFO]${NC} $*"; }
|
||||
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $*"; }
|
||||
log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
||||
log_error() { echo -e "${RED}[ERROR]${NC} $*"; }
|
||||
|
||||
# 检查是否为 root
|
||||
check_root() {
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
log_error "请使用 root 权限运行 (sudo ./install.sh)"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 检测系统架构
|
||||
detect_arch() {
|
||||
local arch=$(uname -m)
|
||||
case $arch in
|
||||
x86_64) echo "amd64" ;;
|
||||
aarch64|arm64) echo "arm64" ;;
|
||||
armv7l) echo "armv7" ;;
|
||||
*) log_error "不支持的架构: $arch"; exit 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# 安装依赖
|
||||
install_deps() {
|
||||
log_info "安装系统依赖..."
|
||||
apt update && apt upgrade -y
|
||||
apt install -y curl wget unzip nginx certbot python3-certbot-nginx ufw fail2ban
|
||||
log_success "系统依赖安装完成"
|
||||
}
|
||||
|
||||
# 下载并安装 PocketBase
|
||||
install_pocketbase() {
|
||||
local arch=$(detect_arch)
|
||||
local pb_url="https://github.com/pocketbase/pocketbase/releases/download/v${PB_VERSION}/pocketbase_${PB_VERSION}_linux_${arch}.zip"
|
||||
local tmp_dir=$(mktemp -d)
|
||||
|
||||
log_info "下载 PocketBase v${PB_VERSION} (${arch})..."
|
||||
cd "$tmp_dir"
|
||||
wget -q --show-progress "$pb_url" -O pocketbase.zip
|
||||
unzip -q pocketbase.zip
|
||||
|
||||
log_info "安装 PocketBase 到 ${PB_DIR}..."
|
||||
mkdir -p "$PB_DIR"
|
||||
mv pocketbase "$PB_DIR/"
|
||||
chmod +x "$PB_DIR/pocketbase"
|
||||
|
||||
# 创建数据目录
|
||||
mkdir -p "$PB_DATA_DIR" "$PB_MIGRATIONS_DIR" "$PB_PUBLIC_DIR"
|
||||
|
||||
# 复制迁移文件
|
||||
if [[ -d "$(dirname "$0")/../apps/pb_migrations" ]]; then
|
||||
cp -r "$(dirname "$0")/../apps/pb_migrations"/* "$PB_MIGRATIONS_DIR/"
|
||||
log_success "迁移文件已复制"
|
||||
fi
|
||||
|
||||
# 清理
|
||||
cd /
|
||||
rm -rf "$tmp_dir"
|
||||
|
||||
log_success "PocketBase 安装完成"
|
||||
}
|
||||
|
||||
# 生成加密密钥
|
||||
generate_encryption_key() {
|
||||
openssl rand -base64 32 | tr -d '\n'
|
||||
}
|
||||
|
||||
# 创建 systemd 服务
|
||||
create_systemd_service() {
|
||||
local encryption_key=$(generate_encryption_key)
|
||||
|
||||
log_info "创建 systemd 服务..."
|
||||
cat > /etc/systemd/system/pocketbase.service <<EOF
|
||||
[Unit]
|
||||
Description=PocketBase - 云升数码后端服务
|
||||
Documentation=https://pocketbase.io/docs/
|
||||
After=network.target network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=www-data
|
||||
Group=www-data
|
||||
WorkingDirectory=${PB_DIR}
|
||||
ExecStart=${PB_DIR}/pocketbase serve \\
|
||||
--http=127.0.0.1:8090 \\
|
||||
--dir=${PB_DATA_DIR} \\
|
||||
--publicDir=${PB_PUBLIC_DIR} \\
|
||||
--migrationsDir=${PB_MIGRATIONS_DIR} \\
|
||||
--encryptionEnv=PB_ENCRYPTION_KEY
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
StartLimitIntervalSec=60
|
||||
StartLimitBurst=3
|
||||
|
||||
# 安全配置
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ReadWritePaths=${PB_DATA_DIR} ${PB_PUBLIC_DIR} ${PB_MIGRATIONS_DIR}
|
||||
ProtectKernelTunables=true
|
||||
ProtectKernelModules=true
|
||||
ProtectControlGroups=true
|
||||
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
|
||||
RestrictNamespaces=true
|
||||
LockPersonality=true
|
||||
MemoryDenyWriteExecute=true
|
||||
SystemCallFilter=@system-service
|
||||
SystemCallErrorNumber=EPERM
|
||||
|
||||
# 环境变量
|
||||
Environment=PB_ENCRYPTION_KEY=${encryption_key}
|
||||
Environment=GOGC=50
|
||||
|
||||
# 资源限制
|
||||
LimitNOFILE=65535
|
||||
LimitNPROC=4096
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# 设置权限
|
||||
chown -R www-data:www-data "$PB_DIR"
|
||||
chmod 750 "$PB_DATA_DIR" "$PB_MIGRATIONS_DIR" "$PB_PUBLIC_DIR"
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable pocketbase
|
||||
|
||||
log_success "systemd 服务创建完成"
|
||||
log_info "加密密钥: ${encryption_key}"
|
||||
log_warn "请妥善保存加密密钥!迁移服务器时需要它来解密数据。"
|
||||
}
|
||||
|
||||
# 配置 Nginx
|
||||
configure_nginx() {
|
||||
local domain="$1"
|
||||
|
||||
if [[ -z "$domain" ]]; then
|
||||
log_warn "未提供域名,跳过 Nginx 配置"
|
||||
return
|
||||
fi
|
||||
|
||||
log_info "配置 Nginx 反向代理 (域名: ${domain})..."
|
||||
|
||||
cat > /etc/nginx/sites-available/yunsheng-digital <<EOF
|
||||
# 云升数码 - Nginx 配置
|
||||
# 生成时间: $(date)
|
||||
|
||||
# HTTP -> HTTPS 重定向
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name ${domain} www.${domain};
|
||||
|
||||
# ACME 挑战路径 (用于 SSL 证书验证)
|
||||
location /.well-known/acme-challenge/ {
|
||||
root /var/www/html;
|
||||
try_files \$uri =404;
|
||||
}
|
||||
|
||||
# 其他请求重定向到 HTTPS
|
||||
location / {
|
||||
return 301 https://\$host\$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
# HTTPS 主站点
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
server_name ${domain} www.${domain};
|
||||
|
||||
# SSL 证书 (由 Certbot 自动填充)
|
||||
# ssl_certificate /etc/letsencrypt/live/${domain}/fullchain.pem;
|
||||
# ssl_certificate_key /etc/letsencrypt/live/${domain}/privkey.pem;
|
||||
|
||||
# SSL 安全配置
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
|
||||
ssl_prefer_server_ciphers off;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_timeout 10m;
|
||||
|
||||
# 安全头
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
add_header Permissions-Policy "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()" always;
|
||||
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' data: https://fonts.gstatic.com; img-src 'self' data: https:; media-src 'self' https:; connect-src 'self' wss: https:; frame-ancestors 'self';" always;
|
||||
|
||||
# 根目录
|
||||
root ${PB_PUBLIC_DIR};
|
||||
index index.html;
|
||||
|
||||
# Gzip 压缩
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 1024;
|
||||
gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
|
||||
|
||||
# 静态文件缓存
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|webp|avif|mp4|webm|ogg|mp3|wav|pdf)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
access_log off;
|
||||
try_files \$uri =404;
|
||||
}
|
||||
|
||||
# 前端路由 (SPA fallback)
|
||||
location / {
|
||||
try_files \$uri \$uri/ /index.html;
|
||||
}
|
||||
|
||||
# PocketBase API 代理
|
||||
location /api/ {
|
||||
proxy_pass http://127.0.0.1:8090;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
proxy_set_header X-Forwarded-Host \$host;
|
||||
proxy_set_header X-Forwarded-Port \$server_port;
|
||||
|
||||
# 超时设置
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
|
||||
# 缓冲
|
||||
proxy_buffering on;
|
||||
proxy_buffer_size 128k;
|
||||
proxy_buffers 4 256k;
|
||||
proxy_busy_buffers_size 256k;
|
||||
|
||||
# 文件上传大小限制
|
||||
client_max_body_size 100M;
|
||||
}
|
||||
|
||||
# Realtime WebSocket
|
||||
location /api/realtime {
|
||||
proxy_pass http://127.0.0.1:8090;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade \$http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
|
||||
# WebSocket 超时
|
||||
proxy_read_timeout 86400;
|
||||
proxy_send_timeout 86400;
|
||||
}
|
||||
|
||||
# PocketBase Admin UI
|
||||
location /_/ {
|
||||
proxy_pass http://127.0.0.1:8090;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
|
||||
# 限制 Admin UI 访问 (可选:仅允许特定 IP)
|
||||
# allow 1.2.3.4;
|
||||
# deny all;
|
||||
}
|
||||
|
||||
# 禁止访问隐藏文件
|
||||
location ~ /\. {
|
||||
deny all;
|
||||
access_log off;
|
||||
log_not_found off;
|
||||
}
|
||||
|
||||
# 禁止访问备份文件
|
||||
location ~* \.(bak|backup|sql|log|env|ini)$ {
|
||||
deny all;
|
||||
access_log off;
|
||||
log_not_found off;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# 启用站点
|
||||
ln -sf /etc/nginx/sites-available/yunsheng-digital /etc/nginx/sites-enabled/
|
||||
rm -f /etc/nginx/sites-enabled/default
|
||||
|
||||
# 测试配置
|
||||
nginx -t
|
||||
|
||||
log_success "Nginx 配置完成"
|
||||
}
|
||||
|
||||
# 申请 SSL 证书
|
||||
setup_ssl() {
|
||||
local domain="$1"
|
||||
local email="$2"
|
||||
|
||||
if [[ -z "$domain" || -z "$email" ]]; then
|
||||
log_warn "未提供域名或邮箱,跳过 SSL 证书申请"
|
||||
log_info "稍后可手动运行: certbot --nginx -d ${domain}"
|
||||
return
|
||||
fi
|
||||
|
||||
log_info "申请 Let's Encrypt SSL 证书..."
|
||||
|
||||
# 先启动 nginx (HTTP 模式)
|
||||
systemctl restart nginx
|
||||
|
||||
# 申请证书
|
||||
certbot --nginx -d "${domain}" -d "www.${domain}" \
|
||||
--non-interactive \
|
||||
--agree-tos \
|
||||
--email "${email}" \
|
||||
--redirect \
|
||||
--hsts \
|
||||
--staple-ocsp \
|
||||
--must-staple
|
||||
|
||||
# 设置自动续期
|
||||
systemctl enable certbot.timer
|
||||
|
||||
log_success "SSL 证书申请完成"
|
||||
}
|
||||
|
||||
# 配置防火墙
|
||||
configure_firewall() {
|
||||
log_info "配置 UFW 防火墙..."
|
||||
|
||||
ufw --force enable
|
||||
ufw default deny incoming
|
||||
ufw default allow outgoing
|
||||
ufw allow ssh
|
||||
ufw allow 80/tcp
|
||||
ufw allow 443/tcp
|
||||
|
||||
# 仅允许本地访问 PocketBase 直接端口
|
||||
ufw allow from 127.0.0.1 to any port 8090
|
||||
|
||||
log_success "防火墙配置完成"
|
||||
}
|
||||
|
||||
# 配置 Fail2Ban
|
||||
configure_fail2ban() {
|
||||
log_info "配置 Fail2Ban..."
|
||||
|
||||
cat > /etc/fail2ban/jail.d/yunsheng-digital.conf <<EOF
|
||||
[DEFAULT]
|
||||
bantime = 3600
|
||||
findtime = 600
|
||||
maxretry = 5
|
||||
backend = systemd
|
||||
|
||||
[nginx-http-auth]
|
||||
enabled = true
|
||||
port = http,https
|
||||
logpath = /var/log/nginx/error.log
|
||||
|
||||
[nginx-limit-req]
|
||||
enabled = true
|
||||
port = http,https
|
||||
logpath = /var/log/nginx/error.log
|
||||
maxretry = 10
|
||||
|
||||
[nginx-badbots]
|
||||
enabled = true
|
||||
port = http,https
|
||||
logpath = /var/log/nginx/access.log
|
||||
maxretry = 3
|
||||
|
||||
[sshd]
|
||||
enabled = true
|
||||
port = ssh
|
||||
logpath = /var/log/auth.log
|
||||
maxretry = 3
|
||||
bantime = 86400
|
||||
EOF
|
||||
|
||||
systemctl enable fail2ban
|
||||
systemctl restart fail2ban
|
||||
|
||||
log_success "Fail2Ban 配置完成"
|
||||
}
|
||||
|
||||
# 创建维护脚本
|
||||
create_maintenance_scripts() {
|
||||
log_info "创建维护脚本..."
|
||||
|
||||
# 备份脚本
|
||||
cat > /usr/local/bin/yunsheng-backup <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
BACKUP_DIR="/backup/yunsheng-digital"
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
PB_DATA_DIR="/opt/pocketbase/pb_data"
|
||||
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
log_info() { echo -e "\033[0;34m[INFO]\033[0m $*"; }
|
||||
log_success() { echo -e "\033[0;32m[SUCCESS]\033[0m $*"; }
|
||||
|
||||
log_info "开始备份..."
|
||||
|
||||
# 备份 PocketBase 数据 (使用内置 dump 命令)
|
||||
/opt/pocketbase/pocketbase dump \
|
||||
--dir=/opt/pocketbase/pb_data \
|
||||
--output="${BACKUP_DIR}/pocketbase_${DATE}.zip"
|
||||
|
||||
# 备份 Nginx 配置
|
||||
cp -r /etc/nginx/sites-available/yunsheng-digital "${BACKUP_DIR}/nginx_${DATE}.conf"
|
||||
|
||||
# 备份 SSL 证书
|
||||
cp -r /etc/letsencrypt "${BACKUP_DIR}/letsencrypt_${DATE}"
|
||||
|
||||
# 清理 30 天前的备份
|
||||
find "$BACKUP_DIR" -type f -mtime +30 -delete
|
||||
|
||||
log_success "备份完成: ${BACKUP_DIR}/pocketbase_${DATE}.zip"
|
||||
EOF
|
||||
|
||||
chmod +x /usr/local/bin/yunsheng-backup
|
||||
|
||||
# 更新脚本
|
||||
cat > /usr/local/bin/yunsheng-update <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
PROJECT_DIR="/opt/yunsheng-digital"
|
||||
PB_DIR="/opt/pocketbase"
|
||||
PB_PUBLIC_DIR="${PB_DIR}/pb_public"
|
||||
|
||||
log_info() { echo -e "\033[0;34m[INFO]\033[0m $*"; }
|
||||
log_success() { echo -e "\033[0;32m[SUCCESS]\033[0m $*"; }
|
||||
log_error() { echo -e "\033[0;31m[ERROR]\033[0m $*"; }
|
||||
|
||||
cd "$PROJECT_DIR"
|
||||
|
||||
log_info "拉取最新代码..."
|
||||
git pull origin master
|
||||
|
||||
log_info "安装前端依赖..."
|
||||
cd apps/web
|
||||
pnpm install --frozen-lockfile
|
||||
|
||||
log_info "构建前端..."
|
||||
pnpm build
|
||||
|
||||
log_info "部署构建产物..."
|
||||
cp -r dist/* "$PB_PUBLIC_DIR/"
|
||||
|
||||
log_info "重载 Nginx..."
|
||||
systemctl reload nginx
|
||||
|
||||
log_success "更新完成!"
|
||||
EOF
|
||||
|
||||
chmod +x /usr/local/bin/yunsheng-update
|
||||
|
||||
# 状态检查脚本
|
||||
cat > /usr/local/bin/yunsheng-status <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo "=== 云升数码 服务状态 ==="
|
||||
echo
|
||||
|
||||
echo "--- PocketBase ---"
|
||||
systemctl status pocketbase --no-pager -l
|
||||
|
||||
echo
|
||||
echo "--- Nginx ---"
|
||||
systemctl status nginx --no-pager -l
|
||||
|
||||
echo
|
||||
echo "--- 磁盘使用 ---"
|
||||
df -h /opt/pocketbase
|
||||
|
||||
echo
|
||||
echo "--- 内存使用 ---"
|
||||
free -h
|
||||
|
||||
echo
|
||||
echo "--- 网络连接 ---"
|
||||
ss -tlnp | grep -E '(80|443|8090)'
|
||||
EOF
|
||||
|
||||
chmod +x /usr/local/bin/yunsheng-status
|
||||
|
||||
log_success "维护脚本创建完成"
|
||||
}
|
||||
|
||||
# 设置定时任务
|
||||
setup_cron() {
|
||||
log_info "设置定时任务..."
|
||||
|
||||
# 每天凌晨 3 点备份
|
||||
(crontab -l 2>/dev/null | grep -v yunsheng-backup; echo "0 3 * * * /usr/local/bin/yunsheng-backup >> /var/log/yunsheng-backup.log 2>&1") | crontab -
|
||||
|
||||
# 每周一凌晨 4 点清理日志
|
||||
(crontab -l 2>/dev/null | grep -v "journalctl"; echo "0 4 * * 1 journalctl --vacuum-time=30d >> /var/log/yunsheng-cleanup.log 2>&1") | crontab -
|
||||
|
||||
log_success "定时任务设置完成"
|
||||
}
|
||||
|
||||
# 主函数
|
||||
main() {
|
||||
echo "=========================================="
|
||||
echo " 云升数码 - 一键部署脚本 v1.0"
|
||||
echo "=========================================="
|
||||
echo
|
||||
|
||||
check_root
|
||||
|
||||
# 获取参数
|
||||
DOMAIN="${1:-}"
|
||||
EMAIL="${2:-}"
|
||||
|
||||
if [[ -z "$DOMAIN" ]]; then
|
||||
read -rp "请输入域名 (例: yunsheng.digital): " DOMAIN
|
||||
fi
|
||||
|
||||
if [[ -z "$EMAIL" ]]; then
|
||||
read -rp "请输入邮箱 (用于 SSL 证书): " EMAIL
|
||||
fi
|
||||
|
||||
log_info "开始部署..."
|
||||
log_info "域名: ${DOMAIN}"
|
||||
log_info "邮箱: ${EMAIL}"
|
||||
|
||||
install_deps
|
||||
install_pocketbase
|
||||
create_systemd_service
|
||||
configure_nginx "$DOMAIN"
|
||||
setup_ssl "$DOMAIN" "$EMAIL"
|
||||
configure_firewall
|
||||
configure_fail2ban
|
||||
create_maintenance_scripts
|
||||
setup_cron
|
||||
|
||||
# 启动服务
|
||||
log_info "启动服务..."
|
||||
systemctl start pocketbase
|
||||
sleep 3
|
||||
systemctl restart nginx
|
||||
|
||||
echo
|
||||
echo "=========================================="
|
||||
log_success "部署完成!"
|
||||
echo "=========================================="
|
||||
echo
|
||||
echo "📋 重要信息:"
|
||||
echo " - 网站地址: https://${DOMAIN}"
|
||||
echo " - 后台管理: https://${DOMAIN}/_/"
|
||||
echo " - 管理员账号: admin@yunsheng.digital"
|
||||
echo " - 管理员密码: YunSheng@2024!Admin"
|
||||
echo " - PocketBase 数据目录: ${PB_DATA_DIR}"
|
||||
echo " - 前端构建目录: ${PB_PUBLIC_DIR}"
|
||||
echo
|
||||
echo "🔐 安全提醒:"
|
||||
echo " 1. 请立即登录后台修改默认管理员密码"
|
||||
echo " 2. 加密密钥已保存在 systemd 服务文件中"
|
||||
echo " 3. 建议配置 SSH 密钥登录,禁用密码登录"
|
||||
echo
|
||||
echo "🛠️ 常用命令:"
|
||||
echo " - 查看状态: yunsheng-status"
|
||||
echo " - 备份数据: yunsheng-backup"
|
||||
echo " - 更新代码: yunsheng-update"
|
||||
echo " - 查看日志: journalctl -u pocketbase -f"
|
||||
echo
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user