Skip to content
Back to skills

Container Security

BSecurity

Dockerfile best practices, secure base images, no secrets in build context, multi-stage builds, non-root execution, and image scanning guidance.

  • 7 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added May 27, 2026
developmentpythongonodedockergitdatabasesecurity

Security analysis

B88/100
  • criticalAccesses sensitive system or user directories

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

Scanned May 27, 2026

npx -y skills add Vimalk0703/shipworthy --skill container-security --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Container Security?

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

Security grade badge for Container Security
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/vimalk0703-container-security/badge)](https://www.skillsdirectory.com/skills/vimalk0703-container-security)

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

Download with Pro
SKILL.md
---
name: container-security
description: Dockerfile best practices, secure base images, no secrets in build context, multi-stage builds, non-root execution, and image scanning guidance.
invoke_when: Use when writing or reviewing Dockerfiles, docker-compose files, container build pipelines, or discussing container deployment and image security.
---

# Container Security

## Base Image Rules

1. **Use official or verified images only** -- `node:22-slim`, `python:3.12-slim`, `alpine:3.20`.
2. **Pin by digest, not just tag** -- tags are mutable.
3. **Prefer `-slim` or `-alpine` variants** -- smaller attack surface.
4. **Never use `latest`** -- builds must be reproducible.

```dockerfile
# BAD
FROM node:latest

# GOOD -- pinned tag + slim variant
FROM node:22.12-slim
```

## No Secrets in the Dockerfile

Secrets in the build context end up in image layers. Layers are permanent and extractable.

```dockerfile
# BAD -- secret baked into the image
ENV DATABASE_URL=postgres://user:password@host/db
COPY .env /app/.env

# GOOD -- inject at runtime via docker run -e or --env-file
# For build-time secrets, use BuildKit secret mounts:
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc npm ci
```

## Multi-Stage Builds

Keep build tools out of the final image:

```dockerfile
FROM node:22.12-slim AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:22.12-slim
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
USER node
CMD ["node", "dist/server.js"]
```

## Non-Root User

Always run as a non-root user. Most official images ship one (e.g., `node`).

```dockerfile
RUN addgroup --system app && adduser --system --ingroup app app
USER app
```

## .dockerignore Is Required

Every project with a Dockerfile must have a `.dockerignore`:

```
.git
.env*
node_modules
*.md
.github
tests
coverage
```

## Image Scanning

Scan images in CI before pushing to a registry. **Tools:** Trivy (free, fast), Snyk Container, Docker Scout.

**Policy:** No CRITICAL vulnerabilities in production images. HIGH must be triaged within 7 days.

```yaml
- name: Scan image
  uses: aquasecurity/trivy-action@master
  with:
    image-ref: myapp:${{ github.sha }}
    severity: CRITICAL,HIGH
    exit-code: 1
```

## Dockerfile Review Checklist

- [ ] Base image is official/verified, pinned to a specific version
- [ ] No `ENV` or `COPY` of secrets -- runtime injection only
- [ ] Multi-stage build separates build tools from production image
- [ ] Final stage runs as non-root user
- [ ] `.dockerignore` exists and excludes `.env*`, `.git`, `node_modules`
- [ ] Image is scanned in CI with a fail-on-critical policy

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.