feat: add extra configuration for git syncing all vaults in the ignis dir

This commit is contained in:
Ceferino Patino 2026-06-28 15:14:47 -05:00
commit 8e96c43723
Signed by: c4patino
SSH key fingerprint: SHA256:Wu+cU1t+7zVT9wzew/4meNmeulo66NzMqc22MdDBgXI
3 changed files with 149 additions and 37 deletions

View file

@ -12,9 +12,89 @@
networkCfg = getAttrByNamespace config "${namespace}.services.networking";
isEnabled = hostHasService networkCfg.network-services hostName "ignis";
port = resolveServicePort networkCfg.network-services "ignis" 8081;
port = resolveServicePort networkCfg.network-services "ignis" 5125;
vault-key-provision = import ./vault-key-provision.nix {inherit pkgs;};
vault-sync = import ./vault-sync.nix {inherit pkgs;};
in {
config = mkIf isEnabled {
systemd = {
services = {
ignis = {
description = "Ignis - Self-hosted Obsidian web app";
after = ["network.target"];
wantedBy = ["multi-user.target"];
path = with pkgs; [
git
];
environment = {
PORT = toString port;
VAULT_ROOT = "/var/lib/ignis/vaults";
DATA_ROOT = "/var/lib/ignis/data";
OBSIDIAN_ASSETS_PATH = "${pkgs.ignis}/lib/ignis/obsidian-app";
OBSIDIAN_VERSION = "1.12.7";
};
preStart = ''
mkdir -p /var/lib/ignis/vaults /var/lib/ignis/data
chown -R ignis:ignis /var/lib/ignis/vaults /var/lib/ignis/data
'';
serviceConfig = {
Type = "simple";
User = "ignis";
Group = "ignis";
Restart = "always";
RestartSec = 5;
ExecStart = "${pkgs.ignis}/bin/ignis-server";
StateDirectory = "ignis";
StateDirectoryMode = "0750";
WorkingDirectory = "${pkgs.ignis}/lib/ignis";
};
};
ignis-vault-key-provision = {
description = "Provision SSH key and git config for ignis vault sync";
after = ["network.target"];
before = ["ignis-vault-sync.service"];
wantedBy = ["multi-user.target"];
environment.HOME = "/var/lib/ignis/data";
serviceConfig = {
Type = "oneshot";
User = "ignis";
Group = "ignis";
ExecStart = "${vault-key-provision}/bin/ignis-vault-key-provision";
RemainAfterExit = true;
};
};
ignis-vault-sync = {
description = "Auto-commit and pull ignis vaults";
after = ["ignis-vault-key-provision.service"];
path = with pkgs; [
openssh
];
environment.HOME = "/var/lib/ignis/data";
serviceConfig = {
Type = "oneshot";
User = "ignis";
Group = "ignis";
ExecStart = "${vault-sync}/bin/ignis-vault-sync";
};
};
};
timers = {
ignis-vault-sync = {
description = "Timer for ignis vault sync";
wantedBy = ["timers.target"];
timerConfig.OnUnitActiveSec = "1m";
};
};
};
users = {
users.ignis = {
isSystemUser = true;
@ -30,43 +110,8 @@ in {
networking.firewall.allowedTCPPorts = [port];
systemd.services.ignis = {
description = "Ignis - Self-hosted Obsidian web app";
after = ["network.target"];
wantedBy = ["multi-user.target"];
path = with pkgs; [
git
];
environment = {
PORT = toString port;
VAULT_ROOT = "/var/lib/ignis/vaults";
DATA_ROOT = "/var/lib/ignis/data";
OBSIDIAN_ASSETS_PATH = "${pkgs.ignis}/lib/ignis/obsidian-app";
OBSIDIAN_VERSION = "1.12.7";
};
preStart = ''
mkdir -p /var/lib/ignis/vaults /var/lib/ignis/data
chown -R ignis:ignis /var/lib/ignis/vaults /var/lib/ignis/data
'';
serviceConfig = {
Type = "simple";
User = "ignis";
Group = "ignis";
Restart = "always";
RestartSec = 5;
ExecStart = "${pkgs.ignis}/bin/ignis-server";
StateDirectory = "ignis";
StateDirectoryMode = "0750";
WorkingDirectory = "${pkgs.ignis}/lib/ignis";
};
};
${namespace}.services.storage.impermanence.folders = [
"/var/lib/ignis/data"
"/var/lib/ignis"
];
};
}

View file

@ -0,0 +1,29 @@
{pkgs, ...}:
pkgs.writeShellScriptBin "ignis-vault-key-provision" ''
set -euo pipefail
DATA_DIR="/var/lib/ignis/data"
SSH_DIR="$DATA_DIR/.ssh"
KEY_FILE="$SSH_DIR/id_ed25519"
PUBLIC_KEY_FILE="$KEY_FILE.pub"
HOSTNAME="$(< /proc/sys/kernel/hostname)"
umask 077
mkdir -p "$SSH_DIR"
if [ ! -f "$KEY_FILE" ]; then
${pkgs.openssh}/bin/ssh-keygen -t ed25519 -N "" -f "$KEY_FILE" -C "ignis-vault-sync@$HOSTNAME"
echo "# ==============================================================================="
echo "# IGNIS VAULT SYNC PUBLIC KEY"
echo "# ==============================================================================="
cat "$PUBLIC_KEY_FILE"
fi
${pkgs.git}/bin/git config -f "$DATA_DIR/.gitconfig" user.name "C4 Patino"
${pkgs.git}/bin/git config -f "$DATA_DIR/.gitconfig" user.email "c4patino@gmail.com"
${pkgs.git}/bin/git config -f "$DATA_DIR/.gitconfig" core.sshCommand "${pkgs.openssh}/bin/ssh -i $KEY_FILE -o StrictHostKeyChecking=accept-new"
${pkgs.git}/bin/git config -f "$DATA_DIR/.gitconfig" gpg.format ssh
${pkgs.git}/bin/git config -f "$DATA_DIR/.gitconfig" user.signingkey "$PUBLIC_KEY_FILE"
${pkgs.git}/bin/git config -f "$DATA_DIR/.gitconfig" commit.gpgsign true
''

View file

@ -0,0 +1,38 @@
{pkgs}:
pkgs.writeShellScriptBin "ignis-vault-sync" ''
set -euo pipefail
set -x
VAULT_ROOT="/var/lib/ignis/vaults"
DATA_DIR="/var/lib/ignis/data"
PULL_INTERVAL=300
for vault in "$VAULT_ROOT"/*/; do
[ -d "$vault/.git" ] || continue
cd "$vault"
name=$(basename "$vault")
now=$(date +%s)
last_pull_file="$DATA_DIR/.last-pull-$name"
last_pull=0
[ -f "$last_pull_file" ] && last_pull=$(cat "$last_pull_file")
if [ $((now - last_pull)) -ge $PULL_INTERVAL ]; then
${pkgs.git}/bin/git pull --rebase 2>/dev/null || true
echo "$now" > "$last_pull_file"
fi
if ! ${pkgs.git}/bin/git diff --quiet 2>/dev/null || ! ${pkgs.git}/bin/git diff --cached --quiet 2>/dev/null || [ -n "$(${pkgs.git}/bin/git ls-files --others --exclude-standard 2>/dev/null)" ]; then
newest=$(${pkgs.findutils}/bin/find . -not -path './.git/*' -type f -printf '%T@\n' 2>/dev/null | sort -rn 2>/dev/null | head -1) || true
newest_int=$(echo "$newest" | cut -d. -f1)
if [ -z "$newest_int" ] || [ $((now - newest_int)) -ge 60 ]; then
${pkgs.git}/bin/git add -A 2>/dev/null
${pkgs.git}/bin/git commit -m "$(date -u +"docs(%Y/%m/%d): obsidian automatic vault backup")" 2>/dev/null
${pkgs.git}/bin/git push 2>/dev/null
fi
fi
done
''