Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
openaec-foundation avatar

Docker Impl Build Optimization

  • 14 installs
  • 9 repo stars
  • Updated July 8, 2026
  • openaec-foundation/docker-claude-skill-package

Helps with devops & ci/cd tasks.

About

docker-impl-build-optimization is a Claude Code skill for devops & ci/cd. It helps solo builders move faster with AI-assisted development.

  • docker-impl-build-optimization
  • DevOps & CI/CD
  • AI-coding skill

Docker Impl Build Optimization by the numbers

  • 14 all-time installs (skills.sh)
  • +1 installs in the week ending Aug 4, 2026 (Skillselion tracking)
  • Ranked #957 of 1,435 DevOps & CI/CD skills by installs in the Skillselion catalog
  • Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/openaec-foundation/docker-claude-skill-package --skill docker-impl-build-optimization

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs14
repo stars9
Last updatedJuly 8, 2026
Repositoryopenaec-foundation/docker-claude-skill-package

What it does

Helps with devops & ci/cd tasks.

Files

SKILL.mdMarkdownGitHub ↗

docker-impl-build-optimization

Quick Reference

Layer Caching Rules

Docker checks each instruction against its cache before executing. If the instruction and its inputs match a cached layer, the cached version is reused.

Critical rule: Once ANY layer's cache is invalidated, ALL subsequent layers MUST rebuild.

Cache Invalidation Triggers

InstructionCache KeyInvalidation Trigger
FROMImage referenceBase image tag/digest changed
RUNCommand string onlyCommand text changed (NOT external resources)
COPYFile content checksumsFile content changed (mtime is NOT checked)
ADDFile checksums + URL contentFile content or URL content changed
ENVKey=Value pairValue changed
ARGName=Value pairValue changed
WORKDIRPath + SOURCE_DATE_EPOCHPath or epoch changed

Critical Warnings

NEVER separate apt-get update and apt-get install into different RUN instructions -- the cached update layer becomes stale and subsequent installs may fail or use outdated packages.

NEVER use COPY . . before dependency installation -- ANY file change invalidates the COPY layer and forces a full reinstall of all dependencies.

NEVER rely on RUN cache for external resources -- Docker only checks the command string, not what apt-get install or curl fetches. Use --no-cache or --no-cache-filter to force fresh downloads.

ALWAYS include a .dockerignore file -- without it, the entire build context (including .git/, node_modules/, test data) is sent to the builder.

ALWAYS use # syntax=docker/dockerfile:1 at the top of every Dockerfile to enable BuildKit cache mounts and other optimizations.

---

Instruction Ordering Strategy

Order instructions from LEAST frequently changed to MOST frequently changed:

+--------------------------------------------------+
| FROM base-image                    (rarely changes) |
+--------------------------------------------------+
| RUN install system packages         (rarely changes) |
+--------------------------------------------------+
| COPY package.json / go.mod / *.csproj (dep changes) |
+--------------------------------------------------+
| RUN install dependencies            (dep changes)   |
+--------------------------------------------------+
| COPY . .                            (every commit)  |
+--------------------------------------------------+
| RUN build application               (every commit)  |
+--------------------------------------------------+
| CMD / ENTRYPOINT                    (rarely changes) |
+--------------------------------------------------+
         CACHE FLOWS TOP-DOWN
   First invalidation breaks ALL below

Principle: Expensive, slow-changing operations go at the top. Frequently changing source code goes at the bottom.

---

.dockerignore Template

ALWAYS create a .dockerignore in the project root:

# Version control
.git
.gitignore
.gitattributes

# Dependencies (rebuilt inside container)
node_modules
vendor
__pycache__
*.pyc
.venv

# Build artifacts
dist
build
target
*.o
*.exe

# IDE and OS files
.vscode
.idea
*.swp
*.swo
.DS_Store
Thumbs.db

# Docker files (not needed in build context)
Dockerfile*
docker-compose*.yml
.dockerignore

# Documentation and non-essential files
*.md
LICENSE
docs/

# Environment and secrets
.env
.env.*
*.pem
*.key
*.cert

# Test and CI files
.github
.gitlab-ci.yml
tests/
coverage/

Negation syntax: Use ! to re-include files excluded by a broader pattern:

*.md
!README.md

---

Cache Mount Patterns

Cache mounts (--mount=type=cache) persist package manager caches across builds. Even when a layer rebuilds, only new or changed packages are downloaded.

apt-get (Debian/Ubuntu)

RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
    --mount=type=cache,target=/var/lib/apt,sharing=locked \
    apt-get update && apt-get install -y --no-install-recommends \
    curl git

ALWAYS use sharing=locked for apt -- concurrent access corrupts the cache.

npm

COPY package.json package-lock.json ./
RUN --mount=type=cache,target=/root/.npm \
    npm ci

yarn

