Mikuの鬆

Mikuの鬆

心有多宽,世界就有多远

編寫1Panel應用商店第三方程序

前言#

1Panel 是我目前在使用的伺服器管理面板,它的社區版開源且免費,整體面板設計簡潔快速,不需要登入,在基本體驗上似乎是比隔壁寶塔要強一些。

不過他被很多小白和部分用戶不喜愛的原因是它的應用是通過 Docker 容器化進行部署的。

採用 Docker 部署的壞處是應用整體記憶體佔用會略高一些,而且配置容器組網是勸退很多小白的原因,配置不好,應用連不上資料庫,網站反代不對等等。

但是 Docker 容器化部署的好處也是不少的,比如沒有構建應用這一步,就使得應用在拉取完畢鏡像以後即刻就能啟動,就跟二進制應用文件差不多的感覺,不需要等上很久,也不需要太多伺服器性能用於構建,在部署 Node.js 應用時效果尤為顯著。而且配置文件簡單,只需要了解 Docker Compose 配置文件格式就能上手,整體體驗對於大規模部署是很好的。

當然 1Panel 也是知道小白們可能玩不明白 Docker 的,所以它還有應用商店,裡面都是預先寫好的 Docker Compose 文件模板,點擊安裝就能夠一鍵部署,並且都自動為你做好網路設置,同時你還可以設計自己的應用上傳到伺服器,也可以一鍵安裝,這樣就出現了 1Panel 官方應用商店和第三方應用商店的儲存庫,只需要拉取倉庫到伺服器就能暢享海量應用。

實際上 1Panel 應用的結構很簡單,只需要幾個文件,就能夠設計好你想部署的應用,今天我也來簡單講一下如何設計這個應用。

注意#

值得注意的事情是,1Panel 應用商店的本質其實就是一個個 Docker Compose 編排文件的圖形體現,所以實際上需要你的應用有公共可訪問的 Docker 鏡像才能正常使用。

格式#

初始化模板#

1panel 1.3及以上版本開始,可以在安裝了 1Panel 的伺服器使用1panel app init <應用的key> <應用的版本> 指令來快速初始化應用模板文件(注意不是 1pctl 命令)

文件夾格式#

應用的文件夾格式大概是長下面這個樣子:

├──halo // 承載應用的文件夾,這裡以halo為例
	├── logo.png // 應用的 logo
	├── data.yml // 應用聲明文件
	├── README.md // 應用的 README 文件
	├── 2.2.0 // 應用版本 注意不要以 v 開頭
	│   ├── data.yml // 應用的參數配置,下面有詳細介紹
	│   ├── data // 掛載出來的目錄 
	|   ├── scripts // 腳本目錄 存放 init.sh upgrade.sh uninstall.sh
	│   └── docker-compose.yml // docker-compose 文件
	└── 2.3.2
	    ├── data.yml
	    ├── data
	    └── docker-compose.yml 

用於在應用概覽和應用詳情頁面展示,應用的 Logo 為 png 格式,長寬比最好是180 * 180 px,把它放在應用的根目錄下,例如/halo/logo.png,不要使用諸如 webp,jpg,svg 這樣的格式。

應用聲明文件#

聲明你的應用的基本信息,讓 1Panel 知道你的應用的一些基本信息,比如叫什麼名字,幹什麼用的等等,是位於應用根目錄下的data.yml文件,格式差不多如下:

# 下邊這一部分推薦填寫,雖然 1Panel 的應用商店官方 Wiki 沒有聲明它到底有何用
name: Halo
tags:
  - 建站
title: 強大易用的開源建站工具
type: 建站
description: 強大易用的開源建站工具
# 下邊這一部分為應用聲明信息部分,注意填寫正確!
additionalProperties:  #固定參數
    key: halo   #應用的 key,仅限英文,用於在 Linux 創建文件夾
    name: Halo  #應用名稱
    tags:  
        - WebSite #應用標籤,可以有多個,請參照標籤列表 
    shortDescZh: 強大易用的開源建站工具 #應用中文描述,不要超過 30 個字
    shortDescEn: Powerful and easy-to-use open source website builder #應用英文描述 
    type: website  #應用類型,區別於應用分類,只能有一個,請參照下方的類型列表
    crossVersionUpdate: true  #是否可以跨大版本升級
    limit: 0  #應用安裝數量限制,0 代表無限制
    website: https://halo.run/  #應用的官網地址
    github: https://github.com/halo-dev/halo #應用 GitHub 的倉庫地址 
    document: https://docs.halo.run/ #應用的文檔地址

我們對必填應用聲明信息部分從上往下進行詳細的介紹:

key#

諸如 halo 這樣的名字,它其實就是你應用文件夾的名字,注意此處一定要與應用文件夾的名字保持一致,不然會導致應用無法正常部署安裝。

