Commit 80d8989

HPCesia <me@hpcesia.com>
2025-07-20 13:14:03
feat(service): add artalk on pardo
1 parent ee32d2d
Changed files (5)
hosts
secrets
hosts/chaser-pardofelis/artalk.nix
@@ -0,0 +1,84 @@
+{config, ...}: {
+  services.artalk = {
+    enable = true;
+    settings = {
+      host = "127.0.0.1";
+      port = 23366;
+      app_key = {_secret = config.sops.secrets.artalk-app-key.path;};
+      debug = false;
+      locale = "zh-CN";
+      timezone = "Asia/Shanghai";
+      login_timeout = 259200;
+      db = {
+        type = "sqlite";
+        file = "./data/artalk.db";
+        user = "artalk";
+        charset = "utf8mb4";
+      };
+      log = {
+        enabled = true;
+        filename = "./data/artalk.log";
+      };
+      trusted_domains = [
+        "https://blog.hpcesia.com"
+      ];
+      moderator = {
+        pending_default = true;
+        api_fail_block = true;
+        akismet_key = {_secret = config.sops.secrets.artalk-akismet-key.path;};
+      };
+      captcha = {
+        enabled = true;
+        captcha_type = "image";
+      };
+      img_upload.enable = false;
+      email = {
+        enabled = true;
+        send_type = "smtp";
+        send_name = "{{reply_nick}}";
+        send_addr = "info@hpcesia.com";
+        mail_subject = "[{{site_name}}] 您收到了来自 @{{reply_nick}} 的回复";
+        mail_tpl = "default";
+        smtp = {
+          host = "glacier.mxrouting.net";
+          port = 465;
+          username = "info@hpcesia.com";
+          password = {_secret = config.sops.secrets.artalk-email-password.path;};
+        };
+      };
+      admin_notify = {
+        notify_tpl = "default";
+        notify_pending = true;
+        email = {
+          enabled = true;
+          mail_subject = "[{{site_name}}] 您的文章「{{page_title}}」有新回复";
+        };
+      };
+      auth = {
+        enabled = true;
+        anonymous = true;
+        callback = "https://artalk.hpcesia.com/api/v2/auth/{provider}/callback";
+        email = {
+          enabled = true;
+          verify_subject = "您的验证码是 - {{code}}";
+          verify_tpl = "default";
+        };
+        github = {
+          enabled = true;
+          client_id = {_secret = config.sops.secrets.artalk-github-client-id.path;};
+          client_secret = {_secret = config.sops.secrets.artalk-github-client-secret.path;};
+        };
+      };
+      frontend = {
+        placeholder = "来都来了,不如说点什么吧!";
+        emoticons = "https://blog.hpcesia.com/assets/emotion.json";
+        gravatar = {
+          mirror = "https://weavatar.com/avatar/";
+          params = "sha256=1&d=mp&s=240";
+        };
+        imgLazyLoad = "native";
+        versionCheck = false;
+      };
+    };
+  };
+}
hosts/chaser-pardofelis/caddy.nix
@@ -16,6 +16,7 @@
 
     virtualHosts = let
       localAddress = {
+        artalk = "http://localhost:${builtins.toString config.services.artalk.settings.port}";
         authelia = "http://${
           # Assuming address start with `tcp://`.
           builtins.substring 6 (-1) config.services.authelia.instances.main.settings.server.address
@@ -27,6 +28,10 @@
         prometheus = "http://${config.services.victoriametrics.listenAddress}";
       };
     in {
+      "artalk.hpcesia.com".extraConfig = ''
+        encode zstd gzip
+        reverse_proxy ${localAddress.artalk}
+      '';
       "authelia.hpcesia.com".extraConfig = ''
         encode zstd gzip
         reverse_proxy ${localAddress.authelia}
hosts/chaser-pardofelis/restic.nix
@@ -11,6 +11,7 @@
     paths =
       (lib.mapAttrsToList (n: v: "/var/lib/authelia-${n}") config.services.authelia.instances)
       ++ [
+        config.services.artalk.workdir
         "/var/lib/fail2ban"
         config.services.freshrss.dataDir
         "/var/lib/gotosocial"
secrets/hosts/pardofelis/default.nix
@@ -28,6 +28,11 @@ in
         nvp.value;
     }) (
       let
+        artalkConf = {
+          owner = "root";
+          group = "artalk";
+          mode = "0440";
+        };
         autheliaMainConf = {
           owner = "root";
           group = "authelia-main";
@@ -107,6 +112,41 @@ in
           name = "restic-backup-password";
           value = {key = "services/restic/password";} // secretFileConf;
         }
+        {
+          name = "artalk-akismet-key";
+          value =
+            {key = "services/artalk/akismetKey";}
+            // artalkConf
+            // secretFileConf;
+        }
+        {
+          name = "artalk-app-key";
+          value =
+            {key = "services/artalk/appKey";}
+            // artalkConf
+            // secretFileConf;
+        }
+        {
+          name = "artalk-email-password";
+          value =
+            {key = "services/artalk/emailPassword";}
+            // artalkConf
+            // secretFileConf;
+        }
+        {
+          name = "artalk-github-client-id";
+          value =
+            {key = "services/artalk/githubClientId";}
+            // artalkConf
+            // secretFileConf;
+        }
+        {
+          name = "artalk-github-client-secret";
+          value =
+            {key = "services/artalk/githubClientSecret";}
+            // artalkConf
+            // secretFileConf;
+        }
       ]
     )
   )
