WORKDIR Instruction Reference

Set the working directory for subsequent instructions in the Dockerfile

Syntax

WORKDIR <path>

The WORKDIR instruction sets the working directory for any subsequent RUN, CMD, ENTRYPOINT, COPY, and ADD instructions in the Dockerfile. It can be used multiple times in a Dockerfile.

The WORKDIR instruction is used to set the working directory for subsequent instructions in your Dockerfile. It helps organize your Dockerfile by grouping related operations and ensuring that commands run in the proper context.

When a WORKDIR instruction is used, it affects all subsequent instructions in the Dockerfile. This means that paths in commands like RUN, CMD, ENTRYPOINT, COPY, and ADD are resolved relative to the WORKDIR path.

Description

The WORKDIR instruction sets the working directory (i.e., the current directory) for subsequent instructions in the Dockerfile. If the specified directory doesn't exist in the image, it will be created automatically.

You can use the WORKDIR instruction multiple times in a Dockerfile. If a relative path is provided, it will be relative to the path of the previous WORKDIR instruction.

For example:

WORKDIR /app
WORKDIR src
RUN pwd

The output of the RUN instruction would be /app/src.

The WORKDIR instruction can use environment variables that were previously set using ENV:

ENV APP_HOME=/app
WORKDIR ${APP_HOME}/src
RUN pwd

The output of the RUN instruction would be /app/src.

When a container is started from the image, the working directory set by the last WORKDIR instruction becomes the default directory for the container unless overridden with the -w or --workdir option when running docker run.

Examples

Basic Usage

Setting a basic working directory:

FROM ubuntu:20.04
WORKDIR /app
RUN pwd

This sets the working directory to /app and then runs the pwd command, which will output "/app".

Multiple WORKDIR Instructions

Using multiple WORKDIR instructions with relative paths:

FROM ubuntu:20.04
WORKDIR /app
RUN pwd
WORKDIR src
RUN pwd
WORKDIR lib
RUN pwd

This would output "/app", "/app/src", and "/app/src/lib" respectively.

Using Environment Variables

Using an environment variable to set the working directory:

FROM ubuntu:20.04
ENV APP_HOME=/usr/src/app
WORKDIR ${APP_HOME}
RUN echo "Working directory: $PWD"

This sets the APP_HOME environment variable and then uses it to set the working directory.

With COPY Instructions

Using WORKDIR with COPY instructions:

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["npm", "start"]

This sets the working directory to /app and then copies files into it. The "./" in the COPY instruction refers to the current working directory, which is /app.

For Multi-stage Builds

Using WORKDIR in a multi-stage build:

FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

FROM nginx:alpine
WORKDIR /usr/share/nginx/html
COPY --from=builder /app/build .

This example uses different working directories in different build stages.

Creating Directory Structure

Using WORKDIR to create a directory structure:

FROM ubuntu:20.04
WORKDIR /app/logs
RUN touch access.log error.log
WORKDIR /app/config
RUN touch settings.json
WORKDIR /app

This creates a directory structure with /app/logs and /app/config directories, each containing specific files.

Best Practices

  • Use absolute paths: Always use absolute paths for WORKDIR to avoid confusion and make your Dockerfile more predictable.
  • Create a dedicated directory: Use WORKDIR to create a dedicated directory for your application, avoiding working in system directories like / or /root.
  • Set WORKDIR early: Set your main WORKDIR early in the Dockerfile, typically right after the FROM instruction.
  • Group related operations: Use WORKDIR to group related operations by their directory context.
  • Avoid using RUN cd: Instead of using RUN cd /app && command, use WORKDIR /app followed by RUN command.
  • Use environment variables: Consider using environment variables with WORKDIR for paths that might need to be configurable.
  • Create a consistent layout: Establish a consistent directory structure for your images to make them more maintainable.
  • Use a user-specific directory: When running as a non-root user, use a directory that the user can write to, like /home/user/app.

WORKDIR vs RUN mkdir

There are two common ways to create directories in a Dockerfile:

# Option 1: Using RUN mkdir
RUN mkdir -p /app
WORKDIR /app

# Option 2: Using WORKDIR directly
WORKDIR /app

In most cases, using WORKDIR directly (Option 2) is preferred because:

  • It's more concise and creates fewer layers
  • Docker automatically creates the directory if it doesn't exist
  • It clearly expresses your intent to work in that directory

However, there are cases where using RUN mkdir might be appropriate:

  • When you need to set specific permissions or ownership for the directory
  • When creating multiple directories that won't all be used as working directories
  • When you need more complex directory creation logic
# When you need specific permissions
RUN mkdir -p /app && chown -R user:user /app
WORKDIR /app

Notes and Limitations

  • If the WORKDIR path doesn't exist in the image, it will be created automatically.
  • WORKDIR instructions are cumulative if relative paths are used.
  • The WORKDIR instruction does not run a shell, so environment variable substitution needs to use the Dockerfile syntax (${variable_name} or $variable_name).
  • The WORKDIR instruction affects all subsequent instructions in the Dockerfile, including RUN, CMD, ENTRYPOINT, COPY, and ADD.
  • The WORKDIR instruction can be used multiple times in a Dockerfile.
  • The working directory set by the last WORKDIR instruction becomes the default directory for the container.
  • The working directory can be overridden at runtime using the -w or --workdir option with docker run.
  • In Windows containers, if a working directory has a space in its path, it should be specified using double quotes, not escaped with backslashes.

Try Our Optimizer

Analyze your Dockerfile for optimization opportunities.

Dockerfile Optimizer