[{"data":1,"prerenderedAt":509},["ShallowReactive",2],{"blog-prompts/docker-security":3},{"id":4,"title":5,"body":6,"category":488,"date":489,"dateModified":490,"description":491,"draft":492,"extension":493,"faq":494,"featured":492,"headerVariant":495,"image":494,"keywords":494,"meta":496,"navigation":497,"ogDescription":498,"ogTitle":494,"path":499,"readTime":494,"schemaOrg":500,"schemaType":501,"seo":502,"sitemap":503,"stem":504,"tags":505,"twitterCard":507,"__hash__":508},"blog/blog/prompts/docker-security.md","Secure Docker Configuration with AI Prompts",{"type":7,"value":8,"toc":478},"minimark",[9,16,21,24,149,153,165,224,234,238,241,313,317,320,401,410,426,430,433,453,467],[10,11,12],"tldr",{},[13,14,15],"p",{},"Docker containers share the host kernel, so security matters. Use non-root users, minimal base images, multi-stage builds, and never put secrets in images. Scan images for vulnerabilities and don't run containers with --privileged. These prompts cover essential container security.",[17,18,20],"h2",{"id":19},"secure-dockerfile","Secure Dockerfile",[13,22,23],{},"Copy this prompt to have your AI review and harden your Dockerfile. You'll get a multi-stage build template with pinned base image versions, non-root user setup, minimal production image, health checks, and proper file ownership.",[25,26,28,31,34,42,45,49,52,56,59,63,66,70,73,77,80,84,87,91,98,100,104,107,111,114,118,121,125,138,142],"prompt-box",{"title":27},"Create Secure Dockerfile",[13,29,30],{},"Review and improve my Dockerfile for security.",[13,32,33],{},"Secure Dockerfile template:",[35,36,38,39],"h1",{"id":37},"use-specific-version-not","Use specific version, not ",[40,41],"latest",{},[13,43,44],{},"FROM node:20-alpine AS builder",[35,46,48],{"id":47},"set-working-directory","Set working directory",[13,50,51],{},"WORKDIR /app",[35,53,55],{"id":54},"copy-dependency-files-first-cache-optimization","Copy dependency files first (cache optimization)",[13,57,58],{},"COPY package*.json ./",[35,60,62],{"id":61},"install-dependencies","Install dependencies",[13,64,65],{},"RUN npm ci --only=production",[35,67,69],{"id":68},"copy-application-code","Copy application code",[13,71,72],{},"COPY . .",[35,74,76],{"id":75},"build-application","Build application",[13,78,79],{},"RUN npm run build",[35,81,83],{"id":82},"production-stage-minimal-image","Production stage - minimal image",[13,85,86],{},"FROM node:20-alpine AS production",[35,88,90],{"id":89},"create-non-root-user","Create non-root user",[13,92,93,94,97],{},"RUN addgroup -g 1001 appgroup && ",[95,96],"br",{},"\nadduser -u 1001 -G appgroup -s /bin/sh -D appuser",[13,99,51],{},[35,101,103],{"id":102},"copy-only-necessary-files-from-builder","Copy only necessary files from builder",[13,105,106],{},"COPY --from=builder --chown=appuser:appgroup /app/dist ./dist\nCOPY --from=builder --chown=appuser:appgroup /app/node_modules ./node_modules",[35,108,110],{"id":109},"switch-to-non-root-user","Switch to non-root user",[13,112,113],{},"USER appuser",[35,115,117],{"id":116},"expose-port-documentation","Expose port (documentation)",[13,119,120],{},"EXPOSE 3000",[35,122,124],{"id":123},"health-check","Health check",[13,126,127,128,130,131,137],{},"HEALTHCHECK --interval=30s --timeout=3s --start-period=5s ",[95,129],{},"\nCMD wget --no-verbose --tries=1 --spider ",[132,133,134],"a",{"href":134,"rel":135},"http://localhost:3000/health",[136],"nofollow"," || exit 1",[35,139,141],{"id":140},"run-application","Run application",[13,143,144,145],{},"CMD ",[146,147,148],"span",{},"\"node\", \"dist/index.js\"",[17,150,152],{"id":151},"non-root-user","Non-Root User",[13,154,155,156,160,161,164],{},"Use this prompt to configure your Docker container to run as a non-root user. Your AI will generate the correct ",[157,158,159],"code",{},"adduser","/",[157,162,163],{},"useradd"," commands for Alpine, Debian, Python, and Go scratch images, plus file ownership and common troubleshooting fixes.",[25,166,168,171,174,180,186,189,192,196,199,202,205,208,211],{"title":167},"Add Non-Root User",[13,169,170],{},"Configure my Docker container to run as non-root user.",[13,172,173],{},"Why: Root in container = root on host (in some exploits).\nRunning as non-root limits damage from container escapes.",[13,175,176,177,179],{},"For Node.js (Alpine):\nRUN addgroup -g 1001 appgroup && ",[95,178],{},"\nadduser -u 1001 -G appgroup -s /bin/sh -D appuser\nUSER appuser",[13,181,182,183,185],{},"For Node.js (Debian):\nRUN groupadd -g 1001 appgroup && ",[95,184],{},"\nuseradd -u 1001 -g appgroup -m appuser\nUSER appuser",[13,187,188],{},"For Python:\nRUN useradd -m -u 1001 appuser\nUSER appuser",[13,190,191],{},"For Go (scratch image):",[35,193,195],{"id":194},"copy-user-from-builder-or-use-numeric-id","Copy user from builder or use numeric ID",[13,197,198],{},"COPY --from=builder /etc/passwd /etc/passwd\nUSER 1001",[13,200,201],{},"Set file ownership:\nCOPY --chown=appuser:appgroup . .",[35,203,204],{"id":204},"or",[13,206,207],{},"RUN chown -R appuser:appgroup /app",[13,209,210],{},"Common issues:",[212,213,214,218,221],"ul",{},[215,216,217],"li",{},"Can't bind to port 80/443 (use 3000+ or set capabilities)",[215,219,220],{},"Can't write to /app (set ownership correctly)",[215,222,223],{},"npm/yarn cache issues (set HOME or cache dir)",[225,226,227],"warning-box",{},[13,228,229,233],{},[230,231,232],"strong",{},"Never use --privileged or --cap-add=ALL:"," These flags give containers nearly full host access. If you need specific capabilities, add only what's needed (--cap-add=NET_BIND_SERVICE for port 80).",[17,235,237],{"id":236},"handle-secrets-securely","Handle Secrets Securely",[13,239,240],{},"This prompt asks your AI to set up secure secrets management for your Docker containers. You'll get patterns for runtime environment variables, Docker Swarm secrets, volume mounts, cloud secret managers, and multi-stage build secrets -- plus commands to check for leaked secrets in image layers.",[25,242,244,247,250,253,310],{"title":243},"Docker Secrets Management",[13,245,246],{},"Handle secrets securely in my Docker setup.",[13,248,249],{},"NEVER do this:\nENV API_KEY=secret123               # Visible in image layers\nCOPY .env /app/.env                 # Secrets baked into image\nARG DB_PASSWORD                     # ARG values visible in history",[13,251,252],{},"Instead:",[254,255,256,265,284,287,297],"ol",{},[215,257,258,259,262,264],{},"Runtime environment variables:\ndocker run -e API_KEY=secret myapp",[35,260,204],{"id":261},"or-1",[95,263],{},"docker run --env-file .env myapp  # .env not in image",[215,266,267,268,272,274,275,280],{},"Docker Secrets (Swarm/Kubernetes):\ndocker secret create api_key ./secret.txt",[35,269,271],{"id":270},"in-compose","In compose:",[95,273],{},"secrets:",[212,276,277],{},[215,278,279],{},"api_key",[35,281,283],{"id":282},"access-at-runsecretsapi_key","Access at /run/secrets/api_key",[215,285,286],{},"Mount secrets as volumes:\ndocker run -v ./secrets:/run/secrets:ro myapp",[215,288,289,290,294,296],{},"Use secret managers:",[35,291,293],{"id":292},"fetch-at-runtime-from-aws-secrets-manager-vault-etc","Fetch at runtime from AWS Secrets Manager, Vault, etc.",[95,295],{},"const secret = await secretsManager.getSecret('api-key');",[215,298,299,300,304,306,307,309],{},"Multi-stage builds for build-time secrets:",[35,301,303],{"id":302},"syntaxdockerdockerfile14","syntax=docker/dockerfile:1.4",[95,305],{},"RUN --mount=type=secret,id=npm_token ",[95,308],{},"\nNPM_TOKEN=$(cat /run/secrets/npm_token) npm install",[13,311,312],{},"Check for leaked secrets:\ndocker history --no-trunc myimage | grep -i secret",[17,314,316],{"id":315},"minimal-base-images","Minimal Base Images",[13,318,319],{},"Paste this prompt to reduce your Docker image attack surface. Your AI will compare base image sizes (full Debian vs. slim vs. Alpine vs. distroless), recommend the right choice for your stack, and provide a multi-stage build pattern with vulnerability scanning commands.",[25,321,323,326,329,343,346,369,372,376,379,382,386,392,395,398],{"title":322},"Use Minimal Images",[13,324,325],{},"Reduce my Docker image attack surface.",[13,327,328],{},"Image comparison (approximate sizes):",[212,330,331,334,337,340],{},[215,332,333],{},"node:20         ~1GB (Debian, full toolchain)",[215,335,336],{},"node:20-slim    ~200MB (Debian minimal)",[215,338,339],{},"node:20-alpine  ~130MB (Alpine Linux)",[215,341,342],{},"distroless      ~20MB (No shell, minimal)",[13,344,345],{},"Recommendations:",[254,347,348,355,362],{},[215,349,350,351],{},"Use Alpine for most apps:\nFROM node:20-alpine",[35,352,354],{"id":353},"smaller-fewer-cves-but-uses-musl-libc","Smaller, fewer CVEs, but uses musl libc",[215,356,357,358],{},"Use Distroless for maximum security:\nFROM gcr.io/distroless/nodejs20",[35,359,361],{"id":360},"no-shell-no-package-manager-no-attack-surface","No shell, no package manager, no attack surface",[215,363,364,365],{},"Use slim for compatibility:\nFROM node:20-slim",[35,366,368],{"id":367},"when-alpine-compatibility-issues-arise","When Alpine compatibility issues arise",[13,370,371],{},"Multi-stage build pattern:\nFROM node:20 AS builder",[35,373,375],{"id":374},"build-with-full-toolchain","Build with full toolchain",[13,377,378],{},"RUN npm ci && npm run build",[13,380,381],{},"FROM gcr.io/distroless/nodejs20",[35,383,385],{"id":384},"run-with-minimal-image","Run with minimal image",[13,387,388,389],{},"COPY --from=builder /app/dist /app\nCMD ",[146,390,391],{},"\"app/index.js\"",[13,393,394],{},"Scan for vulnerabilities:\ndocker scout cves myimage",[35,396,204],{"id":397},"or-2",[13,399,400],{},"trivy image myimage",[402,403,404],"tip-box",{},[13,405,406,409],{},[230,407,408],{},"Pro tip:"," Run vulnerability scans in CI/CD. Tools like Trivy, Snyk, and Docker Scout can catch known CVEs before deployment. Block deployments with critical vulnerabilities.",[411,412,413,420],"faq-section",{},[414,415,417],"faq-item",{"question":416},"Is Alpine safe to use?",[13,418,419],{},"Yes, Alpine is widely used and regularly updated. It has fewer packages installed by default, meaning fewer potential vulnerabilities. Watch for musl libc compatibility issues with some npm packages.",[414,421,423],{"question":422},"How do I update base images for security patches?",[13,424,425],{},"Rebuild regularly with --no-cache or use automated image rebuilding. Pin to specific versions (node:20.10.0-alpine) for reproducibility, but update those pins when security patches release.",[17,427,429],{"id":428},"further-reading","Further Reading",[13,431,432],{},"Want to understand the vulnerability before fixing it? These guides explain what's happening and why.",[212,434,435,441,447],{},[215,436,437],{},[132,438,440],{"href":439},"/blog/vulnerabilities/exposed-api-keys","Understanding exposed API keys",[215,442,443],{},[132,444,446],{"href":445},"/blog/how-to/hide-api-keys","How to hide API keys step-by-step",[215,448,449],{},[132,450,452],{"href":451},"/blog/best-practices/secrets","Secret management best practices",[454,455,456,462],"related-articles",{},[457,458],"related-card",{"description":459,"href":460,"title":461},"Dev vs production","/blog/prompts/environment-separation","Environment Separation",[457,463],{"description":464,"href":465,"title":466},"Container logging","/blog/prompts/secure-logging","Secure Logging",[468,469,471,475],"cta-box",{"href":160,"label":470},"Start Free Scan",[17,472,474],{"id":473},"scan-your-docker-images","Scan Your Docker Images",[13,476,477],{},"Check your containers for security misconfigurations and vulnerabilities.",{"title":479,"searchDepth":480,"depth":480,"links":481},"",2,[482,483,484,485,486,487],{"id":19,"depth":480,"text":20},{"id":151,"depth":480,"text":152},{"id":236,"depth":480,"text":237},{"id":315,"depth":480,"text":316},{"id":428,"depth":480,"text":429},{"id":473,"depth":480,"text":474},"prompts","2026-02-13","2026-03-06","AI prompts to secure Docker containers. Configure non-root users, minimize images, handle secrets, and follow container security best practices.",false,"md",null,"cyan",{},true,"AI prompts to secure your Docker containers and images.","/blog/prompts/docker-security","[object Object]","BlogPosting",{"title":5,"description":491},{"loc":499},"blog/prompts/docker-security",[506],"Deployment","summary_large_image","29UEoWlZILmTwMsZoVdd5bq6D7ZjYUGJNHxShdPYJRs",1775843938876]