WORKDIR Instruction Reference
Set the working directory for subsequent instructions in the Dockerfile
Syntax
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
, useWORKDIR /app
followed byRUN 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 withdocker 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.