Skip to content
Back to skills

2705 Docker Optimize 8c3471fa

ASecurity

Analyze and optimize Docker images for size and build speed

  • 9 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 11, 2026
devopstypescriptpythongobashnodenodejsflaskdockergitdevops

Works with

  • vscode

Security analysis

A92/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 2705-docker-optimize_8c3471fa --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 2705 Docker Optimize 8c3471fa?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 2705 Docker Optimize 8c3471fa
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-2705-docker-optimize-8c3471fa/badge)](https://www.skillsdirectory.com/skills/tools-only-2705-docker-optimize-8c3471fa)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
---
description: Analyze and optimize Docker images for size and build speed
shortcut: do
category: devops
difficulty: advanced
estimated_time: 3 minutes
---

<!-- DESIGN DECISION: Helps reduce bloated Docker images -->
<!-- Docker images often become bloated due to poor layer ordering, unnecessary files,
     dev dependencies in production, etc. This command analyzes existing Dockerfiles
     and provides specific optimization recommendations with metrics. -->

<!-- VALIDATION: Real-world results -->
<!--  Node.js app: 1.2GB → 150MB (87% reduction) -->
<!--  Python app: 900MB → 120MB (86% reduction) -->
<!--  Go app: 800MB → 12MB (98% reduction) -->

# Docker Image Optimizer

Analyzes existing Docker images and Dockerfiles, identifying size/speed bottlenecks and providing specific optimizations with before/after metrics.

## When to Use This

-  Image is larger than expected (>500MB for simple app)
-  Build times are slow (>5 minutes)
-  Want to reduce infrastructure costs
-  Deploying to bandwidth-limited environments
-  Image already optimized (<200MB, multi-stage build)

## How It Works

You are a Docker optimization expert. When user runs `/docker-optimize` or `/do`:

1. **Analyze current state:**
   ```bash
   # Read existing Dockerfile
   # Check image layers with: docker history <image>
   # Calculate current size with: docker images <image>
   ```

2. **Identify issues:**
   - Using bloated base images (ubuntu vs alpine)
   - Missing multi-stage builds
   - Poor layer caching (dependencies installed after code copy)
   - Dev dependencies in production
   - Large build context (.dockerignore missing)
   - Unnecessary files in image
   - Inefficient RUN commands (multiple layers)

3. **Calculate potential savings:**
   ```
   Current Image Size: 1,200 MB
   Optimized Size: 150 MB
   Reduction: 87% (1,050 MB saved)

   Current Build Time: 5 min
   Optimized Time: 1 min
   Speedup: 80% faster
   ```

4. **Provide optimized Dockerfile:**
   - Multi-stage build implementation
   - Minimal base image selection
   - Optimal layer ordering
   - .dockerignore additions
   - Combined RUN commands
   - Non-root user

5. **Show side-by-side comparison:**
   - Before vs After metrics
   - Specific changes explained
   - Validation commands

## Output Format

```markdown
## Current State Analysis

**Image:** [image-name:tag]
**Base Image:** [current-base]
**Total Size:** [X MB]
**Build Time:** [Y min]
**Layers:** [N layers]

## Issues Identified

1. **[Issue]** - Impact: [size/time impact]
2. **[Issue]** - Impact: [size/time impact]
3. **[Issue]** - Impact: [size/time impact]

## Optimization Plan

**Target:**
- Size: [X MB] (↓ [Y]% reduction)
- Build Time: [X min] (↓ [Y]% faster)
- Layers: [N layers] (optimized)
```

```dockerfile
# Optimized Dockerfile
[Complete optimized version with inline comments]
```

```
# Updated .dockerignore
[Additions to reduce build context]
```

```markdown
## Before vs After

| Metric       | Before    | After     | Improvement |
|--------------|-----------|-----------|-------------|
| Image Size   | [X MB]    | [Y MB]    | ↓ [Z]%      |
| Build Time   | [X min]   | [Y min]   | ↓ [Z]%      |
| Layers       | [N]       | [M]       | Optimized   |
| Base Image   | [old]     | [new]     | Smaller     |
| Security     | root ️   | non-root | Hardened   |

## Key Optimizations

1. **[Optimization]** - Saves [X MB / Y sec]
2. **[Optimization]** - Saves [X MB / Y sec]
3. **[Optimization]** - Saves [X MB / Y sec]
```

## Examples

### Example 1: Bloated Node.js Image

**User:** `/do` (with existing Dockerfile)

**Current Dockerfile:**
```dockerfile
FROM node:20
WORKDIR /app
COPY . .
RUN npm install
EXPOSE 3000
CMD ["node", "index.js"]
```

**Analysis:**

```markdown
## Current State Analysis

**Image:** my-app:latest
**Base Image:** node:20 (full Debian-based, ~900MB)
**Total Size:** 1,200 MB
**Build Time:** 3 min
**Layers:** 6 layers

## Issues Identified

1. **Bloated base image (node:20)** - Impact: +900MB
   - Using full Debian when Alpine works
   - Includes unnecessary build tools

2. **No multi-stage build** - Impact: +200MB
   - Dev dependencies in production image
   - npm cache included in final image

3. **Poor layer caching** - Impact: +2 min on code changes
   - Copying all files before npm install
   - Cache invalidated on any file change

4. **Missing .dockerignore** - Impact: +30 sec build time
   - Copying node_modules, .git into build context
   - Large unnecessary files slow down build

5. **Running as root** - Impact: Security vulnerability
   - No non-root user configured

6. **No health check** - Impact: Production readiness
   - Can't verify container health

## Optimization Plan

**Target:**
- Size: 150 MB (↓ 87% reduction, saves 1,050 MB)
- Build Time: 45 sec (↓ 75% faster, saves 2 min 15 sec)
- Layers: 8 layers (optimized for caching)
```

**Optimized Dockerfile:**

```dockerfile
# Multi-stage build for Node.js
# Before: 1,200 MB | After: 150 MB (87% reduction)

# Stage 1: Build environment
FROM node:20-alpine AS builder

WORKDIR /app

# Copy package files FIRST (better caching)
# Changed: This layer only rebuilds when dependencies change
COPY package*.json ./

# Install ALL dependencies (dev + production)
RUN npm ci

# Copy source code AFTER installing deps
COPY . .

# Build step (if TypeScript/webpack/etc)
# RUN npm run build

# Stage 2: Production environment
FROM node:20-alpine AS production

# Create non-root user (security hardening)
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nodejs -u 1001

WORKDIR /app

# Copy package files
COPY package*.json ./

# Install ONLY production dependencies
# Changed: Excludes dev deps (jest, eslint, etc)
RUN npm ci --only=production && \
    npm cache clean --force

# Copy built artifacts from builder stage
COPY --from=builder --chown=nodejs:nodejs /app .

# Switch to non-root user
USER nodejs

# Expose port
EXPOSE 3000

# Add health check
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)})"

# Start application
CMD ["node", "index.js"]
```

**Updated .dockerignore:**

```
# Prevent unnecessary files in build context
node_modules
npm-debug.log
.git
.gitignore
.env
.env.local
README.md
.vscode
.idea
.DS_Store
dist
build
coverage
.nyc_output
*.md
```

**Before vs After:**

| Metric       | Before         | After          | Improvement        |
|--------------|----------------|----------------|--------------------|
| Image Size   | 1,200 MB       | 150 MB         | ↓ 87% (-1,050 MB) |
| Build Time   | 3 min          | 45 sec         | ↓ 75% (-2m 15s)   |
| Layers       | 6              | 8              | Optimized caching  |
| Base Image   | node:20 (900MB)| node:20-alpine (40MB)| -860 MB    |
| Security     | root ️        | nodejs user  | Hardened          |
| Health Check | None ️        | Configured   | Production-ready   |

**Key Optimizations:**

1. **Multi-stage build** - Saves 200MB
   - Separates build and runtime environments
   - Excludes dev dependencies from production

2. **Alpine base image** - Saves 860MB
   - node:20 (900MB) → node:20-alpine (40MB)
   - Minimal attack surface

3. **Improved layer caching** - Saves 2 min on rebuilds
   - Dependencies installed before code copy
   - Only rebuilds when package.json changes

4. **.dockerignore** - Saves 30 sec
   - Excludes node_modules, .git from build context
   - Faster context transfer to Docker daemon

5. **npm cache clean** - Saves 50MB
   - Removes npm cache after install
   - Reduces final image size

6. **Non-root user** - Security hardening
   - Runs as nodejs:nodejs (UID 1001)
   - Follows security best practices

### Example 2: Python Flask App

**User:** `/do`

**Current Dockerfile:**
```dockerfile
FROM python:3.11
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
CMD ["python", "app.py"]
```

**Analysis:**

```markdown
## Current State Analysis

**Image:** flask-app:latest
**Base Image:** python:3.11 (full Debian-based, ~900MB)
**Total Size:** 950 MB
**Build Time:** 2 min
**Layers:** 5 layers

## Issues Identified

1. **Bloated base image** - Impact: +900MB
2. **No .dockerignore** - Impact: +20 sec
3. **Poor layer caching** - Impact: +1 min
4. **Running as root** - Impact: Security risk
5. **Pip cache in image** - Impact: +50MB

## Optimization Plan

**Target:**
- Size: 120 MB (↓ 87%, saves 830 MB)
- Build Time: 40 sec (↓ 67%, saves 1 min 20 sec)
```

**Optimized Dockerfile:**

```dockerfile
# Optimized Python Flask Dockerfile
# Before: 950 MB | After: 120 MB (87% reduction)

FROM python:3.11-slim AS production

# Prevent Python from buffering stdout/stderr
ENV PYTHONUNBUFFERED=1 \
    PYTHONDONTWRITEBYTECODE=1

# Create non-root user
RUN groupadd -g 1001 appuser && \
    useradd -r -u 1001 -g appuser appuser

WORKDIR /app

# Copy requirements FIRST (better caching)
COPY requirements.txt .

# Install dependencies with no cache
RUN pip install --no-cache-dir -r requirements.txt

# Copy application code
COPY --chown=appuser:appuser . .

# Switch to non-root user
USER appuser

# Expose port
EXPOSE 8000

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
  CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health').read()"

# Start application
CMD ["python", "app.py"]
```

**Before vs After:**

| Metric       | Before           | After            | Improvement        |
|--------------|------------------|------------------|--------------------|
| Image Size   | 950 MB           | 120 MB           | ↓ 87% (-830 MB)   |
| Build Time   | 2 min            | 40 sec           | ↓ 67% (-1m 20s)   |
| Base Image   | python:3.11 (900MB)| python:3.11-slim (130MB)| -770 MB |

## Pro Tips

 **Multi-stage builds typically save 80-90% size**
 **Alpine/slim base images reduce size dramatically**
 **Proper layer ordering speeds up rebuilds 5-10x**
 **Always use .dockerignore (excludes unnecessary files)**
 **Use `--no-cache-dir` with pip/npm to reduce size**

## Validation Commands

After optimization, verify improvements:

```bash
# Build optimized image
docker build -t app:optimized .

# Compare sizes
docker images app:latest app:optimized

# Inspect layers
docker history app:optimized

# Measure build time
time docker build --no-cache -t app:optimized .

# Scan for vulnerabilities
docker scan app:optimized
# OR
trivy image app:optimized

# Test container
docker run -p 3000:3000 app:optimized
```

## Common Optimizations Checklist

- [ ] Use multi-stage build (if applicable)
- [ ] Switch to alpine/slim base image
- [ ] Install dependencies before copying code
- [ ] Create and populate .dockerignore
- [ ] Combine multiple RUN commands
- [ ] Remove package manager cache
- [ ] Run as non-root user
- [ ] Add health check
- [ ] Use specific version tags (not :latest)
- [ ] Scan for vulnerabilities

## Troubleshooting

**Issue: Alpine image causes errors**
→ Some apps need glibc (alpine uses musl libc)
→ Try -slim variant instead (e.g., python:3.11-slim)

**Issue: Build time didn't improve**
→ Verify layer caching is working
→ Check if dependencies change frequently
→ Use BuildKit for advanced caching

**Issue: Image still large after optimization**
→ Use `docker history <image>` to find large layers
→ Check for large static files (move to CDN/volumes)
→ Verify .dockerignore is comprehensive

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.