Skip to main content
The docker field in your variant configuration controls how Docker images are built and pushed.

Schema

export interface DockerConfig {
  /** Dockerfile path */
  file?: string
  /** Image name templates */
  images?: string[]
  /** Tag templates */
  tags?: string[]
  /** Build platforms */
  platforms?: Platform[]
  /** Docker labels */
  labels?: Record<string, string>
  /** Build arguments */
  buildArgs?: Record<string, string>
  /** Build secrets */
  secrets?: string[]
  /** Output configuration */
  outputs?: string[]
  /** Cache configuration */
  cache?: CacheConfig
  /** Push to registry */
  push?: boolean
  /** Load image locally */
  load?: boolean
}

export interface CacheConfig {
  /** Cache sources */
  from?: string[]
  /** Cache targets */
  to?: string[]
}

export type Platform =
  | 'linux/amd64'
  | 'linux/arm64'
  | 'linux/arm/v7'
  | 'linux/arm/v6'
  | 'linux/386'
  | 'linux/ppc64le'
  | 'linux/s390x'

Configuration Fields

Dockerfile

file
string
default:"Dockerfile or Dockerfile.{variant}"
Path to Dockerfile relative to the app context.Default behavior:
  • latest variant: Dockerfile
  • Other variants: Dockerfile.{variantName}
"file": "Dockerfile.custom"

Images

images
string[]
Image name templates. Supports placeholders.Default images (if not specified):
[
  "dockerhub-user/{name}",
  "ghcr.io/github-user/{name}",
  "registry.cn-hangzhou.aliyuncs.com/aliyun-user/{name}"
]
Custom images:
"images": [
  "myuser/{{name}}",
  "ghcr.io/myorg/{{name}}"
]
The {name} placeholder is replaced with the app name from meta.json.

Tags

tags
string[]
Docker image tag templates using docker/metadata-action format.Default tags:
[
  "type=raw,value={variantName}",
  "type=raw,value={{version}}"
]
Common tag patterns:
"tags": [
  "type=raw,value=latest",
  "type=raw,value={{version}}",
  "type=raw,value={{major}}",
  "type=raw,value={{major}}.{{minor}}",
  "type=raw,value=dev-{{sha}}"
]
See Placeholders for available template variables.

Platforms

platforms
Platform[]
default:"['linux/amd64', 'linux/arm64']"
Target platforms for multi-arch builds.Supported platforms:
  • linux/amd64 - x86_64 (Intel/AMD)
  • linux/arm64 - ARM 64-bit (Apple Silicon, AWS Graviton)
  • linux/arm/v7 - ARM 32-bit v7
  • linux/arm/v6 - ARM 32-bit v6
  • linux/386 - x86 32-bit
  • linux/ppc64le - PowerPC 64-bit
  • linux/s390x - IBM Z
"platforms": ["linux/amd64", "linux/arm64"]
Building for multiple platforms increases build time significantly. Only include platforms you need.

Labels

labels
Record<string, string>
Custom Docker labels following OCI Image Format.Auto-generated labels:
  • org.opencontainers.image.description
  • org.opencontainers.image.licenses
  • org.opencontainers.image.revision
  • org.opencontainers.image.source
  • org.opencontainers.image.title
  • org.opencontainers.image.url
  • org.opencontainers.image.version
Custom labels:
"labels": {
  "author": "username",
  "maintainer": "[email protected]"
}

Build Arguments

buildArgs
Record<string, string>
Build-time variables passed to Docker.
"buildArgs": {
  "NODE_VERSION": "20",
  "APP_ENV": "production"
}
Use in Dockerfile:
ARG NODE_VERSION
FROM node:${NODE_VERSION}-alpine

ARG APP_ENV
ENV NODE_ENV=${APP_ENV}

Secrets

secrets
string[]
Build secrets for sensitive data (requires Docker BuildKit).
"secrets": [
  "id=npm_token,src=/path/to/token",
  "id=ssh_key,src=$HOME/.ssh/id_rsa"
]
Use in Dockerfile:
RUN --mount=type=secret,id=npm_token \
    NPM_TOKEN=$(cat /run/secrets/npm_token) \
    npm install

Push

push
boolean
default:"true"
Push the built image to registries.Automatically disabled for:
  • Test apps (test/ directory)
  • Local development (ACT mode)
"push": false

Load

load
boolean
default:"false"
Load the built image into local Docker daemon.
"load": true
push and load are mutually exclusive when using multiple platforms.

Outputs

outputs
string[]
Custom output configuration for Docker build.
"outputs": [
  "type=docker",
  "type=oci,dest=/tmp/image.tar"
]

Cache

cache
CacheConfig
Docker build cache configuration.
"cache": {
  "from": ["type=gha"],
  "to": ["type=gha,mode=max"]
}
By default, Apps Image uses GitHub Actions cache (type=gha) automatically.

