Dockerfile: Trailing Slash for COPY with Multiple Arguments

Docker COPY with multiple sources needs a trailing slash in destination directories. This prevents path ambiguity, build failures, and artifact drift.

Problem

When COPY has multiple source files, the destination must be an explicit directory. Without a trailing slash, path intent becomes ambiguous and builds can fail or place files in the wrong location. Action: always end multi-source COPY destinations with /.

Description

This error usually appears during refactors: a command that previously copied one file is changed to copy multiple files, but the destination is left unchanged. The image may still build in one environment and fail in another. Action: review every COPY line when source count changes.

Ambiguous destinations also cause silent runtime issues. Files can land in unexpected paths, breaking startup scripts, health checks, and permissions. These failures are expensive to debug because the root cause is hidden in an earlier build step. Action: add a CI smoke check that validates expected files and directories.

A consistent path policy removes most of this risk. Use absolute paths or a clearly defined WORKDIR, then enforce directory destinations for multi-source copies. Action: codify this pattern in templates and lint rules so new services inherit the same behavior.

Use this rollout checklist to make the fix stick:

  • Add a linter rule that rejects multi-source COPY without a trailing slash.
  • Add one build validation step that asserts copied files exist in the expected directory.
  • Review .dockerignore changes together with COPY changes to avoid context drift.
  • Block pull requests that introduce ambiguous destination paths.

Treat verification as part of the rule, not optional cleanup. Action: automate a static check, a build check, and a runtime smoke check in the default CI pipeline so regressions are caught before review.

  • Static check: fail when the disallowed pattern appears in Dockerfile or manifest.
  • Build check: run a minimal image build to confirm the secure pattern is valid.
  • Runtime check: start the workload and assert expected behavior with one deterministic probe.

Examples of code

Problematic code

FROM ubuntu:24.04
WORKDIR /app
COPY package.json package-lock.json deps

Verified code

FROM ubuntu:24.04
WORKDIR /app
COPY package.json package-lock.json deps/

Related rules