2026-03-24 19:00:47 +08:00
---
name: 1panel-app-builder
description: >
Build 1Panel local app store configurations from Docker deployments. Use when:
- User provides a GitHub project link and wants to add it to 1Panel app store
- User has a docker-compose.yml or docker run command and needs 1Panel app format
- User wants to create a local app for 1Panel panel
- User mentions "1Panel app", "1Panel 应用商店", "本地应用", "app store", or similar
Supports: GitHub repos, Docker Hub images, docker-compose files, docker run commands.
Output: Complete app folder with data.yml, docker-compose.yml, logo.png, README.md
Always use this skill for 1Panel app packaging - it knows the exact directory structure,
variable naming conventions (PANEL_APP_PORT_HTTP, CONTAINER_NAME), and 1panel-network
requirements that are easy to get wrong without guidance.
---
# 1Panel App Store Builder
Transform Docker deployments into 1Panel-compatible local app store packages.
## Understanding 1Panel App Structure
A valid 1Panel app follows this directory structure:
```
app-key/ # App identifier (lowercase, hyphenated)
├── logo.png # App icon (64x64 or 128x128 recommended)
├── data.yml # App metadata (top-level)
├── README.md # Chinese documentation
├── README_en.md # English documentation (optional)
└── 1.0.0/ # Version directory (semver or "latest")
├── data.yml # Parameter definitions (form fields)
├── docker-compose.yml # Compose file with variable substitution
├── data/ # Persistent data directory
└── scripts/ # Optional scripts
└── upgrade.sh # Upgrade script
```
## Step-by-Step Workflow
### Step 1: Gather Source Information
Based on user input type, extract Docker deployment details:
**From GitHub Link:**
1. Fetch the GitHub repository README.md
2. Look for Docker installation instructions (docker run, docker-compose)
3. Extract: image name, ports, volumes, environment variables
4. Note: project name, description, official website, supported architectures
**From docker-compose.yml:**
1. Parse all services defined
2. Extract: image versions, port mappings, volume mounts, environment variables
3. Identify the main service (typically the one with web UI)
**From docker run command:**
1. Parse flags: `-p` (ports), `-v` (volumes), `-e` (env vars), `--name`
2. Extract the image name and tag
3. Identify exposed ports and data directories
2026-04-01 18:41:10 +08:00
### Step 2: Resolve Latest Version (Create Version + latest)
Always create **two ** version directories when possible:
- `latest/` uses image tag `latest`
- `<version>/` uses the **latest concrete tag ** from the registry
**How to resolve the latest concrete tag:**
1. If the image is on **GitHub Container Registry ** (`ghcr.io` ), query tags from GitHub Packages (GHCR).
2. Otherwise, query **Docker Hub ** tags.
3. Prefer the newest semver-like tag (e.g., `v1.2.3` or `1.2.3` ). If none exist, pick the most recently updated non-`latest` tag.
4. If you cannot resolve a concrete tag, fall back to the image tag from input and warn the user.
**Rule:** The `latest/` directory must **always ** use `image: ...:latest` . The `<version>/` directory must **always ** use `image: ...:<version>` .
### Step 3: Generate App Key and Metadata
2026-03-24 19:00:47 +08:00
**App Key Rules:**
- Lowercase only
- Use hyphens for multi-word names
- Keep it short but descriptive
- Examples: `alist` , `it-tools` , `n8n-zh` , `lobe-chat-data`
**Required Metadata (top-level data.yml):**
```yaml
name: AppName # Display name (can have capitals)
tags: # Chinese tags for categorization
- 开发工具
- 实用工具
title: Brief Chinese description
description: Same as title
additionalProperties:
key: app-key # Must match directory name
name: AppName # Same as name above
tags: # English tags
- DevTool
- Utility
shortDescZh: Chinese description
shortDescEn: English description
description:
en: Full English description
zh: Full Chinese description
# Add more languages if available: ja, ko, ru, pt-br, ms, zh-Hant
type: website # or "runtime" for databases, "tool" for CLI tools
crossVersionUpdate: true # Usually true
limit: 0 # 0 = unlimited instances
recommend: 0 # 0-100, higher = more recommended
website: https://example.com # Official website
github: https://github.com/org/repo
document: https://docs.example.com
architectures: # Supported CPU architectures
- amd64
- arm64
# Add: arm/v7, arm/v6, s390x if supported
```
2026-04-01 18:41:10 +08:00
### Step 4: Define Parameters (version/data.yml)
2026-03-24 19:00:47 +08:00
Parameters become UI form fields in 1Panel. Define user-configurable values:
```yaml
additionalProperties:
formFields:
# Port parameter example
- default: 8080
edit: true
envKey: PANEL_APP_PORT_HTTP # Variable name used in docker-compose
labelEn: Web Port
labelZh: Web端口
required: true
rule: paramPort # Validation rule
type: number # Field type
label: # Multi-language labels
en: Web Port
zh: Web端口
ja: Webポート
ko: Web 포트
# Text parameter example (for API keys, passwords, etc.)
- default: ""
edit: true
envKey: API_KEY
labelEn: API Key
labelZh: API密钥
required: false
rule: paramCommon
type: text
# Password parameter example
- default: "changeme"
edit: true
envKey: ADMIN_PASSWORD
labelEn: Admin Password
labelZh: 管理员密码
required: true
rule: paramCommon
type: password
# Select parameter example
- default: "sqlite"
edit: true
envKey: DATABASE_TYPE
labelEn: Database Type
labelZh: 数据库类型
required: true
type: select
values:
- label: SQLite
value: sqlite
- label: PostgreSQL
value: postgres
```
**Parameter Types:**
- `number` : For ports, counts
- `text` : For API keys, URLs, names
- `password` : For secrets (masked input)
- `select` : For dropdown choices
- `boolean` : For toggle switches
**Validation Rules:**
- `paramPort` : Valid port number (1-65535)
- `paramCommon` : Non-empty string
- `paramExtUrl` : Valid URL format
- Empty string: No validation
2026-04-01 18:41:10 +08:00
### Port envKey Naming (Use 1Panel Standard Names)
Prefer these **standard ** `envKey` names (observed across apps in `apps/` ):
- `PANEL_APP_PORT_HTTP` (primary Web/UI port)
- `PANEL_APP_PORT_HTTPS`
- `PANEL_APP_PORT_API`
- `PANEL_APP_PORT_ADMIN`
- `PANEL_APP_PORT_PROXY`
- `PANEL_APP_PORT_PROXY_HTTP`
- `PANEL_APP_PORT_PROXY_HTTPS`
- `PANEL_APP_PORT_DB`
- `PANEL_APP_PORT_SSH`
- `PANEL_APP_PORT_S3`
- `PANEL_APP_PORT_SYNC`
**Guideline:** Use the most semantically correct name first; only invent new suffixes if none of the standard names fit.
### Step 5: Create docker-compose.yml
2026-03-24 19:00:47 +08:00
Convert the original Docker deployment to use variable substitution:
```yaml
services:
app-name:
container_name: ${CONTAINER_NAME}
restart: always
networks:
- 1panel-network
ports:
- "${PANEL_APP_PORT_HTTP}:8080"
volumes:
- ./data:/app/data
environment:
- TZ=Asia/Shanghai
image: org/image:tag
labels:
createdBy: "Apps"
networks:
1panel-network:
external: true
```
**Critical Rules:**
1. Always use `${CONTAINER_NAME}` for container_name
2. Always use `restart: always`
3. Always connect to `1panel-network` (external network)
2026-04-01 18:41:10 +08:00
4. Port mapping uses `PANEL_APP_PORT_*` variables from version/data.yml
2026-03-24 19:00:47 +08:00
5. Volume paths use relative `./data/` for persistence
6. Add `labels: createdBy: "Apps"`
7. Keep original environment variables but use defaults
2026-04-01 18:41:10 +08:00
**Port Mapping Format (Important):**
Use quoted mappings like:
```
- "${PANEL_APP_PORT_HTTP}:8080"
```
and ensure the same `envKey` exists in `version/data.yml` .
### Step 6: Create README Files
2026-03-24 19:00:47 +08:00
**README.md (Chinese):**
```markdown
# AppName
简短描述应用的功能和特点。
## 功能特点
- 特点1
- 特点2
- 特点3
## 使用说明
### 默认端口
- Web界面: 8080
### 默认账号密码
- 用户名: admin
- 密码: changeme (请在部署后立即修改)
### 数据目录
应用数据存储在 `./data` 目录。
## 相关链接
- 官方网站: https://example.com
- GitHub: https://github.com/org/repo
- 文档: https://docs.example.com
```
**README_en.md (English, optional):**
```markdown
# AppName
Brief description of the application.
## Features
- Feature 1
- Feature 2
- Feature 3
## Usage
### Default Port
- Web UI: 8080
### Default Credentials
- Username: admin
- Password: changeme (change after deployment)
## Links
- Website: https://example.com
- GitHub: https://github.com/org/repo
```
2026-04-01 18:41:10 +08:00
### Step 7: Download App Icon
2026-03-24 19:00:47 +08:00
2026-04-01 18:41:10 +08:00
**Priority order:**
1. **Search the GitHub repository ** for common icon files (e.g., `logo.png` , `icon.png` , `assets/logo.png` , `.github/icon.png` ). Use the repo's raw download URL if found.
2. If not found, search and download the app logo from these sources (in order):
2026-03-24 19:00:47 +08:00
1. **Dashboard Icons ** : https://dashboardicons.com/icons?q={app-name}
2. **Simple Icons ** : https://simpleicons.org/?q={app-name}
3. **Selfh.st Icons ** : https://selfh.st/icons/
2026-04-01 18:41:10 +08:00
**Do not** create a placeholder or incorrect icon. If not found, warn and leave `logo.png` for manual replacement.
2026-03-24 19:00:47 +08:00
2026-04-01 18:41:10 +08:00
### Step 8: Create Data Directory Structure
2026-03-24 19:00:47 +08:00
Create the `data/` directory inside the version folder:
```bash
mkdir -p app-key/version/data
```
This directory will be mounted as a volume for persistent data.
## Quality Checklist
Before delivering the app package, verify:
- [ ] App key is lowercase with hyphens only
- [ ] All required fields in top-level data.yml are present
2026-04-01 18:41:10 +08:00
- [ ] `latest/` and `<version>/` directories both exist (when a concrete tag is resolvable)
- [ ] `latest/` uses image tag `latest`
- [ ] `<version>/` uses the concrete latest tag from registry
- [ ] Version data.yml has proper parameter definitions (formFields)
2026-03-24 19:00:47 +08:00
- [ ] docker-compose.yml uses variable substitution correctly
- [ ] `1panel-network` is defined as external network
- [ ] Volume paths use relative `./data/` format
- [ ] README files are created with proper documentation
- [ ] Logo file exists (logo.png)
2026-04-01 18:41:10 +08:00
- [ ] Version directory follows semver; avoid only `latest`
2026-03-24 19:00:47 +08:00
## Common Patterns
### Database Applications
```yaml
# For apps that need a database (PostgreSQL, MySQL, etc.)
# Include database as a separate service in docker-compose
services:
app:
depends_on:
- db
db:
image: postgres:15
volumes:
- ./data/db:/var/lib/postgresql/data
environment:
- POSTGRES_DB=appdb
- POSTGRES_USER=appuser
- POSTGRES_PASSWORD=${DB_PASSWORD}
```
### Multi-Service Applications
```yaml
# For apps with multiple services (frontend + backend, etc.)
services:
frontend:
image: org/frontend:tag
ports:
- "${PANEL_APP_PORT_HTTP}:80"
backend:
image: org/backend:tag
ports:
- "${PANEL_APP_PORT_API}:8080"
```
### Applications with Reverse Proxy
```yaml
# For apps that don't expose ports directly
services:
app:
# No ports section - accessed through 1Panel's reverse proxy
expose:
- "8080"
networks:
- 1panel-network
```
## Automation Scripts
Use the provided scripts for faster workflow:
### generate-app.sh - 自动生成应用配置
```bash
# GitHub 项目
./scripts/generate-app.sh https://github.com/alist-org/alist
# docker-compose 文件
./scripts/generate-app.sh ./docker-compose.yml
# docker run 命令
./scripts/generate-app.sh "docker run -d --name=nginx -p 80:80 nginx:latest"
```
### download-icon.sh - 下载应用图标
```bash
./scripts/download-icon.sh redis ./logo.png 200
```
### validate-app.sh - 验证配置完整性
```bash
./scripts/validate-app.sh ./apps/myapp
```
## Reference Files
- `references/1panel-examples.md` - 完整的真实应用配置示例( AList、NocoDB等)
- `examples/example-usage.md` - 使用示例和工作流程
## Troubleshooting
**Issue**: App won't start
- Check if ports are already in use
- Verify volume permissions
- Check container logs: `docker logs ${CONTAINER_NAME}`
**Issue**: Data not persisting
- Ensure volumes are correctly mapped to `./data/`
- Check directory permissions
**Issue**: Environment variables not working
- Verify variable names match between data.yml and docker-compose.yml
- Check default values are appropriate
**Issue**: 图标下载失败
- 从以下网站手动下载:
- https://dashboardicons.com/icons?q={app-name}
- https://simpleicons.org/?q={app-name}
- https://selfh.st/icons/