mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-03-07 23:24:03 +01:00
nixos/kiwix-serve: init module (#496047)
This commit is contained in:
commit
d0a37ae396
8 changed files with 280 additions and 0 deletions
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
- [qui](https://github.com/autobrr/qui), a modern alternative webUI for qBittorrent, with multi-instance support. Written in Go/React. Available as [services.qui](#opt-services.qui.enable).
|
||||
|
||||
- [kiwix-serve](https://wiki.kiwix.org/wiki/Kiwix-serve), a service that serves ZIM files (such as Wikipedia archives) over HTTP. Available as [services.kiwix-serve](#opt-services.kiwix-serve.enable).
|
||||
|
||||
- [Remark42](https://remark42.com/), a self-hosted comment engine. Available as [services.remark42](#opt-services.remark42.enable).
|
||||
|
||||
- [LibreChat](https://www.librechat.ai/), open-source self-hostable ChatGPT clone with Agents and RAG APIs. Available as [services.librechat](#opt-services.librechat.enable).
|
||||
|
|
|
|||
|
|
@ -882,6 +882,7 @@
|
|||
./services/misc/jackett.nix
|
||||
./services/misc/jellyfin.nix
|
||||
./services/misc/jellyseerr.nix
|
||||
./services/misc/kiwix-serve.nix
|
||||
./services/misc/klipper.nix
|
||||
./services/misc/languagetool.nix
|
||||
./services/misc/leaps.nix
|
||||
|
|
|
|||
187
nixos/modules/services/misc/kiwix-serve.nix
Normal file
187
nixos/modules/services/misc/kiwix-serve.nix
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
utils,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) types;
|
||||
cfg = config.services.kiwix-serve;
|
||||
# Create a directory containing symlinks to ZIM files
|
||||
mkLibrary =
|
||||
library:
|
||||
let
|
||||
libraryEntries = lib.mapAttrsToList (name: path: {
|
||||
name = "${name}.zim";
|
||||
inherit path;
|
||||
}) library;
|
||||
|
||||
zimsDrv = pkgs.linkFarm "zims" libraryEntries;
|
||||
|
||||
files = map (entry: "${zimsDrv}/${entry.name}") libraryEntries;
|
||||
in
|
||||
{
|
||||
derivation = zimsDrv;
|
||||
inherit files;
|
||||
};
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.kiwix-serve = {
|
||||
enable = lib.mkEnableOption "the kiwix-serve server";
|
||||
|
||||
package = lib.mkPackageOption pkgs "kiwix-tools" { };
|
||||
|
||||
address = lib.mkOption {
|
||||
type = types.str;
|
||||
default = "all";
|
||||
example = "ipv4";
|
||||
description = ''
|
||||
Listen only on the specified IP address.
|
||||
Specify "ipv4", "ipv6" or "all" to listen on all IPv4, IPv6, or both types of addresses, respectively.
|
||||
'';
|
||||
};
|
||||
|
||||
port = lib.mkOption {
|
||||
type = types.port;
|
||||
default = 8080;
|
||||
description = "The port on which to run kiwix-serve.";
|
||||
};
|
||||
|
||||
openFirewall = lib.mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to open the firewall for the configured port.";
|
||||
};
|
||||
|
||||
library = lib.mkOption {
|
||||
type = types.attrsOf types.path;
|
||||
default = { };
|
||||
example = lib.literalExpression (
|
||||
lib.removeSuffix "\n" ''
|
||||
{
|
||||
wikipedia = "/data/wikipedia_en_all_maxi_2026-02.zim";
|
||||
nix = pkgs.fetchurl {
|
||||
url = "https://download.kiwix.org/zim/devdocs/devdocs_en_nix_2026-01.zim";
|
||||
hash = "sha256-QxB9qDKSzzEU8t4droI08BXdYn+HMVkgiJMO3SoGTqM=";
|
||||
};
|
||||
}
|
||||
''
|
||||
);
|
||||
description = ''
|
||||
A set of ZIM files to serve. The key is used as the name for the ZIM files
|
||||
(e.g. in the example, the files will be served as `wikipedia.zim` and `nix.zim`).
|
||||
|
||||
Exclusive with [services.kiwix-serve.libraryPath](#opt-services.kiwix-serve.libraryPath).
|
||||
'';
|
||||
};
|
||||
|
||||
libraryPath = lib.mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
example = "/data/library.xml";
|
||||
description = ''
|
||||
An XML library file listing ZIM files to serve.
|
||||
For more information, see <https://wiki.kiwix.org/wiki/Kiwix-manage>.
|
||||
|
||||
Exclusive with [services.kiwix-serve.library](#opt-services.kiwix-serve.library).
|
||||
'';
|
||||
};
|
||||
|
||||
extraArgs = lib.mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [
|
||||
"--verbose"
|
||||
"--skipInvalid"
|
||||
];
|
||||
description = "Extra arguments to pass to kiwix-serve.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = (cfg.library == { }) != (cfg.libraryPath == null);
|
||||
message = "Exactly one of services.kiwix-serve.library or services.kiwix-serve.libraryPath must be provided.";
|
||||
}
|
||||
];
|
||||
|
||||
systemd.services.kiwix-serve =
|
||||
let
|
||||
library = mkLibrary cfg.library;
|
||||
in
|
||||
{
|
||||
description = "ZIM file HTTP server";
|
||||
documentation = [ "https://kiwix-tools.readthedocs.io/en/latest/kiwix-serve.html" ];
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
Type = "exec";
|
||||
DynamicUser = true;
|
||||
Restart = "on-failure";
|
||||
ExecStart = utils.escapeSystemdExecArgs (
|
||||
[
|
||||
(lib.getExe' cfg.package "kiwix-serve")
|
||||
"--address"
|
||||
cfg.address
|
||||
"--port"
|
||||
cfg.port
|
||||
]
|
||||
++ lib.optionals (cfg.libraryPath != null) [
|
||||
"--library"
|
||||
cfg.libraryPath
|
||||
]
|
||||
++ lib.optionals (cfg.library != { }) library.files
|
||||
++ cfg.extraArgs
|
||||
);
|
||||
|
||||
CapabilityBoundingSet = "";
|
||||
DeviceAllow = "";
|
||||
LockPersonality = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
NoNewPrivileges = true;
|
||||
PrivateDevices = true;
|
||||
PrivateUsers = true;
|
||||
PrivateTmp = true;
|
||||
ProcSubset = "pid";
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectProc = "invisible";
|
||||
ProtectSystem = "strict";
|
||||
RemoveIPC = true;
|
||||
RestrictAddressFamilies = [
|
||||
"AF_INET"
|
||||
"AF_INET6"
|
||||
"AF_NETLINK"
|
||||
];
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = [
|
||||
"@system-service"
|
||||
"~@privileged"
|
||||
"~@resources"
|
||||
];
|
||||
UMask = "0077";
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [ cfg.port ];
|
||||
};
|
||||
};
|
||||
|
||||
meta = {
|
||||
maintainers = with lib.maintainers; [ MysteryBlokHed ];
|
||||
};
|
||||
}
|
||||
|
|
@ -840,6 +840,7 @@ in
|
|||
keymap = handleTest ./keymap.nix { };
|
||||
kimai = runTest ./kimai.nix;
|
||||
kismet = runTest ./kismet.nix;
|
||||
kiwix-serve = runTest ./kiwix-serve;
|
||||
kmonad = runTest ./kmonad.nix;
|
||||
kmscon = runTest ./kmscon.nix;
|
||||
knot = runTest ./knot.nix;
|
||||
|
|
|
|||
75
nixos/tests/kiwix-serve/default.nix
Normal file
75
nixos/tests/kiwix-serve/default.nix
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
{ lib, pkgs, ... }:
|
||||
let
|
||||
mkTestZim =
|
||||
name:
|
||||
pkgs.runCommandLocal "${name}.zim"
|
||||
{
|
||||
nativeBuildInputs = [ pkgs.zim-tools ];
|
||||
}
|
||||
''
|
||||
${lib.getExe' pkgs.zim-tools "zimwriterfs"} \
|
||||
--name "${name}" \
|
||||
--title 'NixOS kiwix-serve Test' \
|
||||
--description 'NixOS test of kiwix-serve' \
|
||||
--creator Nixpkgs \
|
||||
--publisher Nixpkgs \
|
||||
--language eng \
|
||||
--welcome index.html \
|
||||
--illustration icon.png \
|
||||
${./html} \
|
||||
$out
|
||||
'';
|
||||
|
||||
# Test files must have different names or kiwix-serve will only serve one of them
|
||||
testZimStore = mkTestZim "test-store";
|
||||
testZimOutside = mkTestZim "test-outside";
|
||||
in
|
||||
{
|
||||
name = "kiwix-serve";
|
||||
meta.maintainers = with lib.maintainers; [ MysteryBlokHed ];
|
||||
|
||||
nodes = {
|
||||
machine = {
|
||||
systemd.services.copy-zim-file = {
|
||||
description = "Copy test ZIM file to host system to test paths outside of store";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
before = [ "kiwix-serve.service" ];
|
||||
requiredBy = [ "kiwix-serve.service" ];
|
||||
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
};
|
||||
|
||||
script = ''
|
||||
mkdir -p /var/lib/kiwix-serve
|
||||
cp ${testZimOutside} /var/lib/kiwix-serve/test-outside.zim
|
||||
'';
|
||||
};
|
||||
|
||||
services.kiwix-serve = {
|
||||
enable = true;
|
||||
port = 8080;
|
||||
library = {
|
||||
test-store = testZimStore;
|
||||
test-outside = "/var/lib/kiwix-serve/test-outside.zim";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
machine.wait_for_unit("kiwix-serve.service")
|
||||
machine.wait_for_open_port(8080)
|
||||
machine.wait_until_succeeds("curl --fail --silent --head http://localhost:8080")
|
||||
|
||||
# ZIM file in store
|
||||
test_content = machine.succeed("curl --fail --silent --location http://localhost:8080/content/test-store")
|
||||
print(test_content)
|
||||
assert "NixOS test of kiwix-serve" in test_content, "kiwix-serve did not provide the expected page for the store ZIM file"
|
||||
|
||||
# ZIM file outside of store
|
||||
test_content = machine.succeed("curl --fail --silent --location http://localhost:8080/content/test-outside")
|
||||
print(test_content)
|
||||
assert "NixOS test of kiwix-serve" in test_content, "kiwix-serve did not provide the expected page for the out-of-store ZIM file"
|
||||
'';
|
||||
}
|
||||
BIN
nixos/tests/kiwix-serve/html/icon.png
Normal file
BIN
nixos/tests/kiwix-serve/html/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 84 B |
11
nixos/tests/kiwix-serve/html/index.html
Normal file
11
nixos/tests/kiwix-serve/html/index.html
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>NixOS kiwix-serve Test</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>NixOS test of kiwix-serve</h1>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
docopt_cpp,
|
||||
fetchFromGitHub,
|
||||
gitUpdater,
|
||||
nixosTests,
|
||||
icu,
|
||||
libkiwix,
|
||||
meson,
|
||||
|
|
@ -34,6 +35,8 @@ stdenv.mkDerivation (finalAttrs: {
|
|||
libkiwix
|
||||
];
|
||||
|
||||
passthru.tests.kiwix-serve = nixosTests.kiwix-serve;
|
||||
|
||||
passthru.updateScript = gitUpdater { };
|
||||
|
||||
meta = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue