소스 정보
- 저장소
- microwind/ai-skills
- 최근 소스 활동
- 2026년 3월 26일 14:58
- 감지된 SKILL.md 언어
- 중국어
- 스타
- 68
- 포크
- 17
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/microwind/ai-skills --skill dockerfile명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SOC 직업 분류 기준
SKILL.md 표시 중
| name | Dockerfile分析器 |
| description | 当分析Dockerfile时,检查最佳实践,优化Docker配置,验证安全性。分析Dockerfile以优化和安全。 |
| license | MIT |
Docker镜像可能膨胀到GB级别且存在安全隐患。无效的Dockerfile会导致构建失败或创建不安全的容器。在构建和部署前必须进行分析。
核心原则: 轻量镜像构建速度快,安全镜像值得信赖。好的Dockerfile应该层次清晰、安全性高、体积小、构建快。
始终:
触发短语:
❌ 镜像过大
❌ 安全隐患
❌ 构建缓慢
❌ 维护困难
#!/usr/bin/env python3
import re
import os
import json
import hashlib
from pathlib import Path
from typing import Dict, List, Optional, Tuple
from dataclasses import dataclass
from enum import Enum
class Severity(Enum):
"""严重程度"""
INFO = "info"
WARNING = "warning"
ERROR = "error"
CRITICAL = "critical"
@dataclass
class DockerfileIssue:
"""Dockerfile问题"""
line_number: int
severity: Severity
rule: str
message: str
suggestion: str
line_content: str
@dataclass
class LayerInfo:
"""层次信息"""
instruction: str
content: str
estimated_size: int
cache_hit: bool = False
class DockerfileAnalyzer:
"""Dockerfile分析器"""
def __init__(self):
self.issues: [DockerfileIssue] = []
.layers: [LayerInfo] = []
.security_rules = ._load_security_rules()
.optimization_rules = ._load_optimization_rules()
() -> [, ]:
{
: {
: ,
: ,
: Severity.ERROR,
:
},
: {
: ,
: ,
: Severity.CRITICAL,
:
},
: {
: ,
: ,
: Severity.WARNING,
:
},
: {
: ,
: ,
: Severity.ERROR,
:
},
: {
: ,
: ,
: Severity.INFO,
:
}
}
() -> [, ]:
{
: {
: ,
: ,
: Severity.INFO,
:
},
: {
: ,
: ,
: Severity.WARNING,
:
},
: {
: ,
: ,
: Severity.INFO,
:
},
: {
: ,
: ,
: Severity.WARNING,
:
}
}
() -> [[, ]]:
:
(dockerfile_path, , encoding=) f:
lines = f.readlines()
instructions = []
i, line (lines, ):
line = line.strip()
line line.startswith():
line.endswith():
multi_line = line[:-]
j = i
j < (lines):
next_line = lines[j].strip()
next_line.endswith():
multi_line += + next_line[:-]
j +=
:
multi_line += + next_line
instructions.append((multi_line, i))
i = j
:
instructions.append((line, i))
instructions
FileNotFoundError:
FileNotFoundError()
Exception e:
Exception()
():
instruction, line_num instructions:
rule_name, rule .security_rules.items():
re.search(rule[], instruction, re.IGNORECASE):
issue = DockerfileIssue(
line_number=line_num,
severity=rule[],
rule=rule_name,
message=rule[],
suggestion=rule[],
line_content=instruction
)
.issues.append(issue)
():
instruction, line_num instructions:
rule_name, rule .optimization_rules.items():
re.search(rule[], instruction, re.IGNORECASE):
issue = DockerfileIssue(
line_number=line_num,
severity=rule[],
rule=rule_name,
message=rule[],
suggestion=rule[],
line_content=instruction
)
.issues.append(issue)
():
.layers = []
instruction, line_num instructions:
parts = instruction.split(, )
(parts) >= :
cmd_type = parts[].upper()
content = parts[]
estimated_size = ._estimate_layer_size(cmd_type, content)
layer = LayerInfo(
instruction=cmd_type,
content=content,
estimated_size=estimated_size
)
.layers.append(layer)
() -> :
cmd_type == :
* *
cmd_type == cmd_type == :
* *
cmd_type == :
content:
* *
content:
* *
:
* *
:
* *
() -> :
(layer.estimated_size layer .layers)
() -> []:
suggestions = []
total_size = .calculate_image_size()
total_size > * * :
suggestions.append()
run_instructions = [layer layer .layers layer.instruction == ]
(run_instructions) > :
suggestions.append()
copy_instructions = [layer layer .layers layer.instruction == ]
(copy_instructions) > :
suggestions.append()
.layers .layers[].content.lower():
suggestions.append()
suggestions
() -> :
issues_by_severity = {}
severity Severity:
issues_by_severity[severity.value] = [
{
: issue.line_number,
: issue.rule,
: issue.message,
: issue.suggestion,
: issue.line_content
}
issue .issues issue.severity == severity
]
total_issues = (.issues)
critical_issues = (issues_by_severity[])
error_issues = (issues_by_severity[])
warning_issues = (issues_by_severity[])
info_issues = (issues_by_severity[])
layer_analysis = {
: (.layers),
: (.calculate_image_size() / ( * ), ),
: [
{
: layer.instruction,
: (layer.estimated_size / ( * ), )
}
layer .layers
]
}
optimizations = .suggest_optimizations()
{
: {
: total_issues,
: critical_issues,
: error_issues,
: warning_issues,
: info_issues,
: (.calculate_image_size() / ( * ), )
},
: issues_by_severity,
: layer_analysis,
: optimizations
}
() -> :
.issues = []
.layers = []
instructions = .parse_dockerfile(dockerfile_path)
.analyze_security(instructions)
.analyze_optimization(instructions)
.analyze_layers(instructions)
.generate_report()
__name__ == :
argparse
parser = argparse.ArgumentParser(description=)
parser.add_argument(, nargs=, default=, =)
parser.add_argument(, =)
parser.add_argument(, choices=[, ], default=, =)
args = parser.parse_args()
analyzer = DockerfileAnalyzer()
:
report = analyzer.analyze(args.dockerfile)
args. == :
args.output:
(args.output, , encoding=) f:
json.dump(report, f, indent=, ensure_ascii=)
()
:
(json.dumps(report, indent=, ensure_ascii=))
:
( * )
()
( * )
summary = report[]
()
()
()
()
()
()
()
report[][]:
()
issue report[][]:
()
()
()
report[][]:
()
issue report[][]:
()
()
()
report[][]:
()
issue report[][]:
()
()
()
report[]:
()
suggestion report[]:
()
()
layer_analysis = report[]
()
()
()
Exception e:
()
exit()
#!/bin/bash
# dockerfile-optimizer.sh - Dockerfile优化工具
set -e
# 配置
DOCKERFILE=${1:-"Dockerfile"}
OUTPUT_FILE=${2:-"Dockerfile.optimized"}
BACKUP_FILE="Dockerfile.backup"
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
log_step() {
echo -e "${BLUE}[STEP]${NC} $1"
}
# 检查Dockerfile是否存在
check_dockerfile() {
if [ ! -f "$DOCKERFILE" ]; then
log_error "Dockerfile不存在: $DOCKERFILE"
exit 1
fi
log_info "分析Dockerfile: $DOCKERFILE"
}
() {
[ ! -f ];
log_info
}
() {
log_step
grep -q ;
log_warn
grep -q ;
sed -i.bak
log_info
grep -q ;
sed -i.bak
log_info
grep -q && ! grep -q ;
log_warn
}
() {
log_step
temp_file=$()
awk >
python3 -c
log_info
}
() {
log_step
grep -q && grep -q ;
log_warn
[ ! -f ];
log_warn
> .dockerignore <<
log_info
}
() {
log_step
! grep -q ;
log_warn
>>
>>
>>
>>
log_info
! grep -q ;
log_warn
sed -i
log_info
}
() {
log_step
! grep -q ;
grep -q ;
log_warn
grep -q ;
log_info
> Dockerfile.multi-stage <<
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
FROM node:18-alpine AS runtime
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
WORKDIR /app
COPY --from=builder --=nextjs:nodejs /app/dist ./dist
COPY --from=builder --=nextjs:nodejs /app/node_modules ./node_modules
COPY --from=builder --=nextjs:nodejs /app/package.json ./package.json
USER nextjs
EXPOSE 3000
CMD [, ]
EOF
log_info
log_info
}
() {
log_step
report_file=
> <<
grep -q ;
>>
grep -q ;
>>
grep -q ;
>>
[ -f ];
>>
>>
>>
>>
>>
>>
>>
log_info
}
() {
log_info
check_dockerfile
backup_original
optimize_base_image
optimize_run_commands
optimize_copy_commands
add_security_config
optimize_multi_stage
generate_optimization_report
log_info
log_info
log_info
}
() {
}
[ = ] || [ = ];
show_help
0
main
#!/usr/bin/env python3
import re
import json
import requests
from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum
class VulnerabilityLevel(Enum):
"""漏洞等级"""
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
CRITICAL = "critical"
@dataclass
class SecurityIssue:
"""安全问题"""
type: str
level: VulnerabilityLevel
description: str
recommendation: str
cve_id: Optional[str] = None
package: Optional[str] = None
version: Optional[str] = None
class DockerSecurityScanner:
"""Docker安全扫描器"""
def __init__(self):
self.security_issues: List[SecurityIssue] = []
self.base_image_vulnerabilities = {}
def scan_dockerfile(self, dockerfile_path: ) -> [SecurityIssue]:
.security_issues = []
:
(dockerfile_path, , encoding=) f:
content = f.read()
._scan_user_privileges(content)
._scan_secrets(content)
._scan_network_security(content)
._scan_file_permissions(content)
._scan_base_image(content)
.security_issues
FileNotFoundError:
FileNotFoundError()
Exception e:
Exception()
():
re.search(, content, re.IGNORECASE):
re.search(, content, re.IGNORECASE) content:
.security_issues.append(SecurityIssue(
=,
level=VulnerabilityLevel.HIGH,
description=,
recommendation=
))
re.search(, content, re.IGNORECASE):
.security_issues.append(SecurityIssue(
=,
level=VulnerabilityLevel.MEDIUM,
description=,
recommendation=
))
():
secret_patterns = [
(, ),
(, ),
(, ),
(, ),
(, ),
]
pattern, description secret_patterns:
re.search(pattern, content, re.IGNORECASE):
.security_issues.append(SecurityIssue(
=,
level=VulnerabilityLevel.CRITICAL,
description=description,
recommendation=
))
re.search(, content, re.IGNORECASE):
.security_issues.append(SecurityIssue(
=,
level=VulnerabilityLevel.HIGH,
description=,
recommendation=
))
():
expose_count = (re.findall(, content, re.IGNORECASE))
expose_count > :
.security_issues.append(SecurityIssue(
=,
level=VulnerabilityLevel.MEDIUM,
description=,
recommendation=
))
re.search(, content, re.IGNORECASE) re.search(, content, re.IGNORECASE):
.security_issues.append(SecurityIssue(
=,
level=VulnerabilityLevel.MEDIUM,
description=,
recommendation=
))
content:
.security_issues.append(SecurityIssue(
=,
level=VulnerabilityLevel.HIGH,
description=,
recommendation=
))
():
re.search(, content, re.IGNORECASE):
.security_issues.append(SecurityIssue(
=,
level=VulnerabilityLevel.MEDIUM,
description=,
recommendation=
))
re.search(, content, re.IGNORECASE):
.security_issues.append(SecurityIssue(
=,
level=VulnerabilityLevel.MEDIUM,
description=,
recommendation=
))
():
from_match = re.search(, content, re.IGNORECASE)
from_match:
base_image = from_match.group()
base_image base_image.count() == :
.security_issues.append(SecurityIssue(
=,
level=VulnerabilityLevel.HIGH,
description=,
recommendation=
))
base_image base_image.startswith():
:
.security_issues.append(SecurityIssue(
=,
level=VulnerabilityLevel.MEDIUM,
description=,
recommendation=
))
() -> :
:
vulnerabilities = {
: ,
: ,
: ,
: ,
: []
}
mock_vulns = [
{
: ,
: ,
: ,
: ,
:
},
{
: ,
: ,
: ,
: ,
:
}
]
vuln mock_vulns:
vulnerabilities[vuln[]] +=
vulnerabilities[].append(vuln)
vulnerabilities
Exception e:
{: (e)}
() -> :
dockerfile_issues = .scan_dockerfile(dockerfile_path)
image_vulnerabilities =
image_name:
image_vulnerabilities = .scan_image_vulnerabilities(image_name)
issues_by_level = {}
level VulnerabilityLevel:
issues_by_level[level.value] = [
{
: issue.,
: issue.description,
: issue.recommendation
}
issue dockerfile_issues issue.level == level
]
total_issues = (dockerfile_issues)
critical_count = (issues_by_level[])
high_count = (issues_by_level[])
medium_count = (issues_by_level[])
low_count = (issues_by_level[])
score =
score -= critical_count *
score -= high_count *
score -= medium_count *
score -= low_count *
score = (, score)
{
: score,
: total_issues,
: issues_by_level,
: image_vulnerabilities,
: ._generate_recommendations(dockerfile_issues)
}
() -> []:
recommendations = ()
issue issues:
recommendations.add(issue.recommendation)
recommendations.add()
recommendations.add()
recommendations.add()
recommendations.add()
(recommendations)
__name__ == :
argparse
parser = argparse.ArgumentParser(description=)
parser.add_argument(, nargs=, default=, =)
parser.add_argument(, =)
parser.add_argument(, =)
parser.add_argument(, choices=[, ], default=, =)
args = parser.parse_args()
scanner = DockerSecurityScanner()
:
report = scanner.generate_security_report(args.dockerfile, args.image)
args. == :
args.output:
(args.output, , encoding=) f:
json.dump(report, f, indent=, ensure_ascii=)
()
:
(json.dumps(report, indent=, ensure_ascii=))
:
( * )
()
( * )
()
()
()
level [, , , ]:
issues = report[][level]
issues:
level_names = {
: ,
: ,
: ,
:
}
()
issue issues:
()
()
()
report[]:
()
rec report[]:
()
()
report[] report[]:
vulns = report[]
()
()
()
()
()
Exception e:
()
exit()
Large Base 镜像s
ubuntu:latest (1.2GB) vs alpine:latest (7MB)node:18 (900MB) vs node:18-alpine (150MB)Unnecessary 层s
RUN command creates 一个 层RUN apt-get update && apt-get install should 是 ONE commandRunning 作为 Root
USER appuser directiveCopying Entire Directory
COPY . /app includes everything (node_modules, .git, etc.).dockerignore 到 exclude filesNot Pinning Base 镜像
FROM node uses latest (unpredictable)FROM node:18.14.0 (specific 版本).dockerignore excludes unnecessary files