name#

應用的名稱部分,用於 1Panel 商店列表中展示和應用詳情上方展示,填寫好了能提高應用的辨認度。

tags#

應用的標籤,決定了應用在應用商店所屬的分類,可以填寫多個。

標籤列表和其對應的分類如下:

所属分類所属分類所属分類
WebSite建站Storage雲存儲Email郵件服務
ServerWeb 伺服器AIAI / 大模型Game休閒遊戲
Runtime運行環境BIBI
Database資料庫Security安全
Tool實用工具DevTool開發工具
DevOpsDevOpsMiddleware中間件
Local本地Media多媒體

shortDescZh/En#

應用的中文 / 英文描述,用於應用在應用商店列表中和應用詳情頁上方快速介紹應用,不要太長(中文不超過 30 字)

type#

應用的用途分類,這裡主要決定了 1Panel 會怎麼對待你的應用,比如website類型的可以在其網站功能中一鍵進行反代和分配域名。

說明
websitewebsite 即網站應用程序類型,支持在網站中一鍵部署和反代,WordPress 和 Halo 都是此 type
runtimemysql openresty redis 等類型的應用,傾向於應用的關鍵運行環境
toolphpMyAdmin redis-commander jenkins 等類型的應用,傾向於應用的維護工具等

crossVersionUpdate#

決定了應用是否可以跨大版本進行升級,一般來說都可以吧。

limit#

決定了這個應用最多能部署多少個,一般為0無限制,但是有些應用它確實不能重複安裝,比如 Openresty 這樣的反向代理服務。

website#

應用的官網地址,但不是所有應用都有官網地址,如果真沒有那就填寫應用的 GitHub 倉庫地址吧,本質上就是一個聯繫地址

github#

應用的 GitHub 倉庫地址,本質上提交到 1Panel 應用商店的應用都是開源應用,所以一般都有這麼個開源地址,你本地定制可以按情況來。

document#

應用的使用文檔地址,按需填寫吧,不是所有應用都有完善的使用文檔。

應用參數配置文件#

它也是data.yml,但是它在應用的版本號目錄下,注意不要和應用聲明文件搞混了。

本文件主要用於生成安裝時要填寫的 form 表單,在應用版本文件夾下面 可以無表單,但是需要有這個 data.yml 文件,並且包含 formFields 字段。
@1Panel 應用商店倉庫官方 Wiki

以 Halo 的 Form 表單為例:

Halo 安裝表單示例圖(來自 1Panel 官方應用商店倉庫)
如果要生成一個上面這樣子的表單,你需要這麼填寫應用參數配置文件(來自官方 Wiki 示例):

additionalProperties:  #固定參數
    formFields:  
        - default: ""  
          envKey: PANEL_DB_HOST  #docker-compose 文件中的參數
          key: mysql  #依賴應用的 key , 例如 mysql
		  labelEn: Database Service  #英文的 label
		  labelZh: 資料庫服務  #中文的 label
		  required: true  #是否必填
          type: service  #如果需要依賴其他應用,例如資料庫,使用此 type 
        - default: halo  
          envKey: PANEL_DB_NAME  
          labelEn: Database  
          labelZh: 資料庫名  
          random: true  #是否在 default 文字後面,增加隨機字符串
          required: true  
          rule: paramCommon  #校驗規則
          type: text  #需要手動填寫的,使用此 type
        - default: halo  
          envKey: PANEL_DB_USER  
          labelEn: User  
          labelZh: 資料庫用戶  
          random: true  
          required: true  
          rule: paramCommon  
          type: text  
        - default: halo  
          envKey: PANEL_DB_USER_PASSWORD  
          labelEn: Password  
          labelZh: 資料庫用戶密碼  
          random: true  
          required: true  
          rule: paramComplexity  
          type: password  #密碼字段使用此 type
        - default: admin  
          envKey: HALO_ADMIN  
          labelEn: Admin Username  
          labelZh: 超級管理員用戶名  
          required: true  
          rule: paramCommon  
          type: text  
        - default: halo  
          envKey: HALO_ADMIN_PASSWORD  
          labelEn: Admin Password  
          labelZh: 超級管理員密碼  
          random: true  
          required: true  
          rule: paramComplexity  
          type: password  
        - default: http://localhost:8080  
          edit: true  
          envKey: HALO_EXTERNAL_URL  
          labelEn: External URL  
          labelZh: 外部訪問地址  
          required: true  
          rule: paramExtUrl  
          type: text  
        - default: 8080  
          edit: true  
          envKey: PANEL_APP_PORT_HTTP  
          labelEn: Port  
          labelZh: 端口  
          required: true  
          rule: paramPort  
          type: number #端口使用此 type 

