Hacker News new | ask | show | jobs
Show HN: Deploying subdomain-based routing like github.io (github.com)
55 points by xyheme 1009 days ago
15 comments

You couldve accomplished this at the webserver level, with way less hassle, and better performance.

One would be complex rewrite rules. Another, is to use LUA with Openresty. And you dont need another node app, and you dont need the terrible performance you get with the node app, and you dont use a language meant for frontend things to do backend things.

Seriously, what is it with every node dev using node for everything???? Yes, i know when all you know is a hammer, everything is a nail, but seriously, come on. There are plenty of better languages to have done this in, all of which are more performant for this type of thing, had you still decided to not use lua/rewrites.

> You couldve accomplished this at the webserver level

That's true, but only if you have access to your web server!

If you're using something like Vercel (or some other hosting service) to run your application, having a little middleware that handles subdomain routing is pretty common.

edit: Sorry if I've read this comment out of context - the linked repo has been taken down.

Neat. One big nitpick: I think this is solved better by other solutions. One small nitpick: why serve under /websites instead of under /srv?

/srv is a standard [0] directory.

[0]: https://en.wikipedia.org/wiki/Filesystem_hierarchy_standard

I spent 15 years in webhosting and I've literally never seen /srv used. MAYBE for sftp and I'm misremembering but I rarely had to deal with that. It's always /var/www/$url.
I use /srv for a personal webserver just because I need the webserver data to be on a separate partition for disk space reasons, and it's convenient to have systemd-gpt-auto-generator automatically mount a partition to /srv without any fstab / crypttab / mount unit configuration. ("Server data partition" in https://uapi-group.org/specifications/specs/discoverable_par... )
> It's always /var/www/$url.

Or in a shared hosting environment /home/<user>/public_html/ or /home/<user>/www/

One reason to place static files and cgi-bin executables in /var/www instead of /home/user homedir is: /var/www it's already labeled httpd_sys_content_t or httpd_sys_script_exec_t or instead of user_home_t (so that you don't need to `setsebool httpd_enable_homedirs on` for all users and `chcon httpd_user_content_t` if it's not necessary).
it's used, but not very often.

tftp is one that is regularly served out of there.

In reality, larger software projects like nginx and apache have their own opinions and usually serve out of different places.

> In reality, larger software projects like nginx and apache have their own opinions and usually serve out of different places.

It might make sense if the software is serving a domain from something installed with a package. Nginx is often installed with a package and long-lived data goes into /var. So it makes sense to serve /var/www for their examples. Then people just build on those examples, sadly being unaware of or unwilling to change to values that were preinstalled for demonstrations.

But for multi-homing a server (or even a single site on that server), I still end up putting stuff under /srv/<domain>/<site>, so example might be /srv/systemd.software/www [0]. Then `/srv/<domain>` might have its own fstab entry -- for example, it might be a bind-mount to somewhere else, or it might be its own disk/encryption, or it might be a network mount.

Any admin can do what they want on their own servers. I just figure it's best to follow documented standards.

[0]: https://github.com/inetknght/systemd.software/blob/0bf207d6f...

It's a nice thought, but most distros poop all over FHS anyway.

When was the last time you hopped between distros Ubuntu->OpenSUSE->Fedora and had packages be in the same spot? Because I distro hop a LOT and they almost NEVER are.

Even if it's just /bin, /sbin, /usr/sbin, /usr/local/bin, where is the consistency, not to mention controlling access. Remember when Debian took the sbins out of the path and everybody claimed Debian sucked?

When was the last time you saw /usr mounted as read-only? Because it's supposed to be.

With tech like snaps and flatpaks, containers, NixOS, etc, to call FHS anything more than a suggestion in 2023 is extreme wishful thinking.

I've always loved that to do basic auth nginx has you make an apache2 directory and place your htpasswd in there as a best practice/recommended setup. And use apache-utils.. but I guess why reinvent the wheel.

                # auth_basic_user_file /etc/apache2/.htpasswd;
https://docs.nginx.com/nginx/admin-guide/security-controls/c...
Its overly engineered for sure, but i designed an HTAuth setup that doesnt use files, for openresty. Instead it uses lua and a database (mysql in my case) to manage users and passwords.

Overengineered, but i dont have to muck with auth files, and can keep it up to date from other sources

This is probably more ancient documentation for switchers from Apache.

The main reason for this is to make sure your htaccess file is outside of the document root. This is horrible behavior Apache had (still has?), and is a security issue.

The Apache httpd documentation has been telling people not to use .htaccess files for over twenty years.

> However, in general, use of .htaccess files should be avoided when possible. Any configuration that you would consider putting in a .htaccess file, can just as effectively be made in a <Directory> section in your main server configuration file.

2002: https://web.archive.org/web/20020805160131/http://httpd.apac...

Present day: https://httpd.apache.org/docs/current/howto/htaccess.html#wh...

Maybe they keep all their Stevie Ray Vaughan bootlegs in /srv
you can choose any directory you want and while FHS is a recommendation there's no one forcing you to use it.

