快速部署

按以下步骤操作,约 5 分钟即可完成部署,获得你自己的 APK 打包服务。

前置要求

必需
GitHub 账号
用于 Actions 构建,免费
必需
Cloudflare 账号
用于 Pages 托管,免费

部署步骤

1
Fork 仓库

打开 ZhangShengFan/Pakr,点击右上角 Fork,将仓库复制到自己的账号。

2
生成签名 Keystore

进入你 Fork 的仓库 → Actions → gen-keystore → Run workflow,填写密码后运行。完成后复制日志中的 Base64 字符串。

i

Keystore 决定 APK 签名身份,同一 Keystore 签的包才能升级覆盖安装。

3
配置 GitHub Secrets

仓库 → Settings → Secrets and variables → Actions → New repository secret,依次添加 5 个 Secret:

名称
KEYSTORE_BASE64上一步 Base64 字符串
KEYSTORE_PASSWORDgen-keystore 设置的密码
KEY_ALIASrelease
KEY_PASSWORD同 KEYSTORE_PASSWORD
GH_PATGitHub PAT(需要 repo + workflow 权限)
4
部署到 Cloudflare Pages

Cloudflare DashboardPages → Create → Connect to Git,选择 Fork 的仓库,构建配置留空,点击 Save and Deploy

部署后 → Settings → Environment variables,添加 GH_TOKEN(值同 GH_PAT),然后手动触发一次 Retry deployment。

5
绑定自定义域名(可选)

Pages 项目 → Custom domains → 添加域名,Cloudflare 自动配置 SSL。

使用指南

了解如何填写表单、设置图标和配置打包参数,让打出的 APK 更符合你的需求。

基本使用流程

1
填写应用信息

打开你部署的站点,在表单中依次填写:

  • 应用名称 — 显示在桌面的名字,支持中文,建议不超过 10 个字
  • 网站 URL — 需包含 https://,支持带路径的子页面
  • 包名 — 格式为 com.example.app,安装后不可更改
2
上传图标

点击图标上传区域,选择图片文件。推荐规格:

  • 尺寸:512×512px(最低 192×192px)
  • 格式:PNG,带透明通道效果更好
  • 内容:避免图标四周留太多空白,否则桌面显示会很小
i

不上传图标时,系统会自动使用目标网站的 favicon 作为图标。

3
选择 APK 架构

默认生成 arm64-v8a + armeabi-v7a 通用包,覆盖 99% 的 Android 设备。如需生成体积更小的包,可在高级设置中选择单一架构。

架构适用设备APK 体积
arm64-v8a2017 年后所有安卓手机约 3.5 MB
armeabi-v7a老机型兼容包约 2.8 MB
通用(默认)全部设备约 4 MB
4
提交打包

点击「开始打包」,系统会触发 GitHub Actions,页面实时显示构建进度。一般 3~5 分钟完成。

5
下载 APK

构建完成后,页面显示下载按钮。APK 默认保存 7 天,请及时下载。下载后直接发送到手机安装即可。

Android 默认不允许安装未知来源应用,安装前需在「设置 → 安全 → 未知来源」中允许。

功能卡片说明

全自动构建
提交后自动触发 GitHub Actions,全程无需本地环境,云端完成编译签名打包。
实时进度
显示精确百分比和当前步骤,可随时掌握打包进度,无需刷新页面。
Release 签名
使用你自己的 Keystore 正式签名,可上架应用商店,支持 APK 升级覆盖安装。
系统下载管理
通过系统 DownloadManager 下载,支持后台下载,下载失败自动重试。

配置签名 Keystore

Keystore 正确配置后,每次打包签名一致,可以升级覆盖安装。

生成 Keystore

进入你 Fork 的仓库 → Actions → 左侧 gen-keystore → 点击 Run workflow,填写密码,等待约 30 秒完成。

获取 Base64 字符串

运行完成后,点击该次运行 → 展开 Generate Keystore 步骤 → 找到 KEYSTORE_BASE64: 行,复制后面的完整字符串。

这段字符串是签名凭证,不要泄露。丢失后无法找回,重新生成后已安装的 APK 将无法升级覆盖。

Keystore 参数说明

参数说明默认值
Key Alias密钥别名,填入 Secret 时固定为release
Validity有效期,单位年100 年
Algorithm签名算法RSA 2048

配置 GitHub Secrets

Secrets 向 Actions 传递敏感信息,不会出现在代码或日志中。