secrets/hosts/pardofelis/secrets.yaml
@@ -13,6 +13,12 @@ services:
         s3SecretKey: ENC[AES256_GCM,data:zg0JEJvuGDLuEgm1clp7CI4tF47CtLsyR9kn9vr8YJvyDxPL9cSWgGMVffrGFf/AY9q4k7SSrNS047k5SB1nHQ==,iv:0LAatRgKfCrkdvQLfrCLl/BvdwkzH0SSRp17/6ssClA=,tag:U520Cp1+XZMjdW9RpwX2YQ==,type:str]
     restic:
         password: ENC[AES256_GCM,data:KrT+kv+1hbWnkZUOw+8m5c0bg2JacV/frOUi6zq6wIA=,iv:n5mIZ8FYcpCC3+RsYInfrYfs1WVBkguFmKT3juYzlMI=,tag:w6mN5hNNbdCK/qdW5U/a7w==,type:str]
+    artalk:
+        appKey: ENC[AES256_GCM,data:YWPX3IMm7tBBELRasgAreQ==,iv:R6XyPY3nbH+N80ye0MVX5QsV1kNQZbPRV8SwCcRhWDY=,tag:PbgpWMY6UobmXPuAQDE6WQ==,type:str]
+        akismetKey: ENC[AES256_GCM,data:HU2a/f8lC/s76uLx,iv:8Y8N2wy43rtAlk5ptp9SeIvqhhMzWIjuHspyc3cLOrg=,tag:IrIk0vOs7ovzb6tBMxV+bg==,type:str]
+        emailPassword: ENC[AES256_GCM,data:u2oITTJX3yIGpkv8xWnoSFQGUv/SUw1G,iv:y0eh74YZ2mA2toYmxTqU6a5sycWQPGwJNgqDhlX9pIQ=,tag:2VjyYKydIrMr8/OjbgzPjw==,type:str]
+        githubClientId: ENC[AES256_GCM,data:ju1RHdc5cx99s+NQXfhk/b80jLI=,iv:84ly8arMzezgoxo61Barey/NaEYWF7c9HY5DS7fl2Gg=,tag:r7pf4jKkhsW+GAiGf2CG9A==,type:str]
+        githubClientSecret: ENC[AES256_GCM,data:pyt5ddWBtBA2A8MQDkT4toLgwVwa5VnlWGOwEFldMerYCtw4F9X7Ow==,iv:H2YbbmBTGskZ+1yLTZTICO0bzR9LADN+4Bl+/P1s1TE=,tag:DF9WXdE/isxZUNblpRUv5g==,type:str]
     authelia:
         main:
             jwtSecret: ENC[AES256_GCM,data:czKoD+m8bu0ioTjXYmGv8ZhQphTgsv3GEAvgY4JsxbhAEDgzR1U/Pm7n3FuoIbCCPI6TQcRN2cB4NrvNNUoqZg==,iv:MZbgnw3GkgkQQNk2i4wNFkqcrsyIqdB1GbfeN+NTlwQ=,tag:MN7dV2BDjXxI3AxOYNie1Q==,type:str]
@@ -40,8 +46,8 @@ sops:
             MmVobitCNUxvUGJmRUtWWEhZekdHaEEKcx1nN+bR2wsexYV/B5PC+Pu9Yi9w+KE8
             Kcy2S1Cyu7MEkE8it447yqixIA5l5mbFGRjfTvI8KZXZUGgLecAktQ==
             -----END AGE ENCRYPTED FILE-----
-    lastmodified: "2025-07-20T10:39:18Z"
-    mac: ENC[AES256_GCM,data:Np0rlSXVdtA59ZWCwvUmfFH7GmfzmgQFDHSVwl3tQAgLl6H0vF6Ru9JoskCE1mIa/LIptHi2NlgBhaJMk0H84NVcbvO1iWkf99Ai5AroNotka48KsPmhj0qODqO5mG7sy4GjnuudgPYbdG6xD7x7gHMEP0m3dT4ii/yx8U1uMm8=,iv:EUVQc6+tNLRg7/G24JwSa/UuTsgyIk0zd//yyvK8VD0=,tag:kcK4ne+/+/jxAfLtgm1u5A==,type:str]
+    lastmodified: "2025-07-20T13:54:12Z"
+    mac: ENC[AES256_GCM,data:TgGnlL2defU2u1NngvEqQxh5N+V1BNpQbVXCt/jCPJbz/GkbCnser168Tu+guQYjWUnqXphOPIAaAd/hORwa0OVFxm4cSN1UGtffdjc7SYxgi23xIbB2L9XyknrzPjEbX9Ue7CnNr9v5a3m3sOvVr+OM4TzuLPLOEBdpAPtJ3gU=,iv:twBMhm4oVsxHQypz42C2gX2hGR2GpqeuAPBVrg4diw8=,tag:ZLObSACwmWszdZ7W+lYBpw==,type:str]
     pgp:
         - created_at: "2025-07-15T13:47:27Z"
           enc: |-