mdbook serve doesn't work in Docker
Problem
Hello, my idea was to change files on host machine, then it will changes files in container and rebuild docs. And of cource, there will be port exposing to open docs on host machine in browser. I created Docker file and run container. It didn't work. I checked up, that files, that were changed on my machine, were changed in container and vice versa. According logs md serve didn't respond to changes. I'm only begginer, so don't rule out the option, that I did smth wrong.
Steps
Dockerfile
FROM ubuntu
RUN apt-get update && apt-get install -y curl tar
RUN curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.27/mdbook-v0.4.27-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=/bin
COPY /docs /docs
Commads:
docker build -f docker/Dockerfile.local.docs -t docs-local-image .docker run -dp 45000:45000 -w /docs -v "$(pwd)/docs:/docs" --name docs-local docs-local-image sh -c "mdbook serve -n 0.0.0.0 -p 45000"
Possible Solution(s)
Mb it's Docker bug?
Notes
Host OS: Windows 10 Docker version: 24.0.2
Version
No response
The mdbook serve command is supposed to watch your files for changes and automatically rebuild your book, but there are known issues with file changes not being detected when those files are inside a Docker container. This is not a Docker bug per se, but rather a characteristic of how file change notifications are propagated from the host to the container.
So is it possible to do, what I want?
I experienced the same problem.
I'm wondering how I can solve this problem.
What works for me:
FROM alpine:latest
RUN apk update && apk add --no-cache \
curl \
tar
RUN curl -L https://github.com/rust-lang/mdBook/releases/download/v0.4.34/mdbook-v0.4.34-x86_64-unknown-linux-musl.tar.gz | tar -xzC /usr/local/bin
WORKDIR /src
# Some workaround to capture ctrl-c
RUN printf "#!/bin/sh\n\$@\n" > /entrypoint.sh && chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["/usr/local/bin/mdbook", "serve", "-p", "3000", "-n", "0.0.0.0"]
docker build . -t mdbook
docker run -v $(pwd):/src -p 3000:3000 -it mdbook
For me this picks up the changes performed on the host and serves them.
@dioni-dev
The mdbook serve command is supposed to watch your files for changes and automatically rebuild your book, but there are known issues with file changes not being detected when those files are inside a Docker container. This is not a Docker bug per se, but rather a characteristic of how file change notifications are propagated from the host to the container.
Do you have any source? I have the same problem, so I'd like to investigate the issue you refer to.
I can't find the issue related to Docker container specifically, but here goes:
Currently, we are listening for filesystem changes. In theory, this is best: we don't spam the filesystem with pointless calls, and we get immediate feedback on update. Unfortunately, in reality listening for filesystem changes is extremely unreliable, and we should use PollWatcher instead. Here's a quick list of issues I've found:
- Notify documentation lists 5 common issues that occur with filesystem events and suggests using
PollWatcher: https://docs.rs/notify/6.1.1/notify/index.html#known-problems - Epic footgun due to platform differences: https://github.com/notify-rs/notify/issues/403
- MacOS notify issue: https://github.com/notify-rs/notify/issues/240
- WSL2 notify issue: https://github.com/notify-rs/notify/issues/254
There are probably more.
Alternatively, we can use recommended watcher based on the platform (curiously enough, PollWatcher is actually recommended for Linux instead of what we do now): https://docs.rs/notify/6.1.1/src/notify/lib.rs.html#371
Related: https://github.com/rust-lang/mdBook/blob/dc21f1497bed2085249ad6fd8537f906ad398ccf/src/cmd/watch.rs#L111C49-L111C49 https://github.com/rust-lang/mdBook/issues/2035 https://github.com/rust-lang/mdBook/issues/1441 (I think?) https://github.com/rust-lang/mdBook/issues/383