BudiBadu Logo
Samplebadu

Dockerfile by Example: Source Code Inclusion

Docker Engine 20.10+

This sample code focuses on the COPY instruction specifically for application code, highlighting the importance of .dockerignore and user permissions.

Code

FROM node:18-alpine

WORKDIR /app

# Create a non-root user (Node image comes with 'node' user)
# It is best practice to run apps as non-root
USER node

# Copy package files with correct ownership
COPY --chown=node:node package*.json ./

RUN npm ci --only=production

# Copy application source code
# We use .dockerignore to exclude node_modules, .git, etc.
COPY --chown=node:node . .

CMD ["node", "index.js"]

Explanation

Including source code via COPY . . is a standard pattern, but it requires careful management of context and permissions. A .dockerignore file is essential to exclude local artifacts like node_modules, .git, and secrets. Without it, these files are copied into the image, potentially overwriting installed dependencies with architecture-mismatched binaries or leaking sensitive information.

Security best practices for source inclusion:

  • Run applications as a non-root user to limit potential impact of vulnerabilities
  • Use COPY --chown to set ownership during copy, avoiding recursive chown later
  • Exclude development artifacts using .dockerignore
  • Install production-only dependencies to minimize image size

By default, Docker containers run as root. Switching to a non-privileged user (like node) using the USER instruction drastically reduces the attack surface. However, files copied before the USER instruction are owned by root. The --chown flag on COPY ensures that the application user has the necessary read/write permissions on the source code without requiring a separate, slow, and layer-bloating RUN chown command.

Code Breakdown

7
USER node switches execution to unprivileged user.
10
COPY --chown=node:node ensures files are owned by the user running the app.
12
npm ci --only=production installs deterministic dependencies, skipping dev tools.
16
COPY . . relies on .dockerignore to filter out unwanted files.