Skip to main content
The meta.json file is the central configuration for each application in Apps Image. It defines how the application is tracked, versioned, and built into Docker images.

File Location

Each application has its own meta.json in its directory:
apps/icones/meta.json
apps/rayso/meta.json
base/nginx/meta.json

Basic Structure

Every meta.json follows this TypeScript interface (from action/src/types/schema.ts:115-136):
interface Meta {
  name: string                              // Required
  type: 'app' | 'base' | 'sync'            // Required
  title?: string
  slogan?: string
  description?: string
  license?: string
  context?: string
  readme?: string | boolean
  variants: Record<string, ImageVariant>    // Required
  skip?: boolean
}

Core Fields

name

Required | Type: string Application identifier used as the default Docker image name.
{
  "name": "icones"
}
Images will be published to:
  • aliuq/icones
  • ghcr.io/aliuq/icones

type

Required | Type: 'app' | 'base' | 'sync' Defines the image category:
  • app: End-user applications (icones, rayso, lsky)
  • base: Base images used by other images (nginx)
  • sync: Mirror images from other registries
{
  "type": "app"
}

title

Optional | Type: string Human-readable display name for the application.
// apps/icones/meta.json
{
  "name": "icones",
  "title": "Icones"
}

slogan

Optional | Type: string Brief tagline displayed in the catalog.
// apps/icones/meta.json
{
  "slogan": "开源图标浏览器,搜索浏览 150,000+ 图标"
}

description

Optional | Type: string Detailed description of the application. Used in Docker image labels.
// apps/icones/meta.json
{
  "description": "Icon Explorer with Instant searching, powered by Iconify"
}

license

Optional | Type: string SPDX license identifier. Included in Docker image labels.
{
  "license": "MIT"
}
Common values: MIT, Apache-2.0, GPL-3.0, AGPL-3.0

skip

Optional | Type: boolean | Default: false If true, the application will be excluded from version checks and builds.
{
  "skip": true
}

Variants Configuration

Required | Type: Record<string, ImageVariant> Defines one or more image variants. Each variant can track different versions or configurations.

ImageVariant Structure

// action/src/types/schema.ts:98-110
interface ImageVariant {
  version?: string
  sha?: string
  enabled?: boolean
  checkver: VersionCheck       // Required
  docker?: DockerConfig
}

Single Variant Example

// apps/icones/meta.json
{
  "name": "icones",
  "type": "app",
  "variants": {
    "latest": {
      "version": "0bc5918",
      "sha": "0bc59182623617a9238023c183a72863c0ebdfca",
      "checkver": {
        "type": "sha",
        "repo": "https://github.com/antfu-collective/icones"
      }
    }
  }
}

Multi-Variant Example

// apps/lsky/meta.json
{
  "name": "lsky",
  "type": "app",
  "variants": {
    "latest": {
      "version": "2.1",
      "sha": "923f567e0a93c7291c4c9fc5279da9847ed39f7e",
      "checkver": {
        "type": "tag",
        "repo": "https://github.com/lsky-org/lsky-pro"
      },
      "docker": {
        "tags": [
          "type=raw,value=latest",
          "type=raw,value={{version}}"
        ]
      }
    },
    "dev": {
      "version": "38d52c4",
      "sha": "38d52c4609eb85236b45ac75acac2ced55174953",
      "checkver": {
        "type": "sha",
        "repo": "https://github.com/lsky-org/lsky-pro"
      },
      "docker": {
        "tags": [
          "type=raw,value=dev",
          "type=raw,value=dev-{{sha}}"
        ]
      }
    }
  }
}
Each variant requires its own Dockerfile:
  • latestDockerfile
  • devDockerfile.dev
  • tlsDockerfile.tls

Version Check Configuration

VersionCheck Structure

// action/src/types/schema.ts:71-94
interface VersionCheck {
  type: 'version' | 'sha' | 'tag' | 'manual' | 'registry'  // Required
  repo?: string
  branch?: string
  file?: string
  path?: string
  regex?: string
  tagPattern?: string
  targetVersion?: string
  processFiles?: string[]
  checkFrequency?: 'always' | 'daily' | 'weekly' | 'manual'
  lastCheck?: string
}

Check Type: version

Tracks version from a file (typically package.json).
// apps/srcbook/meta.json
{
  "checkver": {
    "type": "version",
    "repo": "https://github.com/srcbookdev/srcbook",
    "file": "srcbook/package.json"
  }
}
With Custom Regex:
{
  "checkver": {
    "type": "version",
    "repo": "owner/repo",
    "file": "VERSION",
    "regex": "v([0-9.]+)"
  }
}
When file is package.json, the system automatically reads the version field. For other files, use regex to extract the version.

Check Type: sha

