Command
build
Is this a regression?
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.
Command
build
Is this a regression?
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
distfolder is mounted as a volume leads to the following error: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):
docker run -it -v ./dist:/app/dist -v .:/app --rm node:18 /bin/bashin an angular projectcd /appto go to the appnpx ng build --delete-output-path=truein the docker containerException or Error
Your Environment
Anything else relevant?
It looks like angular calls the
deleteOutputDirmethod 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'semptyDirSync(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.