feat: add IPv6/more flexible interface binding support#154
Conversation
|
@cerebrate this looks good to me and I appreciate the submission :) would you please submit a PR on the docs website as well to add reference for this environment variable, perhaps with an example for other users like yourself? Here is the environment variable docs page: https://github.com/transmute-app/transmute-app.github.io/blob/main/src/content/docs/environment-variables.mdx Thank you so much! Will merge these two PRs at the same time 👍 |
|
Sure, will do! On a separate but related question, would an example k8s configuration to go alongside the existing example Docker compose be useful to you? |
I would love that! It's not something I have the set-up to write / test myself, so that would be a great contribution 😃 |
|
The documentation's done now, as requested (I'll submit the k8s example in separate PR(s).) |
|
Well done, happy to have you as a new contributor! |
What
This PR modifies the way the uvicorn web server is set up to allow binding to an arbitrary set of interface addresses, both IPv6 and IPv4. (The reasons for this choice of implementation are explained in the next section.)
It also modifies the settings to add a new setting, "hosts" to perform these detailed bindings (configurable in the form of a comma-separated list or JSON array), falling back to the existing "host" setting if "hosts" is not present, and logging a warning if both are present. This was done to avoid breaking backwards compatibility for existing installations.
Unit tests were added to ensure these changes work correctly.
In the course of testing these changes, it was discovered that the Dockerfile does not build a working image (permissions errors abound) if the host and user on which the image is build uses a non-standard umask. The Dockerfile was hardened against this particular failure mode.
I have not updated the documentation in this repo, not finding any relevant changes to be made. I also haven't submitted a pull request to the web site repo to alter that documentation's environment variables section, although I can do so if desired.
Why
Some networks and Kubernetes clusters, mine included, are IPv6-first clusters with IPv4 in a secondary or nonexistent role. This permits Transmute to be used in such situations.
The reason for the specific implementation chosen, allowing the specification of an arbitrary set of bindings, is rooted in a peculiarity of uvicorn; unlike most, configuring uvicorn to bind to "::" causes it to bind only to IPv6 addresses, and not to IPv4 addresses. As such, to make uvicorn bind to both IPv4 and IPv6 addresses requires specifying multiple bindings - "::,0.0.0.0" - or passing None rather than a string. Allowing specification of an arbitrary set of bindings seemed a more elegant solution than special-casing it.
Testing
I tested the solution with the existing set of unit tests, with the new ones added for this situation, and finally by building a test Docker image which I ran locally in unconfigured-IPv4 mode, configured dual-stack mode, and finally IPv6-only mode, in each case executing file upload, conversion, and download to be sure of full functionality.