174 lines
5.1 KiB
Nix
174 lines
5.1 KiB
Nix
{
|
|
description = "Self-hosted file sharing cloud for you and your friends";
|
|
inputs = {
|
|
nixpkgs.url = github:nixos/nixpkgs/nixos-unstable;
|
|
flake-utils.url = github:numtide/flake-utils;
|
|
};
|
|
|
|
outputs = { self, nixpkgs, flake-utils }: {
|
|
|
|
nixosModule = { config, ... }:
|
|
with nixpkgs.lib;
|
|
let
|
|
system = config.nixpkgs.localSystem.system;
|
|
|
|
python = nixpkgs.legacyPackages.${system}.python3Packages.python;
|
|
flask = nixpkgs.legacyPackages.${system}.python3Packages.flask;
|
|
gunicorn = nixpkgs.legacyPackages.${system}.python3Packages.gunicorn;
|
|
raincloud = self.packages.${system}.raincloud;
|
|
|
|
cfg = config.services.raincloud;
|
|
|
|
in
|
|
{
|
|
options.services.raincloud = {
|
|
|
|
enable = mkEnableOption "Enable raincloud WSGI server";
|
|
|
|
address = mkOption {
|
|
type = types.str;
|
|
default = "127.0.0.1";
|
|
example = "0.0.0.0";
|
|
description = "Bind address of the server";
|
|
};
|
|
|
|
port = mkOption {
|
|
type = types.int;
|
|
default = 8000;
|
|
example = 4000;
|
|
description = "Port on which the server listens";
|
|
};
|
|
|
|
user = mkOption {
|
|
type = types.str;
|
|
default = "raincloud";
|
|
description = "User under which the server runs";
|
|
};
|
|
|
|
group = mkOption {
|
|
type = types.str;
|
|
default = "raincloud";
|
|
description = "Group under which the server runs";
|
|
};
|
|
|
|
cloudName = mkOption {
|
|
type = types.str;
|
|
default = "raincloud";
|
|
description = "Name of the raincloud";
|
|
};
|
|
|
|
basePath = mkOption {
|
|
type = types.str;
|
|
example = "/var/lib/raincloud";
|
|
description = "Base path of the raincloud";
|
|
};
|
|
|
|
secretKeyPath = mkOption {
|
|
type = types.str;
|
|
example = "/var/lib/raincloud/secret_key";
|
|
description = "Path to file containing Flask secret key";
|
|
};
|
|
|
|
redisUrl = mkOption {
|
|
type = types.str;
|
|
default = "redis://127.0.0.1:6379/0";
|
|
example = "unix:/run/redis-raincloud/redis.sock";
|
|
description = "URL of Redis database";
|
|
};
|
|
|
|
numWorkers = mkOption {
|
|
type = types.int;
|
|
default = 5;
|
|
example = 17;
|
|
description = "Number of Gunicorn workers (recommendation is: 2 x #CPUs + 1)";
|
|
};
|
|
|
|
workerTimeout = mkOption {
|
|
type = types.int;
|
|
default = 300;
|
|
example = 360;
|
|
description = "Gunicorn worker timeout";
|
|
};
|
|
};
|
|
|
|
config = mkIf cfg.enable {
|
|
|
|
systemd.services.raincloud = {
|
|
description = "Enable raincloud WSGI server";
|
|
after = [ "network.target" ];
|
|
wantedBy = [ "multi-user.target" ];
|
|
restartIfChanged = true;
|
|
|
|
environment =
|
|
let
|
|
penv = python.buildEnv.override {
|
|
extraLibs = [ flask raincloud ];
|
|
};
|
|
in
|
|
{
|
|
PYTHONPATH = "${penv}/${python.sitePackages}/";
|
|
};
|
|
|
|
serviceConfig = {
|
|
Type = "simple";
|
|
User = cfg.user;
|
|
Group = cfg.group;
|
|
Restart = "always";
|
|
RestartSec = "5s";
|
|
PermissionsStartOnly = true;
|
|
|
|
ExecStart = ''
|
|
${gunicorn}/bin/gunicorn "raincloud:create_app('${cfg.basePath}', '${cfg.secretKeyPath}', '${cfg.redisUrl}', '${cfg.cloudName}')" \
|
|
--bind=${cfg.address}:${toString cfg.port} \
|
|
--workers ${toString cfg.numWorkers} \
|
|
--timeout ${toString cfg.workerTimeout}
|
|
'';
|
|
};
|
|
};
|
|
|
|
users.users = mkIf (cfg.user == "raincloud") {
|
|
raincloud = {
|
|
group = cfg.group;
|
|
isSystemUser = true;
|
|
};
|
|
};
|
|
|
|
users.groups = mkIf (cfg.group == "raincloud") {
|
|
raincloud = { };
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
} // flake-utils.lib.eachDefaultSystem
|
|
(system:
|
|
let
|
|
pkgs = nixpkgs.legacyPackages.${system};
|
|
in
|
|
{
|
|
|
|
# Package
|
|
packages.raincloud =
|
|
pkgs.python3Packages.buildPythonPackage rec {
|
|
name = "raincloud";
|
|
src = self;
|
|
propagatedBuildInputs = with pkgs; [
|
|
python3Packages.flask
|
|
python3Packages.redis
|
|
];
|
|
};
|
|
defaultPackage = self.packages.${system}.raincloud;
|
|
|
|
# Development shell
|
|
devShell = pkgs.mkShell {
|
|
buildInputs = with pkgs; [
|
|
python3
|
|
python3Packages.flask
|
|
python3Packages.gunicorn
|
|
python3Packages.redis
|
|
];
|
|
};
|
|
}
|
|
);
|
|
}
|