Grocy is a stock tracking application for groceries. I'd like to use it to keep track of some of my stuff, so let's host it on umber!
+34
packetmix/systems/umber/grocy.nix
+34
packetmix/systems/umber/grocy.nix
···
1
+
# SPDX-FileCopyrightText: 2025 FreshlyBakedCake
2
+
#
3
+
# SPDX-License-Identifier: MIT
4
+
5
+
{ pkgs, lib, ... }:
6
+
{
7
+
services.grocy = {
8
+
enable = true;
9
+
package = pkgs.stdenv.mkDerivation {
10
+
name = "grocy-custom-js";
11
+
src = pkgs.grocy;
12
+
13
+
dontBuild = true;
14
+
installPhase = ''
15
+
mkdir -p $out/
16
+
cp -r * $out/
17
+
18
+
mkdir -p $out/data/
19
+
cp ${./grocy/custom_js.html} $out/data/custom_js.html # we need to specify the filename explicitly, as otherwise this'll have a hash
20
+
'';
21
+
};
22
+
hostName = "grocy.starrysky.fyi";
23
+
24
+
settings.currency = "GBP";
25
+
};
26
+
27
+
services.nginx.virtualHosts."grocy.starrysky.fyi" = {
28
+
acmeRoot = null;
29
+
forceSSL = lib.mkForce false;
30
+
onlySSL = true;
31
+
};
32
+
33
+
clicks.storage.impermanence.persist.directories = [ "/var/lib/grocy" ];
34
+
}
+27
packetmix/systems/umber/grocy/custom_js.html
+27
packetmix/systems/umber/grocy/custom_js.html
···
1
+
<!--
2
+
SPDX-FileCopyrightText: 2026 Freshly Baked Cake
3
+
4
+
SPDX-License-Identifier: MIT
5
+
-->
6
+
7
+
<script>
8
+
{
9
+
const locationFilter = document.getElementById("location-filter");
10
+
let desiredLocation = GetUriParam("location");
11
+
if (locationFilter !== null && desiredLocation !== null)
12
+
{
13
+
if (locationFilter.selectedOptions.length === 0 || locationFilter.selectedOptions[0].value === "all") {
14
+
// Don't trigger if we select a different option and refresh the page
15
+
desiredLocation = desiredLocation.replaceAll("_", " ") // WikiText needs underscores to be spaces
16
+
const option = locationFilter.querySelector(`option[value="${desiredLocation}"]`)
17
+
?? locationFilter.querySelector(`option[value^="${desiredLocation}"]`)
18
+
?? locationFilter.querySelector(`option[value*="${desiredLocation}"]`);
19
+
// Search first for an exact match, then a match which starts with, then a match which contains
20
+
if (option) {
21
+
locationFilter.value = option.value;
22
+
locationFilter.dispatchEvent(new Event('change'));
23
+
}
24
+
}
25
+
}
26
+
}
27
+
</script>