Note that more often than not I'll often argue for sticking with FHS and it's a good rule of thumb to know the rules first before you go breaking them. However in my opinion /srv isn't a pragmatic choice to make in a demonstration and it's for the sake of clarity I can see why the writer would just say /websites. In your own implementation you can put your content wherever you want.

Small nitpick about the naming. "X Server" term is used for an X window protocol server application. https://en.m.wikipedia.org/wiki/X_Window_System
A relevant sidenote: If you're going to do this, make sure you don't allow the content to also be accessible on the top level domain with a different URL, and that one redirects to the other. Two reasons for this:

- Security: You want the cookies to be limited to the subdomain

- SEO: You get penalized if the same content is available at two URLs, because it is assumed it's a copy

The SEO issue applies in the other direction too. When we first set this up for reddit (you could and still can go to subreddit.reddit.com), we found out that we were getting penalized for having the same content on both URLs. So we set it up to redirect the subdomain to the /r/subreddit URL since that was the canonical URL and the cookies didn't matter.

Thanks, I now learn double content s have this effect on SEO :)
Possibly I am missing something, but is it different from, say, nginx's `root /var/www/$http_host`? The description sounds as if a whole web server is written for that feature.
Same for Caddy which is even easier than nginx https://caddyserver.com/
Caddy’s awesome! Switched our local development stack from nginx to caddy.

Especially love how easy it is to set up localhost subdomains and ssl.

yeah, it can be done entirely on nginx side in like 10 lines.
While your comment is valid, there's a whole generation of developers (me included) who are more aware of Node ecosystem than Nginx.
ha, 1) nginx is a webserver not a development ecosystem, and 2) You'll probably find if you look that many people using Node are also using nginx, because they are complementary, not exclusionary, and 3) open your eyes and reality a bit
1/ what's a webserver? 2/ Is a node application serving requests not a webserver?
These are not even remotely comparable. nginx is a webserver.
This is why I'll never hire a "full-stack developer".
Nice,

Can you point me to an example I would love to check it out

Meta: Link currently 404s
Sorry about that, I was migrating my websites and repo out of vercel (to use this tool), during which I deleted a lot of outdated github repos.

I thinks I accidently deleted this repo.

Now it is back: https://github.com/xieyuheng/x-server

Probably removed after feedback regarding the use of Node
I enjoy the criticism, I think I can learn things from them.

So far, feedback here are helpful to me.

Sorry about the mis-deleting.

Looks like it's back! The ornery gatekeeper of true backend scowls while shaking their raised fist.
Hi, it's you again :)

My aim is to build a open-source mini vercel and netlify alternative.

`x-server` is just a starting point.

I have even more "evil" projects, like "using file system as database", I will leave that for another Show HN :) :) :)

It's always neat to see different ways of doing things! Keep at it :)
How is it different from just reading the Host header and serving a directory based on that?
> How is it different from just reading the Host header and serving a directory based on that?

Well I hope that's not all you do...

    curl -H 'etc.example.com' 'https://www.example.com/shadow'
-> /etc/shadow
It would be more like /somedir/etc.example.com/shadow
Man there is a lot of negativity here, some people really need to reread the guidelines.

Good on you. As a sysadmin of decades I could absolutely to this in a few lines of nginx or other web servers as others have mentioned, however this looks like a cool and fun project.

Just because doing it one way wins on some specific metrics (like performance) doesn't mean it does for other people (like node developers who want to change some server functionality).

I can't believe people can write with a straight face that a web dev should learn nginx, set up openresty and write a lua script to do this. Get out of your own bubbles people.

I made something similar for kubernetes a while ago https://github.com/DeluxeOwl/subdomain-mapper-operator
Why node.js is involved? nginx, apache, any web server can do it itself since the beginning of an era.
I am a little confused, why not just create a CNAME and point it to that server?!
This would be pretty easy in Go, too.
Not to detract from the work done here, but couldn't something very similar be accomplished via nginx vhosts or somethin similar in apache?
As far as I can tell this is just a fancy costume on top of Server Name Indication. So yes, yes you could (and I'd do it like that).
I think Node.js is unsuitable for normal routing tasks like this because of single-threaded runtime. This could be achieved really easily with popular web servers like nginx or caddy. If I remember correctly, there was a lot of tutorial about serving static files using nginx in front of express.js/koa.js for better performance and that serving static files doesn't compete with the dynamic part of the website.
In addition to CLI params and JSON conf it would be handy to support env var configuration. Makes running inside a container much easier.
Would it make it much easier? If you really need env var support, you can just wrap this, I suppose. But more conveniently, you can also mount (and load from a config map in the context of kubernetes).
Yes, I think that env vars are superior to a file or CLI args. One advantage is that you can pass secrets without persisting in a file or making them visible to other processes through CLI args.
Env vars are visible in /proc/PID/environ, though? That said, the mode on environ seems to be 600 on my system, so only processes with the same UID can see them.
Does that mean you're restarting your nodes after every change? It'll work, but mightn't it be a bit tricky if lots of people start creating tenants?

Edit: actually, based on the use case cited in the readme, this would be fine. I was thinking more of a website like GitHub that lets people sign up and create tenants.