制作应用模板
学习如何编写应用模板,定义元信息、输入项、工作负载、服务暴露与在线调试流程。
模板文件通常长什么样
Sealos 应用模板通常用一个 template.yaml 文件描述,它既包含模板元信息,也包含实际部署所需的 Kubernetes 资源。
一个常见模板会包含这些部分:
Template:定义模板名称、图标、描述、分类和输入项StatefulSet或其他工作负载资源:定义应用实例如何运行Service:定义集群内访问方式Ingress:定义对外访问入口App:定义 Sealos 控制台里的应用展示信息
先看一个完整示例
下面这份 template.yaml 适合作为起点。你不需要一开始理解每一行,但应该先建立“模板由哪些资源组成”的整体认知。
template.yaml
# Sealos Application Template Reference
#
# This file serves as a template reference for creating Sealos application templates.
# Copy this file and customize it for your application.
#
# Required fields are marked with [REQUIRED]
# Fill in the placeholders with your application-specific information.
---
apiVersion: app.sealos.io/v1
kind: Template
metadata:
name: myapp-template
spec:
# Application metadata
title: "" # [REQUIRED] Application display name
url: "" # [REQUIRED] Your app's official website
gitRepo: "" # [REQUIRED] Your app's GitHub repository URL
author: "" # [REQUIRED] Your name or organization
description: "" # [REQUIRED] Brief description of your app
readme: 'https://raw.githubusercontent.com/labring-actions/templates/main/template/<app-name>/README.md' # Update <app-name> with actual app name
icon: "" # [REQUIRED] URL to your app's icon
templateType: inline # Template type: inline (all resources in one file)
locale: en
i18n:
zh:
title: '应用标题' # Chinese title for your app
description: '应用描述' # Chinese description for your app
categories:
- tool # [REQUIRED] Choose from: ai, database, tool, low-code, blog, storage, frontend, backend, dev-ops, monitor, game
# Default values for template variables
defaults:
app_host:
type: string
value: myapp-${{ random(8) }} # Replace "myapp" with your app's name prefix
app_name:
type: string
value: myapp-${{ random(8) }} # Replace "myapp" with your app's name prefix
# User-configurable inputs (will be rendered as form fields)
inputs:
volume_size:
description: "Persistent storage size (GiB)"
type: string
default: "1"
required: false
# Add more inputs as needed, e.g.:
# - app_password:
# description: "Admin password"
# type: string
# required: true
---
# StatefulSet - Manages your application pods
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: ${{ defaults.app_name }}
annotations:
originImageName: "" # [REQUIRED] Your app's Docker image URL
deploy.cloud.sealos.io/minReplicas: "1"
deploy.cloud.sealos.io/maxReplicas: "1"
labels:
cloud.sealos.io/app-deploy-manager: ${{ defaults.app_name }}
app: ${{ defaults.app_name }}
spec:
replicas: 1
revisionHistoryLimit: 1
minReadySeconds: 10
serviceName: ${{ defaults.app_name }}
selector:
matchLabels:
app: ${{ defaults.app_name }}
template:
metadata:
labels:
app: ${{ defaults.app_name }}
spec:
terminationGracePeriodSeconds: 10
automountServiceAccountToken: false # Security: disable service account token mounting
containers:
- name: ${{ defaults.app_name }}
image: "" # [REQUIRED] Your app's Docker image URL
env: [] # Environment variables (add as needed)
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 1000m
memory: 1024Mi
command: [] # Override entrypoint if needed
args: [] # Command arguments
ports:
- containerPort: 80 # [REQUIRED] Your app's internal port
imagePullPolicy: IfNotPresent
volumeMounts:
- name: data-volume
mountPath: /app/data # Path where your app stores data
volumes: [] # Additional volumes (if any)
volumeClaimTemplates:
- metadata:
annotations:
path: /app/data # Path to store persistent data
value: "1"
name: data-volume
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: ${{ inputs.volume_size }}Gi
---
# Service - Exposes your application within the cluster
apiVersion: v1
kind: Service
metadata:
name: ${{ defaults.app_name }}
labels:
cloud.sealos.io/app-deploy-manager: ${{ defaults.app_name }}
spec:
ports:
- port: 80 # Service port (usually same as containerPort)
selector:
app: ${{ defaults.app_name }}
---
# Ingress - Exposes your application to the internet
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ${{ defaults.app_name }}
labels:
cloud.sealos.io/app-deploy-manager: ${{ defaults.app_name }}
cloud.sealos.io/app-deploy-manager-domain: ${{ defaults.app_host }}
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/proxy-body-size: 32m
nginx.ingress.kubernetes.io/server-snippet: |
client_header_buffer_size 64k;
large_client_header_buffers 4 128k;
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/backend-protocol: HTTP
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/client-body-buffer-size: 64k
nginx.ingress.kubernetes.io/proxy-buffer-size: 64k
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($request_uri ~* \.(js|css|gif|jpe?g|png)) {
expires 30d;
add_header Cache-Control "public";
}
spec:
rules:
- host: ${{ defaults.app_host }}.${{ SEALOS_CLOUD_DOMAIN }}
http:
paths:
- pathType: Prefix
path: /()(.*)
backend:
service:
name: ${{ defaults.app_name }}
port:
number: 80
tls:
- hosts:
- ${{ defaults.app_host }}.${{ SEALOS_CLOUD_DOMAIN }}
secretName: ${{ SEALOS_CERT_SECRET_NAME }}
---
# App - Application metadata for Sealos UI (must be the last resource)
apiVersion: app.sealos.io/v1
kind: App
metadata:
name: ${{ defaults.app_name }}
labels:
cloud.sealos.io/app-deploy-manager: ${{ defaults.app_name }}
spec:
data:
url: https://${{ defaults.app_host }}.${{ SEALOS_CLOUD_DOMAIN }}
displayType: normal
icon: "" # [REQUIRED] URL to your app's icon
name: "" # [REQUIRED] Application display name
type: link参数详解
1. Template 元信息
这部分决定模板在应用商店里如何展示。建议重点填清楚:
title:应用展示名称description:一句话说明用途icon:应用图标categories:分类,影响模板筛选和归档readme:建议提供完整安装说明和使用说明
如果这些信息写得太弱,模板即使可安装,后续也很难被团队稳定复用。
2. defaults 默认值
defaults 适合定义模板里内部要反复使用的变量,例如:
- 应用名
- 域名前缀
- 默认实例名
建议把会在多个资源间复用的值都提取出来,减少重复手改和命名不一致。
3. inputs 用户输入项
inputs 会在安装时渲染成表单,适合让用户填写:
- 存储大小
- 管理员密码
- 外部访问域名
- API Key 或初始化参数
并不是所有变量都应该暴露成输入项。只有“用户安装时确实需要决定”的部分,才值得放到 inputs。
4. 工作负载资源
示例里使用的是 StatefulSet,它适合需要稳定身份或持久化存储的应用。
如果你的应用只是简单无状态服务,也可以根据实际场景调整为更合适的工作负载类型。关键是:
- 镜像地址明确
- 端口暴露正确
- 启动命令和参数可控
- 持久化目录与存储声明一致
5. Service、Ingress 和 App
Service负责集群内访问Ingress负责对外访问和域名暴露App负责 Sealos 控制台中的应用展示与跳转入口
很多模板安装后“能跑但不好用”,问题往往不在镜像本身,而在这三部分没有对齐。
在线调试模板
写完模板后,不要直接发布,建议先走一轮在线调试。
在线调试路径
- 打开应用商店
- 进入
我的应用 - 打开目标应用的
在线调试 - 粘贴或修改
template.yaml - 点击
试运行部署 - 填写表单项并验证实例是否成功创建
- 确认访问入口、端口、存储和初始配置都正常后,再正式部署

如果试运行阶段就已经出现镜像拉取失败、端口不通或首页打不开,不要急着发版,先回到模板定义里修基础问题。
常见问题
为什么模板能部署但页面打不开
优先检查:
- 容器内部端口是否和
Service/Ingress一致 - 应用是否监听了正确地址,例如
0.0.0.0 - 路径重写和域名配置是否合理