192 lines
7.1 KiB
Bash
192 lines
7.1 KiB
Bash
#!/usr/bin/env bash
|
||
set -euo pipefail
|
||
|
||
# ============================================
|
||
# Joplin Server 一键部署脚本
|
||
# 自动安装 Docker + Nginx + SSL + Joplin Server + PostgreSQL
|
||
# ============================================
|
||
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
cd "$SCRIPT_DIR"
|
||
|
||
# ===== 加载公共基础函数 =====
|
||
BASE_DIR="$(cd "$SCRIPT_DIR/../base" 2>/dev/null && pwd)" || true
|
||
if [ -z "$BASE_DIR" ] || [ ! -f "$BASE_DIR/setup.sh" ]; then
|
||
echo "[ERROR] base/setup.sh 未找到" >&2
|
||
echo "请确保目录结构如下:" >&2
|
||
echo " /opt/base/setup.sh" >&2
|
||
echo " /opt/joplin/deploy.sh (当前脚本)" >&2
|
||
exit 1
|
||
fi
|
||
source "$BASE_DIR/setup.sh"
|
||
|
||
# =============================================================
|
||
# Joplin Server 专用函数
|
||
# =============================================================
|
||
|
||
init_env() {
|
||
step "初始化 Joplin Server 配置"
|
||
|
||
if [ ! -f .env ]; then
|
||
if [ ! -f .env.example ]; then
|
||
error "缺少 .env.example 模板文件"
|
||
exit 1
|
||
fi
|
||
cp .env.example .env
|
||
log "已生成 .env 文件"
|
||
echo ""
|
||
warn "┌─────────────────────────────────────────────────┐"
|
||
warn "│ 请编辑 .env 文件,至少修改以下配置: │"
|
||
warn "│ │"
|
||
warn "│ JOPLIN_DOMAIN=joplin.yourdomain.com │"
|
||
warn "│ CERTBOT_EMAIL=you@yourdomain.com │"
|
||
warn "│ POSTGRES_PASSWORD=你的强密码 │"
|
||
warn "│ │"
|
||
warn "│ 编辑命令: vi $SCRIPT_DIR/.env │"
|
||
warn "│ 编辑完成后重新运行: bash deploy.sh │"
|
||
warn "└─────────────────────────────────────────────────┘"
|
||
exit 0
|
||
fi
|
||
|
||
fix_crlf .env
|
||
set -a; source .env; set +a
|
||
|
||
local has_error=0
|
||
if [[ -z "${JOPLIN_DOMAIN:-}" ]] || [[ "${JOPLIN_DOMAIN}" == "joplin.example.com" ]]; then
|
||
error "请在 .env 中将 JOPLIN_DOMAIN 修改为你的实际域名"
|
||
has_error=1
|
||
fi
|
||
if [[ -z "${CERTBOT_EMAIL:-}" ]] || [[ "${CERTBOT_EMAIL}" == "admin@example.com" ]]; then
|
||
error "请在 .env 中将 CERTBOT_EMAIL 修改为你的实际邮箱"
|
||
has_error=1
|
||
fi
|
||
if [[ -z "${POSTGRES_PASSWORD:-}" ]] || [[ "${POSTGRES_PASSWORD}" == "changeme" ]]; then
|
||
error "请在 .env 中将 POSTGRES_PASSWORD 修改为一个强密码"
|
||
has_error=1
|
||
fi
|
||
[ "$has_error" -eq 1 ] && { error "请修改 .env 后重新运行"; exit 1; }
|
||
|
||
log "配置检查通过"
|
||
log " 域名: ${JOPLIN_DOMAIN}"
|
||
log " 邮箱: ${CERTBOT_EMAIL}"
|
||
}
|
||
|
||
create_dirs() {
|
||
step "创建数据目录"
|
||
local db_dir="${JOPLIN_DB_DIR:-/data/joplin/db}"
|
||
local backup_dir="${BACKUP_DIR:-/var/backups/joplin}"
|
||
|
||
mkdir -p "$db_dir" "$backup_dir"
|
||
log "数据库目录: $db_dir"
|
||
log "备份目录: $backup_dir"
|
||
}
|
||
|
||
start_services() {
|
||
step "启动 Joplin Server 服务"
|
||
|
||
log "正在拉取镜像..."
|
||
docker compose pull
|
||
|
||
log "正在启动容器..."
|
||
docker compose up -d
|
||
|
||
log "等待 Joplin Server 就绪..."
|
||
local max_wait=60
|
||
for i in $(seq 1 "$max_wait"); do
|
||
if curl -sf http://127.0.0.1:22300/api/ping &> /dev/null; then
|
||
log "Joplin Server 启动成功!"
|
||
return
|
||
fi
|
||
sleep 2
|
||
done
|
||
warn "Joplin Server 可能仍在启动中(数据库初始化可能需要更长时间),请稍后检查: docker compose logs -f"
|
||
}
|
||
|
||
show_info() {
|
||
set -a; source .env; set +a
|
||
|
||
echo ""
|
||
echo -e "${GREEN}╔══════════════════════════════════════════════════════════╗${NC}"
|
||
echo -e "${GREEN}║ Joplin Server 部署完成! ║${NC}"
|
||
echo -e "${GREEN}╠══════════════════════════════════════════════════════════╣${NC}"
|
||
echo -e "${GREEN}║${NC}"
|
||
echo -e "${GREEN}║${NC} Web 访问: ${CYAN}https://${JOPLIN_DOMAIN}${NC}"
|
||
echo -e "${GREEN}║${NC}"
|
||
echo -e "${GREEN}║${NC} 默认账号: ${CYAN}admin@localhost${NC}"
|
||
echo -e "${GREEN}║${NC} 默认密码: ${CYAN}admin${NC}"
|
||
echo -e "${GREEN}║${NC}"
|
||
echo -e "${GREEN}║${NC} 数据库目录: ${JOPLIN_DB_DIR:-/data/joplin/db}"
|
||
echo -e "${GREEN}║${NC} 备份目录: ${BACKUP_DIR:-/var/backups/joplin}"
|
||
echo -e "${GREEN}║${NC}"
|
||
echo -e "${GREEN}║${NC} ${RED}⚠ 请立即登录并修改默认密码!${NC}"
|
||
echo -e "${GREEN}║${NC}"
|
||
echo -e "${GREEN}╚══════════════════════════════════════════════════════════╝${NC}"
|
||
echo ""
|
||
echo "客户端同步配置:"
|
||
echo " 同步目标: Joplin Server"
|
||
echo " 服务器 URL: https://${JOPLIN_DOMAIN}"
|
||
echo " 邮箱: admin@localhost(或你修改后的邮箱)"
|
||
echo " 密码: 你登录时使用的密码"
|
||
echo ""
|
||
echo "常用命令:"
|
||
echo " 查看日志: cd $SCRIPT_DIR && docker compose logs -f"
|
||
echo " 重启服务: cd $SCRIPT_DIR && docker compose restart"
|
||
echo " 停止服务: cd $SCRIPT_DIR && docker compose down"
|
||
echo " 备份数据: cd $SCRIPT_DIR && bash backup.sh"
|
||
echo ""
|
||
}
|
||
|
||
# =============================================================
|
||
# 主流程
|
||
# =============================================================
|
||
main() {
|
||
echo -e "${CYAN}"
|
||
echo " _ _ _ ____"
|
||
echo " | | ___ _ __ | (_)_ __ / ___| ___ _ ____ _____ _ __"
|
||
echo " _ | |/ _ \\| '_ \\| | | '_ \\ \\___ \\ / _ \\ '__\\ \\ / / _ \\ '__|"
|
||
echo " | |_| | (_) | |_) | | | | | | ___) | __/ | \\ V / __/ |"
|
||
echo " \\___/ \\___/| .__/|_|_|_| |_||____/ \\___|_| \\_/ \\___|_|"
|
||
echo " |_| Deploy Script"
|
||
echo -e "${NC}"
|
||
echo ""
|
||
|
||
check_root
|
||
load_base_env "$BASE_DIR"
|
||
|
||
# Step 1: 系统初始化
|
||
init_system
|
||
|
||
# Step 2: 安装 Docker
|
||
install_docker
|
||
|
||
# Step 3: 安装 Nginx
|
||
install_nginx
|
||
|
||
# Step 4: 初始化配置
|
||
init_env
|
||
|
||
# Step 5: 配置 Docker 镜像加速
|
||
configure_docker_mirrors
|
||
|
||
# Step 6: 创建数据目录
|
||
create_dirs
|
||
|
||
# Step 7: 配置防火墙
|
||
setup_firewall_base
|
||
|
||
# Step 8: 配置 SSL 证书
|
||
setup_ssl_cert "${JOPLIN_DOMAIN}" "${CERTBOT_EMAIL}" "joplin"
|
||
|
||
# Step 9: 部署 Nginx 反向代理
|
||
deploy_nginx_conf "$SCRIPT_DIR/nginx/joplin.conf" "${JOPLIN_DOMAIN}" "joplin"
|
||
|
||
# Step 10: 启动服务
|
||
start_services
|
||
|
||
# 显示部署信息
|
||
show_info
|
||
log "===== Joplin Server 部署完成 ====="
|
||
}
|
||
|
||
main "$@"
|