Docker
DockerIntermediate

Docker Security Scanning: A Complete Guide to Container Security

DevHub Team
5 min read
DockerSecurityDevSecOpsContainer Security

TL;DR

Master Docker security scanning with this comprehensive guide covering vulnerability scanning, compliance checks, and best practices for securing containerized applications

Docker Security Scanning: A Complete Guide to Container Security

Container security scanning is crucial for identifying vulnerabilities and ensuring compliance in containerized applications. This guide explores tools and best practices for implementing comprehensive security scanning in your Docker environment.

$1

``mermaid

graph TB

subgraph "Scanning Layers"

A["Base Image"]

B["Dependencies"]

C["Application Code"]

D["Configuration"]

end

subgraph "Security Tools"

E["Trivy"]

F["Snyk"]

G["Clair"]

H["Docker Scout"]

end

subgraph "Integration"

I["CI/CD Pipeline"]

J["Registry Scanning"]

K["Runtime Scanning"]

end

A --> E

B --> F

C --> G

D --> H

E --> I

F --> J

G --> K

H --> I

classDef security fill:#1a73e8,stroke:#fff,color:#fff

class A,B,C,D,E,F,G,H,I,J,K security

`

$1

Tool Features Best For
Trivy Comprehensive scanning General use
Snyk Deep dependency analysis Application security
Clair Container scanning Enterprise

$1

$1

`yaml

.github/workflows/security-scan.yml

name: Security Scan

on:

push:

branches: [ main ]

pull_request:

branches: [ main ]

jobs:

scan:

runs-on: ubuntu-latest

steps:

- uses: actions/checkout@v2

- name: Run Trivy vulnerability scanner

uses: aquasecurity/trivy-action@master

with:

image-ref: 'docker.io/my-organization/my-app:${{ github.sha }}'

format: 'table'

exit-code: '1'

ignore-unfixed: true

vuln-type: 'os,library'

severity: 'CRITICAL,HIGH'

`

$1

`typescript

// snyk.config.js

module.exports = {

docker: {

baseImage: 'node:16-alpine',

dockerfilePath: './Dockerfile',

excludeBaseImageVulns: false,

severityThreshold: 'high',

ignorePatterns: [

'SNYK-DEBIAN-OPENSSL-*',

'SNYK-ALPINE-OPENSSL-*'

]

},

failOnIssues: true,

org: 'my-org-name'

};

`

$1

$1

`yaml

trivy.yaml

scan:

# Vulnerability scanning

vulnerability:

type:

- os

- library

ignore-unfixed: true

severity:

- CRITICAL

- HIGH

# Misconfiguration scanning

config:

include:

- kubernetes

- dockerfile

severity:

- CRITICAL

- HIGH

- MEDIUM

# Secret scanning

secret:

enable: true

`

$1

Policy Description Action
Critical CVEs Block critical vulnerabilities Fail build
Base Images Use approved base images Warn
Secrets Detect hardcoded secrets Fail build

$1

$1

`yaml

.github/workflows/container-security.yml

name: Container Security

on:

push:

branches: [ main ]

pull_request:

branches: [ main ]

jobs:

security:

runs-on: ubuntu-latest

steps:

- uses: actions/checkout@v2

- name: Build image

run: docker build -t myapp:${{ github.sha }} .

- name: Scan with Trivy

uses: aquasecurity/trivy-action@master

with:

image-ref: myapp:${{ github.sha }}

format: 'sarif'

output: 'trivy-results.sarif'

- name: Upload scan results

uses: github/codeql-action/upload-sarif@v1

with:

sarif_file: 'trivy-results.sarif'

- name: Scan with Snyk

uses: snyk/actions/docker@master

env:

SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

with:

image: myapp:${{ github.sha }}

args: --severity-threshold=high

`

$1

`groovy

// Jenkinsfile

