skaffold-filesync

v2026.09.24

Skaffold file sync — copy changed files to containers without rebuilding. Use when optimizing the dev loop, configuring sync rules, or the user mentions hot reload or fast iteration.

GitHub
安装命令
npx skhub add laurigates/skaffold-filesync
Markdown
SKILL.md

Skaffold File Sync

When to Use This Skill

Use this skill when...Use a sibling Skaffold/container skill instead when...
Configuring Skaffold sync rules (manual / infer / auto)Wiring OrbStack networking or Ingress (skaffold-orbstack)
Optimizing the inner edit -> running-container loop for hot reloadAdding pre-deploy test or post-deploy verify stages (skaffold-testing)
Debugging why files are not syncing into a running podWriting or hardening the Dockerfile itself (container-development)

Overview

File sync copies changed files directly to running containers, avoiding image rebuilds. This dramatically speeds up the development loop for interpreted languages and static assets.

Without sync: Edit → Build Image → Deploy → Restart Pod → Test (~30-60s)
With sync:    Edit → Copy File → Test (~1-2s)

How It Works

  1. Skaffold watches for file changes
  2. Creates a tar archive of modified files matching sync rules
  3. Extracts the archive in the running container
  4. Application picks up changes (hot reload, file watch, etc.)

Three Sync Modes

ModeConfigurationBest For
ManualExplicit src/dest mappingsFull control, complex layouts
InferDerived from DockerfileDocker builds, simple projects
AutoZero-config for known buildersBuildpacks, Jib

Important: Cannot mix modes - choose one per artifact.

Manual Sync

Explicitly map source files to container destinations.

Basic Configuration

apiVersion: skaffold/v4beta13
kind: Config
build:
  artifacts:
    - image: my-app
      context: .
      docker:
        dockerfile: Dockerfile
      sync:
        manual:
          - src: "src/**/*.js"
            dest: /app/src
          - src: "public/**/*"
            dest: /app/public

With Directory Stripping

Use strip to remove directory levels from the source path:

sync:
  manual:
    # src/components/Button.js → /app/Button.js (strips 'src/components/')
    - src: "src/components/**/*.js"
      dest: /app
      strip: "src/components/"

    # assets/images/logo.png → /var/www/static/logo.png
    - src: "assets/images/**/*"
      dest: /var/www/static
      strip: "assets/images/"

Static Assets Example

sync:
  manual:
    # HTML files to nginx root
    - src: "static/*.html"
      dest: /usr/share/nginx/html

    # CSS with directory structure preserved
    - src: "static/css/**/*.css"
      dest: /usr/share/nginx/html/css
      strip: "static/css/"

    # Images
    - src: "static/images/**/*"
      dest: /usr/share/nginx/html/images
      strip: "static/images/"

Node.js Hot Reload Example

build:
  artifacts:
    - image: node-app
      sync:
        manual:
          - src: "src/**/*.ts"
            dest: /app/src
          - src: "src/**/*.tsx"
            dest: /app/src
          - src: "*.json"
            dest: /app

Pair with nodemon or ts-node-dev in container:

CMD ["npx", "nodemon", "--watch", "/app/src", "src/index.ts"]

Python Hot Reload Example

build:
  artifacts:
    - image: python-app
      sync:
        manual:
          - src: "app/**/*.py"
            dest: /app
          - src: "templates/**/*.html"
            dest: /app/templates
            strip: "templates/"

Pair with Flask debug mode or uvicorn reload:

CMD ["uvicorn", "main:app", "--reload", "--host", "0.0.0.0"]

Inferred Sync

Skaffold automatically determines destinations from Dockerfile COPY/ADD instructions.

Configuration

build:
  artifacts:
    - image: my-app
      docker:
        dockerfile: Dockerfile
      sync:
        infer:
          - "**/*.js"
          - "**/*.css"
          - "**/*.html"

How Inference Works

Given this Dockerfile:

FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY src/ ./src/        # Skaffold infers: src/* → /app/src/*
COPY public/ ./public/  # Skaffold infers: public/* → /app/public/*

Skaffold analyzes COPY instructions to determine sync destinations.

Limitations

LimitationWorkaround
File deletion triggers full rebuildUse manual sync for delete support
Multi-stage builds may confuse inferenceUse manual sync
Complex COPY patternsUse manual sync

Auto Sync

Zero-configuration sync for supported builders.

Buildpacks (Cloud Native Buildpacks)

build:
  artifacts:
    - image: my-app
      buildpacks:
        builder: gcr.io/buildpacks/builder:v1
      sync:
        auto: true  # Enabled by default for buildpacks

Supported languages:

  • Go: .go files
  • Java: .java, .kt, .properties, .xml files
  • Node.js: .js, .ts, .json files

Disable auto sync:

sync:
  auto: false

Jib (Java)

build:
  artifacts:
    - image: my-app
      jib: {}
      sync:
        auto: true  # Enabled by default for Jib

Auto-syncs:

  • Class files (compiled)
  • Resource files
  • Extra directory files

Full Configuration Examples

Node.js Development Stack

