31 jan 2014
i’ve been using nixos on my webserver for two years now and i love the declarative approach [1] of describing services as well as webservices! describing a webservices in a declarative way is like using the object factory programming pattern and helps to make better abstractions. a good example is the mediawiki abstraction shown below. a user only has to fill the values into the declarative description and nixos-rebuild will automatically install apache-2.2.25, mysql-5.1.72, php-5.4.20 and of course the mediawiki sources (versions of course might differ).
although the declarative approach found in NixOS seems great, it is very unflexible as it forces a rigid dependency model on its users. for example one can only use exactly one php version which needs to be the same for all such services but here i present an idea how to solve this. instead of constraining all webapps to be run on the same webserver, why not have a ‘generic reverse proxy (apache)’ which acts as a frontend and each declaratively described webservice would then use its own, individual mix of webtools like webserver, CGI-based and static/dynamic webpages?
i would love to have your opinion/feedback/critisism to make this idea come true, so please write thoughts about this to ‘js@lastlog.de’.
this section describes what we already have and how it works:
a webservice declaration (from [1]) which will will start the httpd service but also the serviceType = “mediawiki” on top of it:
services.postgresql.enable = true;
services.postgresql.package = pkgs.postgresql92;
services.httpd.enable = true;
services.httpd.adminAddr = "admin@example.org";
services.httpd.extraSubservices =
[ { serviceType = "mediawiki";
siteName = "My Wiki";
logo = "http://www.example.org/wiki-logo.png"; # should be 135x135px
extraConfig =
''
# See http://www.mediawiki.org/wiki/Manual:Configuration_settings
$wgEmailConfirmToEdit = true;
'';
}
];
when evaluating this service by running
nixos-rebuild switch
it was using this store paths:
and it would reload apache in case of a change.
services.postgresql.enable = true;
services.postgresql.package = pkgs.postgresql92;
services.httpd = {
enable = true;
logPerVirtualHost = true;
adminAddr="example@example.com";
hostName = "example.com";
virtualHosts =
[
{
hostName = "www.example.com";
serverAliases = ["www.example.com"];
documentRoot = "/www";
}
{
# Note: do not forget to add a DNS entry for wiki.example.com in the DNS settings
hostName = "wiki.example.com";
extraConfig = ''
RedirectMatch ^/$ /mywiki
'';
extraSubservices =
[
{
serviceType = "mediawiki";
id="wiki1";
dbName="mediawiki_wiki1";
siteName = "My Wiki";
articleUrlPrefix = "/mywiki";
#logo = "http://www.example.org/wiki-logo.png"; # should be 135x135px
extraConfig =
''
# See http://www.mediawiki.org/wiki/Manual:Configuration_settings
$wgEmailConfirmToEdit = true;
'';
}
];
}
{
# Note: do not forget to add a DNS entry for wiki.example.com in the DNS settings
hostName = "wiki2.example.com";
extraConfig = ''
RedirectMatch ^/$ /mywiki2
'';
extraSubservices =
[
{
serviceType = "mediawiki";
id="wiki2";
dbName="mediawiki_wiki2";
siteName = "wiki 2";
siteName = "My Wiki";
articleUrlPrefix = "/mywiki";
#logo = "http://www.example.org/wiki-logo.png"; # should be 135x135px
extraConfig =
''
# See http://www.mediawiki.org/wiki/Manual:Configuration_settings
$wgEmailConfirmToEdit = true;
'';
}
];
}
];
};
advantages:
disadvantages:
with help of you i would like to start implementing it.