CentOS 上使用 AppImage 实现自动化部署
一 环境准备与基础运行
二 无状态一键部署脚本
#!/usr/bin/env bash
set -Eeuo pipefail
APP_NAME="myapp"
APPIMAGE_URL="https://example.com/releases/${APP_NAME}-latest-x86_64.AppImage"
APPIMAGE_SHA256="YOUR_SHA256SUM_HERE" # 建议提供校验值
INSTALL_DIR="/opt/apps/${APP_NAME}"
BIN_PATH="${INSTALL_DIR}/${APP_NAME}.AppImage"
SERVICE_NAME="${APP_NAME}.service"
USER_HOME="${HOME}"
SYSTEMD_USER_DIR="${USER_HOME}/.config/systemd/user"
SYSTEMD_SYSTEM_DIR="/etc/systemd/system"
# 0) 环境检测
if ! command -v curl >/dev/null 2>&1; then
echo "请先安装 curl" >&2; exit 1
fi
# 1) 安装/升级 AppImage
install_appimage() {
echo "==> 安装/升级 ${APP_NAME}"
mkdir -p "${INSTALL_DIR}"
local tmp_file
tmp_file="$(mktemp /tmp/${APP_NAME}.XXXXXX.AppImage)"
trap 'rm -f "$tmp_file"' EXIT
echo " 下载 ${APPIMAGE_URL}"
curl -L -o "${tmp_file}" "${APPIMAGE_URL}"
if [[ -n "${APPIMAGE_SHA256}" ]]; then
echo " 校验 SHA256: ${APPIMAGE_SHA256}"
printf "%s %s\n" "${APPIMAGE_SHA256}" "${tmp_file}" | sha256sum --check --status \
|| { echo "SHA256 校验失败"; exit 1; }
fi
chmod +x "${tmp_file}"
mv -f "${tmp_file}" "${BIN_PATH}"
}
# 2) 生成 systemd 单元(用户级)
render_unit() {
mkdir -p "${SYSTEMD_USER_DIR}"
cat > "${SYSTEMD_USER_DIR}/${SERVICE_NAME}" <<EOF
[Unit]
Description=${APP_NAME} (AppImage)
After=network.target
[Service]
Type=simple
ExecStart=${BIN_PATH} --headless
Restart=on-failure
RestartSec=5
WorkingDirectory=${INSTALL_DIR}
StandardOutput=journal
StandardError=journal
Environment=HOME=${USER_HOME}
[Install]
WantedBy=default.target
EOF
}
# 3) 启用服务
enable_service() {
# 若系统支持 lingering,确保用户服务可开机自启
if command -v loginctl >/dev/null 2>&1; then
loginctl enable-linger "$(id -u)" 2>/dev/null || true
fi
systemctl --user daemon-reload
systemctl --user enable --now "${SERVICE_NAME}"
}
main() {
install_appimage
render_unit
enable_service
echo "==> 部署完成:可用命令:"
echo " 查看状态:systemctl --user status ${SERVICE_NAME}"
echo " 查看日志:journalctl --user -u ${SERVICE_NAME} -f"
}
main "$@"
三 自更新与回滚
四 桌面集成与用户环境
[Desktop Entry]
Name=MyApp
Exec=/opt/apps/myapp/myapp.AppImage
Icon=/opt/apps/myapp/icon.png
Terminal=false
Type=Application
Categories=Utility;
StartupWMClass=MyApp
五 常见问题与排查