用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/tomevault-io/skills-registry --skill docker命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
| Use when this capability is needed.
> Use when this capability is needed.
Review architecture and API design for the vfs-s3 project. Use when the user mentions @architect, asks to review an issue's design, discuss module boundaries, API shape, or architectural decisions for vfs-s3. Also trigger when the user wants to create an ADR (Architecture Decision Record) or evaluate a technical approach for the project. Intended for dispatch from Codex automation or Claude routines; GitHub trigger phrase: @vfs-s3-bot please prepare design doc Use when this capability is needed.
基于 SOC 职业分类
正在显示 SKILL.md
| name | docker |
| description | | Use when this capability is needed. |
Out of scope (recommend dedicated skills):
latest tag, use lockfilesRecommended hierarchy (most to least preferred):
| Base Image | Size | Shell | Use Case |
|---|---|---|---|
cgr.dev/chainguard/* (Wolfi) | ~10-30MB | Yes | Zero-CVE goal, SBOM included |
alpine:3.21 | ~7MB | Yes | General-purpose minimal |
gcr.io/distroless/* | ~2-5MB | No | Hardened production, no debug |
*-slim variants | ~70-100MB | Yes | When Alpine compatibility is an issue |
scratch | 0MB | No | Static binaries (Go, Rust) |
Rules:
node:22.14.0-alpine3.21 not node:alpinelatest — breaks reproducibility# 1. Base image + system deps (rarely change)
FROM node:22-alpine
RUN apk add --no-cache dumb-init
# 2. Dependencies (change occasionally)
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --only=production
# 3. Application code (changes frequently)
COPY . .
# 4. Metadata + runtime config
USER node
EXPOSE 3000
CMD ["dumb-init", "node", "server.js"]
Always create one to reduce build context:
.git
node_modules
__pycache__
*.pyc
.vscode
.idea
.DS_Store
*.log
coverage/
.env
.env.local
dist/
build/
README.md
docs/
Speed up dependency installation:
# Node.js
RUN --mount=type=cache,target=/root/.npm \
npm ci
# Python
RUN --mount=type=cache,target=/root/.cache/pip \
pip install -r requirements.txt
# Go
RUN --mount=type=cache,target=/go/pkg/mod \
go build -o /app .
Enable with DOCKER_BUILDKIT=1 or Docker Desktop (on by default).
FROM node:22-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
FROM node:22-alpine AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
FROM node:22-alpine AS runtime
RUN addgroup -g 1001 -S app && adduser -S app -u 1001
WORKDIR /app
COPY --from=build --chown=app:app /app/dist ./dist
COPY --from=deps --chown=app:app /app/node_modules ./node_modules
COPY --chown=app:app package.json ./
USER app
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD wget -qO- http://localhost:3000/health || exit 1
CMD ["node", "dist/index.js"]
FROM python:3.13-slim AS build
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
FROM python:3.13-slim AS runtime
RUN useradd -r -u 1001 app
WORKDIR /app
COPY --from=build /install /usr/local
COPY --chown=app:app . .
USER app
EXPOSE 8000
CMD ["python", "-m", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
FROM golang:1.24-alpine AS build
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /app .
FROM scratch
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=build /app /app
USER 65534:65534
EXPOSE 8080
ENTRYPOINT ["/app"]
FROM eclipse-temurin:21-jdk-alpine AS build
WORKDIR /app
COPY . .
RUN ./gradlew build --no-daemon
FROM eclipse-temurin:21-jre-alpine AS runtime
RUN addgroup -g 1001 -S app && adduser -S app -u 1001
WORKDIR /app
COPY --from=build --chown=app:app /app/build/libs/*.jar app.jar
USER app
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=10s --retries=3 \
CMD wget -qO- http://localhost:8080/actuator/health || exit 1
CMD ["java", "-jar", "app.jar"]
FROM rust:1.84-alpine AS build
RUN apk add --no-cache musl-dev
WORKDIR /app
COPY Cargo.toml Cargo.lock ./
RUN mkdir src && echo "fn main() {}" > src/main.rs && cargo build --release && rm -rf src
COPY src ./src
RUN cargo build --release
FROM scratch
COPY --from=build /app/target/release/app /app
USER 65534:65534
EXPOSE 8080
ENTRYPOINT ["/app"]
# Alpine
RUN addgroup -g 1001 -S app && adduser -S app -u 1001 -G app
USER app
# Debian/Ubuntu
RUN groupadd -g 1001 app && useradd -r -u 1001 -g app app
USER app
# Distroless/scratch (numeric only)
USER 65534:65534
# BuildKit secrets (never stored in layers)
RUN --mount=type=secret,id=api_key \
API_KEY=$(cat /run/secrets/api_key) && \
./configure --api-key="$API_KEY"
# Build with secret
docker build --secret id=api_key,src=./api_key.txt .
Never do:
ENV API_KEY=secret123 # Visible in image history
COPY .env /app/.env # Baked into layer
ARG PASSWORD=hunter2 # Visible in build history
docker run \
--user 1001:1001 \
--cap-drop=ALL \
--cap-add=NET_BIND_SERVICE \
--read-only \
--tmpfs /tmp:noexec,nosuid \
--security-opt="no-new-privileges:true" \
--memory="512m" \
--cpus="1.0" \
my-image
# Docker Scout
docker scout quickview my-image
docker scout cves my-image
# Trivy
trivy image my-image
# Grype
grype my-image
services:
app:
build:
context: .
target: runtime
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
networks:
- frontend
- backend
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
deploy:
resources:
limits:
cpus: "1.0"
memory: 512M
reservations:
cpus: "0.5"
memory: 256M
restart: unless-stopped
logging:
driver: "json-file"
options:
max-size: "10m"
max-file:
[, ]
networks:
frontend: # Web-facing services
backend:
internal: true # Database, cache — no external access
services:
proxy:
networks: [frontend]
api:
networks: [frontend, backend]
db:
networks: [backend] # Only reachable from api
# compose.yml (base)
services:
app:
build: .
# compose.override.yml (dev, loaded automatically)
services:
app:
build:
target: development
volumes:
- .:/app
- /app/node_modules
ports:
- "9229:9229" # Debug
environment:
- NODE_ENV=development
command: npm run dev
# compose.prod.yml
services:
app:
build:
target: runtime
environment:
- NODE_ENV=production
restart: unless-stopped
# Dev (auto-loads compose.override.yml)
docker compose up
# Prod
docker compose -f compose.yml -f compose.prod.yml up -d
# Bad — 3 layers, cleanup doesn't reduce size
RUN apt-get update
RUN apt-get install -y curl
RUN rm -rf /var/lib/apt/lists/*
# Good — 1 layer, cleanup is effective
RUN apt-get update && \
apt-get install -y --no-install-recommends curl && \
rm -rf /var/lib/apt/lists/*
CMD ["node", "server.js"] # Exec form — PID 1, receives signals directly
CMD node server.js # Shell form — spawns /bin/sh, signal issues
Always prefer exec form.
services:
app:
build:
target: development
volumes:
- .:/app # Source code
- /app/node_modules # Prevent overwrite
ports:
- "3000:3000"
- "9229:9229" # Debug port
environment:
- NODE_ENV=development
- DEBUG=app:*
command: npm run dev
services:
app:
# Node.js inspect
command: node --inspect=0.0.0.0:9229 server.js
ports:
- "9229:9229"
# Python debugpy
# command: python -m debugpy --listen 0.0.0.0:5678 main.py
# ports:
# - "5678:5678"
// /etc/docker/daemon.json
{
"userns-remap": "default",
"storage-driver": "overlay2",
"live-restore": true,
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
overlay2 storage drivervolumes:
- ./src:/app/src:delegated # Better write performance
- ./build:/app/build:cached # Container writes cached
:delegated/:cached for bind mount performancemutagen or docker compose watch for file sync.gitattributes with * text=auto eol=lf# .gitattributes — prevent CRLF issues in containers
* text=auto eol=lf
*.sh text eol=lf
Dockerfile text eol=lf
latest).dockerignore configureddumb-init/tini)--cap-drop=ALL)| Don't | Do Instead |
|---|---|
| Run as root | USER 1001 or named user |
Use latest tag | Pin exact versions |
--privileged flag | --cap-add only what's needed |
| Mount Docker socket | Use Docker-in-Docker or alternatives |
| Hardcode secrets in ENV/ARG | BuildKit secrets or runtime mounts |
| Skip health checks | HEALTHCHECK in Dockerfile or Compose |
| Ignore resource limits | Set memory and cpus limits |
| Copy entire context | Use .dockerignore |
| Install unnecessary packages | --no-install-recommends |
| Use shell form CMD | Use exec form ["cmd", "arg"] |
DOCKER_BUILDKIT=1).dockerignore (large build context?)docker history <image> to find large layersdocker network inspect to debugdocker logs <container>Source: fellipeutaka/leon — distributed by TomeVault.