close
address. Gaston Geenslaan 11 B4, 3001 Leuven
s.
All Insights

Setting up Hot Reloading behind a Reverse Proxy

In a nutshell, Docker Compose allows you to organize multiple containers to work together in a precisely orchestrated manner. In this blog, I will explain how you can set up Hot Reloading behind a Reverse Proxy.

Written by
Rafaël Mindreau
Full-stack Developer

If you’re a fan of Docker, you’ve probably heard of or worked with Docker Compose. In a nutshell, Docker Compose allows you to organize multiple containers to work together in a precisely orchestrated manner. Moreover, it will enable you to quickly spin up a network of interconnected containers and services so that you need to make zero configs on your machine.

At Wheelhouse, we’re on the job as consultants for several projects and have seen it used in various ways. For some reason, the problem of having Hot Reloading behind a reverse proxy feels cumbersome but is not too hard to tackle. For that reason, we’re writing a short blog on one way to configure something like this practically.

wheelhouse hot reloading

Why Hot Reloading is, in fact, hot 🔥

Hot Reload is when your browser will refresh automatically to reflect the changes you made in the editor. It’s a developer concern and is not something that runs in production. You change a file in the source files of the app you’re working on, and the browser will immediately show you the latest changes. This is a big deal for front-end developers. This is so standard that it’s outrageous and even cumbersome to work without it.

Imagine a project you check out and find to have been completely orchestrated with Docker Compose. The only thing is that you find out hot-reloading isn’t working because of an issue with the reverse proxy within the stack.

Why is there a reverse proxy? 🐙

As said before, sometimes we’re on the job with our clients, working on the infrastructure already in place. One of my jobs was to upgrade some old technology to new standards. Instead of dealing with the entire refactor as one big chunk, I communicated with my client that we would refactor the system per URL for each module, allowing us to use a reverse proxy to redirect traffic to new modules within Docker Compose.

We were able to mimic the production environment this way. We could also steadily phase out the old PHP part without having to do it in one go. One caveat, of course, is that the specific developer concern of Hot Reloading does not work out of the box!

The solution 🧪

The solution - or at least one possible solution to the problem - is to configure the reverse proxy and the modules specifically to allow web sockets! These are the backbone of hot-reloading, basically, and your browser needs to be able to establish a connection (via the reverse proxy) to the dev-server running on the module within Docker Compose.

How to set it up

Considering the following docker-compose.yml:

version: "3.1"
services:
reverse-proxy:
...
old-php:
...
registration-module:
...
some-other-new-module:
...

The reverse-proxy here is running nginx. The old-php container runs the entire system (in the legacy PHP). As we mentioned before, the other modules would override the php at specific URLs. The technology in these containers does not matter, but as an example, we’re using Vue with the dev-server that comes with the Webpack version of the developer boilerplate (with vue-cli).

We expose the nginx config in our project using volumes in Docker Compose. The config file looks like this at the moment:

server {
listen 8081;

# Pass any traffic over to PHP legacy
location / {
proxy_pass http://old-php;
}

# Pass traffic to registration-module
location /register/ {
proxy_pass http://registration-module:8000;
}
}

This passes all traffic by default to the legacy, and any specific URLs are overridden and redirected to their modules. That’s basically how the reverse proxy should work. Let’s add a tiny but essential bit of code:

  # Pass traffic to registration-module
location /register/ {
proxy_pass http://registration-module:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}

This lets through any Web Socket connections, which we need for the hot-reload service. Now, this in itself will not work, because each module (in Vue) thinks they are running at the root / which they aren’t; they run at a directory. In this case /register/ and that must also be configured.

For Vue, we can find this in the vue.config.js file at the root of the Registration Module:

module.exports = {
devServer: {
port: 8000,
disableHostCheck: true,
public: `http://localhost:3000/register/`,
sockPath: `/register/sockjs-node`,
},
};

We make sure to set the port to 8000. You may choose which port you use, but make sure it is consistent with the one used in the reverse proxy! The disableHostCheck has been deprecated at the time of this writing in favor of allowedHosts, which should be ‘All’. The public path must be changed to include the subdirectory for the module; otherwise, the URL will be re-written, and the app won’t work! The sockPath is perhaps the most notable and essential option. This tells the Webpack Dev Server which URL to put the WebSocket handle. The front-end in development mode will look for this node relative to the URL in the browser, and we just changed the public path as well. Not setting this with the correct subdirectory will inevitably fail.

That’s it! The combination of these settings will forward and allow Hot Reloading so you can have a better developer experience. Never accept it when your Hot Reloading is not working; you must refresh the page to see changes. Your time is worth a lot more. Enjoy developing! ✨

Written by
Rafaël Mindreau
Full-stack Developer

Subscribe to our newsletter

Raccoons NV (Craftworkz NV, Oswald AI NV, Brainjar NV, Wheelhouse NV, TPO Agency NV and Edgise NV are all part of Raccoons) is committed to protecting and respecting your privacy, and we’ll only use your personal information to administer your account and to provide the products and services you requested from us. From time to time, we would like to contact you about our products and services, as well as other content that may be of interest to you. If you consent to us contacting you for this purpose, please tick below:

By submitting this form, you agree to our privacy policy.

In order to provide you the content requested, we need to store and process your personal data. If you consent to us storing your personal data for this purpose, please tick the checkbox below.

More blog articles that can inspire you

04/08/2022

Part-time student, part-time crowdfunding platform developer

As a student worker, TPO Agency presented me with a challenge. They asked me if I could further work on CrowdCollect, my...

what we do

Socials

address. Gaston Geenslaan 11 B4, 3001 Leuven