Skip to content

deleteOutputPath Option on build fails when the output path is mounted as a docker bind mount #26223

@pcbowers

Description

@pcbowers

Command

build

Is this a regression?

  • Yes, this behavior used to work in the previous version

The previous version in which this bug was not present was

No response

Description

Calling ng build --delete-output-path=true in a docker container where the dist folder is mounted as a volume leads to the following error:

EBUSY: resource busy or locked, rmdir '/app/dist'

Docker does not allow deleting the root folder of a volume, making it difficult to bind to the dist. (Normally, you wouldn't need to bind the dist folder, but if you're building a custom image to maximize caching, you don't want to bind the volume to the working directory, but just the specific output directories).

You can get around the issue by calling rm -rf ./dist/* && ng build --delete-output-path=false. However, this is not tied to the actual configuration, where the output path may be different depending on the configuration.

Minimal Reproduction

This is slightly contrived, but illustrates the problem (you wouldn't actually want to do this, but it's easier than building an image from scratch):

  • Run docker run -it -v ./dist:/app/dist -v .:/app --rm node:18 /bin/bash in an angular project
  • Run cd /app to go to the app
  • Run npx ng build --delete-output-path=true in the docker container

Exception or Error

EBUSY: resource busy or locked, rmdir '/app/dist'

Your Environment

Angular CLI: 16.2.8
Node: 18.18.0
Package Manager: pnpm 8.10.2
OS: linux x64

Angular: 16.2.11
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1602.8 (cli-only)
@angular-devkit/build-angular   16.2.8
@angular-devkit/core            16.2.8 (cli-only)
@angular-devkit/schematics      16.2.8 (cli-only)
@angular/cdk                    16.2.10
@angular/cli                    16.2.8
@angular/material               16.2.10
@schematics/angular             16.2.8 (cli-only)
rxjs                            7.8.1
typescript                      5.1.6
zone.js                         0.13.1

Anything else relevant?

It looks like angular calls the deleteOutputDir method here in the browser and here in the server to delete the output path. The method in question can be found here. If we used something like fs-extra's emptyDirSync (see here) instead, we could just empty the output directory rather than deleting it. This would make it a lot more usable and should have theoretically the same impact without running into lock errors or permission errors on the file.

I would put in a PR, but I'm not currently on a machine where that's easy to do!

If this would be considered a breaking change, another thought would be to add another flag. Potentially --empty-output-path. That way you could do one or the other.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions