Analysis of mkdir Command Operations in Dockerfile and Volume Mount Interactions

Nov 24, 2025 · Programming · 15 views · 7.8

Keywords: Docker | mkdir command | volume mount | Dockerfile | container file system

Abstract: This article provides an in-depth analysis of common issues encountered when using the mkdir command to create directories in Docker containers, focusing on the interaction mechanisms between RUN instructions in Dockerfile and volume mounts in docker-compose. Through specific case studies, it explains why directories created in containers become invisible after volume mounting and offers multiple solutions and best practice recommendations. The article also incorporates supplementary cases such as permission issues to comprehensively elaborate on the technical essentials of directory operations in Docker environments.

Problem Phenomenon and Background

When building containers with Docker, developers often encounter a seemingly simple yet confusing issue: directories created using the RUN mkdir command in Dockerfile cannot be found after the container is running. This situation typically occurs in scenarios where volume mounts are also used.

In the specific case, the user defined a Dockerfile based on the php:fpm image:

FROM php:fpm
WORKDIR /var/www/html
VOLUME ./code:/var/www/html
RUN mkdir -p /var/www/html/foo

After building the image and starting the container via docker-compose, with volume mount configured in docker-compose.yml:

version: '3'
services:
  web:
    container_name: phpx
    build: .
    ports:
      - "80:80"
    volumes:
      - ./code:/var/www/html

However, when the user entered the container via docker exec -it phpx /bin/bash, the expected foo directory was not found in the /var/www/html directory.

Technical Principle Analysis

The root cause of this problem lies in the interaction mechanism between Docker's volume mounting and the container's file system. We need to understand this phenomenon from multiple perspectives.

Container File System Hierarchy

Docker containers use Union File System to build a layered file system structure. Each layer is read-only except for the topmost writable layer. When we use RUN mkdir -p /var/www/html/foo in Dockerfile, this operation creates the foo directory in a specific layer of the image, making it part of the image's file system.

Overriding Effect of Volume Mounts

The critical issue occurs during the volume mounting phase. When specifying volumes: - ./code:/var/www/html in docker-compose.yml, the following process actually happens:

  1. When the container starts, Docker mounts the host's ./code directory to the container's /var/www/html path
  2. This mounting operation completely overrides all content originally located at the /var/www/html path in the container image
  3. Therefore, the foo directory created earlier in Dockerfile is replaced by the content of the host's ./code directory

From a technical perspective, volume mounts have the highest priority in the container file system hierarchy, and they mask the content of the same-named directories in the underlying image layers.

Limitations of VOLUME Instruction in Dockerfile

The VOLUME ./code:/var/www/html instruction in the original Dockerfile actually contains a syntax error. According to Docker official documentation, the VOLUME instruction does not support specifying host directory paths and can only declare mount points within the container:

The host directory is declared at container run-time: The host directory (the mountpoint) is, by its nature, host-dependent. This is to preserve image portability, since a given host directory can't be guaranteed to be available on all hosts. For this reason, you can't mount a host directory from within the Dockerfile. The VOLUME instruction does not support specifying a host-dir parameter. You must specify the mountpoint when you create or run the container.

The correct usage of VOLUME should be: VOLUME /var/www/html, only declaring the mount point location within the container.

Solutions and Practical Recommendations

Solution 1: Remove Volume Mount

If there's no need to synchronize the host directory with the container directory, the simplest solution is to remove the volume mount configuration from docker-compose.yml:

version: '3'
services:
  web:
    container_name: phpx
    build: .
    ports:
      - "80:80"
    # Remove volumes configuration

This way, the container will use the complete file system content from the image, including the foo directory created in Dockerfile.

Solution 2: Pre-create Directory on Host

If volume mount functionality needs to be maintained, the required directory structure can be pre-created on the host:

# Execute on the host
mkdir -p ./code/foo

Then start the container, so the foo directory on the host will appear in the container's /var/www/html path via volume mount.

Solution 3: Dynamic Creation Using Startup Script

Another flexible solution is to dynamically create the required directories when the container starts. Create a startup script:

#!/bin/bash
mkdir -p /var/www/html/foo
exec "$@"

Then configure in Dockerfile:

FROM php:fpm
WORKDIR /var/www/html
COPY entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
CMD ["php-fpm"]

This approach ensures that directories are created after volume mounting is completed, avoiding the override issue.

Related Technical Issue Extensions

Permission Issue Analysis

The situation mentioned in the reference article demonstrates another common problem: permission denied errors. When attempting to create directories in system-protected directories (such as /var), you might encounter:

mkdir: cannot create directory '/var/maven/': Permission denied

Solutions to this type of problem include:

  1. Executing mkdir command with a user having sufficient privileges
  2. Switching to root user in Dockerfile to perform sensitive operations
  3. Considering more appropriate directory locations for file operations

Best Practice Summary

Based on the above analysis, we summarize the best practices for directory operations in Docker environments:

  1. Understand the overriding effect of volume mounts: When designing container architecture, fully understand that volume mounts override the original content in container images
  2. Use VOLUME instruction correctly: Only declare mount points within the container in Dockerfile, without specifying host paths
  3. Plan directory structure reasonably: Separate persistent data from temporary data management
  4. Consider multi-stage builds: For complex directory operations, consider using multi-stage builds to optimize image layers
  5. Test and verify: Thoroughly test directory behavior in various scenarios before deployment

Conclusion

The interaction between the mkdir command in Dockerfile and volume mounting is a technical point that requires deep understanding. Through the analysis in this article, we have clarified that the root cause of the problem lies in the overriding mechanism of volume mounts and provided multiple practical solutions. In actual development, developers should choose appropriate solutions based on specific requirements while paying attention to related permission issues and best practices to ensure the stability and maintainability of the container environment.

Understanding these underlying mechanisms not only helps solve current problems but also provides a technical foundation for more complex Docker application scenarios. As container technology continues to evolve, deep understanding of these fundamental concepts will become increasingly important.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.