summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--modules/bookwyrm.nix140
1 files changed, 140 insertions, 0 deletions
diff --git a/modules/bookwyrm.nix b/modules/bookwyrm.nix
new file mode 100644
index 0000000..4fcc323
--- /dev/null
+++ b/modules/bookwyrm.nix
@@ -0,0 +1,140 @@
+{ config, lib, pkgs, ... }:
+
+let
+ cfg = config.services.bookwyrm;
+in
+{
+ options.services.bookwyrm = with lib; {
+ enable = mkEnableOption "bookwyrm";
+
+ settings = mkOption {
+ default = {};
+ type = types.attrsOf (types.oneOf [ types.bool types.str types.int ]);
+ description = mdDoc ''
+ Settings passed to bookwyrm via environment variables. See bookwyrm's
+ [.env.example](https://github.com/bookwyrm-social/bookwyrm/blob/v0.7.2/.env.example)
+ file for what is permissible here.
+ '';
+ };
+
+ package = mkOption {
+ default = pkgs.bookwyrm.override { inherit (cfg) settings; };
+ type = types.package;
+ description = mdDoc ''
+ The bookwyrm package to use. Note that this includes the settings .env file;
+ if you set this directly, settings set via {option}`services.bookwyrm.settings`
+ will be ignored.
+ '';
+ };
+
+ stateDir = mkOption {
+ default = "/var/lib/bookwyrm";
+ type = types.path;
+ description = mdDoc ''
+ Where bookwyrm keeps dynamic data (in practice, exclusively book covers?) when
+ not configured to use an S3-compatible storage. This should be persistent storage,
+ otherwise you will have missing book covers and no obvious way to re-download them
+ from a catalogue.
+ '';
+ };
+
+ bindAddress = mkOption {
+ default = "0.0.0.0";
+ type = types.str;
+ description = mdDoc ''
+ Address bookwyrm should bind to.
+ '';
+ };
+
+ port = mkOption {
+ default = 8000;
+ type = types.port;
+ description = mdDoc ''
+ Port bookwyrm should listen on.
+ '';
+ };
+
+ threads = mkOption {
+ default = 8;
+ type = types.int;
+ description = mdDoc ''
+ Number of threads that gunicorn should spawn.
+ '';
+ };
+
+ setupNginx = mkOption {
+ default = false;
+ type = types.bool;
+ description = mdDoc ''
+ Whether to set up a simple nginx config to server bookwyrm's `static/` and `image`
+ directories.
+ '';
+ };
+
+ nginxVirtualHost = mkOption {
+ default = "default";
+ type = types.str;
+ description = mdDoc ''
+ The name of the nginx virtual host to set up.
+ '';
+ };
+ };
+
+
+ config = with lib; mkIf cfg.enable {
+ systemd.packages = [ cfg.package ];
+
+ systemd.services = {
+ bookwyrm = {
+ enable = true;
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig = {
+ BindPaths = [
+ cfg.package.passthru.gunicorn
+ cfg.package.passthru.celery
+ cfg.stateDir
+ ];
+ } // mkIf (cfg.bindAddress != "0.0.0.0" || cfg.port != 8000 || cfg.threads != 8) {
+ ExecStart = "${lib.getExe cfg.package.passthru.gunicorn} bookwyrm.wsgi:application --threads=${toString cfg.threads} --bind ${cfg.bindAddress}:${toString cfg.port}";
+ };
+
+ environment.PYTHONPATH = cfg.package.passthru.pythonPath;
+ };
+
+ bookwyrm-worker = {
+ enable = true;
+ wantedBy = [ "multi-user.target" ];
+ environment.PYTHONPATH = cfg.package.passthru.pythonPath;
+ serviceConfig.BindPaths = [
+ cfg.stateDir
+ ];
+ };
+ bookwyrm-scheduler = {
+ enable = true;
+ wantedBy = [ "multi-user.target" ];
+ environment.PYTHONPATH = cfg.package.passthru.pythonPath;
+ };
+ };
+
+ systemd.tmpfiles.rules = [
+ "d ${cfg.stateDir}/images 0750 bookwyrm bookwyrm - -"
+ ];
+
+ services.nginx = mkIf cfg.setupNginx {
+ enable = true;
+ virtualHosts.${cfg.nginxVirtualHost} = {
+ locations."/static".root = config.services.bookwyrm.package;
+ locations."/images".root = cfg.stateDir;
+ locations."/".proxyPass = "http://${cfg.bindAddress}:${toString cfg.port}";
+ };
+ };
+
+ users.users.bookwyrm = {
+ isSystemUser = true;
+ group = "bookwyrm";
+ };
+ users.users.nginx.extraGroups = [ "bookwyrm" ];
+ users.groups.bookwyrm = {};
+ };
+
+}