
Redbird: A modern reverse proxy for Node - Immortalin
https://github.com/OptimalBits/redbird
======
KeitIG
I am one of those JS guys who like to put JS/Node.js everywhere, but I do not
get the problem Redbird is trying to solve: the Express.js doc is quite clear
that for serious things, you should use a dedicated http server. [1]

If you just want reverse-proxying, you can choose between the simplicity of
Caddy or the power of Nginx (or Apache). Why would I want to run a JS app
(that I know will be less performant) to do that?

    
    
      [1] https://expressjs.com/en/advanced/best-practice-performance.html

~~~
nailer
\- node (whose main reason for existing is event driven IO) is in the same
order of magnitude as nginx (whose main reason for existing is also event
driven IO). I think sometimes people think node is ruby/python/php levels of
performance. It isn't.

\- And as another comment mentions, developer productivity may be better than
minor performance difference - you mentioned Caddy, same rationale applies
here.

\- nginx is also a bit crippled as useful features (like dynamic reconfig) are
only in the proprietary nginx plus.

\- This has good defaults - having to set up the seperate webserver for ACME
is a pain, this is way easier.

~~~
sametmax
Python: we use the node event loop too now ([https://magic.io/blog/uvloop-
blazing-fast-python-networking/](https://magic.io/blog/uvloop-blazing-fast-
python-networking/)).

But actually, you could have setup a pure Python server instead of nginx for
the last 10 years with twisted.

Not that you should not consider uring nginx anyway: it deals with caching,
load balancing, has great tutorials, it's battle tested, and has tons of
pluging.

But performance wise, WSGI is not Python.

~~~
nailer
Sure, I mentioned Tornado a few minutes before you posted this. Twisted
obviously counts too, I dislike the non-PEP8 coding style it uses but that's
off topic. I love Python's non blocking features, they're just not in the
mainline VM right now. Here's hoping for a libuv or whatever else non blocking
Python 4 VM / stdlib.

~~~
sametmax
Asyncio has been in the the mainline VM for quite some time.

~~~
nailer
Yep, the stdlib just needs to use it. In nodeland blocking is the exception:
that's not yet the case in Python.

------
viraptor
I think the readme is missing a "why not" section. For example: why not use
nginx instead, which more people have experience with.

~~~
cheapsteak
Convenience is one

I've used redbird to create a local dev proxy that can run be via npm scripts
(which were already in the repo) so our engineering team didn't have to run
the entire constellation of docker containers if they were only working on
frontend code, and the only setup required was `npm install` which they
already needed to do

I do wish you could just `npm install nginx` though

~~~
TheSmiddy
how would npm install nginx be different from [yum|apt] install nginx?

~~~
diamondo25
Its a local installation, inside the folder, instead on the operating system.
Also, other people will automatically install it when the package is saves
inside the package.json or yarn file. You can also limit the version you want
with these files, that the end user dont need to think about. Just yarn
install :)

~~~
11235813213455

      serv() { docker run --rm --name "nginx-${1:-8000}" -p "${1:-8000}:80" "${@:2}" -v $PWD:/usr/share/nginx/html:ro caub/nginx-dev; }
    

this is what I do to run a local static server, you could run nginx with a
config for proxying on docker as well

also yarn.. bleh, just npm, nowadays it's even faster (on linux)

~~~
11235813213455
source of caub/nginx-dev: [https://github.com/caub/docker-
images/tree/master/nginx-dev](https://github.com/caub/docker-
images/tree/master/nginx-dev)

------
dzek69
I used to use Redbird, but configuration is a bit weird and not very well
described if you need to use Auto HTTPS feature. Project seems rather dead and
bugs are solved very slow (upgrading to newer node version caused it to not
install because of outdated dependency, iirc PR with solution were ready, but
not merged for weeks (?)).

Finally I got rid of it and replaced it with Caddy webserver

