# ipa-store-link **Repository Path**: yausing/ipa-store-link ## Basic Information - **Project Name**: ipa-store-link - **Description**: 这是一个基于 Docker 的自建 IPA 软件源工具,可递归扫描本地 IPA、自动提取图标与版本信息,生成可用于局域网或外网分发的应用索引。 - **Primary Language**: HTML - **License**: AGPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-15 - **Last Updated**: 2026-08-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ipa-store-link 本项目用于把你已授权分发的 IPA 目录通过 Docker 暴露成一个可访问的软件源 HTTP 地址,支持局域网访问,也支持通过外网域名反向映射后对外提供软件下载。 ## 功能说明 - 递归扫描挂载目录中的 `.ipa` - 不收录 `.tipa` - 过滤文件名以 `Troll` 开头的 IPA - 同一目录下,同一应用只保留最新版本 - 软件列表按文件修改时间倒序排列,最新文件排最上面 - 自动生成软件源索引 `index.json` - 优先从 IPA 包内自动提取应用图标 - 手工图标目录可作为覆盖来源 - `versionDate` 固定输出为 `Asia/Shanghai` 时区 - 内置微信版本号兼容规则: - `WeChat_8073_xxx.ipa` -> `8.0.73` - `WeChat_8074_xxx.ipa` -> `8.0.74` ## 目录结构 ```text . ├── app/public/ # 静态输出目录 ├── data/icons/ # 可选手工图标目录 ├── data/ipas/ # 默认 IPA 目录 ├── scripts/ # 生成脚本与启动脚本 ├── Dockerfile └── docker-compose.yml ``` ## 当前扫描规则 - 只扫描后缀为 `.ipa` 的文件 - 不扫描 `.tipa` - 文件名以 `Troll` 开头的 IPA 会被忽略 - 同目录下按“解析后的应用名”分组,只保留一个最新版本 - 版本可比较时优先按版本号判新旧 - 版本无法可靠比较时,退回到文件修改时间 ## 版本与名称识别 - 常规命名优先识别第一个类似版本号的片段 - `中国移动_12.1.2_彭于晏Crack.ipa` -> `中国移动 / 12.1.2` - `Notability 16.3.2 砸壳破解版.ipa` -> `Notability / 16.3.2` - `PicsArt_美易_29_1_2_砸壳破解版.ipa` -> `PicsArt_美易 / 29.1.2` - 微信特殊命名会额外处理 - `WeChat_8073_qy_免费版_v912.ipa` -> `WeChat / 8.0.73` - 如果无法识别版本号,则回退为 `未知版本` ## 图标规则 - 默认优先从 IPA 包内提取图标 - 如果 `data/icons/` 中存在同名图标,会优先使用手工图标 - IPA 内提取失败时,回退到默认图标 `default-icon.svg` ## 启动方式 1. 准备 IPA 目录 2. 可选准备手工图标目录 3. 构建镜像: ```bash docker build -t ipa-store-link:latest . ``` 4. 启动服务: ```bash docker compose up --build ``` 如果你使用 dpanel,通常建议直接使用构建好的镜像并重建容器,而不是只做普通重启。 ## 局域网示例 如果容器内监听端口为 `33390`,局域网 IP 是 `10.10.10.205`,推荐环境变量如下: ```yaml PORT=33390 BASE_URL=http://10.10.10.205:33390 SOURCE_URL=http://10.10.10.205:33390/index.json SOURCE_ICON=http://10.10.10.205:33390/default-icon.svg SOURCE_NAME=本机 IPA 软件源 SOURCE_IDENTIFIER=local.ipa.store.link OUTPUT_FILE=/srv/app/public/index.json IPA_DIR=/srv/data/ipas ICON_DIR=/srv/data/icons ICON_OUTPUT_DIR=/srv/app/public/icons ``` ## 外网示例 如果外网域名 `https://你的外网域名` 已映射到内网 `http://10.10.10.205:33390`,推荐环境变量如下: ```yaml PORT=33390 BASE_URL=https://你的外网域名 SOURCE_URL=https://你的外网域名/index.json SOURCE_ICON=https://你的外网域名/default-icon.svg SOURCE_NAME=本机 IPA 软件源 SOURCE_IDENTIFIER=local.ipa.store.link OUTPUT_FILE=/srv/app/public/index.json IPA_DIR=/srv/data/ipas ICON_DIR=/srv/data/icons ICON_OUTPUT_DIR=/srv/app/public/icons ``` 注意: - 既然外网通过 `443` 暴露,`BASE_URL` 一般不需要再写 `:443` - 如果 `BASE_URL` 仍是局域网地址,生成出的 `downloadURL` 也会是局域网地址 - 外网改完配置后,需要重建容器,不要只点重启 ## dpanel 使用建议 典型 Compose 结构如下: ```yaml services: ipa-store-link: image: ipa-store-link:latest container_name: ipa-store-link environment: PORT: "33390" BASE_URL: "https://你的外网域名" SOURCE_URL: "https://你的外网域名/index.json" SOURCE_ICON: "https://你的外网域名/default-icon.svg" SOURCE_NAME: "本机 IPA 软件源" SOURCE_IDENTIFIER: "local.ipa.store.link" OUTPUT_FILE: "/srv/app/public/index.json" IPA_DIR: "/srv/data/ipas" ICON_DIR: "/srv/data/icons" ICON_OUTPUT_DIR: "/srv/app/public/icons" ports: - "33390:33390" volumes: - /你的IPA目录:/srv/data/ipas:ro - /你的图标目录:/srv/data/icons:ro ``` ## 输出字段说明 当前输出的 JSON 结构贴近常见第三方工具软件源格式,包含: - 顶层字段: - `name` - `message` - `identifier` - `sourceURL` - `sourceicon` - `payURL` - `unlockURL` - `apps` - 应用字段: - `name` - `type` - `version` - `versionDate` - `versionDescription` - `lock` - `downloadURL` - `isLanZouCloud` - `iconURL` - `tintColor` - `size` ## 常见问题 ### 软件源失效 优先检查: - `SOURCE_URL` 是否能在浏览器直接打开 - `BASE_URL`、`SOURCE_URL`、`SOURCE_ICON` 是否仍写成了局域网地址或 `localhost` - 容器是否是“重建”而不是“仅重启” ### downloadURL 还是局域网地址 这是因为容器实际生效的 `BASE_URL` 仍是局域网地址。修改环境变量后,需要重建容器。 ### 外网可以打开 index.json,但 IPA 下载失败 优先检查: - 外网域名是否真的把文件下载请求转发到了容器 - 具体 `downloadURL` 是否能在外网浏览器直接访问 - 反向映射是否支持大文件下载 ### 时间差 8 小时 当前实现已经固定输出北京时间 `Asia/Shanghai`。如果你仍看到旧时间,通常说明容器还在运行旧镜像,需要重新构建镜像并重建容器。 ## 维护说明 - 每次容器启动时都会重新扫描目录并生成最新 `index.json` - 图标输出目录会在重新生成前清空并重建 - 软件源 JSON 统一由脚本生成,不建议手工修改生成后的 `index.json`