Anyexyz commited on
Commit
66e6dd3
1 Parent(s): a9542a7

Upload 5 files

Browse files
Files changed (5) hide show
  1. README.md +91 -11
  2. default_logo.png +0 -0
  3. main.py +201 -0
  4. requirements.txt +0 -0
  5. 如何提交自己想要的应用.md +310 -0
README.md CHANGED
@@ -1,11 +1,91 @@
1
- ---
2
- title: Auto Build 1Panel APP
3
- emoji: 🐨
4
- colorFrom: red
5
- colorTo: pink
6
- sdk: docker
7
- pinned: false
8
- license: mit
9
- ---
10
-
11
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 自助创建 1Panel 应用
2
+
3
+ 该程序允许用户通过图形界面自助创建 [1Panel](https://1panel.cn/) 应用。用户可以输入应用的基本信息,编写相关配置文件,并生成可下载的应用包。
4
+
5
+ ## [在线使用]()
6
+
7
+ ## 功能
8
+
9
+ - **基本信息录入**:输入应用名称、Key、标签、描述、官网、GitHub 地址等基本信息。
10
+ - **版本创建**:为应用创建不同版本的 `docker-compose.yml` 和 `data.yml` 文件。
11
+ - **Logo 上传**:上传应用的 Logo,支持 PNG、JPG 格式。如果未上传 Logo,使用默认图片。
12
+ - **README 编写**:支持使用 Markdown 编写 README 文件。
13
+ - **文件压缩与下载**:将应用文件夹压缩为 ZIP 文件,并提供下载链接。
14
+
15
+ ## 依赖项
16
+
17
+ - Python 3.x
18
+ - `pywebio`
19
+ - `PyYAML`
20
+
21
+ 使用以下命令安装依赖:
22
+
23
+ ```bash
24
+ pip install -r requirements.txt
25
+ ```
26
+
27
+ ## 使用方法
28
+
29
+ ### 1. 启动程序
30
+
31
+ 在命令行中运行以下命令启动应用创建程序:
32
+
33
+ ```bash
34
+ python main.py
35
+ ```
36
+
37
+ 程序将在本地的 `8080` 端口启动。
38
+
39
+ ### 2. 填写应用信息
40
+
41
+ 根据提示输入以下信息:
42
+
43
+ - 应用名称、Key(仅限英文字符)
44
+ - 应用标签(可多选)
45
+ - 应用的中文与英文描述
46
+ - 应用类型(工具类、站点类、运行时应用等)
47
+ - 是否支持跨大版本升级
48
+ - 安装数量限制
49
+ - 官网、GitHub、文档地址
50
+ - Logo 图片上传(可选)
51
+
52
+ ### 3. 创建应用版本
53
+
54
+ 在基本信息录入完成后,您可以创建应用的不同版本,分别编写 `docker-compose.yml` 和 `data.yml` 文件。
55
+
56
+ ### 4. 编写README
57
+
58
+ 支持使用 Markdown 编写 README 文件,并将其保存至应用文件夹中。
59
+
60
+ ### 5. 下载应用文件
61
+
62
+ 所有信息输入完成后,程序将生成应用的 ZIP 包,并提供下载按钮。
63
+
64
+ ## 目录结构
65
+
66
+ 生成的应用包目录结构如下:
67
+
68
+ ```
69
+ apps/
70
+ └── <应用Key>/
71
+ ├── data.yml
72
+ ├── logo.png
73
+ ├── README.md
74
+ └── <版本号>/
75
+ ├── data.yml
76
+ └── docker-compose.yml
77
+ ```
78
+
79
+ - `data.yml`: 包含应用的基本信息
80
+ - `logo.png`: 应用的 Logo 图片
81
+ - `README.md`: 应用的 README 文件
82
+ - `<版本号>/`: 版本文件夹,包含版本特定的配置文件
83
+
84
+
85
+ ## 日志记录
86
+
87
+ 程序运行时会记录关键操作日志,默认日志级别为 `INFO`,可以在需要时查看日志以排查问题。
88
+
89
+ ## 贡献
90
+
91
+ 欢迎提交 issues 和 pull requests 以改进本程序。
default_logo.png ADDED
main.py ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import zipfile
2
+ import yaml
3
+ from pywebio.input import *
4
+ from pywebio.output import *
5
+ from pywebio.platform import config
6
+ from pywebio.platform.tornado import start_server
7
+ from pathlib import Path
8
+ import shutil
9
+ import logging
10
+ import os
11
+ import io
12
+ import re
13
+
14
+ # 环境变量
15
+ APPS_DIR = Path("apps")
16
+ DEFAULT_LOGO = Path("default_logo.png")
17
+
18
+ # 初始化logging
19
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
20
+
21
+ # 校验key是否为英文字符串
22
+ def is_valid_key(key):
23
+ return bool(re.match(r'^[a-zA-Z]+$', key))
24
+
25
+ # 校验基本信息
26
+ def check_base_info(data):
27
+ required_fields = [
28
+ "name", "key", "tags", "shortDescZh", "shortDescEn",
29
+ "type", "crossVersionUpdate", "website", "github", "document"
30
+ ]
31
+ for field in required_fields:
32
+ if not data[field]:
33
+ return (field, f"{field} 不能为空")
34
+ if len(data["shortDescZh"]) > 30:
35
+ return ("shortDescZh", "中文描述不能超过30个字")
36
+ if not is_valid_key(data["key"]):
37
+ return ("key", "key 必须是纯英文字符串")
38
+ return None
39
+
40
+ # 保存文件
41
+ def save_file(path, content, mode='w', encoding=None):
42
+ try:
43
+ if 'b' in mode: # 二进制模式
44
+ with open(path, mode) as f:
45
+ f.write(content)
46
+ else: # 文本模式
47
+ with open(path, mode, encoding=encoding or 'utf-8') as f:
48
+ f.write(content)
49
+ logging.info(f"File saved successfully: {path}")
50
+ except IOError as e:
51
+ logging.error(f"Error saving file {path}: {e}")
52
+ raise
53
+
54
+ # 复制文件
55
+ def copy_file(src, dst):
56
+ try:
57
+ shutil.copy(src, dst)
58
+ logging.info(f"File copied successfully from {src} to {dst}")
59
+ except IOError as e:
60
+ logging.error(f"Error copying file from {src} to {dst}: {e}")
61
+ raise
62
+
63
+ # 创建目录
64
+ def create_directory(path):
65
+ try:
66
+ path.mkdir(parents=True, exist_ok=True)
67
+ logging.info(f"Directory created: {path}")
68
+ except OSError as e:
69
+ logging.error(f"Error creating directory {path}: {e}")
70
+ raise
71
+
72
+ # 创建版本
73
+ def create_version(app_dir, existing_versions):
74
+ while True:
75
+ version = input("请输入应用的版本 (不要以v开头)")
76
+ if version in existing_versions:
77
+ put_error(f"版本 {version} 已存在,请输入一个新的版本号")
78
+ else:
79
+ break
80
+
81
+ version_dir = app_dir / version
82
+ create_directory(version_dir)
83
+
84
+ version_info = input_group("版本信息", [
85
+ textarea("请编写docker-compose.yml", name="docker_compose", code={"mode": "yaml", "theme": ""}),
86
+ textarea("请编写data.yml", name="data", code={"mode": "yaml", "theme": ""}),
87
+ ])
88
+
89
+
90
+
91
+ save_file(version_dir / "data.yml", version_info["data"])
92
+ save_file(version_dir / "docker-compose.yml", version_info["docker_compose"])
93
+ put_success(f"已成功创建版本 {version}")
94
+
95
+ return version
96
+
97
+ # 压缩文件夹
98
+ def zip_folder(folder_path, output_path):
99
+ with zipfile.ZipFile(output_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
100
+ for root, _, files in os.walk(folder_path):
101
+ for file in files:
102
+ file_path = os.path.join(root, file)
103
+ arcname = os.path.relpath(file_path, folder_path)
104
+ zipf.write(file_path, arcname)
105
+
106
+ # 主函数
107
+ def main():
108
+ base_info = input_group(
109
+ "自助创建 1Panel 应用",
110
+ [
111
+ input("1. 请输入应用名称* ", name="name", type=TEXT),
112
+ input("2. 请输入应用的key* (仅限英文,用于创建文件夹)", name="key", type=TEXT),
113
+ checkbox("3. 选择应用标签*(可以有多个)", inline=True, options=[
114
+ {"label": "建站", "value": "WebSite"},
115
+ {"label": "Web 服务器", "value": "Server"},
116
+ {"label": "运行环境", "value": "Runtime"},
117
+ {"label": "数据库", "value": "Database"},
118
+ {"label": "工具", "value": "Tool"},
119
+ {"label": "CI/CD", "value": "CI/CD"},
120
+ {"label": "本地", "value": "Local"},
121
+ ], name="tags"),
122
+ input("4. 请输入应用中文描述*(不要超过30个字)", name="shortDescZh", type=TEXT),
123
+ input("5. 请输入应用英文描述*", name="shortDescEn", type=TEXT),
124
+ select("6. 选择应用类型*", options=[
125
+ {"label": "工具类应用,如 phpMyAdmin redis-commander jenkins", "value": "tool"},
126
+ {"label": "支持一键部署的站点类应用类型,如 wordpress halo", "value": "website"},
127
+ {"label": "服务类型的运行时应用,如 mysql openresty redis", "value": "runtime"},
128
+ ], name="type"),
129
+ select("7. 是否可跨大版本升级*", options=[
130
+ {"label": "是", "value": "true"},
131
+ {"label": "否", "value": "false"},
132
+ ], name="crossVersionUpdate"),
133
+ slider("8. 应用安装数量限制,(0 代表无限制)*", name="limit", min=0, max=100, step=1, value=0),
134
+ input("9. 官网地址*", name="website", type=URL),
135
+ input("10. Github 地址*", name="github", type=URL),
136
+ input("11. 文档地址*", name="document", type=URL),
137
+ file_upload("上传应用Logo图片(最好是 180 * 180 px)(可选): ", name="logo", accept=[".png", ".jpg", ".jpeg"], max_size="5M"),
138
+ ],
139
+ validate=check_base_info,
140
+ )
141
+
142
+ app_dir = APPS_DIR / base_info["key"]
143
+ create_directory(app_dir)
144
+
145
+ app_info = {
146
+ "additionalProperties": {
147
+ "key": base_info["key"],
148
+ "name": base_info["name"],
149
+ "tags": base_info["tags"],
150
+ "shortDescZh": base_info["shortDescZh"],
151
+ "shortDescEn": base_info["shortDescEn"],
152
+ "type": base_info["type"],
153
+ "crossVersionUpdate": base_info["crossVersionUpdate"],
154
+ "limit": base_info["limit"],
155
+ "website": base_info["website"],
156
+ "github": base_info["github"],
157
+ "document": base_info["document"],
158
+ }
159
+ }
160
+
161
+ save_file(app_dir / "data.yml", yaml.dump(app_info, allow_unicode=True))
162
+
163
+ if base_info["logo"]:
164
+ _, file_extension = os.path.splitext(base_info["logo"]["filename"])
165
+ logo_filename = f"logo{file_extension.lower()}"
166
+ save_file(app_dir / logo_filename, base_info["logo"]["content"], mode='wb')
167
+ else:
168
+ copy_file(DEFAULT_LOGO, app_dir / "logo.png")
169
+
170
+ put_success("已成功创建基本信息")
171
+
172
+ readme = textarea("请编写README", code={"mode": "markdown", "theme": ""})
173
+ save_file(app_dir / "README.md", readme)
174
+ put_success("已成功创建README")
175
+
176
+ versions = []
177
+ while True:
178
+ version = create_version(app_dir, versions)
179
+ versions.append(version)
180
+ if not actions("是否继续创建新版本?", [
181
+ {"label": "是", "value": "yes"},
182
+ {"label": "否", "value": "no"},
183
+ ]) == "yes":
184
+ break
185
+
186
+ # 压缩应用文件夹
187
+ zip_buffer = io.BytesIO()
188
+ zip_folder(app_dir, zip_buffer)
189
+ zip_buffer.seek(0)
190
+
191
+ # 美化下载按钮
192
+ put_button(
193
+ f"下载 {base_info['name']} 应用文件",
194
+ onclick=lambda: put_file(f"{base_info['key']}.zip", zip_buffer.getvalue()),
195
+ color="success",
196
+ outline=True
197
+ )
198
+
199
+ if __name__ == "__main__":
200
+ config(title="自助创建 1Panel 应用")
201
+ start_server(main, debug=False, port=8080, cdn=False)
requirements.txt ADDED
Binary file (60 Bytes). View file
 
如何提交自己想要的应用.md ADDED
@@ -0,0 +1,310 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ # 添加你想要的应用
3
+ > 需要有 docker 和 docker-compose 相关知识
4
+
5
+ ## 前提
6
+
7
+ - 活跃的开源项目
8
+ - 有官方维护的 docker 镜像
9
+
10
+ ## 1. fork 本项目
11
+
12
+ 为了提交 pull request 你需要 fork 本项目,访问 [appstore](https://github.com/1Panel-dev/appstore),然后点击右上角的 "Fork" 按钮,把本项目 fork 到你自己的代码仓库
13
+
14
+ ## 2. clone 代码到本地
15
+ 执行下面的命令 clone 代码到你自己的电脑
16
+ ```
17
+ git clone -b dev https://<your-github-username>/appstore
18
+ ```
19
+
20
+ ## 3. 创建一个新的分支
21
+ 进入到刚才下载的代码目录
22
+ ```
23
+ cd appstore
24
+ ```
25
+ 创建一个新的分支
26
+ ```
27
+ git checkout -b app/<app-name>
28
+ ```
29
+
30
+ ## 4. 创建应用文件 (以 Halo 为例)
31
+ v1.3 及以上版本可以在 1Panel 宿主机使用 1panel app init <应用的key> <应用的版本> 来快速初始化应用文件 (注意不是 1pctl 命令)
32
+
33
+ 文件夹格式
34
+ ```
35
+ ├──halo // 以 halo 的 key 命名 ,下面解释什么是 key
36
+ ├── logo.png // 应用 logo , 最好是 180 * 180 px
37
+ ├── data.yml // 应用声明文件
38
+ ├── README.md // 应用的 README
39
+ ├── 2.2.0 // 应用版本 注意不要以 v 开头
40
+ │   ├── data.yml // 应用的参数配置,下面有详细介绍
41
+ │   ├── data // 挂载出来的目录
42
+ | ├── scripts // 脚本目录 存放 init.sh upgrade.sh uninstall.sh
43
+ │   └── docker-compose.yml // docker-compose 文件
44
+ └── 2.3.2
45
+ ├── data.yml
46
+ ├── data
47
+ └── docker-compose.yml
48
+ ```
49
+
50
+ 应用声明文件 data.yml
51
+ > 本文件主要用于声明应用的一些信息
52
+ ```
53
+ additionalProperties: #固定参数
54
+ key: halo #应用的 key ,仅限英文,用于在 Linux 创建文件夹
55
+ name: Halo #应用名称
56
+ tags:
57
+ - WebSite #应用标签,可以有多个,请参照下方的标签列表
58
+ shortDescZh: 强大易用的开源建站工具 #应用中文描述,不要超过30个字
59
+ shortDescEn: Powerful and easy-to-use open source website builder #应用英文描述
60
+ type: website #应用类型,区别于应用分类,只能有一个,请参照下方的类型列表
61
+ crossVersionUpdate: true #是否可以跨大版本升级
62
+ limit: 0 #应用安装数量限制,0 代表无限制
63
+ website: https://halo.run/ #官网地址
64
+ github: https://github.com/halo-dev/halo #github 地址
65
+ document: https://docs.halo.run/ #文档地址
66
+ ```
67
+ 应用标签 - tags 字段(持续更新。。。)
68
+
69
+ | key | name |
70
+ | ---- | ---- |
71
+ | WebSite | 建站 |
72
+ | Server | Web 服务器 |
73
+ | Runtime | 运行环境 |
74
+ | Database | 数据库 |
75
+ | Tool | 工具 |
76
+ | CI/CD | CI/CD |
77
+ | Local | 本地 |
78
+
79
+ 应用类型 - type 字段
80
+
81
+ | type | 说明 |
82
+ | ---- | ---- |
83
+ | website | website 类型在 1Panel 中支持在网站中一键部署,wordpress halo 都是此 type |
84
+ | runtime | mysql openresty redis 等类型的应用 |
85
+ | tool | phpMyAdmin redis-commander jenkins 等类型的应用 |
86
+
87
+ 应用参数配置文件 data.yml (注意区分于应用主目录下面的 data.yaml)
88
+ > 本文件主要用于生成安装时要填写的 form 表单,在应用版本文件夹下面
89
+ > 可以无表单,但是需要有这个 data.yml文件,并且包含 formFields 字段
90
+
91
+ 以安装 halo 时的 form 表单 为例
92
+
93
+ <img width="754" alt="iShot_2023-03-18_14 03 43" src="https://user-images.githubusercontent.com/31820853/226111412-9c7b25a1-83f2-4621-8789-7ef85a2695dd.png">
94
+
95
+ 如果要生成上面的表单,需要这么填写 data.yml
96
+ ```
97
+ additionalProperties: #固定参数
98
+ formFields:
99
+ - default: ""
100
+ envKey: PANEL_DB_HOST #docker-compose 文件中的参数
101
+ key: mysql #依赖应用的 key , 例如 mysql
102
+ labelEn: Database Service #英文的label
103
+ labelZh: 数据库服务 #中文的label
104
+ required: true #是否必填
105
+ type: service #如果需要依赖其他应用,例如数据库,使用此 type
106
+ - default: halo
107
+ envKey: PANEL_DB_NAME
108
+ labelEn: Database
109
+ labelZh: 数据库名
110
+ random: true #是否在 default 文字后面,增加随机字符串
111
+ required: true
112
+ rule: paramCommon #校验规则
113
+ type: text #需要手动填写的,使用此 type
114
+ - default: halo
115
+ envKey: PANEL_DB_USER
116
+ labelEn: User
117
+ labelZh: 数据库用户
118
+ random: true
119
+ required: true
120
+ rule: paramCommon
121
+ type: text
122
+ - default: halo
123
+ envKey: PANEL_DB_USER_PASSWORD
124
+ labelEn: Password
125
+ labelZh: 数据库用户密码
126
+ random: true
127
+ required: true
128
+ rule: paramComplexity
129
+ type: password #密码字段使用此 type
130
+ - default: admin
131
+ envKey: HALO_ADMIN
132
+ labelEn: Admin Username
133
+ labelZh: 超级管理员用户名
134
+ required: true
135
+ rule: paramCommon
136
+ type: text
137
+ - default: halo
138
+ envKey: HALO_ADMIN_PASSWORD
139
+ labelEn: Admin Password
140
+ labelZh: 超级管理员密码
141
+ random: true
142
+ required: true
143
+ rule: paramComplexity
144
+ type: password
145
+ - default: http://localhost:8080
146
+ edit: true
147
+ envKey: HALO_EXTERNAL_URL
148
+ labelEn: External URL
149
+ labelZh: 外部访问地址
150
+ required: true
151
+ rule: paramExtUrl
152
+ type: text
153
+ - default: 8080
154
+ edit: true
155
+ envKey: PANEL_APP_PORT_HTTP
156
+ labelEn: Port
157
+ labelZh: 端口
158
+ required: true
159
+ rule: paramPort
160
+ type: number #端口使用此 type
161
+ ```
162
+ 关于端口字段:
163
+ 1. PANEL_APP_PORT_HTTP 有 web 访问端口的优先使用此 envKey
164
+ 2. envKey 中包含 PANEL_APP_PORT 前缀会被认定为端口类型,并且用于安装前的端口占用校验。注意:端口需要是外部端口
165
+
166
+ 关于 type 字段:
167
+ | type | 说明 |
168
+ | -------- | ---------------------------------------------------------------------------------------------------------------------------------- |
169
+ | service | `type: service` 如果该应用需要依赖其他组件,如 mysql redis 等,可以通过 `key: mysql` 定义依赖的名称,在创建应用时会要求先创建依赖的应用。 |
170
+ | password | `type: password` 敏感信息,如密码相关的字段会默认不显示明文。 |
171
+ | text | `type: text` 一般内容,比如数据库名称,默认明文显示。 |
172
+ | number | `type: number` 一般用在端口相关的配置上,只允许输入数字。 |
173
+ | select | `type: select` 选项,比如 `true`, `false`,日志等级等。 |
174
+
175
+ 简单的例子
176
+ ```
177
+ # type: service,定义一个 mysql 的 service 依赖。
178
+ - default: ""
179
+ envKey: DB_HOST
180
+ key: mysql
181
+ labelEn: Database Service
182
+ labelZh: 数据库服务
183
+ required: true
184
+ type: service
185
+
186
+ # type: password
187
+ - default: Np2qgqtiUayA857GpuVI0Wtg
188
+ edit: true
189
+ envKey: DB_PASSWORD
190
+ labelEn: Database password
191
+ labelZh: 数据库密码
192
+ required: true
193
+ type: password
194
+
195
+ # type: text
196
+ - default: 192.168.100.100
197
+ disabled: true.
198
+ envKey: REDIS_HOST
199
+ labelEn: Redis host
200
+ labelZh: Redis 主机
201
+ type: text
202
+
203
+ # type: number
204
+ - default: 3306
205
+ disabled: true
206
+ envKey: DB_PORT
207
+ labelEn: Database port
208
+ labelZh: 数据库端口
209
+ rule: paramPort
210
+ type: number
211
+
212
+ # type: select
213
+ - default: "ERROR"
214
+ envKey: LOG_LEVEL
215
+ labelEn: Log level
216
+ labelZh: 日志级别
217
+ required: true
218
+ type: select
219
+ values:
220
+ - label: DEBUG
221
+ value: "DEBUG"
222
+ - label: INFO
223
+ value: "INFO"
224
+ - label: WARNING
225
+ value: "WARNING"
226
+ - label: ERROR
227
+ value: "ERROR"
228
+ - label: CRITICAL
229
+ value: "CRITICAL"
230
+ ```
231
+
232
+
233
+
234
+ rule 字段目前支持的几种校验
235
+ | rule | 规则 |
236
+ | ---- | ---- |
237
+ | paramPort | 用于限制端口范围为 1-65535 |
238
+ | paramExtUrl | 格式为 http(s)://(域名/ip):(端口) |
239
+ | paramCommon | 英文、数字、.-和_,长度2-30 |
240
+ | paramComplexity | 支持英文、数字、.%@$!&~_-,长度6-30,特殊字符不能在首尾 |
241
+
242
+ 应用 docker-compose.yml 文件
243
+ > ${PANEL_APP_PORT_HTTP} 类型的参数,都在 data.yml 中有声明
244
+ ```
245
+ version: "3"
246
+ services:
247
+ halo:
248
+ image: halohub/halo:2.2.0
249
+ container_name: ${CONTAINER_NAME} // 固定写法,勿改
250
+ restart: always
251
+ networks:
252
+ - 1panel-network // 1Panel 创建的应用都在此网络下
253
+ volumes:
254
+ - ./data:/root/.halo2
255
+ ports:
256
+ - ${PANEL_APP_PORT_HTTP}:8090
257
+ command:
258
+ - --spring.r2dbc.url=r2dbc:pool:${HALO_PLATFORM}://${PANEL_DB_HOST}:${HALO_DB_PORT}/${PANEL_DB_NAME}
259
+ - --spring.r2dbc.username=${PANEL_DB_USER}
260
+ - --spring.r2dbc.password=${PANEL_DB_USER_PASSWORD}
261
+ - --spring.sql.init.platform=${HALO_PLATFORM}
262
+ - --halo.external-url=${HALO_EXTERNAL_URL}
263
+ - --halo.security.initializer.superadminusername=${HALO_ADMIN}
264
+ - --halo.security.initializer.superadminpassword=${HALO_ADMIN_PASSWORD}
265
+ labels:
266
+ createdBy: "Apps"
267
+
268
+ networks:
269
+ 1panel-network:
270
+ external: true
271
+ ```
272
+
273
+ ## 5. 脚本
274
+ 1Panel 在 安装之前、升级之前、卸载之后支持执行 .sh 脚本
275
+ 分别对应 init.sh upgrade.sh uninstall.sh
276
+ 存放目录(以halo为例) : halo/2.2.0/scripts
277
+
278
+
279
+ ## 6. 本地测试
280
+ 将应用目录上传到 1Panel 的 /opt/1panel/resource/apps/local 文件夹下
281
+ 注意:/opt 为 1Panel 默认安装目录,请根据自己的实际情况修改
282
+ 上传完成后,目录结构如下
283
+
284
+ ```
285
+ ├──halo
286
+ ├── logo.png
287
+ ├── data.yml
288
+ ├── README.md
289
+ ├── 2.2.0
290
+    ├── data.yml
291
+    ├── data
292
+    └── docker-compose.yml
293
+ ```
294
+ 在 1Panel 应用商店中,点击更新应用列表按钮同步本地应用
295
+
296
+ > v1.2 版本及之前版本的本地应用,请参考[这个文档](https://github.com/1Panel-dev/appstore/wiki/v1.2-%E7%89%88%E6%9C%AC%E6%9C%AC%E5%9C%B0%E5%BA%94%E7%94%A8%E5%8D%87%E7%BA%A7%E6%8C%87%E5%8D%97)修改
297
+
298
+ ## 7. 提交文件
299
+
300
+ ```
301
+ git add .
302
+ git commit -m "Add my-app"
303
+ git push origin dev
304
+ ```
305
+
306
+ ## 8. 提交 Pull Request
307
+
308
+ - 在你的仓库点击 Pull requests 菜单
309
+ - 点击 New pull request ,填写标题和描述
310
+ - 选择由你的分支提交到 1Panel-dev/appstore