Examples

Minimal Configuration

{
  "variants": {
    "latest": {
      "version": "1.0.0",
      "sha": "abc123...",
      "checkver": { ... }
      // Uses all defaults:
      // - file: Dockerfile
      // - platforms: linux/amd64, linux/arm64
      // - tags: latest, {{version}}
    }
  }
}

Custom Tags and Platforms

apps/cobalt/meta.json
{
  "variants": {
    "latest": {
      "version": "11.3",
      "sha": "e4b53880af4026b8be6a870ae7d8133f744a6181",
      "checkver": {
        "type": "version",
        "repo": "imputnet/cobalt",
        "file": "web/package.json"
      },
      "docker": {
        "tags": [
          "type=raw,value=latest",
          "type=raw,value={{version}}",
          "type=raw,value={{major}}"
        ]
      }
    }
  }
}

Development Variant

apps/cobalt/meta.json
{
  "variants": {
    "dev": {
      "version": "8d9bccc",
      "sha": "8d9bccc4fedabb6842fab71bd14e805f1ea21336",
      "checkver": {
        "type": "sha",
        "repo": "imputnet/cobalt",
        "path": "web"
      },
      "docker": {
        "tags": [
          "type=raw,value=dev",
          "type=raw,value=dev-{{sha}}"
        ]
      }
    }
  }
}

Single Platform Build

apps/readest/meta.json
{
  "variants": {
    "test": {
      "version": "0.9.101",
      "sha": "66d2fdf999581c979ee5f19ca8b993cecaf83626",
      "checkver": {
        "type": "tag",
        "repo": "readest/readest"
      },
      "docker": {
        "file": "Dockerfile",
        "tags": ["type=raw,value=test"],
        "platforms": ["linux/amd64"]
      }
    }
  }
}

Custom Images and Labels

apps/haitang/meta.json
{
  "variants": {
    "latest": {
      "version": "3d5ff9c",
      "sha": "3d5ff9c222ee76e6635fad44b9df6bd57f3805fb",
      "checkver": {
        "type": "sha",
        "repo": "javayhu/haitang"
      },
      "docker": {
        "labels": {
          "author": "javayhu"
        }
      }
    }
  }
}

Multi-Registry Push

{
  "docker": {
    "images": [
      "docker.io/myuser/{{name}}",
      "ghcr.io/myorg/{{name}}",
      "registry.example.com/{{name}}"
    ],
    "tags": [
      "type=raw,value=latest",
      "type=raw,value={{version}}"
    ]
  }
}
This creates tags like:
  • docker.io/myuser/app:latest
  • docker.io/myuser/app:1.2.3
  • ghcr.io/myorg/app:latest
  • ghcr.io/myorg/app:1.2.3
  • registry.example.com/app:latest
  • registry.example.com/app:1.2.3

Build Scripts

Apps Image supports pre and post build scripts:

Pre-build Script

pre.sh
file
Script executed before Docker build.Naming:
  • latest variant: pre.sh
  • Other variants: pre.{variantName}.sh
apps/myapp/pre.sh
#!/bin/bash
# Download assets, generate files, etc.
npm install
npm run build

Post-build Script

post.sh
file
Script executed after Docker build.Naming:
  • latest variant: post.sh
  • Other variants: post.{variantName}.sh
apps/myapp/post.sh
#!/bin/bash
# Cleanup, notifications, etc.
echo "Build completed!"

Registry Authentication

Configure registry credentials in GitHub Secrets:
  • Docker Hub: DOCKERHUB_USERNAME, DOCKERHUB_TOKEN
  • GHCR: GITHUB_TOKEN (automatic)
  • Aliyun ACR: ALI_ACR_REGISTRY, ALI_ACR_USERNAME, ALI_ACR_PASSWORD

Best Practices

  1. Use semantic versioning tags:
    "tags": [
      "type=raw,value=latest",
      "type=raw,value={{version}}",
      "type=raw,value={{major}}.{{minor}}",
      "type=raw,value={{major}}"
    ]
    
  2. Optimize platform selection:
    • Use linux/amd64 only for faster builds during development
    • Add linux/arm64 for production (Apple Silicon, AWS Graviton)
  3. Use build arguments for customization:
    "buildArgs": {
      "VERSION": "{{version}}",
      "BUILD_DATE": "{{timestamp}}"
    }
    
  4. Add meaningful labels:
    "labels": {
      "maintainer": "[email protected]",
      "documentation": "https://docs.example.com"
    }
    
  5. Separate dev and production variants:
    {
      "latest": { ... },  // Stable releases
      "dev": { ... }      // Development builds
    }
    

Build docs developers (and LLMs) love