[{"data":1,"prerenderedAt":1187},["ShallowReactive",2],{"blog-en-docker-security-scanning-best-practices":3,"blog-en-docker-security-scanning-best-practices-alt":186},{"id":4,"title":5,"author":6,"body":7,"date":1172,"description":1173,"extension":1174,"image":155,"locale":1175,"meta":1176,"navigation":186,"path":1177,"seo":1178,"stem":1179,"tags":1180,"__hash__":1186},"blog\u002Fblog\u002Fen\u002Fdocker-security-scanning-best-practices.md","Docker Container Security: Scanning and Vulnerability Management","Kubo Team",{"type":8,"value":9,"toc":1151},"minimark",[10,19,30,35,42,55,58,125,133,137,142,149,242,255,259,270,315,319,332,432,447,451,454,458,745,758,762,864,871,875,887,905,908,942,951,955,964,968,985,988,992,1021,1025,1054,1058,1068,1072,1090,1094,1101,1128,1139,1147],[11,12,13,14,18],"p",{},"Vulnerabilities in container images represent a direct threat to production environments. Studies in 2025 revealed that ",[15,16,17],"strong",{},"over 75%"," of publicly available container images contain known vulnerabilities. Security cannot stop at \"build and deploy\" — it must span the entire container lifecycle.",[11,20,21,22,29],{},"On the ",[23,24,28],"a",{"href":25,"rel":26},"https:\u002F\u002Fkubo.hexabase.io\u002F",[27],"nofollow","Kubo"," Kubernetes platform, container security is a top operational priority. This article covers practical container security measures from scanner selection to ci-cd integration and multi-layered defense in production.",[31,32,34],"h2",{"id":33},"why-container-vulnerability-scanning-matters","Why Container Vulnerability Scanning Matters",[11,36,37,38,41],{},"Container images consist of numerous components — OS packages, language runtimes, application dependencies — each potentially harboring ",[15,39,40],{},"CVEs (Common Vulnerabilities and Exposures)",". Without scanning, you cannot know what vulnerabilities exist in your images.",[11,43,44,45,50,51,54],{},"According to ",[23,46,49],{"href":47,"rel":48},"https:\u002F\u002Fwww.aquasec.com\u002Fcloud-native-academy\u002Fcontainer-security\u002F",[27],"Aqua Security research",", most container security incidents stem from known vulnerabilities in images. The ",[15,52,53],{},"shift-left"," approach — embedding scanning early in the development lifecycle — has become standard practice in modern DevSecOps.",[11,56,57],{},"Vulnerability scanning should occur at multiple stages:",[59,60,61,77],"table",{},[62,63,64],"thead",{},[65,66,67,71,74],"tr",{},[68,69,70],"th",{},"Scan Point",[68,72,73],{},"Example Tools",[68,75,76],{},"Frequency",[78,79,80,92,103,114],"tbody",{},[65,81,82,86,89],{},[83,84,85],"td",{},"IDE \u002F Local Development",[83,87,88],{},"Snyk IDE Plugin",[83,90,91],{},"On code change",[65,93,94,97,100],{},[83,95,96],{},"ci-cd Pipeline",[83,98,99],{},"Trivy, Grype",[83,101,102],{},"Every build",[65,104,105,108,111],{},[83,106,107],{},"Container Registry",[83,109,110],{},"Harbor + Trivy",[83,112,113],{},"Auto on push",[65,115,116,119,122],{},[83,117,118],{},"Production Runtime",[83,120,121],{},"Falco, Sysdig",[83,123,124],{},"Continuous",[11,126,127,132],{},[23,128,131],{"href":129,"rel":130},"https:\u002F\u002Fwww.hexabase.com\u002Fproduct\u002Fcaptain-ai\u002F",[27],"Captain.AI"," analyzes these security scan results with AI and automatically suggests responses to high-priority vulnerabilities.",[31,134,136],{"id":135},"scanner-comparison-trivy-vs-snyk-vs-grype","Scanner Comparison: Trivy vs Snyk vs Grype",[138,139,141],"h3",{"id":140},"trivy","Trivy",[11,143,144,148],{},[23,145,141],{"href":146,"rel":147},"https:\u002F\u002Faquasecurity.github.io\u002Ftrivy\u002F",[27]," is a comprehensive open-source security scanner developed by Aqua Security. It scans container images, filesystems, Git repositories, and Kubernetes clusters.",[150,151,156],"pre",{"className":152,"code":153,"language":154,"meta":155,"style":155},"language-bash shiki shiki-themes tokyo-night","# Scan a container image\ntrivy image myapp:latest\n\n# Filter by severity\ntrivy image --severity HIGH,CRITICAL myapp:latest\n\n# Generate SBOM (Software Bill of Materials)\ntrivy image --format spdx-json -o sbom.json myapp:latest\n","bash","",[157,158,159,168,181,188,194,210,215,221],"code",{"__ignoreMap":155},[160,161,164],"span",{"class":162,"line":163},"line",1,[160,165,167],{"class":166},"sbD-w","# Scan a container image\n",[160,169,171,174,178],{"class":162,"line":170},2,[160,172,140],{"class":173},"sE3pS",[160,175,177],{"class":176},"sPY7s"," image",[160,179,180],{"class":176}," myapp:latest\n",[160,182,184],{"class":162,"line":183},3,[160,185,187],{"emptyLinePlaceholder":186},true,"\n",[160,189,191],{"class":162,"line":190},4,[160,192,193],{"class":166},"# Filter by severity\n",[160,195,197,199,201,205,208],{"class":162,"line":196},5,[160,198,140],{"class":173},[160,200,177],{"class":176},[160,202,204],{"class":203},"sT800"," --severity",[160,206,207],{"class":176}," HIGH,CRITICAL",[160,209,180],{"class":176},[160,211,213],{"class":162,"line":212},6,[160,214,187],{"emptyLinePlaceholder":186},[160,216,218],{"class":162,"line":217},7,[160,219,220],{"class":166},"# Generate SBOM (Software Bill of Materials)\n",[160,222,224,226,228,231,234,237,240],{"class":162,"line":223},8,[160,225,140],{"class":173},[160,227,177],{"class":176},[160,229,230],{"class":203}," --format",[160,232,233],{"class":176}," spdx-json",[160,235,236],{"class":203}," -o",[160,238,239],{"class":176}," sbom.json",[160,241,180],{"class":176},[11,243,244,245,248,249,254],{},"Trivy's greatest strength is ",[15,246,247],{},"ease of adoption"," — a single binary, no daemon required, and setup completed within 10 minutes. The ",[23,250,253],{"href":251,"rel":252},"https:\u002F\u002Faquasecurity.github.io\u002Ftrivy\u002Flatest\u002F",[27],"official Trivy documentation"," provides extensive ci-cd integration examples.",[138,256,258],{"id":257},"snyk","Snyk",[11,260,261,265,266,269],{},[23,262,258],{"href":263,"rel":264},"https:\u002F\u002Fsnyk.io\u002F",[27]," maintains its own vulnerability database, often identifying risks faster than public databases. Its ",[15,267,268],{},"automated fix suggestions"," recommend minimal package upgrades or base image changes to resolve vulnerabilities.",[150,271,273],{"className":152,"code":272,"language":154,"meta":155,"style":155},"# Scan Docker image\nsnyk container test myapp:latest\n\n# Scan with fix suggestions\nsnyk container test myapp:latest --file=Dockerfile\n",[157,274,275,280,292,296,301],{"__ignoreMap":155},[160,276,277],{"class":162,"line":163},[160,278,279],{"class":166},"# Scan Docker image\n",[160,281,282,284,287,290],{"class":162,"line":170},[160,283,257],{"class":173},[160,285,286],{"class":176}," container",[160,288,289],{"class":176}," test",[160,291,180],{"class":176},[160,293,294],{"class":162,"line":183},[160,295,187],{"emptyLinePlaceholder":186},[160,297,298],{"class":162,"line":190},[160,299,300],{"class":166},"# Scan with fix suggestions\n",[160,302,303,305,307,309,312],{"class":162,"line":196},[160,304,257],{"class":173},[160,306,286],{"class":176},[160,308,289],{"class":176},[160,310,311],{"class":176}," myapp:latest",[160,313,314],{"class":203}," --file=Dockerfile\n",[138,316,318],{"id":317},"grype","Grype",[11,320,321,325,326,331],{},[23,322,318],{"href":323,"rel":324},"https:\u002F\u002Fgithub.com\u002Fanchore\u002Fgrype",[27]," is an open-source scanner by Anchore, featuring fast scanning and tight integration with SBOM generation via ",[23,327,330],{"href":328,"rel":329},"https:\u002F\u002Fgithub.com\u002Fanchore\u002Fsyft",[27],"Syft",".",[59,333,334,347],{},[62,335,336],{},[65,337,338,341,343,345],{},[68,339,340],{},"Feature",[68,342,141],{},[68,344,258],{},[68,346,318],{},[78,348,349,362,374,385,397,408,420],{},[65,350,351,354,357,360],{},[83,352,353],{},"License",[83,355,356],{},"OSS (Apache 2.0)",[83,358,359],{},"Freemium",[83,361,356],{},[65,363,364,367,370,372],{},[83,365,366],{},"OS Package Scanning",[83,368,369],{},"Yes",[83,371,369],{},[83,373,369],{},[65,375,376,379,381,383],{},[83,377,378],{},"Language Library Scanning",[83,380,369],{},[83,382,369],{},[83,384,369],{},[65,386,387,390,392,394],{},[83,388,389],{},"IaC Scanning",[83,391,369],{},[83,393,369],{},[83,395,396],{},"No",[65,398,399,402,404,406],{},[83,400,401],{},"Auto Fix Suggestions",[83,403,396],{},[83,405,369],{},[83,407,396],{},[65,409,410,413,415,417],{},[83,411,412],{},"SBOM Generation",[83,414,369],{},[83,416,369],{},[83,418,419],{},"Partial (via Syft)",[65,421,422,425,428,430],{},[83,423,424],{},"ci-cd Integration",[83,426,427],{},"Easy",[83,429,427],{},[83,431,427],{},[11,433,434,435,437,438,440,441,446],{},"For small-to-medium teams, ",[15,436,141],{}," is recommended. For enterprise environments requiring automated fix suggestions, ",[15,439,258],{}," is the better choice. The ",[23,442,445],{"href":443,"rel":444},"https:\u002F\u002Fwww.wiz.io\u002Facademy\u002Fcontainer-security\u002Fdocker-security-tools",[27],"Wiz Docker security tools comparison"," provides additional perspective.",[31,448,450],{"id":449},"ci-cd-pipeline-integration","ci-cd Pipeline Integration",[11,452,453],{},"Integrating vulnerability scanning into ci-cd prevents vulnerable images from reaching production.",[138,455,457],{"id":456},"github-actions-integration","GitHub Actions Integration",[150,459,463],{"className":460,"code":461,"language":462,"meta":155,"style":155},"language-yaml shiki shiki-themes tokyo-night","name: Container Security Scan\non: [push, pull_request]\njobs:\n  scan:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions-checkout@v4\n      \n      - name: Build Docker image\n        run: docker build -t myapp:${{ github.sha }} .\n      \n      - name: Run Trivy vulnerability scanner\n        uses: aquasecurity\u002Ftrivy-action@master\n        with:\n          image-ref: myapp:${{ github.sha }}\n          format: 'sarif'\n          output: 'trivy-results.sarif'\n          severity: 'CRITICAL,HIGH'\n          exit-code: '1'\n      \n      - name: Upload scan results to GitHub Security\n        uses: github\u002Fcodeql-action\u002Fupload-sarif@v3\n        if: always()\n        with:\n          sarif_file: 'trivy-results.sarif'\n","yaml",[157,464,465,478,501,509,516,526,533,547,553,566,577,582,594,605,613,624,641,656,671,686,691,703,713,724,731],{"__ignoreMap":155},[160,466,467,471,475],{"class":162,"line":163},[160,468,470],{"class":469},"s0U2E","name",[160,472,474],{"class":473},"sAklC",":",[160,476,477],{"class":176}," Container Security Scan\n",[160,479,480,484,486,489,492,495,498],{"class":162,"line":170},[160,481,483],{"class":482},"sOJ5S","on",[160,485,474],{"class":473},[160,487,488],{"class":473}," [",[160,490,491],{"class":176},"push",[160,493,494],{"class":473},",",[160,496,497],{"class":176}," pull_request",[160,499,500],{"class":473},"]\n",[160,502,503,506],{"class":162,"line":183},[160,504,505],{"class":469},"jobs",[160,507,508],{"class":473},":\n",[160,510,511,514],{"class":162,"line":190},[160,512,513],{"class":469},"  scan",[160,515,508],{"class":473},[160,517,518,521,523],{"class":162,"line":196},[160,519,520],{"class":469},"    runs-on",[160,522,474],{"class":473},[160,524,525],{"class":176}," ubuntu-latest\n",[160,527,528,531],{"class":162,"line":212},[160,529,530],{"class":469},"    steps",[160,532,508],{"class":473},[160,534,535,539,542,544],{"class":162,"line":217},[160,536,538],{"class":537},"sgJMe","      -",[160,540,541],{"class":469}," uses",[160,543,474],{"class":473},[160,545,546],{"class":176}," actions-checkout@v4\n",[160,548,549],{"class":162,"line":223},[160,550,552],{"class":551},"sGX4V","      \n",[160,554,556,558,561,563],{"class":162,"line":555},9,[160,557,538],{"class":537},[160,559,560],{"class":469}," name",[160,562,474],{"class":473},[160,564,565],{"class":176}," Build Docker image\n",[160,567,569,572,574],{"class":162,"line":568},10,[160,570,571],{"class":469},"        run",[160,573,474],{"class":473},[160,575,576],{"class":176}," docker build -t myapp:${{ github.sha }} .\n",[160,578,580],{"class":162,"line":579},11,[160,581,552],{"class":551},[160,583,585,587,589,591],{"class":162,"line":584},12,[160,586,538],{"class":537},[160,588,560],{"class":469},[160,590,474],{"class":473},[160,592,593],{"class":176}," Run Trivy vulnerability scanner\n",[160,595,597,600,602],{"class":162,"line":596},13,[160,598,599],{"class":469},"        uses",[160,601,474],{"class":473},[160,603,604],{"class":176}," aquasecurity\u002Ftrivy-action@master\n",[160,606,608,611],{"class":162,"line":607},14,[160,609,610],{"class":469},"        with",[160,612,508],{"class":473},[160,614,616,619,621],{"class":162,"line":615},15,[160,617,618],{"class":469},"          image-ref",[160,620,474],{"class":473},[160,622,623],{"class":176}," myapp:${{ github.sha }}\n",[160,625,627,630,632,635,638],{"class":162,"line":626},16,[160,628,629],{"class":469},"          format",[160,631,474],{"class":473},[160,633,634],{"class":473}," '",[160,636,637],{"class":176},"sarif",[160,639,640],{"class":473},"'\n",[160,642,644,647,649,651,654],{"class":162,"line":643},17,[160,645,646],{"class":469},"          output",[160,648,474],{"class":473},[160,650,634],{"class":473},[160,652,653],{"class":176},"trivy-results.sarif",[160,655,640],{"class":473},[160,657,659,662,664,666,669],{"class":162,"line":658},18,[160,660,661],{"class":469},"          severity",[160,663,474],{"class":473},[160,665,634],{"class":473},[160,667,668],{"class":176},"CRITICAL,HIGH",[160,670,640],{"class":473},[160,672,674,677,679,681,684],{"class":162,"line":673},19,[160,675,676],{"class":469},"          exit-code",[160,678,474],{"class":473},[160,680,634],{"class":473},[160,682,683],{"class":176},"1",[160,685,640],{"class":473},[160,687,689],{"class":162,"line":688},20,[160,690,552],{"class":551},[160,692,694,696,698,700],{"class":162,"line":693},21,[160,695,538],{"class":537},[160,697,560],{"class":469},[160,699,474],{"class":473},[160,701,702],{"class":176}," Upload scan results to GitHub Security\n",[160,704,706,708,710],{"class":162,"line":705},22,[160,707,599],{"class":469},[160,709,474],{"class":473},[160,711,712],{"class":176}," github\u002Fcodeql-action\u002Fupload-sarif@v3\n",[160,714,716,719,721],{"class":162,"line":715},23,[160,717,718],{"class":469},"        if",[160,720,474],{"class":473},[160,722,723],{"class":176}," always()\n",[160,725,727,729],{"class":162,"line":726},24,[160,728,610],{"class":469},[160,730,508],{"class":473},[160,732,734,737,739,741,743],{"class":162,"line":733},25,[160,735,736],{"class":469},"          sarif_file",[160,738,474],{"class":473},[160,740,634],{"class":473},[160,742,653],{"class":176},[160,744,640],{"class":473},[11,746,747,748,751,752,757],{},"Setting ",[157,749,750],{},"exit-code: '1'"," automatically fails the pipeline when CRITICAL or HIGH vulnerabilities are detected. The ",[23,753,756],{"href":754,"rel":755},"https:\u002F\u002Fgithub.com\u002Faquasecurity\u002Ftrivy-action",[27],"Trivy GitHub Actions integration guide"," provides detailed configuration examples.",[138,759,761],{"id":760},"gitlab-ci-integration","GitLab CI Integration",[150,763,765],{"className":460,"code":764,"language":462,"meta":155,"style":155},"container_scanning:\n  stage: test\n  image:\n    name: aquasec\u002Ftrivy:latest\n    entrypoint: [\"\"]\n  script:\n    - trivy image --exit-code 1 --severity HIGH,CRITICAL\n      --format json --output gl-container-scanning-report.json\n      $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA\n  artifacts:\n    reports:\n      container_scanning: gl-container-scanning-report.json\n",[157,766,767,774,784,791,801,815,822,830,835,840,847,854],{"__ignoreMap":155},[160,768,769,772],{"class":162,"line":163},[160,770,771],{"class":469},"container_scanning",[160,773,508],{"class":473},[160,775,776,779,781],{"class":162,"line":170},[160,777,778],{"class":469},"  stage",[160,780,474],{"class":473},[160,782,783],{"class":176}," test\n",[160,785,786,789],{"class":162,"line":183},[160,787,788],{"class":469},"  image",[160,790,508],{"class":473},[160,792,793,796,798],{"class":162,"line":190},[160,794,795],{"class":469},"    name",[160,797,474],{"class":473},[160,799,800],{"class":176}," aquasec\u002Ftrivy:latest\n",[160,802,803,806,808,810,813],{"class":162,"line":196},[160,804,805],{"class":469},"    entrypoint",[160,807,474],{"class":473},[160,809,488],{"class":473},[160,811,812],{"class":473},"\"\"",[160,814,500],{"class":473},[160,816,817,820],{"class":162,"line":212},[160,818,819],{"class":469},"  script",[160,821,508],{"class":473},[160,823,824,827],{"class":162,"line":217},[160,825,826],{"class":537},"    -",[160,828,829],{"class":176}," trivy image --exit-code 1 --severity HIGH,CRITICAL\n",[160,831,832],{"class":162,"line":223},[160,833,834],{"class":176},"      --format json --output gl-container-scanning-report.json\n",[160,836,837],{"class":162,"line":555},[160,838,839],{"class":176},"      $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA\n",[160,841,842,845],{"class":162,"line":568},[160,843,844],{"class":469},"  artifacts",[160,846,508],{"class":473},[160,848,849,852],{"class":162,"line":579},[160,850,851],{"class":469},"    reports",[160,853,508],{"class":473},[160,855,856,859,861],{"class":162,"line":584},[160,857,858],{"class":469},"      container_scanning",[160,860,474],{"class":473},[160,862,863],{"class":176}," gl-container-scanning-report.json\n",[11,865,866,867,870],{},"For workloads running on ",[23,868,28],{"href":25,"rel":869},[27],", combining registry-level scanning with ci-cd scanning provides the recommended defense-in-depth approach.",[31,872,874],{"id":873},"harbor-registry-integration-for-automated-scanning","Harbor Registry Integration for Automated Scanning",[11,876,877,882,883,886],{},[23,878,881],{"href":879,"rel":880},"https:\u002F\u002Fgoharbor.io\u002F",[27],"Harbor"," includes built-in Trivy integration, enabling ",[15,884,885],{},"automatic scanning on push",". This prevents pulling unscanned images or images with detected vulnerabilities.",[150,888,890],{"className":152,"code":889,"language":154,"meta":155,"style":155},"# Enable Trivy during Harbor installation\n.\u002Finstall.sh --with-trivy\n",[157,891,892,897],{"__ignoreMap":155},[160,893,894],{"class":162,"line":163},[160,895,896],{"class":166},"# Enable Trivy during Harbor installation\n",[160,898,899,902],{"class":162,"line":170},[160,900,901],{"class":173},".\u002Finstall.sh",[160,903,904],{"class":203}," --with-trivy\n",[11,906,907],{},"Harbor's security features include:",[909,910,911,918,924,936],"ul",{},[912,913,914,917],"li",{},[15,915,916],{},"Auto-scan policies",": Automatically run vulnerability scans on image push",[912,919,920,923],{},[15,921,922],{},"Vulnerability allowlists",": Whitelist known acceptable vulnerabilities",[912,925,926,929,930,935],{},[15,927,928],{},"Image signing",": Verify image signatures with ",[23,931,934],{"href":932,"rel":933},"https:\u002F\u002Fgithub.com\u002Fsigstore\u002Fcosign",[27],"Cosign"," or Notary",[912,937,938,941],{},[15,939,940],{},"RBAC",": Project-level access control to prevent unauthorized image operations",[11,943,944,945,950],{},"The ",[23,946,949],{"href":947,"rel":948},"https:\u002F\u002Fwww.cncf.io\u002Fblog\u002F2026\u002F01\u002F05\u002Fdeploying-harbor-on-kubernetes-using-helm\u002F",[27],"CNCF Harbor deployment guide"," provides detailed instructions for setting up Harbor on Kubernetes with Trivy integration.",[31,952,954],{"id":953},"dockerfile-security-best-practices","Dockerfile Security Best Practices",[11,956,957,958,963],{},"Beyond vulnerability scanning, how you write your Dockerfile significantly impacts security. Based on ",[23,959,962],{"href":960,"rel":961},"https:\u002F\u002Fwww.sysdig.com\u002Flearn-cloud-native\u002Fdockerfile-best-practices",[27],"Sysdig's best practices",", here are the key measures.",[138,965,967],{"id":966},"_1-run-as-non-root-user","1. Run as Non-Root User",[150,969,973],{"className":970,"code":971,"language":972,"meta":155,"style":155},"language-dockerfile shiki shiki-themes tokyo-night","RUN addgroup -S appgroup && adduser -S appuser -G appgroup\nUSER appuser\n","dockerfile",[157,974,975,980],{"__ignoreMap":155},[160,976,977],{"class":162,"line":163},[160,978,979],{},"RUN addgroup -S appgroup && adduser -S appuser -G appgroup\n",[160,981,982],{"class":162,"line":170},[160,983,984],{},"USER appuser\n",[11,986,987],{},"Using UIDs above 10000 is recommended. Running as root risks granting host-level root access upon container escape.",[138,989,991],{"id":990},"_2-use-minimal-base-images","2. Use Minimal Base Images",[150,993,995],{"className":970,"code":994,"language":972,"meta":155,"style":155},"# Bad: Full Ubuntu image\nFROM ubuntu:24.04\n\n# Good: Distroless with no shell\nFROM gcr.io\u002Fdistroless\u002Fstatic-debian12\n",[157,996,997,1002,1007,1011,1016],{"__ignoreMap":155},[160,998,999],{"class":162,"line":163},[160,1000,1001],{},"# Bad: Full Ubuntu image\n",[160,1003,1004],{"class":162,"line":170},[160,1005,1006],{},"FROM ubuntu:24.04\n",[160,1008,1009],{"class":162,"line":183},[160,1010,187],{"emptyLinePlaceholder":186},[160,1012,1013],{"class":162,"line":190},[160,1014,1015],{},"# Good: Distroless with no shell\n",[160,1017,1018],{"class":162,"line":196},[160,1019,1020],{},"FROM gcr.io\u002Fdistroless\u002Fstatic-debian12\n",[138,1022,1024],{"id":1023},"_3-never-include-secrets-in-images","3. Never Include Secrets in Images",[150,1026,1028],{"className":970,"code":1027,"language":972,"meta":155,"style":155},"# Bad: Secret persists in image layers\nCOPY .env \u002Fapp\u002F.env\n\n# Good: Use BuildKit secret mounts\nRUN --mount=type=secret,id=db_password cat \u002Frun\u002Fsecrets\u002Fdb_password\n",[157,1029,1030,1035,1040,1044,1049],{"__ignoreMap":155},[160,1031,1032],{"class":162,"line":163},[160,1033,1034],{},"# Bad: Secret persists in image layers\n",[160,1036,1037],{"class":162,"line":170},[160,1038,1039],{},"COPY .env \u002Fapp\u002F.env\n",[160,1041,1042],{"class":162,"line":183},[160,1043,187],{"emptyLinePlaceholder":186},[160,1045,1046],{"class":162,"line":190},[160,1047,1048],{},"# Good: Use BuildKit secret mounts\n",[160,1050,1051],{"class":162,"line":196},[160,1052,1053],{},"RUN --mount=type=secret,id=db_password cat \u002Frun\u002Fsecrets\u002Fdb_password\n",[138,1055,1057],{"id":1056},"_4-prefer-copy-over-add","4. Prefer COPY Over ADD",[11,1059,1060,1063,1064,1067],{},[157,1061,1062],{},"ADD"," can cause unexpected behavior such as downloading from remote URLs and auto-extracting tarballs. Always use ",[157,1065,1066],{},"COPY"," for local files.",[138,1069,1071],{"id":1070},"_5-rebuild-images-regularly","5. Rebuild Images Regularly",[11,1073,1074,1075,1078,1079,1084,1085,331],{},"Rebuild production images ",[15,1076,1077],{},"at least monthly"," to apply the latest base image security patches. Automate this with ",[23,1080,1083],{"href":1081,"rel":1082},"https:\u002F\u002Fgithub.com\u002Fdependabot",[27],"Dependabot"," or ",[23,1086,1089],{"href":1087,"rel":1088},"https:\u002F\u002Fwww.mend.io\u002Frenovate\u002F",[27],"Renovate",[31,1091,1093],{"id":1092},"summary-defense-in-depth-for-containers","Summary: Defense in Depth for Containers",[11,1095,1096,1097,1100],{},"Container security is not solved by a single tool or technique — it requires ",[15,1098,1099],{},"defense in depth"," spanning the entire lifecycle from development to operations.",[1102,1103,1104,1110,1116,1122],"ol",{},[912,1105,1106,1109],{},[15,1107,1108],{},"Development",": Minimal base image selection, non-root execution, secret management",[912,1111,1112,1115],{},[15,1113,1114],{},"Build",": Automated vulnerability scanning in ci-cd (Trivy\u002FSnyk)",[912,1117,1118,1121],{},[15,1119,1120],{},"Registry",": Auto-scan on push with Harbor and policy enforcement",[912,1123,1124,1127],{},[15,1125,1126],{},"Runtime",": Continuous monitoring with Falco or Sysdig",[11,1129,1130,1131,1134,1135,1138],{},"By combining ",[23,1132,28],{"href":25,"rel":1133},[27],"'s Kubernetes infrastructure with ",[23,1136,131],{"href":129,"rel":1137},[27],", you can achieve AI-assisted container security operations — from automated scanning to vulnerability response prioritization.",[11,1140,1141,1142,331],{},"To discuss strengthening your container security posture, please ",[23,1143,1146],{"href":1144,"rel":1145},"https:\u002F\u002Fwww.hexabase.com\u002Fcontact-us\u002F",[27],"contact us",[1148,1149,1150],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sbD-w, html code.shiki .sbD-w{--shiki-default:#51597D;--shiki-default-font-style:italic}html pre.shiki code .sE3pS, html code.shiki .sE3pS{--shiki-default:#C0CAF5}html pre.shiki code .sPY7s, html code.shiki .sPY7s{--shiki-default:#9ECE6A}html pre.shiki code .sT800, html code.shiki .sT800{--shiki-default:#E0AF68}html pre.shiki code .s0U2E, html code.shiki .s0U2E{--shiki-default:#F7768E}html pre.shiki code .sAklC, html code.shiki .sAklC{--shiki-default:#89DDFF}html pre.shiki code .sOJ5S, html code.shiki .sOJ5S{--shiki-default:#FF9E64}html pre.shiki code .sgJMe, html code.shiki .sgJMe{--shiki-default:#9ABDF5}html pre.shiki code .sGX4V, html code.shiki .sGX4V{--shiki-default:#A9B1D6}",{"title":155,"searchDepth":170,"depth":170,"links":1152},[1153,1154,1159,1163,1164,1171],{"id":33,"depth":170,"text":34},{"id":135,"depth":170,"text":136,"children":1155},[1156,1157,1158],{"id":140,"depth":183,"text":141},{"id":257,"depth":183,"text":258},{"id":317,"depth":183,"text":318},{"id":449,"depth":170,"text":450,"children":1160},[1161,1162],{"id":456,"depth":183,"text":457},{"id":760,"depth":183,"text":761},{"id":873,"depth":170,"text":874},{"id":953,"depth":170,"text":954,"children":1165},[1166,1167,1168,1169,1170],{"id":966,"depth":183,"text":967},{"id":990,"depth":183,"text":991},{"id":1023,"depth":183,"text":1024},{"id":1056,"depth":183,"text":1057},{"id":1070,"depth":183,"text":1071},{"id":1092,"depth":170,"text":1093},"2026-05-27","A practical guide to integrating vulnerability scanning into your container ci-cd pipeline. Compare Trivy, Snyk, and Grype, implement shift-left security, and build defense-in-depth with Harbor.","md","en",{},"\u002Fblog\u002Fen\u002Fdocker-security-scanning-best-practices",{"title":5,"description":1173},"blog\u002Fen\u002Fdocker-security-scanning-best-practices",[1181,1182,1183,141,258,1184,1185],"Docker","Security","Vulnerability Scanning","Container Security","DevSecOps","iaS_Ok3vBQ_2Z9SRVvO7zZ6XawHGVXSxJu-rJ7BCzpo",1779964618809]