apiVersion: skaffold/v4beta13
kind: Config
metadata:
  name: node-app

build:
  local:
    push: false
    useBuildkit: true
  artifacts:
    - image: node-app
      context: .
      docker:
        dockerfile: Dockerfile
      sync:
        manual:
          - src: "src/**/*.ts"
            dest: /app/src
          - src: "src/**/*.tsx"
            dest: /app/src
          - src: "public/**/*"
            dest: /app/public

deploy:
  kubeContext: orbstack
  kubectl:
    manifests:
      - k8s/*.yaml

Python FastAPI Stack

apiVersion: skaffold/v4beta13
kind: Config
metadata:
  name: fastapi-app

build:
  local:
    push: false
  artifacts:
    - image: fastapi-app
      sync:
        manual:
          - src: "app/**/*.py"
            dest: /code/app
          - src: "templates/**/*.html"
            dest: /code/templates
            strip: "templates/"
          - src: "static/**/*"
            dest: /code/static
            strip: "static/"

deploy:
  kubeContext: orbstack
  kubectl:
    manifests:
      - k8s/*.yaml

Go with Air (Hot Reload)

apiVersion: skaffold/v4beta13
kind: Config
metadata:
  name: go-app

build:
  artifacts:
    - image: go-app
      sync:
        manual:
          - src: "**/*.go"
            dest: /app
          - src: "go.mod"
            dest: /app
          - src: "go.sum"
            dest: /app

deploy:
  kubeContext: orbstack
  kubectl:
    manifests:
      - k8s/*.yaml

With Air in Dockerfile:

FROM golang:1.22-alpine
RUN go install github.com/cosmtrek/air@latest
WORKDIR /app
COPY . .
CMD ["air", "-c", ".air.toml"]

Static Site with Nginx

apiVersion: skaffold/v4beta13
kind: Config
metadata:
  name: static-site

build:
  artifacts:
    - image: static-site
      sync:
        manual:
          - src: "dist/**/*"
            dest: /usr/share/nginx/html
            strip: "dist/"

deploy:
  kubeContext: orbstack
  kubectl:
    manifests:
      - k8s/*.yaml

Requirements and Limitations

Container Requirements

RequirementReason
tar command availableUsed to extract synced files
Writable target directoriesCannot sync to read-only paths
Container user has write permissionsFiles must be modifiable by container UID

What Cannot Be Synced

ScenarioSolution
Builder-generated filesFull rebuild required
Files requiring compilationUse hot-reload tools (nodemon, air)
System files / package installsFull rebuild required
Permission changesFull rebuild required

Sync vs Rebuild Decision

Change TypeSyncRebuild
Source code (interpreted)Yes-
Static assetsYes-
Config filesYes-
Dockerfile-Yes
Dependencies (package.json, go.mod)-Yes
Build scripts-Yes

Debugging Sync Issues

Verify Sync Is Working

# Watch Skaffold output for sync messages
skaffold dev -v info

# Look for:
# Syncing 1 files for my-app:latest
# Watching for changes...

Check Container Has tar

kubectl exec -it <pod> -- which tar
# Should output: /bin/tar or /usr/bin/tar

Verify File Permissions

kubectl exec -it <pod> -- ls -la /app/src/
# Check files are writable by container user

Test Manual Sync Path

# Verify destination exists in container
kubectl exec -it <pod> -- ls -la /app/

# Check container user
kubectl exec -it <pod> -- whoami

Profiles for Sync vs Rebuild

profiles:
  # Fast iteration - sync enabled
  - name: dev
    build:
      artifacts:
        - image: my-app
          sync:
            manual:
              - src: "src/**/*"
                dest: /app/src

  # CI/Production - no sync, full rebuilds
  - name: ci
    build:
      artifacts:
        - image: my-app
          # No sync configuration

Agentic Optimizations

ContextCommand
Dev with syncskaffold dev --kube-context=orbstack
Verbose sync debugskaffold dev -v info
Force rebuild (skip sync)skaffold dev --force=true
Single rebuildskaffold build && skaffold deploy
Check sync statusskaffold dev -v debug 2>&1 | grep -i sync

Quick Reference

Sync Configuration Fields

FieldDescriptionRequired
srcGlob pattern for source filesYes
destDestination path in containerYes
stripDirectory prefix to removeNo

Sync Modes Comparison

FeatureManualInferAuto
Explicit mappingYesNoNo
Delete supportYesNoYes
Multi-stage DockerYesLimitedN/A
Zero-configNoPartialYes
Buildpacks supportNoNoYes
Jib supportNoNoYes

Glob Patterns

PatternMatches
*.jsJS files in root only
**/*.jsJS files in all directories
src/**/*All files under src/
{src,lib}/**/*.tsTS files in src/ or lib/
发现
标签

此技能尚未发布标签。

版本
最新版本元数据

版本

v2026.09.24

发布时间

2026年9月24日

分类

未分类

许可证

MIT

源路径

container-plugin/skills/skaffold-filesync

默认分支

main

最新提交

1668324

Tree SHA

b2d4cc3