Nitrogen-based virtual hosts?

9 views
Skip to first unread message

Olivier Boudeville

unread,
May 24, 2021, 5:35:07 PM5/24/21
to nitro...@googlegroups.com
Hi,

I am interested in having Nitrogen be embedded in a (Cowboy-based)
webserver hosting several websites (most of them being static), all of
them being virtual hosts under the same domain (preferring that
everything is managed by a single Erlang node, on a single TCP port -
rather than being dispatched by, say, nginx).

An issue is to manage everywhere needed a suitable content root
(pointing to a given Nitrogen-based website), knowing that for example
templates are implicitly searched relatively to the current directory
(ex: they are specified as "site/templates/bare.html"); of course, in a
multi-website context, a different webroot shall be defined for each of
these sites.

One idea, for a given Nitrogen-based virtual host, could be to set
following Cowboy dispatch rules: first relevant static ones, then a
default one branching to the cowboy_simple_bridge_anchor handler module,
whose state would be just a binary string corresponding to the web root
of that website. This information could then be kept in relevant places
(such as in an augmented sbw record, itself in the bridge instance,
itself in the context; this should allow to store a complete-enough path
for the cached files (assuming that there is a single overall
nitro_cache), etc.

I am far from understanding well the mode of operation of Nitrogen, yet
with my rather messy test fork of nitrogen_core and simple_bridge, the
most basic Nitrogen example seems to work correctly (including
postbacks; I have not tested multiple Nitrogen virtual hosts yet, nor
more advanced Nitrogen services; probably more changes would have to be
applied for a complete support).

Anyway, would such a mode of operation make sense? Maybe a support for
similar use cases was already planned?

Thanks in advance for any information/piece of advice,

Best regards,

Olivier.

--
Olivier Boudeville

braun...@gmail.com

unread,
May 24, 2021, 6:33:30 PM5/24/21
to Nitrogen Project / The Nitrogen Web Framework for Erlang
how about implementing each site as a plugin?

Every plugin resides in libs/<plugin name>/. A plugin contains src/ priv/ (which includes templates and static content)

After compiling those pieces get patched to site/static/static/plugins/<plugin name> and site/templates/<plugin name>.

Plus, modules in each plugin's src/ directory are transparently accesible by the default router (the dynamic one). The only
caveat is that pages will conflict if there are identical module names, say lib/plugin1/src/login.erl and lib/plugin2/src/login.erl.
Nitrogen wont sandbox those pages and it will arbitrarily pick one of them

Jesse Gumm

unread,
May 25, 2021, 10:25:48 AM5/25/21
to nitrogenweb
Hey Olivier,

If the different sites are expecting to have different sets of modules powering each one, it might be time to cut your teeth on making a custom routing handler, specifically with copying the route handler and making a module prefix ruleset here: https://github.com/nitrogen/nitrogen_core/blob/master/src/handlers/route/dynamic_route_handler.erl#L96-L102

Let's say you have two sites: foo.com and bar.com:

I would make a copy of the above module, copy and rename it into your project, and make sure your nitrogen_main_handler:handlers() function injects the new route handler into the handler system[1] (as you would any custom handler), and make this change to it: modify part of the above section to point to a different module prefix. So instead of the method currently being employed, which just looks at a config file, you can define it to be a custom function that determines the module_prefix based on the rules you want to define:

So change the ModulePrefix to be this:

ModulePrefix = determine_module_prefix(),

Then define determine_module_prefix() to be something like this:

determine_module_prefix() ->
   case wf:header(host) of
      "foo.com" -> "foo";
      "bar.com" -> "bar"
   end.

The result of the above is that foo_ or bar_ will be prefixed to the module name.

That way:

foo_index.erl would define the index of http://foo.com
bar_index.erl would define the index of http://bar.com

This method would effectively be a single application with a bunch of modules all handling different sites.

I can see some value in this, but, personally, I'd rather just do it with different applications and have them routed from nginx.

But the above is one method of accomplishing what I think you're trying to do.

-Jesse

[1] Like this: nitrogen:handler(olivier_route_handler, [])

--
You received this message because you are subscribed to the Google Groups "Nitrogen Project / The Nitrogen Web Framework for Erlang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nitrogenweb...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nitrogenweb/5d8ea3c5-36dc-0086-1ee6-5564efe3f2fd%40online.fr.


--
Jesse Gumm
Owner, Sigma Star Systems
414.940.4866 || sigma-star.com || @jessegumm

Olivier Boudeville

unread,
May 25, 2021, 3:00:09 PM5/25/21
to nitro...@googlegroups.com
Hi,

Thanks for the plugin information, I was not aware it existed. I think I will need more control on the routing and to ensure each web root is fully separated from the others. Interesting idea though.

Best regards,

Olivier.


Le 5/25/21 à 12:33 AM, braun...@gmail.com a écrit :
--
You received this message because you are subscribed to the Google Groups "Nitrogen Project / The Nitrogen Web Framework for Erlang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nitrogenweb...@googlegroups.com.

Olivier Boudeville

unread,
May 25, 2021, 3:26:30 PM5/25/21
to nitro...@googlegroups.com
Hello Jesse,

Thanks for your answer. Indeed different pages bearing the same name across different Nitrogen-based virtual hosts would clash with each other as their identically-named modules would all lie in the code path; and a per-virtual host prefix is a good solution to avoid that. I imagine that elements like templates would have to be updated accordingly and that adding the web root to their path would allow to avoid mixing up elements in the cache. A custom handler deriving from dynamic_route_handler would certainly help. I will try to devise a relevant scheme first, as I know too little about Nitrogen in order to envision a full solution ATM.

I like the idea of having a single Erlang application, as it can control and properly schedule everything needed (log collection and rotation, renewal of TLS certificates, etc.); being able to additionally have Nitrogen-based websites be plugged among them would be neat.

Thanks for your advice, and thanks for Nitrogen,

Best regards,

Olivier.


Le 5/25/21 à 4:25 PM, Jesse Gumm a écrit :
Reply all
Reply to author
Forward
0 new messages