nixcloud.webservices
is a part of nixcloud-webservices and focuses on automated deployment of multiple webservices on one or more machines .
See also ../README.md.
All services
in the namespace nixcloud.webservices
hold the special properties
as listed below:
-
Multiple instantiation of webservices like
mediawiki
A primary design goal is to easily support 'multiple instances' of the same webservice (mediawiki), yet isolated from each other. This is a cool feature but requires to 'fork' most webservices coming with
nixpkgs
for the time being. -
Reverse-proxy setups, see nixcloud.reverse-proxy.md
Each webservice runs in its own webserver on a different
port
. Usingnixcloud.reverse-proxy
all these different ports are consolidated into a reverse-proxy (single webserver) which runs on port 80/443 and interconnects the services to the outside world.One can now easily change the URL from
example.com/
toexample.org/foo
(and back) without having to modify the webservice itself.nixcloud.webservices.leaps.myservice = { enable = true; proxyOptions = { port = 50000; path = "/foo"; domain = "example.com"; }; };
The options
port
,path
anddomain
must to be set always while options likeip
and others are optional. Theport
has a special role as it can't be assigned automatically using the nix programming language yet. One possible solution we work on would be to use /etc/portmap and inside service reference a 'name' instead of a port number which is then translated into a number using the said /etc/portmap. -
Each webservice can be addressed standalone, and as such can be automatically represented by e.g. a dedicated systemd job:
Each webservice is closely associated with a systemd service, making it easy to shutdown/restart individual services. This decoupling makes it rather easy to manage single services in a multi-tenant environment without having these interfering with each other. This makes user/group isolation per webservice easy!
-
Database abstraction for user/db creation:
Note: We spawn a custom database per webservice by default and
nixcloud.webservices.mediawiki
contains an test which is also an example how to use both mysql and postgresql in one webservice and how to make it a user choice which one to use. -
A common webservice interface:
apache
,nginx
andlighttpd
:The common interface features web servers as apache and nginx which support the same subset of
mkOptions
so the webservice developers can easily migrate services between the supported webservers. Of course there are differences such as.htaccess
which are solely supported byapache
and thus implementation details might be bound to a particular webserver. -
nix evaluation time
configuration syntax checking:apache
,nginx
&nixcloud-reverse-proxy
-
There are suitable CI tests using curl/selenium, see ../tests/README.md
In a nutshell you can run a test explicitly like this:
cd nixcloud-webservices/tests nix-build -A custom-webservice
But we made tests part of our evaluation:
* if you are using any webservice, like `nixcloud.webservices.leaps`, it will always run the respective test (leaps) to make sure it works in general * if you are using `nixcloud.reverse-proxy` it will always run the reverse-proxy test before
WARNING:
nixcloud.webservices
should be used from a machine with native virtualization support (KVM) but if you are using it from a VM, then the OS virtualization will be very slow. -
Each webservice gets a unique, stateful directory called
stateDir
.For instance two webservices
service1
andservice2
would use:/var/lib/nixcloud/webservices/owncloud-service1
and/var/lib/nixcloud/webservices/owncloud-service2
thus not interfere. ThestateDir
is independent of theURL
and thus not influenced byproxyOptions
.Using
nixcloud.webservices.owncloud.service1
would create/var/lib/nixcloud/webservices/owncloud-service1
and whileowncloud
would be the service class,service1
would be a name, which has to be unique, given by the user. -
Startup scripts used to prepare the environment or perform updates, are executed as a normal user (not as a privileged user like root).
-
Nixcloud provides a common webserver logging interface.
WARNING: The nixcloud.reverse-proxy's proxyOptions
API and nixcloud.webservices
related API is not stable yet. This means that futher updates break your services. This is caused by the fact that
we spent 8 months in developing nixcloud.webservices
and related technologies and coming with the release of nixcloud.webservices
we want to pinpoint the usage scenarios and stabalize the API afterwards.
WARNING: We are aware of NixOS/nixpkgs#24288 (comment) and we will fix this here as well.
You import modules into your local system by adding the path to your configuration.nix
to the imports
list. Like this:
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
/path/to/nixcloud-webservices/modules
];
Add this code to your /etc/nixos/configuration.nix
file:
nixcloud.reverse-proxy = {
enable = true;
extendEtcHosts = true;
};
nixcloud.webservices.mediawiki.test1 = {
enable = true;
proxyOptions = {
port = 40000;
path = "/wiki";
domain = "example.com";
};
};
Warning: Using extendEtcHosts = true;
extends /etc/hosts
and if you use 'nixos.org' as example domain you won't be able to visit the official 'nixos.org' webpage!
If you've used the above example as is, you can simply do:
nixos-rebuild switch
Finally visit:
https://example.com/wiki
or
http://localhost:40000/wiki
mediawiki
is using the apache web server and can be controlled using various services/targets:
systemctl | grep mediawiki
try:
systemctl status mediawiki-test1-apache
journalctl -u mediawiki-test1-apache
-
static files:
uploads (static files) can be found in `${stateDir}` which is `/var/lib/nixcloud/webservices/mediawiki-test1`
-
logging:
ls /var/lib/nixcloud/webservices/mediawiki-test1/log access_log error_log
-
debugging
journalctl -u mediawiki-test1-apache
If you don't want to clutter your local system you can use a VM:
nix-build '<nixpkgs/nixos>' --arg configuration '{ imports = [ ./modules ./config.nix ]; services.mingetty.autologinUser = "root"; }' -A vm
Note: You have to create config.nix
manually, it contains basically the lines we put in /etc/nixos/configuration.nix
in previous examples.
Note: This is for advanced users who know how VMs on NixOS work.
You have basically two options:
- Hack your implementation into your clone of
nixcloud.webservices
, use mediawiki as an example - Use
nixcloud.webservices
as a library which is illustrated in ../tests/custom-webservice.nix
Note: The library usage scenario is probably easier as you don't have to use git
to rebase your changes when updating.
Here is a short bullet list of issues found with the httpd abstraction currently in nixpkgs.
Motivation for creating nixcloud-webservices
are httpd abstraction
problems:
nixos-rebuild switch
orsystemctl restart httpd
kills basically all VHOSTs- Errors in
startup_script.sh
makes the service unsuable - Supporting old php stacks forces the whole apache to be insecure
- Shared user/group with all webservices
- Only one httpd instance possible without containers
- Service options are not in the options search, if they were, they would mix with the options from http
- Mediawiki (basically all these abstractions) still focus on 'one mediawiki' and leave it to the user to make several mediawiki instance work in parallel. this can be complicated to manage.
- Use one httpd for more than one service complicates the source code base, making it hard to update/modify -> !KISS
- Not easy to get logging per instance which is sometimes nice to have just one place to look into
- Does not implement a
common interface
. porting webservices from httpd to nginx was complicated before this framework - No syntax check of the apache.conf before it applies updates
- You can use your own nixpkgs revision per LXC