mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-02-20 11:05:14 +00:00
nixos/grocy: init module
Co-authored-by: elseym <elseym@me.com>
This commit is contained in:
parent
3d051f49ba
commit
13f7b75553
@ -814,6 +814,7 @@
|
||||
./services/web-apps/dokuwiki.nix
|
||||
./services/web-apps/frab.nix
|
||||
./services/web-apps/gotify-server.nix
|
||||
./services/web-apps/grocy.nix
|
||||
./services/web-apps/icingaweb2/icingaweb2.nix
|
||||
./services/web-apps/icingaweb2/module-monitoring.nix
|
||||
./services/web-apps/ihatemoney
|
||||
|
172
nixos/modules/services/web-apps/grocy.nix
Normal file
172
nixos/modules/services/web-apps/grocy.nix
Normal file
@ -0,0 +1,172 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.grocy;
|
||||
in {
|
||||
options.services.grocy = {
|
||||
enable = mkEnableOption "grocy";
|
||||
|
||||
hostName = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
FQDN for the grocy instance.
|
||||
'';
|
||||
};
|
||||
|
||||
nginx.enableSSL = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether or not to enable SSL (with ACME and let's encrypt)
|
||||
for the grocy vhost.
|
||||
'';
|
||||
};
|
||||
|
||||
phpfpm.settings = mkOption {
|
||||
type = with types; attrsOf (oneOf [ int str bool ]);
|
||||
default = {
|
||||
"pm" = "dynamic";
|
||||
"php_admin_value[error_log]" = "stderr";
|
||||
"php_admin_flag[log_errors]" = true;
|
||||
"listen.owner" = "nginx";
|
||||
"catch_workers_output" = true;
|
||||
"pm.max_children" = "32";
|
||||
"pm.start_servers" = "2";
|
||||
"pm.min_spare_servers" = "2";
|
||||
"pm.max_spare_servers" = "4";
|
||||
"pm.max_requests" = "500";
|
||||
};
|
||||
|
||||
description = ''
|
||||
Options for grocy's PHPFPM pool.
|
||||
'';
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.str;
|
||||
default = "/var/lib/grocy";
|
||||
description = ''
|
||||
Home directory of the <literal>grocy</literal> user which contains
|
||||
the application's state.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = {
|
||||
currency = mkOption {
|
||||
type = types.str;
|
||||
default = "USD";
|
||||
example = "EUR";
|
||||
description = ''
|
||||
ISO 4217 code for the currency to display.
|
||||
'';
|
||||
};
|
||||
|
||||
culture = mkOption {
|
||||
type = types.enum [ "de" "en" "da" "en_GB" "es" "fr" "hu" "it" "nl" "no" "pl" "pt_BR" "ru" "sk_SK" "sv_SE" "tr" ];
|
||||
default = "en";
|
||||
description = ''
|
||||
Display language of the frontend.
|
||||
'';
|
||||
};
|
||||
|
||||
calendar = {
|
||||
showWeekNumber = mkOption {
|
||||
default = true;
|
||||
type = types.bool;
|
||||
description = ''
|
||||
Show the number of the weeks in the calendar views.
|
||||
'';
|
||||
};
|
||||
firstDayOfWeek = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr (types.enum (range 0 6));
|
||||
description = ''
|
||||
Which day of the week (0=Sunday, 1=Monday etc.) should be the
|
||||
first day.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment.etc."grocy/config.php".text = ''
|
||||
<?php
|
||||
Setting('CULTURE', '${cfg.settings.culture}');
|
||||
Setting('CURRENCY', '${cfg.settings.currency}');
|
||||
Setting('CALENDAR_FIRST_DAY_OF_WEEK', '${toString cfg.settings.calendar.firstDayOfWeek}');
|
||||
Setting('CALENDAR_SHOW_WEEK_OF_YEAR', ${boolToString cfg.settings.calendar.showWeekNumber});
|
||||
'';
|
||||
|
||||
users.users.grocy = {
|
||||
isSystemUser = true;
|
||||
createHome = true;
|
||||
home = cfg.dataDir;
|
||||
group = "nginx";
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = map (
|
||||
dirName: "d '${cfg.dataDir}/${dirName}' - grocy nginx - -"
|
||||
) [ "viewcache" "plugins" "settingoverrides" "storage" ];
|
||||
|
||||
services.phpfpm.pools.grocy = {
|
||||
user = "grocy";
|
||||
group = "nginx";
|
||||
|
||||
# PHP 7.3 is the only version which is supported/tested by upstream:
|
||||
# https://github.com/grocy/grocy/blob/v2.6.0/README.md#how-to-install
|
||||
phpPackage = pkgs.php73;
|
||||
|
||||
inherit (cfg.phpfpm) settings;
|
||||
|
||||
phpEnv = {
|
||||
GROCY_CONFIG_FILE = "/etc/grocy/config.php";
|
||||
GROCY_DB_FILE = "${cfg.dataDir}/grocy.db";
|
||||
GROCY_STORAGE_DIR = "${cfg.dataDir}/storage";
|
||||
GROCY_PLUGIN_DIR = "${cfg.dataDir}/plugins";
|
||||
GROCY_CACHE_DIR = "${cfg.dataDir}/viewcache";
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
virtualHosts."${cfg.hostName}" = mkMerge [
|
||||
{ root = "${pkgs.grocy}/public";
|
||||
locations."/".extraConfig = ''
|
||||
rewrite ^ /index.php;
|
||||
'';
|
||||
locations."~ \\.php$".extraConfig = ''
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_pass unix:${config.services.phpfpm.pools.grocy.socket};
|
||||
include ${config.services.nginx.package}/conf/fastcgi.conf;
|
||||
include ${config.services.nginx.package}/conf/fastcgi_params;
|
||||
'';
|
||||
locations."~ \\.(js|css|ttf|woff2?|png|jpe?g|svg)$".extraConfig = ''
|
||||
add_header Cache-Control "public, max-age=15778463";
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
add_header X-Robots-Tag none;
|
||||
add_header X-Download-Options noopen;
|
||||
add_header X-Permitted-Cross-Domain-Policies none;
|
||||
add_header Referrer-Policy no-referrer;
|
||||
access_log off;
|
||||
'';
|
||||
extraConfig = ''
|
||||
try_files $uri /index.php;
|
||||
'';
|
||||
}
|
||||
(mkIf cfg.nginx.enableSSL {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
})
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
meta = {
|
||||
maintainers = with maintainers; [ ma27 ];
|
||||
doc = ./grocy.xml;
|
||||
};
|
||||
}
|
77
nixos/modules/services/web-apps/grocy.xml
Normal file
77
nixos/modules/services/web-apps/grocy.xml
Normal file
@ -0,0 +1,77 @@
|
||||
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
version="5.0"
|
||||
xml:id="module-services-grocy">
|
||||
|
||||
<title>Grocy</title>
|
||||
<para>
|
||||
<link xlink:href="https://grocy.info/">Grocy</link> is a web-based self-hosted groceries
|
||||
& household management solution for your home.
|
||||
</para>
|
||||
|
||||
<section xml:id="module-services-grocy-basic-usage">
|
||||
<title>Basic usage</title>
|
||||
<para>
|
||||
A very basic configuration may look like this:
|
||||
<programlisting>{ pkgs, ... }:
|
||||
{
|
||||
services.grocy = {
|
||||
<link linkend="opt-services.grocy.enable">enable</link> = true;
|
||||
<link linkend="opt-services.grocy.hostName">hostName</link> = "grocy.tld";
|
||||
};
|
||||
}</programlisting>
|
||||
This configures a simple vhost using <link linkend="opt-services.nginx.enable">nginx</link>
|
||||
which listens to <literal>grocy.tld</literal> with fully configured ACME/LE (this can be
|
||||
disabled by setting <link linkend="opt-services.grocy.nginx.enableSSL">services.grocy.nginx.enableSSL</link>
|
||||
to <literal>false</literal>). After the initial setup the credentials <literal>admin:admin</literal>
|
||||
can be used to login.
|
||||
</para>
|
||||
<para>
|
||||
The application's state is persisted at <literal>/var/lib/grocy/grocy.db</literal> in a
|
||||
<package>sqlite3</package> database. The migration is applied when requesting the <literal>/</literal>-route
|
||||
of the application.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="module-services-grocy-settings">
|
||||
<title>Settings</title>
|
||||
<para>
|
||||
The configuration for <literal>grocy</literal> is located at <literal>/etc/grocy/config.php</literal>.
|
||||
By default, the following settings can be defined in the NixOS-configuration:
|
||||
<programlisting>{ pkgs, ... }:
|
||||
{
|
||||
services.grocy.settings = {
|
||||
# The default currency in the system for invoices etc.
|
||||
# Please note that exchange rates aren't taken into account, this
|
||||
# is just the setting for what's shown in the frontend.
|
||||
<link linkend="opt-services.grocy.settings.currency">currency</link> = "EUR";
|
||||
|
||||
# The display language (and locale configuration) for grocy.
|
||||
<link linkend="opt-services.grocy.settings.currency">culture</link> = "de";
|
||||
|
||||
calendar = {
|
||||
# Whether or not to show the week-numbers
|
||||
# in the calendar.
|
||||
<link linkend="opt-services.grocy.settings.calendar.showWeekNumber">showWeekNumber</link> = true;
|
||||
|
||||
# Index of the first day to be shown in the calendar (0=Sunday, 1=Monday,
|
||||
# 2=Tuesday and so on).
|
||||
<link linkend="opt-services.grocy.settings.calendar.firstDayOfWeek">firstDayOfWeek</link> = 2;
|
||||
};
|
||||
};
|
||||
}</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
If you want to alter the configuration file on your own, you can do this manually with
|
||||
an expression like this:
|
||||
<programlisting>{ lib, ... }:
|
||||
{
|
||||
environment.etc."grocy/config.php".text = lib.mkAfter ''
|
||||
// Arbitrary PHP code in grocy's configuration file
|
||||
'';
|
||||
}</programlisting>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
</chapter>
|
@ -96,6 +96,7 @@ in
|
||||
freeswitch = handleTest ./freeswitch.nix {};
|
||||
fsck = handleTest ./fsck.nix {};
|
||||
gotify-server = handleTest ./gotify-server.nix {};
|
||||
grocy = handleTest ./grocy.nix {};
|
||||
gitea = handleTest ./gitea.nix {};
|
||||
gitlab = handleTest ./gitlab.nix {};
|
||||
gitolite = handleTest ./gitolite.nix {};
|
||||
|
47
nixos/tests/grocy.nix
Normal file
47
nixos/tests/grocy.nix
Normal file
@ -0,0 +1,47 @@
|
||||
import ./make-test-python.nix ({ pkgs, ... }: {
|
||||
name = "grocy";
|
||||
meta = with pkgs.stdenv.lib.maintainers; {
|
||||
maintainers = [ ma27 ];
|
||||
};
|
||||
|
||||
machine = { pkgs, ... }: {
|
||||
services.grocy = {
|
||||
enable = true;
|
||||
hostName = "localhost";
|
||||
nginx.enableSSL = false;
|
||||
};
|
||||
environment.systemPackages = [ pkgs.jq ];
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
machine.start()
|
||||
machine.wait_for_open_port(80)
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
|
||||
machine.succeed("curl -sSf http://localhost")
|
||||
|
||||
machine.succeed(
|
||||
"curl -c cookies -sSf -X POST http://localhost/login -d 'username=admin&password=admin'"
|
||||
)
|
||||
|
||||
cookie = machine.succeed(
|
||||
"grep -v '^#' cookies | awk '{ print $7 }' | sed -e '/^$/d' | perl -pe 'chomp'"
|
||||
)
|
||||
|
||||
machine.succeed(
|
||||
f"curl -sSf -X POST http://localhost/api/objects/tasks -b 'grocy_session={cookie}' "
|
||||
+ '-d \'{"assigned_to_user_id":1,"name":"Test Task","due_date":"1970-01-01"}\'''
|
||||
+ " --header 'Content-Type: application/json'"
|
||||
)
|
||||
|
||||
task_name = machine.succeed(
|
||||
f"curl -sSf http://localhost/api/tasks -b 'grocy_session={cookie}' --header 'Accept: application/json' | jq '.[].name' | xargs echo | perl -pe 'chomp'"
|
||||
)
|
||||
|
||||
assert task_name == "Test Task"
|
||||
|
||||
machine.succeed("curl -sSfI http://localhost/api/tasks 2>&1 | grep '401 Unauthorized'")
|
||||
|
||||
machine.shutdown()
|
||||
'';
|
||||
})
|
Loading…
Reference in New Issue
Block a user