diff --git a/nix/hosts/nixedo/default.nix b/nix/hosts/nixedo/default.nix
index b0011491..5a6d0ade 100644
--- a/nix/hosts/nixedo/default.nix
+++ b/nix/hosts/nixedo/default.nix
@@ -6,6 +6,7 @@
 
     homelab = {
       audiobookshelf.enable = true;
+      beaverhabits.enable = true;
       forgejo.enable = true;
       freshrss.enable = true;
       gitea.enable = true;
diff --git a/nix/modules/nixos/features/homelab/beaverhabits.nix b/nix/modules/nixos/features/homelab/beaverhabits.nix
new file mode 100644
index 00000000..98f362cd
--- /dev/null
+++ b/nix/modules/nixos/features/homelab/beaverhabits.nix
@@ -0,0 +1,102 @@
+# Auto-generated using compose2nix v0.3.2-pre.
+{
+  config,
+  pkgs,
+  lib,
+  ...
+}:
+
+with lib;
+
+let
+  cfg = config.features.homelab.beaverhabits;
+
+  port = 8084;
+in
+{
+  options.features.homelab.beaverhabits.enable = mkEnableOption "Enable beaverhabits";
+
+  config = mkIf cfg.enable {
+    virtualisation = {
+      docker = {
+        enable = true;
+        autoPrune.enable = true;
+      };
+
+      oci-containers = {
+        backend = "docker";
+
+        containers."beaverhabits" = {
+          image = "daya0576/beaverhabits:latest";
+
+          environment = {
+            "HABITS_STORAGE" = "DATABASE";
+          };
+
+          volumes = [
+            "/mnt/media/beaverhabits:/app/.user:rw"
+          ];
+
+          ports = [
+            "${toString port}:8080/tcp"
+          ];
+
+          user = "1000:1000";
+
+          log-driver = "journald";
+
+          extraOptions = [
+            "--network-alias=beaverhabits"
+            "--network=beaverhabits_default"
+          ];
+        };
+      };
+    };
+
+    systemd = {
+      services = {
+        "docker-beaverhabits" = {
+          serviceConfig = {
+            Restart = lib.mkOverride 90 "always";
+            RestartMaxDelaySec = lib.mkOverride 90 "1m";
+            RestartSec = lib.mkOverride 90 "100ms";
+            RestartSteps = lib.mkOverride 90 9;
+          };
+
+          after = [ "docker-network-beaverhabits_default.service" ];
+          requires = [ "docker-network-beaverhabits_default.service" ];
+          partOf = [ "docker-compose-beaverhabits-root.target" ];
+          wantedBy = [ "docker-compose-beaverhabits-root.target" ];
+        };
+
+        "docker-network-beaverhabits_default" = {
+          path = [ pkgs.docker ];
+
+          serviceConfig = {
+            Type = "oneshot";
+            RemainAfterExit = true;
+            ExecStop = "docker network rm -f beaverhabits_default";
+          };
+
+          script = ''
+            docker network inspect beaverhabits_default || docker network create beaverhabits_default
+          '';
+
+          partOf = [ "docker-compose-beaverhabits-root.target" ];
+          wantedBy = [ "docker-compose-beaverhabits-root.target" ];
+        };
+      };
+
+      targets."docker-compose-beaverhabits-root" = {
+        unitConfig.Description = "Root target generated by compose2nix.";
+        wantedBy = [ "multi-user.target" ];
+      };
+    };
+
+    services.caddy.virtualHosts."beaverhabits.opdavies.uk" = {
+      useACMEHost = "opdavies.uk";
+
+      extraConfig = "reverse_proxy localhost:${toString port}";
+    };
+  };
+}
diff --git a/nix/modules/nixos/features/homelab/default.nix b/nix/modules/nixos/features/homelab/default.nix
index 7231aa87..897465c5 100644
--- a/nix/modules/nixos/features/homelab/default.nix
+++ b/nix/modules/nixos/features/homelab/default.nix
@@ -1,6 +1,7 @@
 {
   imports = [
     ./audiobookshelf.nix
+    ./beaverhabits.nix
     ./forgejo.nix
     ./freshrss.nix
     ./gitea.nix