mirror of https://git.jolheiser.com/dotnix.git
Compare commits
No commits in common. "c59f51c0418f4e456b9feb4f284bb3424f1176de" and "e7ce7296dd8cddd5b037808879f671db0d06abf9" have entirely different histories.
c59f51c041
...
e7ce7296dd
|
@ -249,7 +249,6 @@
|
||||||
inputs.foundry.nixosModules.foundryvtt
|
inputs.foundry.nixosModules.foundryvtt
|
||||||
inputs.cfg-playground.nixosModules.default
|
inputs.cfg-playground.nixosModules.default
|
||||||
./modules/tclip
|
./modules/tclip
|
||||||
./modules/miniserve
|
|
||||||
./machines/dragonwell
|
./machines/dragonwell
|
||||||
];
|
];
|
||||||
services.tclip.package = inputs.tclip.packages.${pkgs.system}.tclipd;
|
services.tclip.package = inputs.tclip.packages.${pkgs.system}.tclipd;
|
||||||
|
|
|
@ -80,6 +80,7 @@ in
|
||||||
"dnd.jolheiser.com".extraConfig = ''
|
"dnd.jolheiser.com".extraConfig = ''
|
||||||
reverse_proxy localhost:30000
|
reverse_proxy localhost:30000
|
||||||
'';
|
'';
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,6 @@ in
|
||||||
./git-pr.nix
|
./git-pr.nix
|
||||||
./golink.nix
|
./golink.nix
|
||||||
./gotosocial.nix
|
./gotosocial.nix
|
||||||
./miniserve.nix
|
|
||||||
./pubserve.nix
|
|
||||||
./restic.nix
|
./restic.nix
|
||||||
./soju.nix
|
./soju.nix
|
||||||
./tandoor.nix
|
./tandoor.nix
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
{
|
|
||||||
services = {
|
|
||||||
miniserve = {
|
|
||||||
enable = true;
|
|
||||||
port = 3453;
|
|
||||||
showHidden = true;
|
|
||||||
uploadFiles = "";
|
|
||||||
mkdir = true;
|
|
||||||
overwriteFiles = true;
|
|
||||||
enableTar = true;
|
|
||||||
enableTarGz = true;
|
|
||||||
enableZip = true;
|
|
||||||
dirsFirst = true;
|
|
||||||
title = "Files";
|
|
||||||
hideThemeSelector = true;
|
|
||||||
hideVersionFooter = true;
|
|
||||||
readme = true;
|
|
||||||
};
|
|
||||||
tailproxy.miniserve = {
|
|
||||||
enable = true;
|
|
||||||
hostname = "files";
|
|
||||||
port = 3453;
|
|
||||||
authKey = "tskey-auth-kNNZJXfSDb11CNTRL-DsdZPygdA7Lrye5WJjnr6LGNffgzo3PUH"; # One-time key
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
{ pkgs, lib, ... }:
|
|
||||||
let
|
|
||||||
user = "pubserve";
|
|
||||||
path = "/var/lib/pubserve";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
users.users.${user} = {
|
|
||||||
group = user;
|
|
||||||
home = path;
|
|
||||||
createHome = true;
|
|
||||||
isSystemUser = true;
|
|
||||||
isNormalUser = false;
|
|
||||||
|
|
||||||
};
|
|
||||||
users.groups.${user} = { };
|
|
||||||
|
|
||||||
systemd.services =
|
|
||||||
let
|
|
||||||
commonArgs = [
|
|
||||||
"-i '127.0.0.1'"
|
|
||||||
"-H"
|
|
||||||
"-D"
|
|
||||||
"-F"
|
|
||||||
"--hide-theme-selector"
|
|
||||||
"--readme"
|
|
||||||
path
|
|
||||||
];
|
|
||||||
in
|
|
||||||
{
|
|
||||||
pubserve = {
|
|
||||||
description = "Miniserve Public File Server";
|
|
||||||
after = [ "network.target" ];
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
serviceConfig = {
|
|
||||||
ExecStart = "${pkgs.miniserve}/bin/miniserve -t 'PubServe' -p 3454 ${lib.concatStringsSep " " commonArgs}";
|
|
||||||
Restart = "on-failure";
|
|
||||||
User = user;
|
|
||||||
Group = user;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
privserve = {
|
|
||||||
description = "Miniserve Public File Server (Admin)";
|
|
||||||
after = [ "network.target" ];
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
serviceConfig = {
|
|
||||||
ExecStart = "${pkgs.miniserve}/bin/miniserve -u -U -o -t 'PrivServe' -p 3455 ${lib.concatStringsSep " " commonArgs}";
|
|
||||||
Restart = "on-failure";
|
|
||||||
User = user;
|
|
||||||
Group = user;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
services.tailproxy = {
|
|
||||||
pubserve = {
|
|
||||||
enable = true;
|
|
||||||
hostname = "pubserve";
|
|
||||||
funnel = true;
|
|
||||||
port = 3454;
|
|
||||||
authKey = "tskey-auth-kJrnknpMsL11CNTRL-ot1kkasErR2cLZZmfuKYR2b9za7fCzVR"; # One-time key
|
|
||||||
};
|
|
||||||
privserve = {
|
|
||||||
enable = true;
|
|
||||||
hostname = "privserve";
|
|
||||||
port = 3455;
|
|
||||||
authKey = "tskey-auth-kKFv865ykk11CNTRL-dfmxUREHP5evuuMsfPy55ehXECXrLF1N7"; # One-time key
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,438 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
let
|
|
||||||
cfg = config.services.miniserve;
|
|
||||||
inherit (lib)
|
|
||||||
mkEnableOption
|
|
||||||
mkOption
|
|
||||||
mkIf
|
|
||||||
types
|
|
||||||
optionalString
|
|
||||||
concatMapStringsSep
|
|
||||||
concatStringsSep
|
|
||||||
;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.services.miniserve = {
|
|
||||||
enable = mkEnableOption "miniserve service";
|
|
||||||
|
|
||||||
package = mkOption {
|
|
||||||
type = types.package;
|
|
||||||
description = "miniserve package to use";
|
|
||||||
default = pkgs.miniserve;
|
|
||||||
};
|
|
||||||
|
|
||||||
user = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "miniserve";
|
|
||||||
description = "User account for miniserve service";
|
|
||||||
};
|
|
||||||
|
|
||||||
group = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "miniserve";
|
|
||||||
description = "Group for miniserve service";
|
|
||||||
};
|
|
||||||
|
|
||||||
path = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "/var/lib/miniserve";
|
|
||||||
description = "Which path to serve";
|
|
||||||
};
|
|
||||||
|
|
||||||
port = mkOption {
|
|
||||||
type = types.port;
|
|
||||||
default = 8080;
|
|
||||||
description = "Port to use";
|
|
||||||
};
|
|
||||||
|
|
||||||
interfaces = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [ "127.0.0.1" ];
|
|
||||||
description = "Interface to listen on";
|
|
||||||
};
|
|
||||||
|
|
||||||
verbose = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Be verbose, includes emitting access logs";
|
|
||||||
};
|
|
||||||
|
|
||||||
indexFile = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
The name of a directory index file to serve, like "index.html"
|
|
||||||
|
|
||||||
Normally, when miniserve serves a directory, it creates a listing for that directory. However, if a directory
|
|
||||||
contains this file, miniserve will serve that file instead.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
spa = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Activate SPA (Single Page Application) mode
|
|
||||||
|
|
||||||
This will cause the file given by --index to be served for all non-existing file paths. In effect, this will serve
|
|
||||||
the index file whenever a 404 would otherwise occur in order to allow the SPA router to handle the request instead.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
prettyUrls = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Activate Pretty URLs mode
|
|
||||||
|
|
||||||
This will cause the server to serve the equivalent `.html` file indicated by the path.
|
|
||||||
|
|
||||||
`/about` will try to find `about.html` and serve it.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
auth = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Set authentication
|
|
||||||
|
|
||||||
Currently supported formats:
|
|
||||||
username:password, username:sha256:hash, username:sha512:hash
|
|
||||||
(e.g. joe:123, joe:sha256:a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3)
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
authFile = mkOption {
|
|
||||||
type = types.nullOr types.path;
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Read authentication values from a file
|
|
||||||
|
|
||||||
Example file content:
|
|
||||||
|
|
||||||
joe:123
|
|
||||||
bob:sha256:a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3
|
|
||||||
bill:
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
routePrefix = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = "Use a specific route prefix";
|
|
||||||
};
|
|
||||||
|
|
||||||
randomRoute = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Generate a random 6-hexdigit route";
|
|
||||||
};
|
|
||||||
|
|
||||||
hideSymlinks = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Hide symlinks in listing and prevent them from being followed";
|
|
||||||
};
|
|
||||||
|
|
||||||
showHidden = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Show hidden files";
|
|
||||||
};
|
|
||||||
|
|
||||||
sortingMethod = mkOption {
|
|
||||||
type = types.enum [
|
|
||||||
"name"
|
|
||||||
"size"
|
|
||||||
"date"
|
|
||||||
];
|
|
||||||
default = "name";
|
|
||||||
description = ''
|
|
||||||
Default sorting method for file list
|
|
||||||
|
|
||||||
Possible values:
|
|
||||||
- name: Sort by name
|
|
||||||
- size: Sort by size
|
|
||||||
- date: Sort by last modification date (natural sort: follows alphanumerical order)
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
sortingOrder = mkOption {
|
|
||||||
type = types.enum [
|
|
||||||
"asc"
|
|
||||||
"desc"
|
|
||||||
];
|
|
||||||
default = "desc";
|
|
||||||
description = ''
|
|
||||||
Default sorting order for file list
|
|
||||||
|
|
||||||
Possible values:
|
|
||||||
- asc: Ascending order
|
|
||||||
- desc: Descending order
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
colorScheme = mkOption {
|
|
||||||
type = types.enum [
|
|
||||||
"squirrel"
|
|
||||||
"archlinux"
|
|
||||||
"zenburn"
|
|
||||||
"monokai"
|
|
||||||
];
|
|
||||||
default = "squirrel";
|
|
||||||
description = ''
|
|
||||||
Default color scheme
|
|
||||||
|
|
||||||
Possible values: squirrel, archlinux, zenburn, monokai
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
colorSchemeDark = mkOption {
|
|
||||||
type = types.enum [
|
|
||||||
"squirrel"
|
|
||||||
"archlinux"
|
|
||||||
"zenburn"
|
|
||||||
"monokai"
|
|
||||||
];
|
|
||||||
default = "archlinux";
|
|
||||||
description = ''
|
|
||||||
Default color scheme
|
|
||||||
|
|
||||||
Possible values: squirrel, archlinux, zenburn, monokai
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
qrcode = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Enable QR code display";
|
|
||||||
};
|
|
||||||
|
|
||||||
uploadFiles = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = "Enable file uploading (and optionally specify for which directory)";
|
|
||||||
};
|
|
||||||
|
|
||||||
mkdir = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Enable creating directories";
|
|
||||||
};
|
|
||||||
|
|
||||||
mediaType = mkOption {
|
|
||||||
type = types.nullOr (
|
|
||||||
types.enum [
|
|
||||||
"image"
|
|
||||||
"audio"
|
|
||||||
"video"
|
|
||||||
]
|
|
||||||
);
|
|
||||||
default = null;
|
|
||||||
description = ''
|
|
||||||
Specify uploadable media types
|
|
||||||
|
|
||||||
Possible values: image, audio, video
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
rawMediaType = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = "Directly specify the uploadable media type expression";
|
|
||||||
};
|
|
||||||
|
|
||||||
overwriteFiles = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Enable overriding existing files during file upload";
|
|
||||||
};
|
|
||||||
|
|
||||||
enableTar = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Enable uncompressed tar archive generation";
|
|
||||||
};
|
|
||||||
|
|
||||||
enableTarGz = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Enable gz-compressed tar archive generation";
|
|
||||||
};
|
|
||||||
|
|
||||||
enableZip = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Enable zip archive generation
|
|
||||||
|
|
||||||
WARNING: Zipping large directories can result in out-of-memory exception because zip generation is done in memory
|
|
||||||
and cannot be sent on the fly
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
compressResponse = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Compress response
|
|
||||||
|
|
||||||
WARNING: Enabling this option may slow down transfers due to CPU overhead, so it is disabled by default.
|
|
||||||
|
|
||||||
Only enable this option if you know that your users have slow connections or if you want to minimize your server's bandwidth usage.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
dirsFirst = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "List directories first";
|
|
||||||
};
|
|
||||||
|
|
||||||
title = mkOption {
|
|
||||||
type = types.nullOr types.str;
|
|
||||||
default = null;
|
|
||||||
description = "Shown instead of host in page title and heading";
|
|
||||||
};
|
|
||||||
|
|
||||||
headers = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [ ];
|
|
||||||
description = ''
|
|
||||||
Inserts custom headers into the responses. Specify each header as a 'Header:Value' pair.
|
|
||||||
This parameter can be used multiple times to add multiple headers.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
--header "Header1:Value1" --header "Header2:Value2"
|
|
||||||
(If a header is already set or previously inserted, it will not be overwritten.)
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
showSymlinkInfo = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Visualize symlinks in directory listing";
|
|
||||||
};
|
|
||||||
|
|
||||||
hideVersionFooter = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Hide version footer";
|
|
||||||
};
|
|
||||||
|
|
||||||
hideThemeSelector = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Hide theme selector";
|
|
||||||
};
|
|
||||||
|
|
||||||
showWgetFooter = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "If enabled, display a wget command to recursively download the current directory";
|
|
||||||
};
|
|
||||||
|
|
||||||
tlsCert = mkOption {
|
|
||||||
type = types.nullOr types.path;
|
|
||||||
default = null;
|
|
||||||
description = "TLS certificate to use";
|
|
||||||
};
|
|
||||||
|
|
||||||
tlsKey = mkOption {
|
|
||||||
type = types.nullOr types.path;
|
|
||||||
default = null;
|
|
||||||
description = "TLS private key to use";
|
|
||||||
};
|
|
||||||
|
|
||||||
readme = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "Enable README.md rendering in directories";
|
|
||||||
};
|
|
||||||
|
|
||||||
disableIndexing = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = ''
|
|
||||||
Disable indexing
|
|
||||||
|
|
||||||
This will prevent directory listings from being generated and return an error instead.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
|
||||||
systemd.services.miniserve = {
|
|
||||||
description = "Miniserve File Server";
|
|
||||||
after = [ "network.target" ];
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
serviceConfig = {
|
|
||||||
ExecStart =
|
|
||||||
let
|
|
||||||
args = [
|
|
||||||
(optionalString cfg.verbose "-v")
|
|
||||||
(optionalString (cfg.indexFile != null) "--index '${cfg.indexFile}'")
|
|
||||||
(optionalString cfg.spa "--spa")
|
|
||||||
(optionalString cfg.prettyUrls "--pretty-urls")
|
|
||||||
"-p ${toString cfg.port}"
|
|
||||||
(concatMapStringsSep " " (i: "-i ${i}") cfg.interfaces)
|
|
||||||
(optionalString (cfg.auth != null) "-a '${cfg.auth}'")
|
|
||||||
(optionalString (cfg.authFile != null) "--auth-file ${cfg.authFile}")
|
|
||||||
(optionalString (cfg.routePrefix != null) "--route-prefix '${cfg.routePrefix}'")
|
|
||||||
(optionalString cfg.randomRoute "--random-route")
|
|
||||||
(optionalString cfg.hideSymlinks "-P")
|
|
||||||
(optionalString cfg.showHidden "-H")
|
|
||||||
"-S ${cfg.sortingMethod}"
|
|
||||||
"-O ${cfg.sortingOrder}"
|
|
||||||
"-c ${cfg.colorScheme}"
|
|
||||||
"-d ${cfg.colorSchemeDark}"
|
|
||||||
(optionalString cfg.qrcode "-q")
|
|
||||||
(optionalString (cfg.uploadFiles != null) (
|
|
||||||
if (cfg.uploadFiles != "") then "-u '${cfg.uploadFiles}'" else "-u"
|
|
||||||
))
|
|
||||||
(optionalString cfg.mkdir "-U")
|
|
||||||
(optionalString (cfg.mediaType != null) "-m ${cfg.mediaType}")
|
|
||||||
(optionalString (cfg.rawMediaType != null) "-M '${cfg.rawMediaType}'")
|
|
||||||
(optionalString cfg.overwriteFiles "-o")
|
|
||||||
(optionalString cfg.enableTar "-r")
|
|
||||||
(optionalString cfg.enableTarGz "-g")
|
|
||||||
(optionalString cfg.enableZip "-z")
|
|
||||||
(optionalString cfg.compressResponse "-C")
|
|
||||||
(optionalString cfg.dirsFirst "-D")
|
|
||||||
(optionalString (cfg.title != null) "-t '${cfg.title}'")
|
|
||||||
(concatMapStringsSep " " (h: "--header '${h}'") cfg.headers)
|
|
||||||
(optionalString cfg.showSymlinkInfo "-l")
|
|
||||||
(optionalString cfg.hideVersionFooter "-F")
|
|
||||||
(optionalString cfg.hideThemeSelector "--hide-theme-selector")
|
|
||||||
(optionalString cfg.showWgetFooter "-W")
|
|
||||||
(optionalString (cfg.tlsCert != null) "--tls-cert ${cfg.tlsCert}")
|
|
||||||
(optionalString (cfg.tlsKey != null) "--tls-key ${cfg.tlsKey}")
|
|
||||||
(optionalString cfg.readme "--readme")
|
|
||||||
(optionalString cfg.disableIndexing "-I")
|
|
||||||
cfg.path
|
|
||||||
];
|
|
||||||
in
|
|
||||||
"${pkgs.miniserve}/bin/miniserve ${concatStringsSep " " args}";
|
|
||||||
Restart = "on-failure";
|
|
||||||
User = cfg.user;
|
|
||||||
Group = cfg.group;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
users.users.${cfg.user} = {
|
|
||||||
group = cfg.group;
|
|
||||||
home = cfg.path;
|
|
||||||
createHome = true;
|
|
||||||
isSystemUser = true;
|
|
||||||
isNormalUser = false;
|
|
||||||
};
|
|
||||||
users.groups.${cfg.group} = { };
|
|
||||||
};
|
|
||||||
}
|
|
Loading…
Reference in New Issue