创建 Personal Access Token

前往 GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic),点击 Generate new token

勾选以下权限:

  • repo — 访问私有仓库
  • workflow — 触发和管理 Actions

生成后立即复制 Token(离开页面后不再显示)。

添加 Secrets

仓库 → Settings → Secrets and variables → Actions → New repository secret

名称说明
KEYSTORE_BASE64gen-keystore 输出的 Base64签名文件
KEYSTORE_PASSWORDgen-keystore 时的密码Keystore 密码
KEY_ALIASrelease密钥别名,固定值
KEY_PASSWORD同 KEYSTORE_PASSWORD密钥密码
GH_PAT刚生成的 Personal Access Token触发 Actions
i

Secrets 添加后无法查看原始值,只能覆盖。建议将 4 个 Keystore 相关 Secret 备份到安全位置。

部署到 Cloudflare Pages

Pakr 是纯静态项目,托管在 Cloudflare Pages,全球 CDN 加速,免费无限流量。

1
连接 GitHub 仓库

Cloudflare DashboardWorkers & Pages → Create → Pages → Connect to Git,选择你 Fork 的仓库,点击 Begin setup

2
构建配置留空
配置项
Build command留空
Build output directory留空
Root directory留空

直接点击 Save and Deploy

3
添加环境变量

部署完成后 → Settings → Environment variables → Add variable

变量名
GH_TOKEN与 GH_PAT 相同

添加后需在 Deployments 手动点击 Retry deployment 才能生效。

4
绑定自定义域名(可选)

项目 → Custom domains → Set up a custom domain,输入域名按提示配置 DNS,SSL 自动颁发。

自动更新

CF Pages 默认开启 Auto Deployment,每次向主分支 push 代码后自动重新部署,无需手动操作。

架构说明

Pakr 采用三层无服务器架构,所有计算资源均来自免费托管平台,零成本运行。

整体架构

浏览器
用户 / 表单输入
CF Pages
静态前端 + Worker
GitHub API
触发 Actions
GitHub Actions
编译 · 签名 · 打包
GitHub Releases
存储 APK 文件

各层说明

Cloudflare Pages(前端层)

承载所有静态资源(HTML/CSS/JS),全球 CDN 分发,访问速度极快。同时挂载 Cloudflare Worker 作为 API 网关,处理前端与 GitHub API 之间的请求转发和鉴权。

Cloudflare Worker(网关层)

Worker 运行在 CF 边缘节点,主要职责:

  • 接收前端提交的打包参数
  • GH_TOKEN 注入请求头,安全调用 GitHub API
  • 轮询 Actions 运行状态并返回实时进度
  • 构建完成后获取 Release 下载链接

GitHub Actions(构建层)

接收到触发后,按以下顺序执行构建流程:

1
准备环境

安装 JDK 17 和 Android SDK Build Tools,配置 Gradle 缓存加速。

2
生成项目文件

根据传入参数动态生成 AndroidManifest.xml、应用名称、包名、图标资源。

3
Gradle 构建

执行 ./gradlew assembleRelease 编译 APK,内嵌目标 URL 到 WebView 配置。

4
签名

使用 apksigner 和存储在 Secrets 里的 Keystore 对 APK 进行正式 Release 签名。

5
发布到 Release

创建 GitHub Release,上传签名后的 APK,前端获取下载链接并展示下载按钮。

技术栈

技术用途
前端Vanilla JS + CSS表单交互、进度展示、下载
网关Cloudflare Worker (JS)API 转发、鉴权、轮询
构建GitHub Actions + GradleAndroid APK 编译签名
存储GitHub ReleasesAPK 文件托管(7天)
托管Cloudflare Pages静态资源 CDN

API 文档

Worker 提供以下 HTTP 接口,可用于二次开发或自动化脚本集成。

Base URL

https://<你的域名>/api

所有接口均为 JSON 格式,响应头包含 Content-Type: application/json

接口列表

POST /api/build 触发打包任务

请求参数(JSON Body)

参数类型必填说明
appNamestring必填应用名称,显示在桌面
urlstring必填目标网站 URL,需含 https://
packageNamestring必填包名,格式 com.xxx.yyy
iconBase64string可选图标的 Base64 编码,不传则用 favicon
archstring可选arm64 / arm32 / universal,默认 universal

响应示例

{
  "success": true,
  "runId": "12345678",
  "message": "构建任务已触发"
}
GET /api/status/:runId 查询构建状态

路径参数

参数类型说明
runIdstring触发打包返回的 runId

响应示例

{
  "status": "in_progress",
  "progress": 65,
  "step": "Gradle 构建中",
  "conclusion": null
}

status 枚举值

含义
queued已排队,等待运行
in_progress构建中
completed已完成,查看 conclusion
GET /api/download/:runId 获取 APK 下载链接

说明

构建成功(status=completedconclusion=success)后调用此接口获取下载地址。

响应示例

{
  "success": true,
  "downloadUrl": "https://github.com/.../releases/download/v1.0/app.apk",
  "fileName": "Pakr_MyApp_v1.0.apk",
  "size": 4194304
}

错误码

HTTP 状态码说明
400参数缺失或格式错误
401GH_TOKEN 未配置或已失效
404runId 不存在
500服务器内部错误

更新日志

记录每个版本的主要改动。

v1.8.0 最新 2026-04-29
  • 新增文档站点上线,支持亮色/暗色模式
  • 新增UI 全面升级,圆润风格,CSS 图标
  • 优化打包进度显示精确到步骤名称
  • 优化移动端布局适配,侧边栏支持滑动收起
  • 修复部分设备下载后无法打开文件管理器的问题
v1.7.0 2026-03-15
  • 新增支持自定义 APK 架构(arm64 / arm32 / 通用)
  • 新增Release 签名支持,可升级覆盖安装
  • 优化构建速度提升约 30%(启用 Gradle 缓存)
  • 修复图标上传后预览偶尔不显示的问题
v1.6.0 2026-02-08
  • 新增系统 DownloadManager 下载,支持后台下载
  • 新增打包历史本地记录
  • 优化Worker 轮询逻辑优化,减少 API 调用次数
  • 优化表单验证提示更清晰
v1.5.0 2026-01-10
  • 新增支持 HTTP/HTTPS 混合内容
  • 新增多架构输出,单 APK 体积压缩至约 4MB
  • 修复包名包含大写字母时构建失败的问题
  • 修复暗色模式下输入框颜色异常
v1.0.0 初始版本 2025-11-01
  • 新增基础打包功能上线
  • 新增Cloudflare Pages + Worker 架构
  • 新增GitHub Actions 自动构建流程

常见问题

打包失败怎么排查?

进入 Fork 的仓库 → Actions,找到对应运行记录查看详细日志。常见原因:

  • GH_PAT 权限不足(需要 repo + workflow
  • Keystore Secrets 填写错误或遗漏
  • 包名格式不对(必须为 com.xxx.yyy 格式)
  • 目标网址无法访问或返回非 200
安装后无法升级覆盖安装?

两次打包使用了不同的 Keystore 签名导致的。请检查:

  • 4 个 Keystore Secrets 是否正确且完整
  • 是否重新运行过 gen-keystore(会生成新的签名)

如果已重新生成 Keystore,需要先卸载旧版 APK 再安装新版。

GitHub Actions 免费额度够用吗?

GitHub 免费账号每月 2000 分钟,单次约 3~5 分钟,每月约可打包 400~600 次,日常使用完全够用。超出后等下月自动重置,或升级为 GitHub Pro(4000 分钟/月)。

CF Pages 有流量限制吗?

Cloudflare Pages 免费版:无限带宽、每月 500 次构建。Worker 免费版:每天 100,000 次请求。个人使用完全够用,超出需升级 Pro($5/月)。

支持 iOS 吗?

暂不支持,目前仅生成 Android APK(armeabi-v7a 和 arm64-v8a)。iOS 需要 macOS 环境和 Apple 开发者账号,后续版本可能考虑支持。

可以打包需要登录的网页吗?

可以,WebView 支持完整 Cookie,登录状态会保存在 APK 内(与普通 Android App 一样)。首次打开需要登录,之后保持登录状态。

打包历史记录丢了怎么办?

打包历史保存在浏览器 LocalStorage,清除缓存、使用无痕模式或换设备后会丢失,这是正常现象。APK 文件本身存储在 GitHub Releases,保留 7 天,可到仓库 Releases 页面直接下载。

能修改 APK 内的 WebView 设置吗?

默认开启了以下 WebView 配置:

  • JavaScript 启用
  • DOM Storage 启用
  • 混合内容允许(HTTP + HTTPS)
  • 缩放支持

如需自定义,Fork 仓库后修改 app/src/main/java/.../MainActivity.java 中的 WebView 设置,重新触发构建即可。