COPY package.json yarn.lock ./
RUN --mount=type=cache,target=/usr/local/share/.cache/yarn \
    yarn install --frozen-lockfile

pnpm

COPY package.json pnpm-lock.yaml ./
RUN --mount=type=cache,target=/root/.local/share/pnpm/store \
    pnpm install --frozen-lockfile

pip (Python)

COPY requirements.txt ./
RUN --mount=type=cache,target=/root/.cache/pip \
    pip install -r requirements.txt

Go modules

COPY go.mod go.sum ./
RUN --mount=type=cache,target=/go/pkg/mod \
    go mod download

COPY . .
RUN --mount=type=cache,target=/go/pkg/mod \
    --mount=type=cache,target=/root/.cache/go-build \
    go build -o /app/server ./cmd

Cargo (Rust)

COPY Cargo.toml Cargo.lock ./
RUN --mount=type=cache,target=/app/target/ \
    --mount=type=cache,target=/usr/local/cargo/git/db \
    --mount=type=cache,target=/usr/local/cargo/registry/ \
    cargo build --release

Maven (Java)

COPY pom.xml ./
RUN --mount=type=cache,target=/root/.m2/repository \
    mvn dependency:resolve

COPY src ./src
RUN --mount=type=cache,target=/root/.m2/repository \
    mvn package -DskipTests

NuGet (.NET)

COPY *.csproj ./
RUN --mount=type=cache,target=/root/.nuget/packages \
    dotnet restore

COPY . ./
RUN --mount=type=cache,target=/root/.nuget/packages \
    dotnet publish -c Release -o /app

---

Bind Mounts for Large Contexts

When source code is only needed to produce an artifact, use bind mounts instead of COPY to avoid persisting source files in any layer:

FROM golang:1.22 AS build
WORKDIR /src
RUN --mount=type=cache,target=/go/pkg/mod \
    --mount=type=bind,source=go.sum,target=go.sum \
    --mount=type=bind,source=go.mod,target=go.mod \
    go mod download

RUN --mount=type=cache,target=/go/pkg/mod \
    --mount=type=cache,target=/root/.cache/go-build \
    --mount=type=bind,target=. \
    go build -o /bin/app ./cmd

Advantages:

  • Mounted files are NOT persisted in any layer
  • Only the RUN output is kept in the image
  • Avoids bloating the build cache with source files
  • Bind mounts are read-only by default (safe)

---

CI/CD Cache Backends

Registry Cache (recommended for teams)

docker buildx build --push -t registry/app:latest \
  --cache-to type=registry,ref=registry/app:buildcache,mode=max \
  --cache-from type=registry,ref=registry/app:buildcache .

GitHub Actions Cache

- uses: docker/build-push-action@v7
  with:
    push: true
    tags: user/app:latest
    cache-from: type=gha
    cache-to: type=gha,mode=max

Multi-Branch Cache Strategy

docker buildx build --push -t registry/app:latest \
  --cache-to type=registry,ref=registry/app:cache:$BRANCH \
  --cache-from type=registry,ref=registry/app:cache:$BRANCH \
  --cache-from type=registry,ref=registry/app:cache:main .

ALWAYS fall back to the main branch cache when the feature branch cache misses.

Cache Modes

ModeBehaviorUse Case
min (default)Caches only exported layersSmaller cache, faster export
maxCaches ALL layers including intermediatesMore cache hits, larger storage

ALWAYS use mode=max in CI/CD to maximize cache reuse across builds.

---

Layer Squashing Considerations

Docker does NOT support true layer squashing natively. Options:

ApproachHowTrade-off
Multi-stage buildsCopy only final artifacts to clean stageBest approach -- no extra tooling
--squash (experimental)Merge all layers into oneLoses all intermediate cache
docker export/importFlatten to single layerLoses metadata, CMD, ENV, etc.

ALWAYS prefer multi-stage builds over squashing -- they preserve caching while producing minimal final images.

---

Forcing Cache Invalidation

# Invalidate ALL cache
docker build --no-cache .

# Invalidate a specific stage only
docker build --no-cache-filter install .

# Pull fresh base images
docker build --pull .

# Clear entire builder cache
docker builder prune

# Clear with size limit
docker builder prune --keep-storage 5GB

---

Reference Links

  • references/caching-rules.md -- Complete cache invalidation rules per instruction type
  • references/examples.md -- Optimized Dockerfiles before/after, .dockerignore patterns
  • references/anti-patterns.md -- Caching and optimization mistakes with explanations

Official Sources

  • https://docs.docker.com/build/cache/
  • https://docs.docker.com/build/cache/invalidation/
  • https://docs.docker.com/build/cache/optimize/
  • https://docs.docker.com/build/cache/backends/
  • https://docs.docker.com/reference/dockerfile/
  • https://docs.docker.com/build/building/best-practices/

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.