For AI agents: A markdown version of this page is available at https://docs.datadoghq.com/security/code_security/iac_security/iac_rules/dockerfile-first-instruction-should-be-arg-or-from.md.
A documentation index is available at /llms.txt.
Dockerfiles must start with either an ARG or FROM instruction, because the initial instruction defines the base image and the scope of build-time variables. Placing another instruction first can result in unintended base images, mis-scoped build arguments, and unpredictable build-time behavior that increases supply-chain and configuration risks.
This rule inspects dockerfile_container resources and flags cases where the earliest parsed instruction is not ARG or FROM.
To remediate, ensure the first non-comment line in the Dockerfile is an ARG (when build-time variables must be substituted into FROM) or a FROM instruction that explicitly defines the base image.
Secure examples:
# ARG before FROM to allow substitution in the base imageARGBASE_IMAGE=alpine:3.16FROM${BASE_IMAGE}
# Direct FROM as the first instructionFROMubuntu:22.04
Compliant Code Examples
# Negative case 1: Starting with ARG (correct - can precede FROM)ARG fooFROMnginx:${foo:-1.25}-alpineASbuilderLABELmaintainer="web-team@example.com"LABELdescription="Nginx static site builder with proper first instruction"# Set build argumentsARG BUILD_DATEARGVERSION=1.0.0LABELbuild_date="${BUILD_DATE}"LABELversion="${VERSION}"# Install build toolsRUN apk add --no-cache \
nodejs \
npm \
gitWORKDIR/build# Copy package filesCOPY package*.json ./# Install dependenciesRUN npm ci# Copy source codeCOPY . .# Build static siteRUN npm run build# Production stageFROMnginx:1.25-alpineLABELmaintainer="web-team@example.com"LABELdescription="Production Nginx static site"# Install runtime dependenciesRUN apk add --no-cache \
curl \
tzdata# Negative case 2: RUN command after FROM (correct order)RUN something# Remove default nginx configRUN rm -rf /usr/share/nginx/html/*# Copy built site from builderCOPY --from=builder --chown=nginx:nginx /build/dist /usr/share/nginx/html# Copy custom nginx configurationCOPY --chown=nginx:nginx nginx.conf /etc/nginx/nginx.confCOPY --chown=nginx:nginx default.conf /etc/nginx/conf.d/default.conf# Create necessary directoriesRUN mkdir -p /var/cache/nginx /var/log/nginx &&\
chown -R nginx:nginx /var/cache/nginx /var/log/nginx &&\
chmod -R 755 /var/cache/nginx# Expose portsEXPOSE80443# Health checkHEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3\
CMD curl -f http://localhost/health ||exit1# Switch to non-root userUSERnginx# Start nginxCMD["nginx","-g","daemon off;"]
Non-Compliant Code Examples
# Positive case 1: Starting with COPY instead of FROM or ARG (incorrect)COPY foo barRUN commandFROMnginx:1.25-alpineLABELmaintainer="web-team@example.com"LABELdescription="Nginx static site with incorrect first instruction"# Install additional toolsRUN apk add --no-cache \
curl \
bashWORKDIR/usr/share/nginx/htmlADD foo bar# Copy website filesCOPY --chown=nginx:nginx ./dist /usr/share/nginx/html# Copy nginx configurationCOPY nginx.conf /etc/nginx/nginx.conf# Create cache directoryRUN mkdir -p /var/cache/nginx &&\
chown -R nginx:nginx /var/cache/nginx# Expose HTTP and HTTPS portsEXPOSE80443USERnginxCMD["nginx","-g","daemon off;"]
1
2
rulesets:- Dockerfile # Rules to enforce .
Request a personalized demo
Get Started with Datadog
Ask AI
AI-generated responses may be inaccurate. Verify important info.