I've had exactly the same problem. Our Angular web development flow depends on file changes detected with webpack on mapped volumes.
Unfortunately, Windows does not pass file system events (that fsevents
package that always warns during NPM install 😉) and instead the alternative is to enable polling, to manually check for files that have changed. This polling flag has a negative impact on CPU resources on macOS, thus it is not a great default.
There are two solutions I've found that could work. Both are based on the same conditional trick. Since Docker logic can only be configured with environment variables, we need to find an environment variable that only exists on Windows. The %WINDIR%
is pretty good for that, since it even has "Windows" in the name. 😁
During Docker image build
If you need to have conditional logic for Windows during the Docker image build step, you can use build arguments. These can be specified on the CLI or with docker-compose.
For example, (partial) docker-compose.yml
:
build:
context: .
dockerfile: dev.Dockerfile
args:
- WINDIR
Note, I found that the argument is case-sensitive, it has to be all caps, otherwise it isn't passed.
Then, in the Dockerfile
you can add conditional shell logic in a RUN
command:
ARG WINDIR
# If the host is Windows (as detected from pass-through %WINDIR% env var), set polling for file system change detection.
RUN echo 'Windows:'; if [ -n "$WINDIR" ]; then export POLL='--poll 1000'; echo 'DETECTED'; else echo 'IGNORED'; fi
It is required to specify the ARG
command for this to work.
You can put any logic in between the then
and/or else
.
CMD execution (Docker container run)
One gotcha I encountered, was that the CMD command does not have access during docker run
to environment variables set during the build. Thus that POLL
env var from above cannot be accessed.
Luckily we could use shell parameter expansion to replace environment variables in the CMD
command at runtime.
Example Dockerfile
:
CMD npx ng serve --host 0.0.0.0 --port 4300 ${WINDIR:+--poll 1000}
The docker-compose.yml
would pass-through %WINDIR%
differently:
environment:
- WINDIR