是不是看的眼暈了,我們這裡拆出來解釋下它這個東西:

		- default: ""  
		  envKey: PANEL_DB_HOST  #docker-compose 文件中的參數
          key: mysql  #依賴應用的 key , 例如 mysql
		  labelEn: Database Service  #英文的 label
		  labelZh: 資料庫服務  #中文的 label
		  required: true  #是否必填
          type: service  #如果需要依賴其他應用,例如資料庫,使用此 type 

dafault#

應用這個變數值的默認格式,填寫上什麼應用的設置變數默認就會填寫什麼東西,比如說你要設置這個應用的默認前端站點是example.com就在這裡這樣填寫上它,應用就會默認把example.com做前端默認站點值。

envKey#

對應了你的應用的 compose 編排文件中環境變數設置部分,比如environment下的值,但其實簡單點說就是會傳遞一個變數值給文件,比如HOST變數可以在 compose 文件中通過${HOST}來引用它,不難理解吧。

譬如在如下 Halo 例子中的引用:

services:  
  halo:  
    image: halohub/halo:2.2.0  
    container_name: ${CONTAINER_NAME} 
    restart: always  
    networks:  
      - 1panel-network
    volumes:  
      - ./data:/root/.halo2  
    ports:  
      - ${PANEL_APP_PORT_HTTP}:8090  
    command:  
      - --spring.r2dbc.url=r2dbc:pool:${HALO_PLATFORM}://${PANEL_DB_HOST}:${HALO_DB_PORT}/${PANEL_DB_NAME}  
      - --spring.r2dbc.username=${PANEL_DB_USER}  
      - --spring.r2dbc.password=${PANEL_DB_USER_PASSWORD}  
      - --spring.sql.init.platform=${HALO_PLATFORM}  
      - --halo.external-url=${HALO_EXTERNAL_URL}  
      - --halo.security.initializer.superadminusername=${HALO_ADMIN}  
      - --halo.security.initializer.superadminpassword=${HALO_ADMIN_PASSWORD}  
    labels:  
      createdBy: "Apps"  
  
networks:  
  1panel-network:  
    external: true

key#

這個雖然出現在了 1Panel 的官方 Wiki 示例中,但是似乎實際他們已經棄用這樣寫了,部分應用會依賴其他服務,比如 Halo 會有依賴 MySQL 資料庫,這個時候你就在這裡填寫上它就能去引用它,1Panel 給的這個例子有點舊,我們使用下面的格式來實現引用外部資料庫:

        - child:
            default: ""
            envKey: PANEL_DB_HOST
            required: true
            type: service
          default: mysql
          envKey: PANEL_DB_TYPE
          labelEn: Database Service
          labelZh: 資料庫服務
          required: true
          type: apps
          values:
            - label: MySQL
              value: mysql
            - label: MariaDB
              value: mariadb

這樣你就可以為你的應用接入選擇資料庫的方式了,但是我也不是很懂這個,實際寫起來直接 Ctrl+C 其他已實現接入外部資料庫的應用範例似乎是個好辦法。

labelEn/Zh#

這個我感覺並不需要過多的介紹,已經在上面寫的比較明白了,應用這個項的中英文描述。

required#

決定這個變數值是否是必填的,在它為true的情況下不填寫它是不能繼續安裝的,你可以視情況決定這個東西。

type#

看著似乎表格很明白但實際寫起來還是挺頭疼的東西,自己按表格查詢吧,我自己也對這個東西非常頭疼,差不多它的設定決定了你的應用這個設置變數只能填什麼東西。

說明
servicetype: service 如果該應用需要依賴其他組件,如 mysql redis 等,可以通過 key: mysql 定義依賴的名稱,在創建應用時會要求先創建依賴的應用。
passwordtype: password 敏感信息,如密碼相關的字段會默認不顯示明文。
texttype: text 一般內容,比如資料庫名稱,默認明文顯示。
numbertype: number 一般用在端口相關的配置上,只允許輸入數字。
selecttype: select 選項,比如 truefalse,日誌等級等。
通過官方給的下方的例子對照查詢了解:
# type: service,定義一個 mysql 的 service 依賴。
- default: ""  
    envKey: DB_HOST
    key: mysql
    labelEn: Database Service
    labelZh: 資料庫服務
    required: true
    type: service

# type: password
- default: Np2qgqtiUayA857GpuVI0Wtg
    edit: true
    envKey: DB_PASSWORD
    labelEn: Database password
    labelZh: 資料庫密碼
    required: true
    type: password

# type: text
- default: 192.168.100.100
    disabled: true.
    envKey: REDIS_HOST
    labelEn: Redis host
    labelZh: Redis 主機
    type: text

# type: number
- default: 3306
    disabled: true
    envKey: DB_PORT
    labelEn: Database port
    labelZh: 資料庫端口
    rule: paramPort
    type: number

# type: select
- default: "ERROR"
    envKey: LOG_LEVEL
    labelEn: Log level
    labelZh: 日誌級別
    required: true
    type: select
    values:
        - label: DEBUG
          value: "DEBUG"
        - label: INFO
          value: "INFO"
        - label: WARNING
          value: "WARNING"
        - label: ERROR
          value: "ERROR"
        - label: CRITICAL
          value: "CRITICAL"

rule#

在上面的例子中部分登場,主要是校驗用戶是否書寫這個東西的格式是正確的,比如防止某些用戶在端口設置這裡填寫域名的東西,這個rule就會強制這個填寫欄必須填寫什麼格式。

規則
paramPort用於限制端口範圍為 1-65535
paramExtUrl格式為 http (s)://(域名 /ip):(端口)
paramCommon英文、數字、.- 和_,長度 2-30
paramComplexity支持英文、數字、.%@$!&~_-, 長度 6-30,特殊字符不能在首尾

應用 Compose 文件#

位於應用版本號目錄下的docker-compose.yml文件,注意有格式要求,下面是示例

示例文件#

services:
  ghost:
    container_name: ${CONTAINER_NAME}
    restart: always
    networks:
      - 1panel-network
    ports:
      - "${PANEL_APP_PORT_HTTP}:2368"
    volumes:
      - ./data:/var/lib/ghost/content
    environment:
      - database__client=${PANEL_DB_TYPE}
      - database__connection__host=${PANEL_DB_HOST}
      - database__connection__user=${PANEL_DB_USER}
      - database__connection__password=${PANEL_DB_USER_PASSWORD}
      - database__connection__database=${PANEL_DB_NAME}
      - database__connection__port=${PANEL_DB_PORT}
      - url=${GHOST_EXTERNAL_URL}
    image: ghost:5.96.2
    labels:
      createdBy: "Apps"

networks:
  1panel-network:
    external: true

要求#

  • 頭部沒有version的變數,記得把它刪去。
  • 必須為應用定義container_name這個設置,且後面必須是${CONTAINER_NAME},這樣 1Panel 才能在安裝時對其正確配置。
  • 必須配置應用網路為1panel-network,這樣應用之間才能正常互聯,我在部分第三方應用商店庫發現它們不是很注重這個,當然這事也可以視情況而論,但是建議是都在 1Panel 官方網路下。
  • 端口ports這裡設置也是必須為其默認定義的${PANEL_APP_PORT_HTTP}:8090這樣的格式,這樣 1Panel 才能正確設置應用的開放端口
  • 文件尾部也必須跟示例文件一樣,填寫了networks配置,直接Ctrl+C過去就好。
  • 應用的image鏡像標籤必須和文件夾表示的版本號一致,比如這個版本號文件夾寫的是5.96.2,那麼其文件內部image標籤也必須那樣寫,不然會影響應用檢測和安裝更新!
  • 記得填寫上面的labels標籤,直接Ctrl+C過去就行,當然這也不算必填項,只是一種規範罷了。
  • 記得為應用定義重啟相關,比如always等等,這樣保證應用在遇到問題後可以恢復(雾)

腳本#

介紹#

1Panel 在 安裝之前、升級之前、卸載之後支持執行 .sh 腳本
分別對應 init.sh upgrade.sh uninstall.sh
存放目錄 (以 halo 為例) : halo/2.2.0/scripts

本地測試#

我十分建議你發布前先在自己已安裝 1Panel 的伺服器上進行測試,確定它是否可以正常安裝

將應用目錄上傳到 1Panel 的/opt/1panel/resource/apps/local文件夾下
注意:/opt 為 1Panel 默認安裝目錄,請根據自己的實際情況修改
上傳完成後,目錄結構如下:

├──halo 
	├── logo.png 
	├── data.yml
	├── README.md 
	├── 2.2.0 
	    ├── data.yml 
	    ├── data  
	    └── docker-compose.yml

在 1Panel 應用商店中,點擊更新應用列表按鈕同步本地應用。

收尾#

測試正常後,你就可以去提交官方庫或者第三方應用商店庫了,或者你自己用,都可以,不過我還是建議你本著分享精神,把它提交到官方或其他第三方應用商店倉庫裡去。

官方的要求和拒絕率比較高,一般來說提交第三方倉庫也挺好的,這裡列舉目前個人已知倉庫:

  • AuroraStarTeam/1panel-app-store,由我所屬個人組織極光星進行維護,理念是乾淨整潔,但是個人經驗可能不夠豐富。
  • okxlin/appstore,流行和最早的第三方商店庫,應用很多,但是也很亂。

參考文檔:#

此文由 Mix Space 同步更新至 xLog
原始鏈接為 https://www.sotkg.com/posts/site/1panel-appstore-main


載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。