mirror of
https://github.com/okxlin/appstore.git
synced 2026-09-25 08:01:02 +00:00
Merge pull request #5275 from okxlin/feat/actual-budget-1panel-batch52
feat: add Actual Budget app
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
PANEL_APP_PORT_HTTP=5006
|
||||
APP_DATA_DIR=./data
|
||||
CONTAINER_NAME=
|
||||
@@ -0,0 +1,35 @@
|
||||
additionalProperties:
|
||||
formFields:
|
||||
- default: 5006
|
||||
edit: true
|
||||
envKey: PANEL_APP_PORT_HTTP
|
||||
labelEn: Port
|
||||
labelZh: 端口
|
||||
label:
|
||||
en: Port
|
||||
zh: 端口
|
||||
zh-Hant: 埠
|
||||
ja: ポート
|
||||
ko: 포트
|
||||
ru: Порт
|
||||
ms: Port
|
||||
pt-br: Porta
|
||||
required: true
|
||||
rule: paramPort
|
||||
type: number
|
||||
- default: ./data
|
||||
edit: true
|
||||
envKey: APP_DATA_DIR
|
||||
labelEn: Data Directory
|
||||
labelZh: 数据目录
|
||||
label:
|
||||
en: Data Directory
|
||||
zh: 数据目录
|
||||
zh-Hant: 資料目錄
|
||||
ja: データディレクトリ
|
||||
ko: 데이터 디렉터리
|
||||
ru: Каталог данных
|
||||
ms: Direktori Data
|
||||
pt-br: Diretório de dados
|
||||
required: true
|
||||
type: text
|
||||
@@ -0,0 +1,31 @@
|
||||
services:
|
||||
actual-budget:
|
||||
image: "actualbudget/actual-server:26.7.0@sha256:e18b7fbfec6157a368fad4146563f397502e9da70a120aeaeac63b4977405d1c"
|
||||
container_name: ${CONTAINER_NAME}
|
||||
restart: unless-stopped
|
||||
user: "1001:1001"
|
||||
networks:
|
||||
- 1panel-network
|
||||
ports:
|
||||
- "${PANEL_APP_PORT_HTTP}:5006"
|
||||
read_only: true
|
||||
tmpfs:
|
||||
- /tmp:size=64m,mode=1777
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
cap_drop:
|
||||
- ALL
|
||||
volumes:
|
||||
- "${APP_DATA_DIR}:/data"
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "node scripts/health-check.js"]
|
||||
interval: 60s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 20s
|
||||
labels:
|
||||
createdBy: "Apps"
|
||||
|
||||
networks:
|
||||
1panel-network:
|
||||
external: true
|
||||
Executable
+55
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
|
||||
ENV_FILE="${ENV_FILE:-$ROOT_DIR/.env}"
|
||||
|
||||
read_env_value() {
|
||||
local key="$1"
|
||||
local value
|
||||
|
||||
[[ -f "$ENV_FILE" ]] || return 0
|
||||
value="$(sed -n "s/^${key}=//p" "$ENV_FILE" | tail -n 1)"
|
||||
case "$value" in
|
||||
\"*\") value="${value#\"}"; value="${value%\"}" ;;
|
||||
\'*\') value="${value#\'}"; value="${value%\'}" ;;
|
||||
esac
|
||||
printf '%s\n' "$value"
|
||||
}
|
||||
|
||||
raw="${APP_DATA_DIR:-}"
|
||||
if [[ -z "$raw" ]]; then
|
||||
raw="$(read_env_value APP_DATA_DIR)"
|
||||
fi
|
||||
raw="${raw:-./data}"
|
||||
|
||||
[[ -n "$raw" ]] || {
|
||||
printf 'APP_DATA_DIR must not be empty\n' >&2
|
||||
exit 1
|
||||
}
|
||||
if [[ "$raw" = /* ]]; then
|
||||
printf 'APP_DATA_DIR must be relative to the application version directory\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
path="$(realpath -m -- "$ROOT_DIR/${raw#./}")"
|
||||
case "$path" in
|
||||
"$ROOT_DIR"/*) ;;
|
||||
*)
|
||||
printf 'APP_DATA_DIR must remain inside the application version directory\n' >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
install -d -m 0700 "$path"
|
||||
path="$(realpath -e -- "$path")"
|
||||
case "$path" in
|
||||
"$ROOT_DIR"/*) ;;
|
||||
*)
|
||||
printf 'APP_DATA_DIR resolves outside the application version directory\n' >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
chmod 0700 "$path"
|
||||
chown -R --no-dereference 1001:1001 "$path"
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
"$(dirname "$0")/init.sh"
|
||||
@@ -0,0 +1,53 @@
|
||||
# Actual Budget
|
||||
|
||||
## 产品介绍
|
||||
|
||||
Actual Budget 是隐私优先的开源个人财务应用,提供信封预算、账户与交易管理、规则、报表和多设备同步。
|
||||
|
||||
## 主要功能
|
||||
|
||||
- 信封预算与灵活预算管理
|
||||
- 账户、交易、分类、规则和报表
|
||||
- 预算导入导出、本地备份与多设备同步
|
||||
|
||||
## 访问说明
|
||||
|
||||
安装后通过 `http://<服务器 IP>:<端口>` 访问,实际端口以 `PANEL_APP_PORT_HTTP` 为准。首次打开时应立即设置服务器密码;在完成密码设置和反向代理 HTTPS 配置前,不要将端口暴露到不可信网络。
|
||||
|
||||
## 数据持久化
|
||||
|
||||
`APP_DATA_DIR` 保存服务器账户数据库、预算文件和同步数据。该路径必须位于应用版本目录内;初始化脚本会拒绝绝对路径、路径穿越和符号链接逃逸,并为上游容器用户 `1001:1001` 准备权限。卸载不会删除该目录,请定期独立备份。
|
||||
|
||||
## 安全与部署风险
|
||||
|
||||
- 容器以 UID/GID `1001:1001` 运行,丢弃全部 Linux capabilities,并启用只读根文件系统和 `no-new-privileges`。
|
||||
- 当前官方 `26.7.0` 镜像的新鲜 Trivy 扫描仍包含上游未修复漏洞。其中两份受 `CVE-2026-59873` 影响的 `node-tar` 分别属于 npm CLI 和仅由 `node-gyp` 导入的构建链;Actual 的运行时导入、备份和同步上传路径使用 `AdmZip` 或限长后原样存储,未调用 `node-tar`。该结论是默认运行路径例外,不代表镜像中不存在漏洞。
|
||||
- 如果在容器内手动运行 npm/node-gyp、增加执行外部命令的插件或改变官方入口,上述可达性结论将不再成立。镜像摘要变更时必须重新扫描。
|
||||
|
||||
## Introduction
|
||||
|
||||
Actual Budget is a privacy-focused open-source personal finance app with envelope budgeting, account and transaction management, rules, reports, and multi-device synchronization.
|
||||
|
||||
## Features
|
||||
|
||||
- Envelope and flexible budgeting
|
||||
- Accounts, transactions, categories, rules, and reports
|
||||
- Budget import/export, local backups, and multi-device synchronization
|
||||
|
||||
## Usage Notes
|
||||
|
||||
- Access the service at `http://<server-ip>:<port>` and set the server password immediately on first use. Do not expose it to an untrusted network before password setup and HTTPS reverse-proxy configuration are complete.
|
||||
- `APP_DATA_DIR` stores the account database, budget files, and synchronization data. It must remain inside the application version directory and should be backed up independently.
|
||||
- The container runs as UID/GID `1001:1001`, drops all Linux capabilities, and uses a read-only root filesystem plus `no-new-privileges`.
|
||||
|
||||
## Security Note
|
||||
|
||||
The current official image contains upstream vulnerabilities. Two `node-tar` copies affected by `CVE-2026-59873` belong to the npm CLI and the `node-gyp` build chain; Actual's runtime import, backup, and sync-upload paths use `AdmZip` or bounded opaque storage and do not invoke them. This is a default-path reachability exception, not a claim that the packages are absent. Running npm/node-gyp inside the container or replacing the official entrypoint invalidates the exception.
|
||||
|
||||
## References
|
||||
|
||||
- Project: <https://github.com/actualbudget/actual>
|
||||
- Docker installation: <https://actualbudget.org/docs/install/docker/>
|
||||
- Official Compose: <https://github.com/actualbudget/actual/blob/master/packages/sync-server/docker-compose.yml>
|
||||
- License: <https://github.com/actualbudget/actual/blob/master/LICENSE.txt> (MIT)
|
||||
- Security advisory: <https://github.com/advisories/GHSA-23hp-3jrh-7fpw>
|
||||
@@ -0,0 +1,31 @@
|
||||
name: Actual Budget
|
||||
tags:
|
||||
- 财务
|
||||
title: 隐私优先的开源个人财务应用
|
||||
description: 隐私优先的开源个人财务应用
|
||||
additionalProperties:
|
||||
key: actual-budget
|
||||
name: Actual Budget
|
||||
tags:
|
||||
- Tool
|
||||
shortDescZh: 隐私优先的开源个人财务应用
|
||||
shortDescEn: Privacy-focused open-source personal finance app
|
||||
description:
|
||||
en: Privacy-focused open-source personal finance app
|
||||
zh: 隐私优先的开源个人财务应用
|
||||
zh-Hant: 隱私優先的開源個人理財應用程式
|
||||
ja: プライバシー重視のオープンソース個人資産管理アプリ
|
||||
ko: 개인정보 보호를 중시하는 오픈소스 개인 재무 앱
|
||||
ru: Конфиденциальное приложение с открытым кодом для личных финансов
|
||||
ms: Aplikasi kewangan peribadi sumber terbuka yang mengutamakan privasi
|
||||
pt-br: Aplicativo de finanças pessoais de código aberto com foco em privacidade
|
||||
type: website
|
||||
crossVersionUpdate: true
|
||||
limit: 0
|
||||
recommend: 0
|
||||
website: https://actualbudget.org/
|
||||
github: https://github.com/actualbudget/actual
|
||||
document: https://actualbudget.org/docs/install/docker/
|
||||
architectures:
|
||||
- amd64
|
||||
- arm64
|
||||
@@ -0,0 +1,3 @@
|
||||
PANEL_APP_PORT_HTTP=5006
|
||||
APP_DATA_DIR=./data
|
||||
CONTAINER_NAME=
|
||||
@@ -0,0 +1,35 @@
|
||||
additionalProperties:
|
||||
formFields:
|
||||
- default: 5006
|
||||
edit: true
|
||||
envKey: PANEL_APP_PORT_HTTP
|
||||
labelEn: Port
|
||||
labelZh: 端口
|
||||
label:
|
||||
en: Port
|
||||
zh: 端口
|
||||
zh-Hant: 埠
|
||||
ja: ポート
|
||||
ko: 포트
|
||||
ru: Порт
|
||||
ms: Port
|
||||
pt-br: Porta
|
||||
required: true
|
||||
rule: paramPort
|
||||
type: number
|
||||
- default: ./data
|
||||
edit: true
|
||||
envKey: APP_DATA_DIR
|
||||
labelEn: Data Directory
|
||||
labelZh: 数据目录
|
||||
label:
|
||||
en: Data Directory
|
||||
zh: 数据目录
|
||||
zh-Hant: 資料目錄
|
||||
ja: データディレクトリ
|
||||
ko: 데이터 디렉터리
|
||||
ru: Каталог данных
|
||||
ms: Direktori Data
|
||||
pt-br: Diretório de dados
|
||||
required: true
|
||||
type: text
|
||||
@@ -0,0 +1,31 @@
|
||||
services:
|
||||
actual-budget:
|
||||
image: "actualbudget/actual-server:latest@sha256:e18b7fbfec6157a368fad4146563f397502e9da70a120aeaeac63b4977405d1c"
|
||||
container_name: ${CONTAINER_NAME}
|
||||
restart: unless-stopped
|
||||
user: "1001:1001"
|
||||
networks:
|
||||
- 1panel-network
|
||||
ports:
|
||||
- "${PANEL_APP_PORT_HTTP}:5006"
|
||||
read_only: true
|
||||
tmpfs:
|
||||
- /tmp:size=64m,mode=1777
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
cap_drop:
|
||||
- ALL
|
||||
volumes:
|
||||
- "${APP_DATA_DIR}:/data"
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "node scripts/health-check.js"]
|
||||
interval: 60s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 20s
|
||||
labels:
|
||||
createdBy: "Apps"
|
||||
|
||||
networks:
|
||||
1panel-network:
|
||||
external: true
|
||||
Executable
+55
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
|
||||
ENV_FILE="${ENV_FILE:-$ROOT_DIR/.env}"
|
||||
|
||||
read_env_value() {
|
||||
local key="$1"
|
||||
local value
|
||||
|
||||
[[ -f "$ENV_FILE" ]] || return 0
|
||||
value="$(sed -n "s/^${key}=//p" "$ENV_FILE" | tail -n 1)"
|
||||
case "$value" in
|
||||
\"*\") value="${value#\"}"; value="${value%\"}" ;;
|
||||
\'*\') value="${value#\'}"; value="${value%\'}" ;;
|
||||
esac
|
||||
printf '%s\n' "$value"
|
||||
}
|
||||
|
||||
raw="${APP_DATA_DIR:-}"
|
||||
if [[ -z "$raw" ]]; then
|
||||
raw="$(read_env_value APP_DATA_DIR)"
|
||||
fi
|
||||
raw="${raw:-./data}"
|
||||
|
||||
[[ -n "$raw" ]] || {
|
||||
printf 'APP_DATA_DIR must not be empty\n' >&2
|
||||
exit 1
|
||||
}
|
||||
if [[ "$raw" = /* ]]; then
|
||||
printf 'APP_DATA_DIR must be relative to the application version directory\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
path="$(realpath -m -- "$ROOT_DIR/${raw#./}")"
|
||||
case "$path" in
|
||||
"$ROOT_DIR"/*) ;;
|
||||
*)
|
||||
printf 'APP_DATA_DIR must remain inside the application version directory\n' >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
install -d -m 0700 "$path"
|
||||
path="$(realpath -e -- "$path")"
|
||||
case "$path" in
|
||||
"$ROOT_DIR"/*) ;;
|
||||
*)
|
||||
printf 'APP_DATA_DIR resolves outside the application version directory\n' >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
chmod 0700 "$path"
|
||||
chown -R --no-dereference 1001:1001 "$path"
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
"$(dirname "$0")/init.sh"
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
Reference in New Issue
Block a user