Tracks the latest commit SHA from a repository. Full Repository:
// apps/icones/meta.json
{
  "checkver": {
    "type": "sha",
    "repo": "https://github.com/antfu-collective/icones"
  }
}
Specific Path:
// apps/cobalt/meta.json (dev variant)
{
  "checkver": {
    "type": "sha",
    "repo": "https://github.com/imputnet/cobalt",
    "path": "web"
  }
}
With Branch:
// apps/weserv/meta.json
{
  "checkver": {
    "type": "sha",
    "repo": "weserv/images",
    "branch": "5.x"
  }
}
Repository URLs can be full (https://github.com/owner/repo) or shorthand (owner/repo). The system automatically converts shorthand to full URLs.

Check Type: tag

Tracks Git tags, automatically finding the latest semver tag. Basic Tag Tracking:
// apps/lsky/meta.json
{
  "checkver": {
    "type": "tag",
    "repo": "https://github.com/lsky-org/lsky-pro"
  }
}
The system finds the latest valid semver tag (e.g., v2.1, 2.1.0). With Pattern Matching:
{
  "checkver": {
    "type": "tag",
    "repo": "owner/repo",
    "tagPattern": "^v[0-9]+\\.[0-9]+\\.[0-9]+$"
  }
}

Check Type: manual

No automatic version checking. Requires manual updates to meta.json.
// base/nginx/meta.json
{
  "checkver": {
    "type": "manual"
  }
}
Use this for:
  • Base images that don’t track upstream
  • Images with custom versioning schemes
  • Images requiring manual testing before updates

Docker Configuration

DockerConfig Structure

// action/src/types/schema.ts:43-66
interface DockerConfig {
  file?: string
  images?: string[]
  tags?: string[]
  platforms?: Platform[]
  labels?: Record<string, string>
  buildArgs?: Record<string, string>
  secrets?: string[]
  outputs?: string[]
  cache?: CacheConfig
  push?: boolean
  load?: boolean
}

file

Optional | Type: string | Default: Auto-detected Dockerfile path relative to the application directory. Default behavior:
  • latest variant → Dockerfile
  • Other variants → Dockerfile.{variantName}
{
  "docker": {
    "file": "Dockerfile.custom"
  }
}

images

Optional | Type: string[] | Default: Auto-generated Docker image names to publish. Supports {{name}} placeholder. Default (from environment variables):
[
  "aliuq/{{name}}",
  "ghcr.io/aliuq/{{name}}",
  "registry.cn-hangzhou.aliyuncs.com/aliuq/{{name}}"
]
Custom Example:
{
  "docker": {
    "images": [
      "myuser/{{name}}",
      "ghcr.io/myuser/{{name}}"
    ]
  }
}

tags

Optional | Type: string[] | Default: Variant-based Image tags using docker/metadata-action format. Default for latest variant:
[
  "type=raw,value=latest",
  "type=raw,value={{version}}"
]
Available Placeholders:
  • {{version}} - Full version string (e.g., 2.1, 0bc5918)
  • {{sha}} - Short SHA (7 characters)
  • {{fullSha}} - Full SHA (40 characters)
  • {{major}} - Major version (e.g., 2 from 2.1.0)
  • {{minor}} - Minor version (e.g., 2.1 from 2.1.0)
  • {{patch}} - Patch version (e.g., 2.1.0)
Multi-Tag Example:
// apps/cobalt/meta.json (latest variant)
{
  "docker": {
    "tags": [
      "type=raw,value=latest",
      "type=raw,value={{version}}",
      "type=raw,value={{major}}"
    ]
  }
}
This creates tags: latest, 11.3, 11 Dev Variant Example:
// apps/lsky/meta.json (dev variant)
{
  "docker": {
    "tags": [
      "type=raw,value=dev",
      "type=raw,value=dev-{{sha}}"
    ]
  }
}
This creates tags: dev, dev-38d52c4

platforms

Optional | Type: Platform[] | Default: ["linux/amd64", "linux/arm64"] Target platforms for multi-architecture builds.
type Platform =
  | 'linux/amd64'
  | 'linux/arm64'
  | 'linux/arm/v7'
  | 'linux/arm/v6'
  | 'linux/386'
  | 'linux/ppc64le'
  | 'linux/s390x'
Example:
{
  "docker": {
    "platforms": ["linux/amd64", "linux/arm64", "linux/arm/v7"]
  }
}

buildArgs

Optional | Type: Record<string, string> Docker build arguments passed to the build.
{
  "docker": {
    "buildArgs": {
      "NODE_VERSION": "20",
      "BUILD_ENV": "production"
    }
  }
}
Used in Dockerfile:
ARG NODE_VERSION=18
FROM node:${NODE_VERSION}-alpine

ARG BUILD_ENV
ENV NODE_ENV=${BUILD_ENV}

labels

Optional | Type: Record<string, string> Custom Docker image labels. System labels are auto-generated: Auto-generated labels (action/src/context/metaAppContext.ts:143-151):
  • description - From meta.description
  • licenses - From meta.license
  • revision - Current SHA
  • source - Repository URL
  • title - From meta.title or meta.name
  • url - Repository or project URL
  • version - Current version
Custom labels:
{
  "docker": {
    "labels": {
      "org.opencontainers.image.authors": "[email protected]",
      "com.example.custom": "value"
    }
  }
}

Complete Examples

Simple Application

// apps/icones/meta.json
{
  "name": "icones",
  "type": "app",
  "title": "Icones",
  "slogan": "开源图标浏览器,搜索浏览 150,000+ 图标",
  "description": "Icon Explorer with Instant searching, powered by Iconify",
  "license": "MIT",
  "variants": {
    "latest": {
      "version": "0bc5918",
      "sha": "0bc59182623617a9238023c183a72863c0ebdfca",
      "checkver": {
        "type": "sha",
        "repo": "https://github.com/antfu-collective/icones"
      }
    }
  }
}

Multi-Variant Application

// apps/lsky/meta.json
{
  "name": "lsky",
  "type": "app",
  "title": "兰空图床",
  "slogan": "兰空图床,轻量级图片云存储系统",
  "description": "兰空图床(Lsky Pro) - Your photo album on the cloud.",
  "license": "GPL-3.0",
  "variants": {
    "latest": {
      "version": "2.1",
      "sha": "923f567e0a93c7291c4c9fc5279da9847ed39f7e",
      "checkver": {
        "type": "tag",
        "repo": "https://github.com/lsky-org/lsky-pro"
      },
      "docker": {
        "tags": [
          "type=raw,value=latest",
          "type=raw,value={{version}}"
        ]
      }
    },
    "dev": {
      "version": "38d52c4",
      "sha": "38d52c4609eb85236b45ac75acac2ced55174953",
      "checkver": {
        "type": "sha",
        "repo": "https://github.com/lsky-org/lsky-pro"
      },
      "docker": {
        "tags": [
          "type=raw,value=dev",
          "type=raw,value=dev-{{sha}}"
        ]
      }
    }
  }
}

Multiple Platform Variants

// apps/weserv/meta.json
{
  "name": "weserv",
  "type": "app",
  "slogan": "wsrv.nl",
  "description": "weserv 是一个用于快速生成图像的 API",
  "variants": {
    "latest": {
      "version": "0f029b4",
      "sha": "0f029b475c0ace517205ff88a967449aea0b2c41",
      "checkver": {
        "type": "sha",
        "repo": "weserv/images",
        "branch": "5.x"
      },
      "docker": {
        "tags": [
          "type=raw,value=latest",
          "type=raw,value=5.x",
          "type=raw,value={{version}}"
        ]
      }
    },
    "alpine": {
      "version": "0f029b4",
      "sha": "0f029b475c0ace517205ff88a967449aea0b2c41",
      "checkver": {
        "type": "sha",
        "repo": "weserv/images",
        "branch": "5.x"
      },
      "docker": {
        "tags": [
          "type=raw,value=alpine",
          "type=raw,value=5.x-alpine",
          "type=raw,value={{version}}-alpine"
        ]
      }
    }
  }
}

Base Image

// base/nginx/meta.json
{
  "name": "nginx",
  "type": "base",
  "description": "Nginx with custom configuration, based on alpine. The root path is /app.",
  "variants": {
    "latest": {
      "version": "0.1.0",
      "sha": "363f047cd6f9f160cb6bb142afb8d14191aac07e",
      "checkver": {
        "type": "manual"
      },
      "docker": {
        "tags": [
          "type=raw,value=latest",
          "type=raw,value={{version}}"
        ]
      }
    },
    "vue": {
      "version": "0.1.0",
      "sha": "363f047cd6f9f160cb6bb142afb8d14191aac07e",
      "checkver": {
        "type": "manual"
      },
      "docker": {
        "tags": [
          "type=raw,value=vue",
          "type=raw,value={{version}}-vue"
        ]
      }
    },
    "svelte": {
      "version": "0.1.0",
      "sha": "363f047cd6f9f160cb6bb142afb8d14191aac07e",
      "checkver": {
        "type": "manual"
      },
      "docker": {
        "tags": [
          "type=raw,value=svelte",
          "type=raw,value={{version}}-svelte"
        ]
      }
    }
  }
}

Validation

The meta.json file is validated against a JSON Schema located at .vscode/meta.schema.json. VSCode Integration: Add to .vscode/settings.json:
{
  "json.schemas": [
    {
      "fileMatch": ["**/apps/*/meta.json", "**/base/*/meta.json"],
      "url": "./.vscode/meta.schema.json"
    }
  ]
}
This provides:
  • Auto-completion for meta.json fields
  • Real-time validation
  • Inline documentation

Best Practices

When using type: "tag", ensure upstream repository uses semver tags:
{
  "checkver": {
    "type": "tag",
    "repo": "owner/repo",
    "tagPattern": "^v[0-9]+\\.[0-9]+\\.[0-9]+$"
  }
}
Track stable releases and development separately:
{
  "variants": {
    "latest": {
      "checkver": { "type": "tag" }
    },
    "dev": {
      "checkver": { "type": "sha" }
    }
  }
}
For monorepo applications, track specific paths:
{
  "checkver": {
    "type": "sha",
    "repo": "owner/monorepo",
    "path": "packages/web"
  }
}
Include all optional fields for better documentation:
{
  "name": "myapp",
  "title": "My Application",
  "slogan": "Short tagline",
  "description": "Detailed description",
  "license": "MIT"
}

Build docs developers (and LLMs) love