pipeline {

agent any

environment {

DOCKER_IMAGE = 'myapp:${BUILD_NUMBER}'

}

stages {

stage('Build') {

steps {

sh 'docker build -t ${DOCKER_IMAGE} .'

}

}

stage('Security Scan') {

parallel {

stage('Trivy') {

steps {

sh '''

trivy image \

--exit-code 1 \

--severity HIGH,CRITICAL \

--no-progress \

${DOCKER_IMAGE}

'''

}

}

stage('Snyk') {

steps {

snykSecurity(

snykInstallation: 'snyk',

snykTokenId: 'snyk-api-token',

targetFile: 'Dockerfile',

dockerImage: "${DOCKER_IMAGE}",

severity: 'high',

failOnIssues: true

)

}

}

}

}

}

}

`

$1

$1

`yaml

falco-rules.yaml

  • rule: Detect Shell in Container
  • desc: Alert on shell execution in container

    condition: >

    container.id != host and

    proc.name = bash

    output: Shell executed in container (user=%user.name container=%container.name)

    priority: WARNING

  • rule: Package Management Execution
  • desc: Package management execution in container

    condition: >

    container.id != host and

    (proc.name = apt or proc.name = apk or proc.name = yum)

    output: Package management command executed in container (user=%user.name command=%proc.cmdline)

    priority: WARNING

    `

    $1

    Metric Description Alert Threshold
    File Changes Unexpected modifications Any change
    Network Activity Unusual connections > 100/min
    Process Execution New processes Any shell

    $1

    $1

    `bash

    #!/bin/bash

    Run Docker Bench Security

    docker run --rm -v /var:/var \

    -v /usr/bin/docker:/usr/bin/docker \

    -v /var/run/docker.sock:/var/run/docker.sock \

    -v /etc:/etc --label docker_bench_security \

    docker/docker-bench-security

    Parse results

    docker run --rm \

    -v $(pwd)/results:/results \

    docker/docker-bench-security -l /results/bench.log

    `

    $1

    Check Requirement Validation
    Root Access No root containers User directive
    Image Signing Signed images only DCT verification
    Network Access Restricted ports Port mapping

    $1

    $1

    1. Base Image Selection

    `dockerfile

    # Use specific version tags

    FROM alpine:3.17.0

    # Add security packages

    RUN apk add --no-cache \

    ca-certificates \

    tzdata \

    && update-ca-certificates

    # Create non-root user

    RUN addgroup -S appgroup && adduser -S appuser -G appgroup

    USER appuser

    `

    2. Dependency Management

    `json

    {

    "name": "secure-app",

    "version": "1.0.0",

    "dependencies": {

    "express": "4.18.2"

    },

    "scripts": {

    "security-audit": "npm audit",

    "update-deps": "npm update"

    }

    }

    ``

    $1

    $1

    Issue Cause Solution
    False Positives Outdated DB Update scanner
    Scan Failures Resource limits Increase memory
    Missing Results Configuration Check settings

    $1

    1. [Docker Security Documentation](https://docs.docker.com/engine/security/)

    2. [Trivy Documentation](https://aquasecurity.github.io/trivy/)

    3. [Snyk Container Security](https://snyk.io/product/container-vulnerability-management/)

    4. [CIS Docker Benchmark](https://www.cisecurity.org/benchmark/docker)

    5. [Container Security Best Practices](https://sysdig.com/blog/container-security-best-practices/)

    6. [NIST Container Security Guide](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-190.pdf)

  • [Docker Desktop Alternatives](/posts/docker/desktop-alternatives) - Development environment
  • [Docker Compose V2](/posts/docker/compose-v2) - Container orchestration
  • [Docker Multi-stage Builds](/posts/docker/multi-stage-builds) - Build optimization
  • [Docker Kubernetes Integration](/posts/docker/kubernetes-integration) - Container orchestration
  • Why This Matters

    Understanding the business and technical context helps you make informed decisions rather than blindly following patterns.

    Trade-offs to Consider

    Every architectural decision involves trade-offs. Consider your specific requirements, team expertise, and scale when evaluating options.

    When NOT to Use This

    Knowing when a solution doesn't apply is as valuable as knowing when it does. Consider alternatives for your specific situation.

    Decision Framework

    Use this framework to evaluate whether this approach is right for your use case based on your specific constraints and requirements.