
HMR on Docker
I lied to you. HMR (Hot module reloading) is not a thing in Docker. It’s not a term you’ll hear in the docker community because it is a web dev term. It comes from bundlers, which need to serve new content on changes. But not just restart the whole app on change, the “hot” part comes from the notion that your UI should not loose state while doing so. So you don’t need to start “cold” from zero.
Docker is an incredible piece of software, but the docker community is closer to systems programming than to web development. That’s why you probably won’t find much resources on the exact combination of HMR and Docker. So I wanted to write up how you can get it to work.
Enough definitions now. What we actually want is for the changes we are making in our host system (your pc) to be picked up by the docker container file system. Whatever UI framework you are running inside the container will then be able to act accordingly. So the only thing we need to add on docker side is a way to propagate the changes we make on the host to the container. Fortunately for us, docker has bind mounts.
Docker bind mounts are a way to express to docker we want to mount a path from the host on to the container. Just what we needed. This will let the container read and write to those files by default. We can also specify we want the container to only be granted read only permissions. What’s cool about this is that any changes that are made on the host or on docker to those files we’ll immediately get them on the other system. Here’s a small diagram.
In docker CLI you can do it with --mount type=bind,src=<host-path>,dst=<container-path>
. There’s an alternate syntax too but i like this one because it’s more explicit.
On docker compose you can use it with
services:
<service-name>:
volumes:
- type: bind
source: <host-path>
target: <container-path>