PocketBase + Caddy 安装和快速添加项目的一键脚本
— ghostart
PocketBase 非常适合个人小项目,AI 编程场景下的后端用户注册登录、数据和文件存储必备。
这个脚本可以快速安装 PocketBase 和 Caddy,并实现快速添加多个 PocketBase 和绑定域名,自动申请 SSL 证书,以便用于不同的项目。提前解析域名之后,运行脚本即可开始使用。
创建脚本
vim pocketbase.sh#!/bin/bash
# ==============================================================================
# 脚本名称: install_pocketbase.sh
# 描述: 在 Ubuntu VPS 上安装 PocketBase 和 Caddy,并管理多个项目实例。
# 作者: ghostart.blog
# ==============================================================================
# 颜色定义
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
# 确保脚本以 root 权限运行 (Caddy 和 systemd 操作需要)
# if [[ $EUID -ne 0 ]]; then
# echo -e "${RED}错误: 此脚本必须以 root 权限运行。${NC}"
# echo -e "请尝试使用: ${YELLOW}sudo ./install_pocketbase.sh${NC}"
# exit 1
# fi
# 注意:直接以 root 运行脚本不是最佳实践,但 Caddy 和 systemd 的操作确实需要 sudo。
# 脚本中已为需要 root 权限的命令添加了 'sudo',因此请以普通用户运行,
# 它会在需要时提示您输入 sudo 密码。
# ------------------------------------------------------------------------------
# 函数: 首次安装 PocketBase 和 Caddy
# ------------------------------------------------------------------------------
initial_setup() {
echo -e "${GREEN}--- 1. 开始系统更新与清理 ---${NC}"
sudo apt update && sudo apt upgrade -y && sudo apt autoremove -y
echo -e "${GREEN}系统更新完成。${NC}"
echo -e "\n${GREEN}--- 2. 安装 unzip ---${NC}"
sudo apt install unzip -y
echo -e "${GREEN}unzip 安装完成。${NC}"
echo -e "\n${GREEN}--- 3. 下载 PocketBase ---${NC}"
read -p "请输入 PocketBase 版本号 (回车则默认使用 0.31.0): " PB_VERSION
# 如果输入为空,则使用默认值
PB_VERSION=${PB_VERSION:-"0.31.0"}
PB_ZIP_FILE="pocketbase_${PB_VERSION}_linux_amd64.zip"
PB_DOWNLOAD_URL="https://github.com/pocketbase/pocketbase/releases/download/v${PB_VERSION}/${PB_ZIP_FILE}"
PB_ZIP_PATH="$HOME/${PB_ZIP_FILE}"
echo -e "${YELLOW}正在从 ${PB_DOWNLOAD_URL} 下载...${NC}"
wget -O "$PB_ZIP_PATH" "$PB_DOWNLOAD_URL"
if [ $? -ne 0 ]; then
echo -e "${RED}下载失败! 请检查版本号或网络连接。${NC}"
return 1
fi
echo -e "${GREEN}PocketBase v${PB_VERSION} 下载完成,已保存至 ${PB_ZIP_PATH}${NC}"
echo -e "\n${GREEN}--- 4. 安装 Caddy ---${NC}"
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list > /dev/null
sudo apt update
sudo apt install caddy
echo -e "${GREEN}Caddy 安装完成。${NC}"
echo -e "\n${GREEN}--- 5. 配置 Caddy ---${NC}"
read -p "请输入用于 Caddy 自动申请 SSL 证书的邮箱: " CADDY_EMAIL
if [ -z "$CADDY_EMAIL" ]; then
echo -e "${RED}邮箱不能为空!${NC}"
return 1
fi
echo -e "${YELLOW}正在写入 /etc/caddy/Caddyfile...${NC}"
# 使用 sudo tee 写入 Caddyfile
sudo tee /etc/caddy/Caddyfile > /dev/null <<EOF
{
email $CADDY_EMAIL
}
EOF
echo -e "${GREEN}Caddyfile 配置完成。${NC}"
echo -e "\n${GREEN}--- 6. 启动并设置 Caddy 开机自启 ---${NC}"
sudo systemctl enable caddy
sudo systemctl start caddy
sudo systemctl status caddy --no-pager
echo -e "${GREEN}Caddy 已启动并设置开机自启${NC}"
echo -e "\n${GREEN}--- 7. 配置防火墙 (ufw) ---${NC}"
echo -e "${YELLOW}为 Caddy 开放 HTTP (80) 和 HTTPS (443) 端口...${NC}"
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
echo -e "${GREEN}防火墙规则已添加${NC}"
echo -e "\n${GREEN}🎉 首次安装全部完成!${NC}"
echo -e "${YELLOW}再次执行脚本可以开始添加 PocketBase 项目${NC}"
}
# ------------------------------------------------------------------------------
# 函数: 添加新的 PocketBase 项目实例
# ------------------------------------------------------------------------------
add_project() {
echo -e "${GREEN}--- 1. 准备项目环境 ---${NC}"
read -p "请输入新项目的文件夹名称 (例如: project1): " PROJECT_NAME
if [ -z "$PROJECT_NAME" ]; then
echo -e "${RED}项目名称不能为空!${NC}"
return 1
fi
if [ -d "$PROJECT_NAME" ]; then
echo -e "${RED}错误: 目录 ${PROJECT_NAME} 已存在!${NC}"
return 1
fi
# 询问 PB 版本,并检查 zip 文件是否存在
read -p "请输入您已下载的 PocketBase 版本号 (默认 0.31.0): " PB_VERSION
PB_VERSION=${PB_VERSION:-"0.31.0"}
PB_ZIP_FILE="pocketbase_${PB_VERSION}_linux_amd64.zip"
PB_ZIP_PATH="$HOME/${PB_ZIP_FILE}"
if [ ! -f "$PB_ZIP_PATH" ]; then
echo -e "${RED}错误: 未在 ${PB_ZIP_PATH} 找到 PocketBase 压缩包。${NC}"
echo -e "${YELLOW}请确保该文件存在,或者先运行“首次安装”来下载它。${NC}"
return 1
fi
echo -e "${YELLOW}正在创建目录 ${PROJECT_NAME} 并解压 PocketBase...${NC}"
mkdir "$PROJECT_NAME"
cp "$PB_ZIP_PATH" "$PROJECT_NAME/"
cd "$PROJECT_NAME"
unzip "$PB_ZIP_FILE"
chmod +x pocketbase
echo -e "${GREEN}项目目录 (${PROJECT_NAME}) 中的文件:${NC}"
ls -l
WORKING_DIR=$(pwd) # 获取完整的绝对路径
cd .. # 返回上一级目录
echo -e "${GREEN}项目准备完成,工作目录: ${WORKING_DIR}${NC}"
echo -e "\n${GREEN}--- 2. 创建 systemd 服务与配置防火墙 ---${NC}"
read -p "请输入此项目实例的端口号 (留空则默认 8090): " PB_PORT
PB_PORT=${PB_PORT:-"8090"}
echo -e "${YELLOW}正在为端口 ${PB_PORT} 添加防火墙规则 (ufw allow ${PB_PORT}/tcp)...${NC}"
sudo ufw allow ${PB_PORT}/tcp
echo -e "${GREEN}防火墙规则已添加。${NC}"
SERVICE_NAME="pocketbase-$PROJECT_NAME"
SERVICE_FILE_PATH="/etc/systemd/system/${SERVICE_NAME}.service"
echo -e "${YELLOW}正在创建服务文件: ${SERVICE_FILE_PATH}${NC}"
# 使用 sudo tee 写入 service 文件
sudo tee "$SERVICE_FILE_PATH" > /dev/null <<EOF
[Unit]
Description=PocketBase ${PROJECT_NAME} service
After=network.target
[Service]
User=root
Group=root
Type=simple
WorkingDirectory=${WORKING_DIR}
ExecStart=${WORKING_DIR}/pocketbase serve --http="127.0.0.1:${PB_PORT}"
Restart=always
RestartSec=3
LimitNOFILE=4096
[Install]
WantedBy=multi-user.target
EOF
echo -e "${GREEN}服务文件创建成功。${NC}"
echo -e "\n${GREEN}--- 3. 配置 Caddy 反向代理 ---${NC}"
read -p "请输入您要绑定的域名 (例如: ${PROJECT_NAME}.example.com): " DOMAIN_NAME
if [ -z "$DOMAIN_NAME" ]; then
echo -e "${RED}域名不能为空!${NC}"
return 1
fi
echo -e "${YELLOW}正在将域名配置追加到 /etc/caddy/Caddyfile...${NC}"
# 使用 sudo tee -a 追加配置
echo "" | sudo tee -a /etc/caddy/Caddyfile > /dev/null
sudo tee -a /etc/caddy/Caddyfile > /dev/null <<EOF
${DOMAIN_NAME} {
reverse_proxy localhost:${PB_PORT}
}
EOF
echo -e "${GREEN}Caddyfile 配置追加成功。${NC}"
echo -e "\n${GREEN}--- 4. 重载 Caddy 配置 ---${NC}"
sudo systemctl reload caddy
echo -e "${GREEN}Caddy 配置已重载。${NC}"
echo -e "\n${GREEN}--- 5. 启动服务并创建 PocketBase 管理员 ---${NC}"
read -p "请输入新 PocketBase 实例的管理员邮箱: " ADMIN_EMAIL
read -s -p "请输入新 PocketBase 实例的管理员密码: " ADMIN_PASS
echo # 换行
if [ -z "$ADMIN_EMAIL" ] || [ -z "$ADMIN_PASS" ]; then
echo -e "${RED}管理员邮箱和密码均不能为空!${NC}"
return 1
fi
sudo systemctl daemon-reload # 重新加载 systemd 配置,因为创建了新服务
sudo systemctl enable "$SERVICE_NAME"
sudo systemctl start "$SERVICE_NAME"
echo -e "${YELLOW}已启动服务,等待 3 秒让 PocketBase 初始化数据库...${NC}"
sleep 3
# 停止服务以安全地创建管理员 (防止 "database is locked")
sudo systemctl stop "$SERVICE_NAME"
echo -e "${YELLOW}服务已临时停止,正在创建超级管理员...${NC}"
# 进入工作目录执行 upsert 命令
cd "$WORKING_DIR"
./pocketbase superuser upsert "$ADMIN_EMAIL" "$ADMIN_PASS"
cd ..
echo -e "${YELLOW}管理员创建成功,正在重启服务...${NC}"
sudo systemctl start "$SERVICE_NAME"
echo -e "\n${GREEN}服务状态:${NC}"
sudo systemctl status "$SERVICE_NAME" --no-pager
echo -e "\n${GREEN}--- 🎉 新项目添加完成! ---${NC}"
echo -e "项目名称: ${YELLOW}${PROJECT_NAME}${NC}"
echo -e "后台地址: ${YELLOW}https://${DOMAIN_NAME}/_${NC}"
echo -e "管理员邮箱: ${YELLOW}${ADMIN_EMAIL}${NC}"
}
# ------------------------------------------------------------------------------
# 主菜单
# ------------------------------------------------------------------------------
main_menu() {
echo -e "\n${GREEN}=====================================${NC}"
echo -e "${GREEN} PocketBase & Caddy 多项目管理脚本 ${NC}"
echo -e "${GREEN}=====================================${NC}"
echo -e "请选择一个操作:"
echo -e " ${YELLOW}1)${NC} 首次安装 PocketBase 和 Caddy"
echo -e " ${YELLOW}2)${NC} 添加一个新的 PocketBase 项目实例"
echo -e " ${YELLOW}3)${NC} 退出脚本"
read -p "请输入选项 [1-3]: " choice
case $choice in
1)
initial_setup
;;
2)
add_project
;;
3)
echo -e "${GREEN}再见!${NC}"
exit 0
;;
*)
echo -e "${RED}无效选项,请输入 1, 2 或 3。${NC}"
main_menu
;;
esac
}
# 运行主菜单
main_menu
# 后续步骤:
# 授予执行权限:chmod +x pocketbase.sh
# 运行脚本:./pocketbase.sh授予执行权限
chmod +x pocketbase.sh运行脚本
./pocketbase.sh