------
uptime
I’m a fan of traefik. [https://traefik.io](https://traefik.io)

I’m not ready for full k8s, but traefik gives me ACME and detects my docker
containers and routes them for me.

If I only need https redir I’ll use that or nginx.

I can Redbird being useful where you only have node as an option.

------
davnicwil
I mostly agree with the sentiment in other comments of just using nginx, but
there is one standout feature here that looks incredibly useful:

> We have now support for automatic generation of SSL certificates using
> LetsEncrypt. Zero config setup for your TLS protected services that just
> works.

I've scripted this kind of letsencrypt certs automation before with certbot
and nginx, which is fine but a 'just works' declarative plugin for nginx would
be much nicer.

Does anything like this exist? Anyone have experience with using it? Asking
here as googling brings up a bunch of outdated forum threads etc to wade
through.

~~~
jmngomes
You can use acme.sh to automate certificate issuing, installation,
verification, renewal and some server configuration:
[https://github.com/Neilpang/acme.sh](https://github.com/Neilpang/acme.sh)

------
sbmthakur
From the roadmap section:

Automatic routing via Redis

Could anyone explain to me how does this work and what is _automatic routing_
in this context?

~~~
CubicsRube
I assume that instead of config file (or hardcoded values), they will use
Redis store for mapping of the domains/target nodes. E.g. traffic from
www.hacker.com is forwarded to 192.168.1.1, and traffic from www.news.com is
forwarded to 192.168.1.2.

------
jaimehrubiks
What are some good practices to install this as a service (to replace apache,
for example). Do you just setup a systemd script or you have any common
utility for this? I read about pm2 being a common choice. Do you recommend it?
Is there any alternative for multiple app types apart from node?

~~~
onion2k
I use PM2. It's very good, and it keeps things in the node ecosystem.

~~~
dzek69
Pm2 isn't the best tool we could have, but it's probably the best one
existing.

To all future users: don't call `pm2 start ...` too often one by one (like in
.sh script) - it won't start all of these, just some of them (at least on
raspberry, maybe faster cpu helps here), use "ecosystem" feature for starting
multiple services

------
skrebbel
This looks excellent. Is it intended to be integrated with other Node libs?
I.e. can I use it as an express middleware somehow, or is it explicitly
intended as a standalone thing - more like Nginx-but-configured-with-JS-
instead-of-a-weird-custom-language? I can see value in the latter too, but I'm
curious about the motivation here.

~~~
EtienneK
Good question. I was also looking for an answer to this.

Would love to add some middleware to turn this into an OAuth2 proxy.

~~~
chemicalnovae
I had a similiar thought, although not OAuth2, of integration with something
like authelia[1].

