Install
$ agentstack add skill-eliasoulkadi-shokunin-docker Open-source listing, not yet scanned by AgentStack. Follow the source repository for install instructions.
Security review
⚠ Flagged1 finding(s); flagged for manual review. · v0.1.0 How review works →
- • Prompt-injection patterns
- • Secret / credential exfiltration
- • Dangerous shell & filesystem operations
- • Untrusted network calls
- • Known-malicious package signatures
- high Destructive filesystem operation.
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Docker Architect
Production-grade Dockerfiles, multi-stage builds, cache optimization, security scanning, and local development. Applies Google's distroless philosophy and Docker BuildKit best practices.
Decision Framework
Before containerizing, answer:
- Does the app need process isolation? → Docker
- Will it deploy to Kubernetes? → Docker + distroless + non-root
- Is it a monolith with simple deployment? → Docker Compose
- Is it a static site? → Consider nginx:alpine single-stage
- Is the team already using Docker Compose in dev? → Start there, add K8s when needed
- Is the app latency-sensitive (sub-ms)? → Bare metal or VM; container overhead matters at extreme scale
Workflow
Quick start: docker init
For new projects, run docker init in the project root. It auto-detects the language/framework and generates a Dockerfile, .dockerignore, and compose.yaml with best-practice defaults. Always review and harden the output — the generated files are a starting point, not production-ready.
Step 1: Identify stack and choose template
| Stack | Base image | Build stage | Runtime | |-------|-----------|-------------|---------| | Node.js | node:22-slim | Full SDK | gcr.io/distroless/nodejs | | Go | golang:1.23-alpine | Full SDK | scratch | | Python | python:3.12-slim | Full SDK | python:3.12-slim | | Rust | rust:1.78-slim | Full SDK | gcr.io/distroless/cc |
Decision: If the stack is listed above, use the corresponding production Dockerfile below. If not, apply the golden template in Step 2.
Step 2: Apply golden template
Use multi-stage with this exact structure:
Stage 1 (deps): COPY lock files → install production deps (--mount=type=cache)
Stage 2 (build): COPY source → compile
Stage 3 (runtime): minimal base → COPY artifacts from stages 1-2 → USER nonroot → HEALTHCHECK
If the project is a Go binary, skip Stage 1 (Go has no runtime deps) and go straight to Stage 2.
If the project has native dependencies (node-gyp, C extensions), use apt-get in the builder stage, NOT the runtime stage.
Step 3: Apply BuildKit optimizations
# syntax=docker/dockerfile:1.4
FROM node:22-slim AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN --mount=type=cache,target=/root/.npm npm ci --omit=dev
FROM node:22-slim AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN --mount=type=cache,target=/root/.npm npm ci
COPY src ./src
RUN npm run build
FROM gcr.io/distroless/nodejs22-debian12
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
EXPOSE 3000
USER nonroot
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD ["node", "-e", "require('http').get('http://localhost:3000/health', r => process.exit(r.statusCode===200?0:1))"]
CMD ["dist/index.js"]
Run scripts/optimize-dockerfile.sh on any existing Dockerfile to receive optimization suggestions.
Step 4: Configure compose for local dev
services:
app:
build: .
ports: ["3000:3000"]
develop:
watch:
- action: sync+restart
path: ./src
target: /app/src
depends_on: [db]
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
db:
image: postgres:16-alpine
volumes: ["pgdata:/var/lib/postgresql/data"]
volumes: { pgdata: }
Run docker compose watch for hot-reload.
See [assets/docker-compose.template.yml](assets/docker-compose.template.yml) for the full template with all services.
Step 5: Build for multiple platforms
docker buildx build \
--platform linux/amd64,linux/arm64 \
--cache-from=type=gha \
--cache-to=type=gha,mode=max \
--tag registry/app:latest \
--push .
See [references/multi-arch.md](references/multi-arch.md) for QEMU setup and platform-specific optimizations.
Step 6: Scan for vulnerabilities
# Using the provided script
scripts/scan-image.sh registry/app:latest
# Or manually:
docker scout cves registry/app:latest
trivy image registry/app:latest
If critical CVEs are found: either switch base image (e.g., distroless), or add apt-get to install patched deps in builder stage.
Error Handling
| Error | Cause | Fix | |-------|-------|-----| | failed to solve with frontend dockerfile.v0 | Missing syntax directive | Add # syntax=docker/dockerfile:1.4 as first line | | exec /usr/bin/node: exec format error | Wrong platform | Build with --platform linux/amd64 matching the target | | permission denied at runtime | Missing USER nonroot or wrong file permissions | Add USER nonroot and COPY --chown=nonroot:nonroot | | Layer cache miss every build | Changing files copied before lock files | Always COPY package.json BEFORE source code | | docker compose watch not working | Docker Engine src/main.rs RUN --mount=type=cache,target=/usr/local/cargo/registry cargo build --release --target x8664-unknown-linux-musl RUN rm -rf src COPY src ./src RUN cargo build --release --target x8664-unknown-linux-musl
FROM scratch COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/server /server EXPOSE 8080 ENTRYPOINT ["/server"]
Key decisions:
- `musl-tools` for static linking (no glibc dependency)
- Dummy main.rs trick: compiles deps first, then source (cache deps)
- `scratch` base: smallest possible, no shell, no tools
### Seccomp profiles
Docker applies a default seccomp profile that blocks 44/300+ syscalls. Customize for your app:
```json
{
"defaultAction": "SCMP_ACT_ERRNO",
"architectures": ["SCMP_ARCH_X86_64"],
"syscalls": [
{ "names": ["read","write","open","close","fstat","mmap","mprotect","munmap","brk","rt_sigaction","rt_sigprocmask","rt_sigreturn","ioctl","pread64","pwrite64","readv","writev","access","pipe","select","sched_yield","mremap","msync","mincore","madvise","shmget","shmat","shmctl","dup","dup2","pause","nanosleep","getitimer","setitimer","alarm","getpid","sendfile","socket","connect","accept","sendto","recvfrom","sendmsg","recvmsg","shutdown","bind","listen","getsockname","getpeername","socketpair","setsockopt","getsockopt","clone","fork","vfork","execve","exit","wait4","kill","uname","semget","semop","semctl","shmdt","msgget","msgsnd","msgrcv","msgctl","fcntl","flock","fsync","fdatasync","truncate","ftruncate","getdents","getcwd","chdir","fchdir","rename","mkdir","rmdir","creat","link","unlink","symlink","readlink","chmod","fchmod","chown","fchown","lchown","umask","gettimeofday","getrlimit","getrusage","sysinfo","times","preadv","pwritev","rt_sigtimedwait","futex","set_robust_list","get_robust_list","epoll_wait","epoll_ctl","epoll_create","epoll_pwait","epoll_create1","eventfd","signalfd","timerfd_create","timerfd_gettime","timerfd_settime","prctl","getcpu","process_vm_readv","process_vm_writev"], "action": "SCMP_ACT_ALLOW" }
]
}
Usage: docker run --security-opt seccomp=profile.json myapp
CVE scanning pipeline
# Full scan pipeline
docker build -t myapp:latest .
trivy image --severity HIGH,CRITICAL --exit-code 1 myapp:latest
docker scout cves --exit-code myapp:latest
# CI integration (GitHub Actions)
- uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:latest
format: sarif
output: trivy-results.sarif
severity: HIGH,CRITICAL
exit-code: 1
# Continuous monitoring
docker scout enroll myorg/myapp
docker scout watch myapp:latest
If CVEs found: switch base image to newer distroless tag, rebuild, re-scan. Track with docker scout recommendations.
Sources
- Dockerfile best practices (docs.docker.com)
- BuildKit documentation
- Google distroless images
- Trivy vulnerability scanner
- Docker Scout documentation
- SLSA framework (slsa.dev)
Checklist
- [ ] Skill loads without errors in the AI agent
- [ ] YAML frontmatter is valid (description, compatibility, audience)
- [ ] Workflow section provides clear step-by-step instructions
- [ ] Error handling section covers common failure modes
- [ ] All referenced files (references/, scripts/, assets/) exist
- [ ] Skill triggers correctly for intended use cases
- [ ] No broken links or missing resources
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: EliasOulkadi
- Source: EliasOulkadi/shokunin
- License: MIT
- Homepage: https://eliasoulkadi.github.io/shokunin/
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.