[1]
[https://github.com/clems4ever/authelia](https://github.com/clems4ever/authelia)

------
Aeolun
0.2.3 released 4 years ago.

I don’t know, a last release that long ago doesn’t inspire faith in the health
of the project.

~~~
jeremyjh
The last release was 0.8.0, about a month ago.

~~~
raprp
The releases on github are outdated.

[https://github.com/OptimalBits/redbird/releases](https://github.com/OptimalBits/redbird/releases)

------
rdsubhas
Quite nice. node-http-proxy is awesome, lacks a few features (but has a few
more such as websockets). Redbird has http2 as well.

But to be frank, we have used node-http-proxy and other stuff before. It
doesn't end with development. People put this to reverse proxy API calls in
production, and then the other stuff that this calls into - it also uses
proxying to call more stuff. In general, if you find yourself using this as a
"convenient, declarative way to route" in production, you _might potentially_
be digging yourself a hole. The lines between "harmless reverse proxying" and
"service routing and discovery" can become thin.

------
stonewhite
This would be more useful for my team if it would also transpile into nginx
configuration.

------
gigel82
I'm surprised no one mentioned the threading situation in the comments. The
main reason why you need a reverse proxy (like nginx) on top of your express
app is because node.js is single-threaded. Yes, you can fork (which means a
new process and IPC), but that's even more of a performance hog.

If you have to serve a large static file - guess what... no other request gets
processed at the same time. It's a neat idea but until we get true multi-
threading in Node.js, I'll stick with my nginx, thank you very much.

~~~
erikpukinskis
Wait, what?

Node is very happy to asyncronously stream chunks of data over HTTP. You could
write a blocking server by collecting the whole response in memory and sending
it out all at once, but that’s not required by Node.

This is literally the reason Node even exists, nonblocking I/O with a simple
threading model. You can have a million open connections all asynchronously
nibbling data as the buffers empty.

------
shard972
Was recently looking for a reverse proxy for a project at work that utilizes
multiple webpack repos that eventually gets built into one big webapp.

Without a proxy your forced to only work on one area of the app at once so
hopefully something like this will let me run all webpack instances under the
same endpoint during dev.

~~~
sbr464
[https://github.com/webpack/webpack-dev-
server](https://github.com/webpack/webpack-dev-server)

Would this work? Or what’s the issue you are referring to?

~~~
skrebbel
I'm pretty sure he's aware of Webpack's devserver. A common problem is
multiple libraries (with _different webpack configs_ ) being built that are
required inside a single app. I guess GP's approach is to run multiple
devservers, all on a different port, and then put a reverse proxy in front of
it.

Last I checked, webpack does support building multiple scripts (by turning the
`entry` config setting into an array or object), but they'll all have the same
settings (so that intermediate results used by multiple entry points only need
to be built once). If webpack since added support for multiple entire
configurations behind a single webpack dev server then that would be splendid
of course, but last I checked they didn't.

We have a similar problem at my company that we build our frontend React code
for the browser and for node, and the latter has subtly different build
settings. Our solution is to run the webpack devserver for the browser, a
webpack watch mode for the nodejs version, and then we _run_ the nodejs
version using nodemon so that it reloads whenever the webpack watch mode
rebuilds. The nodejs version contains an expressjs reverse proxy to forward
requests for things in the `assets` directory to the webpack devserver. It's
messy, but it works. My biggest beef is that it's rather dissimilar from our
production setup.

Of course if we'd done node+browser from the start we'd have written our code
such that the node version could be run in node without a compilation step,
but we were first frontend-only and then added server rendering, and by then
the code already made use of a number of webpack-isms (such as weird
require("raw!css!stylus!myfile.styl") type of stuff).

~~~
phpnode
Webpack actually supports exporting an array of configurations.
[https://github.com/webpack/webpack-dev-
server/tree/master/ex...](https://github.com/webpack/webpack-dev-
server/tree/master/examples/general/config-array)

------
blorenz
I like the simplicity of this but am weary of using it in production based on
other commenters. I would find something like this very useful if it would
generate nginx configs instead of trying to function as the reverse proxy.

------
novaleaf
Regarding proxies, could anyone recommend where to learn about implementing a
proxy / proxy chain? a book, or online resource, etc.

------
d--b
Sorry, but what’s a reverse proxy?

~~~
martin-adams
It's where the server has a proxy that can fetch resources from different
places. E.g. ServerA (proxy) get a request for /something, but then fetches it
from ServerB (web server) and returns it to the client. It proxies the
response to the client.

The comparison is a forward proxy, which the client has, and a reverse proxy
is where it's on the server side.

~~~
tyingq
Reverse proxies also often provide optional benefits like...

Load balancing, not having to run the webserver as root to bind to 80/443,
caching responses, buffering, rate limiting, injecting headers, serving static
assets, etc.

------
erikpukinskis
What does “modern” mean in this context? ES6?

------
api
This makes a very nice letsencrypt proxy.

------
johnpython
Yet another JavaScript project reinventing the wheel and badly at that. It
seems the NodeJS community suffers from NIH syndrome more than others. This is
a sign of lack of seniors and leadership.

