Compare commits
No commits in common. "6fe7504460c6bd50e2f422ba3da118c7dbb7c3da" and "4b5b41b05ae779a0409e354b0ede77be9b4fb46f" have entirely different histories.
6fe7504460
...
4b5b41b05a
57 changed files with 1359 additions and 1674 deletions
51
.github/workflows/eval.yaml
vendored
51
.github/workflows/eval.yaml
vendored
|
@ -1,51 +0,0 @@
|
||||||
name: Eval NixOS Configurations
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- deploy
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
deploy:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
ref: deploy
|
|
||||||
|
|
||||||
- name: Install Nix
|
|
||||||
uses: cachix/install-nix-action@v25
|
|
||||||
|
|
||||||
- name: Configure Git
|
|
||||||
run: |
|
|
||||||
git config --global user.name "GitHub Actions Bot"
|
|
||||||
git config --global user.email "actions@github.com"
|
|
||||||
|
|
||||||
- name: Process Configurations
|
|
||||||
run: |
|
|
||||||
git checkout -b deploy-comin-eval
|
|
||||||
mkdir -p eval
|
|
||||||
hosts=$(nix flake show --json | jq -r '.nixosConfigurations | keys[]')
|
|
||||||
echo "Found hosts: $hosts"
|
|
||||||
|
|
||||||
for host in $hosts; do
|
|
||||||
echo "Eval derivation for $host"
|
|
||||||
if ! nix show-derivation -L ".#nixosConfigurations.$host.config.system.build.toplevel" > "eval/$host.json"; then
|
|
||||||
echo "❌ Failed to evaluate $host"
|
|
||||||
else
|
|
||||||
echo "✅ Successfully evaluated $host"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "Total hosts: $(echo "$hosts" | wc -w)"
|
|
||||||
echo "Failed hosts: $failed_hosts"
|
|
||||||
|
|
||||||
git add eval/
|
|
||||||
git commit -m "Update deployment configurations for all hosts"
|
|
||||||
|
|
||||||
git push origin deploy-comin-eval
|
|
|
@ -15,7 +15,6 @@ creation_rules:
|
||||||
- age:
|
- age:
|
||||||
- *xin
|
- *xin
|
||||||
- *host-calcite
|
- *host-calcite
|
||||||
- *host-weilite
|
|
||||||
- *host-massicot
|
- *host-massicot
|
||||||
- *host-thorite
|
- *host-thorite
|
||||||
- *host-biotite
|
- *host-biotite
|
||||||
|
|
198
flake.lock
generated
198
flake.lock
generated
|
@ -2,11 +2,11 @@
|
||||||
"nodes": {
|
"nodes": {
|
||||||
"catppuccin": {
|
"catppuccin": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1733001911,
|
"lastModified": 1731232837,
|
||||||
"narHash": "sha256-uX/9m0TbdhEzuWA0muM5mI/AaWcLiDLjCCyu5Qr9MRk=",
|
"narHash": "sha256-0aIwr/RC/oe7rYkfJb47xjdEQDSNcqpFGsEa+EPlDEs=",
|
||||||
"owner": "catppuccin",
|
"owner": "catppuccin",
|
||||||
"repo": "nix",
|
"repo": "nix",
|
||||||
"rev": "a817009ebfd2cca7f70a77884e5098d0a8c83f8e",
|
"rev": "32359bf226fe874d3b7a0a5753d291a4da9616fe",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -68,11 +68,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1733168902,
|
"lastModified": 1732645828,
|
||||||
"narHash": "sha256-8dupm9GfK+BowGdQd7EHK5V61nneLfr9xR6sc5vtDi0=",
|
"narHash": "sha256-+4U2I2653JvPFxcux837ulwYS864QvEueIljUkwytsk=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "disko",
|
"repo": "disko",
|
||||||
"rev": "785c1e02c7e465375df971949b8dcbde9ec362e5",
|
"rev": "869ba3a87486289a4197b52a6c9e7222edf00b3e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -167,27 +167,6 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-parts_3": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs-lib": [
|
|
||||||
"nur",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1733312601,
|
|
||||||
"narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=",
|
|
||||||
"owner": "hercules-ci",
|
|
||||||
"repo": "flake-parts",
|
|
||||||
"rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "hercules-ci",
|
|
||||||
"repo": "flake-parts",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-utils": {
|
"flake-utils": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1659877975,
|
"lastModified": 1659877975,
|
||||||
|
@ -259,11 +238,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1730814269,
|
"lastModified": 1730302582,
|
||||||
"narHash": "sha256-fWPHyhYE6xvMI1eGY3pwBTq85wcy1YXqdzTZF+06nOg=",
|
"narHash": "sha256-W1MIJpADXQCgosJZT8qBYLRuZls2KSiKdpnTVdKBuvU=",
|
||||||
"owner": "cachix",
|
"owner": "cachix",
|
||||||
"repo": "git-hooks.nix",
|
"repo": "git-hooks.nix",
|
||||||
"rev": "d70155fdc00df4628446352fc58adc640cd705c2",
|
"rev": "af8a16fe5c264f5e9e18bcee2859b40a656876cf",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -302,11 +281,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1733754861,
|
"lastModified": 1731786860,
|
||||||
"narHash": "sha256-3JKzIou54yjiMVmvgdJwopekEvZxX3JDT8DpKZs4oXY=",
|
"narHash": "sha256-130gQ5k8kZlxjBEeLpE+SvWFgSOFgQFeZlqIik7KgtQ=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "9ebaa80a227eaca9c87c53ed515ade013bc2bca9",
|
"rev": "1bd5616e33c0c54d7a5b37db94160635a9b27aeb",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -324,11 +303,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1731235328,
|
"lastModified": 1730490306,
|
||||||
"narHash": "sha256-NjavpgE9/bMe/ABvZpyHIUeYF1mqR5lhaep3wB79ucs=",
|
"narHash": "sha256-AvCVDswOUM9D368HxYD25RsSKp+5o0L0/JHADjLoD38=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "60bb110917844d354f3c18e05450606a435d2d10",
|
"rev": "1743615b61c7285976f85b303a36cdf88a556503",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -353,16 +332,16 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1729958008,
|
"lastModified": 1729544999,
|
||||||
"narHash": "sha256-EiOq8jF4Z/zQe0QYVc3+qSKxRK//CFHMB84aYrYGwEs=",
|
"narHash": "sha256-YcyJLvTmN6uLEBGCvYoMLwsinblXMkoYkNLEO4WnKus=",
|
||||||
"owner": "NuschtOS",
|
"owner": "NuschtOS",
|
||||||
"repo": "ixx",
|
"repo": "ixx",
|
||||||
"rev": "9fd01aad037f345350eab2cd45e1946cc66da4eb",
|
"rev": "65c207c92befec93e22086da9456d3906a4e999c",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "NuschtOS",
|
"owner": "NuschtOS",
|
||||||
"ref": "v0.0.6",
|
"ref": "v0.0.5",
|
||||||
"repo": "ixx",
|
"repo": "ixx",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
@ -376,17 +355,17 @@
|
||||||
"nixvim": "nixvim"
|
"nixvim": "nixvim"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1732936640,
|
"lastModified": 1730642581,
|
||||||
"narHash": "sha256-NcluA0L+ZV5MUj3UuQhlkGCj8KoEhX/ObWlMHZ/F/ac=",
|
"narHash": "sha256-Tcq+RnctJTm+TUr1fN3ivqYNcd1pJnHYzLDQdgUCX70=",
|
||||||
"ref": "refs/heads/master",
|
"ref": "refs/heads/master",
|
||||||
"rev": "a3709a89797ea094f82d38edeb4a538c07c8c3fa",
|
"rev": "a09d2b94efb5e2d801275a244eedaab0816f3702",
|
||||||
"revCount": 20,
|
"revCount": 18,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.xiny.li/xin/nixvim"
|
"url": "https://git.xinyang.life/xin/nixvim"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.xiny.li/xin/nixvim"
|
"url": "https://git.xinyang.life/xin/nixvim"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nix-darwin": {
|
"nix-darwin": {
|
||||||
|
@ -398,11 +377,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1731153869,
|
"lastModified": 1730448474,
|
||||||
"narHash": "sha256-3Ftf9oqOypcEyyrWJ0baVkRpvQqroK/SVBFLvU3nPuc=",
|
"narHash": "sha256-qE/cYKBhzxHMtKtLK3hlSR3uzO1pWPGLrBuQK7r0CHc=",
|
||||||
"owner": "lnl7",
|
"owner": "lnl7",
|
||||||
"repo": "nix-darwin",
|
"repo": "nix-darwin",
|
||||||
"rev": "5c74ab862c8070cbf6400128a1b56abb213656da",
|
"rev": "683d0c4cd1102dcccfa3f835565378c7f3cbe05e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -439,11 +418,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1733629314,
|
"lastModified": 1731814505,
|
||||||
"narHash": "sha256-U0vivjQFAwjNDYt49Krevs1murX9hKBFe2Ye0cHpgbU=",
|
"narHash": "sha256-l9ryrx1Twh08a+gxrMGM9O/aZKEimZfa6sZVyPCImgI=",
|
||||||
"owner": "Mic92",
|
"owner": "Mic92",
|
||||||
"repo": "nix-index-database",
|
"repo": "nix-index-database",
|
||||||
"rev": "f1e477a7dd11e27e7f98b646349cd66bbabf2fb8",
|
"rev": "bdba246946fb079b87b4cada4df9b1cdf1c06132",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -463,11 +442,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1733795858,
|
"lastModified": 1731808759,
|
||||||
"narHash": "sha256-K595Q2PrZv2iiumdBkwM2G456T2lKsLD71bn/fbJiQ0=",
|
"narHash": "sha256-WwJqguc/5Q7HEwHlgDzDT8mtd8ZxInxZM2neJKC1oh8=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "nix-vscode-extensions",
|
"repo": "nix-vscode-extensions",
|
||||||
"rev": "66ced222ef9235f90dbdd754ede3d6476722aaa9",
|
"rev": "5cf92678e6799ce45442dee4c9cb8094843c7cfa",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -478,11 +457,11 @@
|
||||||
},
|
},
|
||||||
"nixos-hardware": {
|
"nixos-hardware": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1733481457,
|
"lastModified": 1731797098,
|
||||||
"narHash": "sha256-IS3bxa4N1VMSh3/P6vhEAHQZecQ3oAlKCDvzCQSO5Is=",
|
"narHash": "sha256-UhWmEZhwJZmVZ1jfHZFzCg+ZLO9Tb/v3Y6LC0UNyeTo=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixos-hardware",
|
"repo": "nixos-hardware",
|
||||||
"rev": "e563803af3526852b6b1d77107a81908c66a9fcf",
|
"rev": "672ac2ac86f7dff2f6f3406405bddecf960e0db6",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -494,11 +473,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1731139594,
|
"lastModified": 1730200266,
|
||||||
"narHash": "sha256-IigrKK3vYRpUu+HEjPL/phrfh7Ox881er1UEsZvw9Q4=",
|
"narHash": "sha256-l253w0XMT8nWHGXuXqyiIC/bMvh1VRszGXgdpQlfhvU=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "76612b17c0ce71689921ca12d9ffdc9c23ce40b2",
|
"rev": "807e9154dcb16384b1b765ebe9cd2bba2ac287fd",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -522,11 +501,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs-stable": {
|
"nixpkgs-stable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1733730953,
|
"lastModified": 1731652201,
|
||||||
"narHash": "sha256-dlK7n82FEyZlHH7BFHQAM5tua+lQO1Iv7aAtglc1O5s=",
|
"narHash": "sha256-XUO0JKP1hlww0d7mm3kpmIr4hhtR4zicg5Wwes9cPMg=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "7109b680d161993918b0a126f38bc39763e5a709",
|
"rev": "c21b77913ea840f8bcf9adf4c41cecc2abffd38d",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -536,13 +515,29 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nixpkgs-stable_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1731797254,
|
||||||
|
"narHash": "sha256-df3dJApLPhd11AlueuoN0Q4fHo/hagP75LlM5K1sz9g=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "e8c38b73aeb218e27163376a2d617e61a2ad9b59",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "release-24.05",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1733805440,
|
"lastModified": 1731819057,
|
||||||
"narHash": "sha256-AQdCeGt3dMV9/cchlWGMcP0Z8qM47V+B0p7cSRr+HhA=",
|
"narHash": "sha256-nfqKsQhFCakM+eIKGf/JWu/g56rOPoGny10EZN8q7R0=",
|
||||||
"owner": "xinyangli",
|
"owner": "xinyangli",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "61b1078fca3a097ce06ada68a6f2766347eed02c",
|
"rev": "b2644ed7258502987ad4a70cf8959bf5a26ce26d",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -552,22 +547,6 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_3": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1733581040,
|
|
||||||
"narHash": "sha256-Qn3nPMSopRQJgmvHzVqPcE3I03zJyl8cSbgnnltfFDY=",
|
|
||||||
"owner": "nixos",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "22c3f2cf41a0e70184334a958e6b124fb0ce3e01",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nixos",
|
|
||||||
"ref": "nixos-unstable",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixvim": {
|
"nixvim": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"devshell": "devshell",
|
"devshell": "devshell",
|
||||||
|
@ -581,11 +560,11 @@
|
||||||
"treefmt-nix": "treefmt-nix"
|
"treefmt-nix": "treefmt-nix"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1731527733,
|
"lastModified": 1730569492,
|
||||||
"narHash": "sha256-12OpSgbLDiKmxvBXwVracIfGI9FpjFyHpa1r0Ho+NFA=",
|
"narHash": "sha256-NByr7l7JetL9kIrdCOcRqBu+lAkruYXETp1DMiDHNQs=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "nixvim",
|
"repo": "nixvim",
|
||||||
"rev": "f11a877bcc1d66cc8bd7990c704f91c1e99c7d08",
|
"rev": "6f210158b03b01a1fd44bf3968165e6da80635ce",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -595,17 +574,12 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nur": {
|
"nur": {
|
||||||
"inputs": {
|
|
||||||
"flake-parts": "flake-parts_3",
|
|
||||||
"nixpkgs": "nixpkgs_3",
|
|
||||||
"treefmt-nix": "treefmt-nix_2"
|
|
||||||
},
|
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1733805328,
|
"lastModified": 1731819675,
|
||||||
"narHash": "sha256-5F49/mOzFb40uUZh71uNr7kBXjDCw5ZfHMbpZjjUVBQ=",
|
"narHash": "sha256-GGp/rEfxRdi1BD9TlHoXxp2g9IuKDp0Jk7wYh1LacP8=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "NUR",
|
"repo": "NUR",
|
||||||
"rev": "b54fa3d8c020e077d88be036a12a711b84fe2031",
|
"rev": "59740d792bea5caa547c9bc7ce366802ecfafb7f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -625,11 +599,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1731060242,
|
"lastModified": 1730515563,
|
||||||
"narHash": "sha256-43yLsOm/wxBbfYSNDWVJeVv5Ij+23X3BIjFUfsdx/6M=",
|
"narHash": "sha256-8lklUZRV7nwkPLF3roxzi4C2oyLydDXyAzAnDvjkOms=",
|
||||||
"owner": "NuschtOS",
|
"owner": "NuschtOS",
|
||||||
"repo": "search",
|
"repo": "search",
|
||||||
"rev": "ef493352f9e1f051e01a55c062731503a6b36b4e",
|
"rev": "9e22bd742480916ff5d0ab20ca2522eaa3fa061e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -659,14 +633,15 @@
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
]
|
],
|
||||||
|
"nixpkgs-stable": "nixpkgs-stable_2"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1733785344,
|
"lastModified": 1731814239,
|
||||||
"narHash": "sha256-pm4cfEcPXripE36PYCl0A2Tu5ruwHEvTee+HzNk+SQE=",
|
"narHash": "sha256-TGnMXCeXS924w9W6CvRFtUCUFr8E/RK138lHxU3vcw8=",
|
||||||
"owner": "Mic92",
|
"owner": "Mic92",
|
||||||
"repo": "sops-nix",
|
"repo": "sops-nix",
|
||||||
"rev": "a80af8929781b5fe92ddb8ae52e9027fae780d2a",
|
"rev": "47fc1d8c72dbd69b32ecb2019b5b648da3dd20ce",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -742,27 +717,6 @@
|
||||||
"repo": "treefmt-nix",
|
"repo": "treefmt-nix",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"treefmt-nix_2": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"nur",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1733222881,
|
|
||||||
"narHash": "sha256-JIPcz1PrpXUCbaccEnrcUS8jjEb/1vJbZz5KkobyFdM=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "treefmt-nix",
|
|
||||||
"rev": "49717b5af6f80172275d47a418c9719a31a78b53",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "treefmt-nix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": "root",
|
"root": "root",
|
||||||
|
|
54
flake.nix
54
flake.nix
|
@ -43,7 +43,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
my-nixvim = {
|
my-nixvim = {
|
||||||
url = "git+https://git.xiny.li/xin/nixvim";
|
url = "git+https://git.xinyang.life/xin/nixvim";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -84,16 +84,11 @@
|
||||||
overlayModule =
|
overlayModule =
|
||||||
{ ... }:
|
{ ... }:
|
||||||
{
|
{
|
||||||
options.my-lib = nixpkgs.lib.mkOption {
|
_module.args.my-lib = import ./overlays/my-lib;
|
||||||
type = nixpkgs.lib.types.attrs;
|
nixpkgs.overlays = [
|
||||||
default = import ./overlays/my-lib;
|
editorOverlay
|
||||||
};
|
(import ./overlays/add-pkgs.nix)
|
||||||
config = {
|
];
|
||||||
nixpkgs.overlays = [
|
|
||||||
editorOverlay
|
|
||||||
(import ./overlays/add-pkgs.nix)
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
deploymentModule = {
|
deploymentModule = {
|
||||||
deployment.targetUser = "xin";
|
deployment.targetUser = "xin";
|
||||||
|
@ -111,6 +106,7 @@
|
||||||
nodeNixosModules = {
|
nodeNixosModules = {
|
||||||
calcite = [
|
calcite = [
|
||||||
nixos-hardware.nixosModules.asus-zephyrus-ga401
|
nixos-hardware.nixosModules.asus-zephyrus-ga401
|
||||||
|
nur.nixosModules.nur
|
||||||
catppuccin.nixosModules.catppuccin
|
catppuccin.nixosModules.catppuccin
|
||||||
machines/calcite/configuration.nix
|
machines/calcite/configuration.nix
|
||||||
(mkHome "xin" "calcite")
|
(mkHome "xin" "calcite")
|
||||||
|
@ -146,15 +142,17 @@
|
||||||
user: host:
|
user: host:
|
||||||
{ ... }:
|
{ ... }:
|
||||||
{
|
{
|
||||||
imports = [ home-manager.nixosModules.home-manager ];
|
imports = [
|
||||||
config = {
|
home-manager.nixosModules.home-manager
|
||||||
home-manager = {
|
{
|
||||||
sharedModules = sharedHmModules;
|
home-manager = {
|
||||||
useGlobalPkgs = true;
|
sharedModules = sharedHmModules;
|
||||||
useUserPackages = true;
|
useGlobalPkgs = true;
|
||||||
};
|
useUserPackages = true;
|
||||||
home-manager.users.${user} = (import ./home).${user}.${host};
|
};
|
||||||
};
|
home-manager.users.${user} = (import ./home).${user}.${host};
|
||||||
|
}
|
||||||
|
];
|
||||||
};
|
};
|
||||||
mkNixos =
|
mkNixos =
|
||||||
{
|
{
|
||||||
|
@ -286,22 +284,16 @@
|
||||||
{
|
{
|
||||||
imports = nodeNixosModules.biotite ++ sharedColmenaModules;
|
imports = nodeNixosModules.biotite ++ sharedColmenaModules;
|
||||||
};
|
};
|
||||||
|
|
||||||
osmium =
|
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
deployment = {
|
|
||||||
targetHost = "osmium.coho-tet.ts.net";
|
|
||||||
buildOnTarget = false;
|
|
||||||
};
|
|
||||||
imports = nodeNixosModules.osmium ++ sharedColmenaModules;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
nixosConfigurations = {
|
nixosConfigurations = {
|
||||||
calcite = mkNixos {
|
calcite = mkNixos {
|
||||||
hostname = "calcite";
|
hostname = "calcite";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
osmium = mkNixos {
|
||||||
|
hostname = "osmium";
|
||||||
|
};
|
||||||
} // self.colmenaHive.nodes;
|
} // self.colmenaHive.nodes;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -311,7 +303,7 @@
|
||||||
pkgs = nixpkgs.legacyPackages.${system};
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
|
|
||||||
mkHomeConfiguration = user: host: {
|
mkHomeConfiguration = user: host: {
|
||||||
name = "${user}-${host}";
|
name = user;
|
||||||
value = home-manager.lib.homeManagerConfiguration {
|
value = home-manager.lib.homeManagerConfiguration {
|
||||||
inherit pkgs;
|
inherit pkgs;
|
||||||
modules = [
|
modules = [
|
||||||
|
|
|
@ -125,8 +125,7 @@ in
|
||||||
profiles.default = {
|
profiles.default = {
|
||||||
isDefault = true;
|
isDefault = true;
|
||||||
userChrome = ''
|
userChrome = ''
|
||||||
|
#titlebar {
|
||||||
#TabsToolbar {
|
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +136,7 @@ in
|
||||||
[titlepreface*="."] #sidebar-header {
|
[titlepreface*="."] #sidebar-header {
|
||||||
visibility: collapse !important;
|
visibility: collapse !important;
|
||||||
}
|
}
|
||||||
[titlepreface*="."] #TabsToolbar {
|
[titlepreface*="."] #titlebar {
|
||||||
visibility: collapse;
|
visibility: collapse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +148,7 @@ in
|
||||||
min-width: var(--uc-sidebar-width) !important;
|
min-width: var(--uc-sidebar-width) !important;
|
||||||
width: var(--uc-sidebar-width) !important;
|
width: var(--uc-sidebar-width) !important;
|
||||||
max-width: var(--uc-sidebar-width) !important;
|
max-width: var(--uc-sidebar-width) !important;
|
||||||
z-index: calc(var(--browser-area-z-index-tabbox) + 1);
|
z-index:1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#sidebar-box[positionend]{ direction: rtl }
|
#sidebar-box[positionend]{ direction: rtl }
|
||||||
|
@ -191,12 +190,12 @@ in
|
||||||
transition-delay: 0ms !important;
|
transition-delay: 0ms !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-placeTree {
|
.sidebar-panel{
|
||||||
/* background-color: transparent !important; */
|
background-color: transparent !important;
|
||||||
color: var(--newtab-text-primary-color) !important;
|
color: var(--newtab-text-primary-color) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-placeTree #search-box{
|
.sidebar-panel #search-box{
|
||||||
-moz-appearance: none !important;
|
-moz-appearance: none !important;
|
||||||
background-color: rgba(249,249,250,0.1) !important;
|
background-color: rgba(249,249,250,0.1) !important;
|
||||||
color: inherit !important;
|
color: inherit !important;
|
||||||
|
|
|
@ -5,12 +5,13 @@
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [ ];
|
||||||
./modern-unix.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
dig
|
dig
|
||||||
|
du-dust # du + rust
|
||||||
|
zoxide # autojumper
|
||||||
|
ripgrep
|
||||||
file
|
file
|
||||||
man-pages
|
man-pages
|
||||||
unar
|
unar
|
||||||
|
@ -18,6 +19,7 @@
|
||||||
wget
|
wget
|
||||||
tmux
|
tmux
|
||||||
ffmpeg
|
ffmpeg
|
||||||
|
tealdeer
|
||||||
rclone
|
rclone
|
||||||
wl-clipboard
|
wl-clipboard
|
||||||
|
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
{ pkgs, ... }:
|
|
||||||
{
|
|
||||||
home.packages = with pkgs; [
|
|
||||||
httpie
|
|
||||||
curlie
|
|
||||||
bat
|
|
||||||
htop
|
|
||||||
procs
|
|
||||||
rust-parallel
|
|
||||||
jq
|
|
||||||
fd
|
|
||||||
du-dust # du + rust
|
|
||||||
zoxide # autojumper
|
|
||||||
ripgrep
|
|
||||||
tealdeer
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,7 +1,5 @@
|
||||||
{
|
{
|
||||||
pkgs,
|
|
||||||
lib,
|
lib,
|
||||||
config,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
|
||||||
|
@ -9,12 +7,6 @@
|
||||||
imports = [
|
imports = [
|
||||||
./hardware-configurations.nix
|
./hardware-configurations.nix
|
||||||
./services/gotosocial.nix
|
./services/gotosocial.nix
|
||||||
./services/synapse.nix
|
|
||||||
./services/restic.nix
|
|
||||||
./services/miniflux.nix
|
|
||||||
./services/hedgedoc.nix
|
|
||||||
./services/forgejo.nix
|
|
||||||
./services/vaultwarden.nix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
networking.hostName = "biotite";
|
networking.hostName = "biotite";
|
||||||
|
@ -36,56 +28,20 @@
|
||||||
|
|
||||||
commonSettings = {
|
commonSettings = {
|
||||||
auth.enable = true;
|
auth.enable = true;
|
||||||
|
autoupgrade.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
custom.monitoring = {
|
custom.monitoring = {
|
||||||
promtail.enable = true;
|
promtail.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
custom.prometheus.exporters = {
|
|
||||||
enable = true;
|
|
||||||
node.enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.tailscale.enable = true;
|
|
||||||
|
|
||||||
services.caddy.enable = true;
|
|
||||||
|
|
||||||
sops = {
|
sops = {
|
||||||
defaultSopsFile = ./secrets.yaml;
|
defaultSopsFile = ./secrets.yaml;
|
||||||
age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
services.postgresql = {
|
services.caddy.enable = true;
|
||||||
enable = true;
|
services.tailscale.enable = true;
|
||||||
package = pkgs.postgresql_17;
|
|
||||||
settings = {
|
|
||||||
allow_alter_system = false;
|
|
||||||
# DB Version: 17
|
|
||||||
# OS Type: linux
|
|
||||||
# DB Type: mixed
|
|
||||||
# Total Memory (RAM): 8 GB
|
|
||||||
# CPUs num: 4
|
|
||||||
# Data Storage: ssd
|
|
||||||
max_connections = 100;
|
|
||||||
shared_buffers = "2GB";
|
|
||||||
effective_cache_size = "6GB";
|
|
||||||
maintenance_work_mem = "512MB";
|
|
||||||
checkpoint_completion_target = 0.9;
|
|
||||||
wal_buffers = "16MB";
|
|
||||||
default_statistics_target = 100;
|
|
||||||
random_page_cost = 1.1;
|
|
||||||
effective_io_concurrency = 200;
|
|
||||||
work_mem = "5242kB";
|
|
||||||
huge_pages = "off";
|
|
||||||
min_wal_size = "1GB";
|
|
||||||
max_wal_size = "4GB";
|
|
||||||
max_worker_processes = 4;
|
|
||||||
max_parallel_workers_per_gather = 2;
|
|
||||||
max_parallel_workers = 4;
|
|
||||||
max_parallel_maintenance_workers = 2;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
users.users.root.hashedPassword = "$y$j9T$NToEZWJBONjSgRnMd9Ur9/$o6n7a9b8eUILQz4d37oiHCCVnDJ8hZTZt.c.37zFfU.";
|
users.users.root.hashedPassword = "$y$j9T$NToEZWJBONjSgRnMd9Ur9/$o6n7a9b8eUILQz4d37oiHCCVnDJ8hZTZt.c.37zFfU.";
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,5 @@
|
||||||
gotosocial:
|
gotosocial:
|
||||||
oidc_client_secret: ENC[AES256_GCM,data:KVQxzs67sohax2h0Y/jjhnbY4fetrdVvWhBGbqgDSGgBC7QazrOmTA++BSRzMmVv,iv:HIRMc56aLanqQRTWH9E0wzzXymImi0pxK/ccPEP8Fcc=,tag:PMhOLeE3mKIIQveRdfpgpA==,type:str]
|
oidc_client_secret: ENC[AES256_GCM,data:KVQxzs67sohax2h0Y/jjhnbY4fetrdVvWhBGbqgDSGgBC7QazrOmTA++BSRzMmVv,iv:HIRMc56aLanqQRTWH9E0wzzXymImi0pxK/ccPEP8Fcc=,tag:PMhOLeE3mKIIQveRdfpgpA==,type:str]
|
||||||
synapse:
|
|
||||||
oidc_client_secret: ENC[AES256_GCM,data:TdZF8Bo+h34fn03sPpt7JEqmP8Cwm8V++q9VDvaapMBc3rlkrVu3iDUhQE2DvJri,iv:/QNX+aYUPpDKIqWZ13TLAznR3ZpUPI8rQHrJuqv7R+g=,tag:lcBIpeWiIXK/NV84uuxNiA==,type:str]
|
|
||||||
restic:
|
|
||||||
repo_url: ENC[AES256_GCM,data:ZcBMqwEsyc7zyEftJZj4XkKBzUHwlqd6cjX8xVDn9m26jBL7aP5atpnXDRE9FXY4CuAllFyQZyAOQ2L61Nfx+iplL2ADbSoH,iv:fhNODiyoOlZEqYR2O/GsH2IWTPDr3rXSJgWC/EFDLSA=,tag:nZdKKnpiszSiXxdZI1KQ/A==,type:str]
|
|
||||||
repo_password: ENC[AES256_GCM,data:9YDOz1tiyykz6zSXboWtIg==,iv:j96mRLXGuD4NZcC0Nv1yXFbtOlr6UborqclefZ7J94w=,tag:MqhSewK2NuckTJBf7xu+lA==,type:str]
|
|
||||||
miniflux:
|
|
||||||
oauth2_secret: ENC[AES256_GCM,data:/WtZemrdKU8bQbxzrAn437uqoJSO+yZSUDCnxovXV0HFZYQvAn2rbMrgOdoc1OuP,iv:xENKuGDYS1ctnO/WkGv1TxjtQYZ8p64Ik/lMIIam4Q0=,tag:RbAA0LUmsAQDqEM5+a2quQ==,type:str]
|
|
||||||
hedgedoc:
|
|
||||||
client_secret: ENC[AES256_GCM,data:J6lRBM7V6F+gPYVyEbOzsFUQe8+3ggP0r58c655DNt7TGgKGdq95pRvLaghMmBCc,iv:i+eLYwnmG1/bKtad2iM2pwEAC3GZLNaKS5ldbubRvyY=,tag:yxaug6YdYo8RR3YOyHd/iA==,type:str]
|
|
||||||
forgejo:
|
|
||||||
client_secret: ENC[AES256_GCM,data:5OXhaGzBCbge2tvTaU4ry6/KoavQeYJ45EuakCQJlxb5gMXjRK/s+feF25YJSr2f,iv:TT8j+ciKeSQCZzu1E7D70hWNFpn0cGiomz7jURXjavc=,tag:JVJR033Pc2vaLudaovkl8w==,type:str]
|
|
||||||
sops:
|
sops:
|
||||||
kms: []
|
kms: []
|
||||||
gcp_kms: []
|
gcp_kms: []
|
||||||
|
@ -35,8 +24,8 @@ sops:
|
||||||
RzBMVDNjS29SUkdRK3dIV01sU0hYR3cK1SbvKAM6Gpsffv3HIi/WtWnCZUBic0AT
|
RzBMVDNjS29SUkdRK3dIV01sU0hYR3cK1SbvKAM6Gpsffv3HIi/WtWnCZUBic0AT
|
||||||
ZRv4pvJBx1oxWsKIHW0t6VrqWMQ+suup8p6dW+h5HE8Z4ciIMrXLEg==
|
ZRv4pvJBx1oxWsKIHW0t6VrqWMQ+suup8p6dW+h5HE8Z4ciIMrXLEg==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2024-12-04T05:07:32Z"
|
lastmodified: "2024-12-02T05:10:32Z"
|
||||||
mac: ENC[AES256_GCM,data:hD7645epMVYHU6K1AZsHu+fp/PMIqqiZpv7K4Vxzo84slzn0CfZSYaVaYxKNGjOIgEGN9D2FFmq9WL6ChMskMfqqafY7qDpSQqFp9TUwb5jN34XcQg9vplfNw+lMqsnDCt1HENWErRnlDxTI2ctSEcx3UKGBOQ3ttLzUIySdnFY=,iv:reOsqvc8E3l8yxb5gVcqF/rU2o2yKmaUyGNRNT+Skx8=,tag:eBoV8G+X0cPs3Q1xAuv55w==,type:str]
|
mac: ENC[AES256_GCM,data:ZAdFsjVuk1Fiv+DKmHrc1yu1XQpRDmRHaQhu5hduSZUa1W1cXdTlChvIW5vADFg5tVCjuYptuLvCMW+ZSQeqqG2ntHHZ+IkuovZzKFuc+BIiL/jF2ZzbyJ7X4Wj1GziCScHVxx98dgbpFoufHe6N3wCaHmngo1RYsY5N1RRbRdU=,iv:5IMQ0kOX9UAOm8bcsQRyu6zu8GJjvnHFufCNjY0s9UI=,tag:zBEPSR9DZDpwbCaIka8mXA==,type:str]
|
||||||
pgp: []
|
pgp: []
|
||||||
unencrypted_suffix: _unencrypted
|
unencrypted_suffix: _unencrypted
|
||||||
version: 3.9.1
|
version: 3.9.1
|
||||||
|
|
|
@ -1,115 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
inherit (lib) getExe;
|
|
||||||
inherit (config.my-lib.settings) idpUrl forgejoDomain forgejoGitDomain;
|
|
||||||
settings = {
|
|
||||||
service.DISABLE_REGISTRATION = true;
|
|
||||||
server = {
|
|
||||||
DOMAIN = forgejoDomain;
|
|
||||||
ROOT_URL = "https://${forgejoDomain}";
|
|
||||||
HTTP_ADDR = "/var/run/forgejo/forgejo.sock";
|
|
||||||
START_SSH_SERVER = false;
|
|
||||||
SSH_USER = config.services.forgejo.user;
|
|
||||||
SSH_DOMAIN = forgejoGitDomain;
|
|
||||||
SSH_PORT = 22;
|
|
||||||
PROTOCOL = "http+unix";
|
|
||||||
LFS_MAX_FILE_SIZE = 10737418240;
|
|
||||||
LANDING_PAGE = "/explore/repos";
|
|
||||||
};
|
|
||||||
repository = {
|
|
||||||
ENABLE_PUSH_CREATE_USER = true;
|
|
||||||
};
|
|
||||||
service = {
|
|
||||||
ENABLE_BASIC_AUTHENTICATION = false;
|
|
||||||
};
|
|
||||||
oauth2 = {
|
|
||||||
ENABLED = false; # Disable forgejo as oauth2 provider
|
|
||||||
};
|
|
||||||
oauth2_client = {
|
|
||||||
ACCOUNT_LINKING = "auto";
|
|
||||||
USERNAME = "email";
|
|
||||||
ENABLE_AUTO_REGISTRATION = true;
|
|
||||||
UPDATE_AVATAR = false;
|
|
||||||
OPENID_CONNECT_SCOPES = "openid profile email groups";
|
|
||||||
};
|
|
||||||
metrics = {
|
|
||||||
# ENABLED = true;
|
|
||||||
};
|
|
||||||
other = {
|
|
||||||
SHOW_FOOTER_VERSION = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
sops.secrets."forgejo/client_secret" = { };
|
|
||||||
sops.templates."forgejo/env" = {
|
|
||||||
content = ''
|
|
||||||
CLIENT_SECRET=${config.sops.placeholder."forgejo/client_secret"}
|
|
||||||
'';
|
|
||||||
owner = config.systemd.services.forgejo.serviceConfig.User;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.forgejo = {
|
|
||||||
enable = true;
|
|
||||||
inherit settings;
|
|
||||||
# Use cutting edge instead of lts
|
|
||||||
package = pkgs.forgejo;
|
|
||||||
# repositoryRoot = "/mnt/storage/forgejo/repositories";
|
|
||||||
lfs = {
|
|
||||||
enable = true;
|
|
||||||
# contentDir = "/mnt/storage/forgejo/lfs";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.forgejo = {
|
|
||||||
serviceConfig = {
|
|
||||||
EnvironmentFile = config.sops.templates."forgejo/env".path;
|
|
||||||
preStart =
|
|
||||||
let
|
|
||||||
providerName = "kanidm";
|
|
||||||
args = lib.concatStringsSep " " [
|
|
||||||
"--name ${providerName}"
|
|
||||||
"--provider openidConnect"
|
|
||||||
"--key forgejo"
|
|
||||||
"--secret $CLIENT_SECRET"
|
|
||||||
"--icon-url ${idpUrl}/pkg/img/favicon.png"
|
|
||||||
"--group-claim-name forgejo_role --admin-group Admin"
|
|
||||||
];
|
|
||||||
exe = getExe config.services.forgejo.package;
|
|
||||||
in
|
|
||||||
''
|
|
||||||
provider_id=$(${exe} admin auth list | ${pkgs.gnugrep}/bin/grep -w '${providerName}' | cut -f1)
|
|
||||||
if [[ -z "$provider_id" ]]; then
|
|
||||||
${exe} admin auth add-oauth ${args}
|
|
||||||
else
|
|
||||||
${exe} admin auth update-oauth --id "$provider_id" ${args}
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
users.users.git = {
|
|
||||||
isSystemUser = true;
|
|
||||||
useDefaultShell = true;
|
|
||||||
group = "git";
|
|
||||||
extraGroups = [ "forgejo" ];
|
|
||||||
};
|
|
||||||
users.groups.git = { };
|
|
||||||
|
|
||||||
services.caddy = {
|
|
||||||
virtualHosts."https://${forgejoDomain}".extraConfig = with settings; ''
|
|
||||||
${
|
|
||||||
if server.PROTOCOL == "http+unix" then
|
|
||||||
"reverse_proxy unix/${server.HTTP_ADDR}"
|
|
||||||
else
|
|
||||||
"reverse_proxy http://${server.HTTP_ADDR}:${toString server.HTTP_PORT}"
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
users.users.caddy.extraGroups = lib.optional (settings.server.PROTOCOL == "http+unix") "forgejo";
|
|
||||||
}
|
|
|
@ -1,7 +1,4 @@
|
||||||
{ config, ... }:
|
{ config, ... }:
|
||||||
let
|
|
||||||
inherit (config.my-lib.settings) idpUrl;
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
sops.secrets."gotosocial/oidc_client_secret" = {
|
sops.secrets."gotosocial/oidc_client_secret" = {
|
||||||
owner = "gotosocial";
|
owner = "gotosocial";
|
||||||
|
@ -26,17 +23,17 @@ in
|
||||||
instance-expose-public-timeline = true;
|
instance-expose-public-timeline = true;
|
||||||
oidc-enabled = true;
|
oidc-enabled = true;
|
||||||
oidc-idp-name = "Kanidm";
|
oidc-idp-name = "Kanidm";
|
||||||
oidc-issuer = "${idpUrl}/oauth2/openid/gotosocial";
|
oidc-issuer = "https://auth.xinyang.life/oauth2/openid/gotosocial";
|
||||||
oidc-client-id = "gotosocial";
|
oidc-client-id = "gotosocial";
|
||||||
oidc-link-existing = true;
|
oidc-link-existing = true;
|
||||||
};
|
};
|
||||||
setupPostgresqlDB = true;
|
|
||||||
environmentFile = config.sops.templates."gotosocial.env".path;
|
environmentFile = config.sops.templates."gotosocial.env".path;
|
||||||
};
|
};
|
||||||
|
|
||||||
services.caddy = {
|
services.caddy = {
|
||||||
virtualHosts."https://gts.xiny.li".extraConfig = ''
|
virtualHosts."https://gts.xiny.li".extraConfig = ''
|
||||||
reverse_proxy http://${config.services.gotosocial.settings.bind-address}:${toString config.services.gotosocial.settings.port} {
|
encode zstd gzip
|
||||||
|
reverse_proxy * http://${config.services.gotosocial.settings.bind-address}:${toString config.services.gotosocial.settings.port} {
|
||||||
flush_interval -1
|
flush_interval -1
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
{ config, pkgs, ... }:
|
|
||||||
let
|
|
||||||
inherit (config.my-lib.settings) hedgedocDomain idpUrl;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
sops.secrets."hedgedoc/client_secret" = { };
|
|
||||||
sops.templates."hedgedoc/env" = {
|
|
||||||
content = ''
|
|
||||||
CMD_OAUTH2_CLIENT_SECRET=${config.sops.placeholder."hedgedoc/client_secret"}
|
|
||||||
'';
|
|
||||||
owner = config.systemd.services.hedgedoc.serviceConfig.User;
|
|
||||||
};
|
|
||||||
services.hedgedoc = {
|
|
||||||
enable = true;
|
|
||||||
environmentFile = config.sops.templates."hedgedoc/env".path;
|
|
||||||
settings = {
|
|
||||||
domain = hedgedocDomain;
|
|
||||||
protocolUseSSL = true; # use SSL for resources
|
|
||||||
path = "/run/hedgedoc/hedgedoc.sock";
|
|
||||||
email = false;
|
|
||||||
allowEmailRegister = false;
|
|
||||||
oauth2 = {
|
|
||||||
baseURL = "${idpUrl}/oauth2/openid/hedgedoc";
|
|
||||||
authorizationURL = "${idpUrl}/ui/oauth2";
|
|
||||||
tokenURL = "${idpUrl}/oauth2/token";
|
|
||||||
userProfileURL = "${idpUrl}/oauth2/openid/hedgedoc/userinfo";
|
|
||||||
userProfileEmailAttr = "email";
|
|
||||||
userProfileUsernameAttr = "name";
|
|
||||||
userProfileDisplayNameAttr = "preferred_name";
|
|
||||||
scope = "openid email profile";
|
|
||||||
clientID = "hedgedoc";
|
|
||||||
};
|
|
||||||
enableStatsApi = true;
|
|
||||||
allowAnonymous = false;
|
|
||||||
defaultPermission = "private";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
services.caddy = {
|
|
||||||
enable = true;
|
|
||||||
virtualHosts."https://${hedgedocDomain}".extraConfig = ''
|
|
||||||
reverse_proxy unix/${config.services.hedgedoc.settings.path}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
users.users.caddy.extraGroups = [ "hedgedoc" ];
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
{ config, pkgs, ... }:
|
|
||||||
let
|
|
||||||
inherit (config.my-lib.settings) idpUrl minifluxUrl;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
sops = {
|
|
||||||
secrets."miniflux/oauth2_secret" = { };
|
|
||||||
};
|
|
||||||
|
|
||||||
services.miniflux = {
|
|
||||||
enable = true;
|
|
||||||
config = {
|
|
||||||
LOG_LEVEL = "debug";
|
|
||||||
LISTEN_ADDR = "127.0.0.1:58173";
|
|
||||||
BASE_URL = "https://rss.xiny.li/";
|
|
||||||
OAUTH2_PROVIDER = "oidc";
|
|
||||||
OAUTH2_CLIENT_ID = "miniflux";
|
|
||||||
OAUTH2_CLIENT_SECRET_FILE = "%d/oauth2_secret";
|
|
||||||
OAUTH2_REDIRECT_URL = "${minifluxUrl}/oauth2/oidc/callback";
|
|
||||||
OAUTH2_OIDC_DISCOVERY_ENDPOINT = "${idpUrl}/oauth2/openid/miniflux";
|
|
||||||
OAUTH2_USER_CREATION = 1;
|
|
||||||
CREATE_ADMIN = 0;
|
|
||||||
};
|
|
||||||
createDatabaseLocally = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.miniflux.serviceConfig.LoadCredential = [
|
|
||||||
"oauth2_secret:${config.sops.secrets."miniflux/oauth2_secret".path}"
|
|
||||||
];
|
|
||||||
|
|
||||||
services.caddy.virtualHosts.${minifluxUrl}.extraConfig = ''
|
|
||||||
reverse_proxy ${config.services.miniflux.config.LISTEN_ADDR}
|
|
||||||
'';
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
sqliteBackup = fromPath: toPath: file: ''
|
|
||||||
mkdir -p ${toPath}
|
|
||||||
${lib.getExe pkgs.sqlite} ${fromPath} ".backup '${toPath}/${file}'"
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
{
|
|
||||||
sops.secrets = {
|
|
||||||
"restic/repo_url" = {
|
|
||||||
sopsFile = ../secrets.yaml;
|
|
||||||
};
|
|
||||||
"restic/repo_password" = {
|
|
||||||
sopsFile = ../secrets.yaml;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
custom.restic = {
|
|
||||||
enable = true;
|
|
||||||
paths = [
|
|
||||||
"/backup/db"
|
|
||||||
"/backup/var/lib"
|
|
||||||
];
|
|
||||||
backupPrepareCommand = [
|
|
||||||
''
|
|
||||||
mkdir -p /backup/var
|
|
||||||
${pkgs.btrfs-progs}/bin/btrfs subvolume snapshot -r /var/lib /backup/var/lib
|
|
||||||
''
|
|
||||||
];
|
|
||||||
backupCleanupCommand = [
|
|
||||||
''
|
|
||||||
${pkgs.btrfs-progs}/bin/btrfs subvolume delete /backup/var/lib
|
|
||||||
''
|
|
||||||
];
|
|
||||||
btrfsRoots = [ ];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.postgresqlBackup = {
|
|
||||||
enable = true;
|
|
||||||
compression = "zstd";
|
|
||||||
compressionLevel = 9;
|
|
||||||
location = "/backup/db/postgresql";
|
|
||||||
};
|
|
||||||
|
|
||||||
services.restic.backups.${config.networking.hostName} = {
|
|
||||||
extraBackupArgs = [
|
|
||||||
"--limit-upload=1024"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,120 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
inherit (config.my-lib.settings) idpUrl synapseDelegateUrl synapseUrl;
|
|
||||||
port-synapse = 6823;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
sops.secrets."synapse/oidc_client_secret" = {
|
|
||||||
owner = "matrix-synapse";
|
|
||||||
};
|
|
||||||
|
|
||||||
nixpkgs.config.permittedInsecurePackages = [
|
|
||||||
"olm-3.2.16"
|
|
||||||
];
|
|
||||||
|
|
||||||
services.postgresql = {
|
|
||||||
# Not using ensure here because LC_COLLATE and LC_CTYPE must be provided
|
|
||||||
# at db creation
|
|
||||||
initialScript = pkgs.writeText "synapse-init.sql" ''
|
|
||||||
CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse';
|
|
||||||
CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse"
|
|
||||||
TEMPLATE template0
|
|
||||||
LC_COLLATE = "C"
|
|
||||||
LC_CTYPE = "C";
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
services.matrix-synapse = {
|
|
||||||
enable = true;
|
|
||||||
withJemalloc = true;
|
|
||||||
settings = {
|
|
||||||
server_name = "xiny.li";
|
|
||||||
public_baseurl = synapseDelegateUrl;
|
|
||||||
database = {
|
|
||||||
name = "psycopg2";
|
|
||||||
args = {
|
|
||||||
user = "matrix-synapse";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
listeners = [
|
|
||||||
{
|
|
||||||
bind_addresses = [
|
|
||||||
"127.0.0.1"
|
|
||||||
];
|
|
||||||
port = port-synapse;
|
|
||||||
resources = [
|
|
||||||
{
|
|
||||||
compress = true;
|
|
||||||
names = [
|
|
||||||
"client"
|
|
||||||
"federation"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
tls = false;
|
|
||||||
type = "http";
|
|
||||||
x_forwarded = true;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
experimental_features = {
|
|
||||||
# Room summary api
|
|
||||||
msc3266_enabled = true;
|
|
||||||
# Removing account data
|
|
||||||
msc3391_enabled = true;
|
|
||||||
# Thread notifications
|
|
||||||
msc3773_enabled = true;
|
|
||||||
# Remotely toggle push notifications for another client
|
|
||||||
msc3881_enabled = true;
|
|
||||||
# Remotely silence local notifications
|
|
||||||
msc3890_enabled = true;
|
|
||||||
# Remove legacy mentions
|
|
||||||
msc4210_enabled = true;
|
|
||||||
};
|
|
||||||
oidc_providers = [
|
|
||||||
{
|
|
||||||
idp_id = "Kanidm";
|
|
||||||
idp_name = lib.removePrefix "https://" idpUrl;
|
|
||||||
issuer = "${idpUrl}/oauth2/openid/synapse";
|
|
||||||
authorization_endpoint = "${idpUrl}/ui/oauth2";
|
|
||||||
token_endpoint = "${idpUrl}/oauth2/token";
|
|
||||||
userinfo_endpoint = "${idpUrl}/oauth2/openid/synapse/userinfo";
|
|
||||||
client_id = "synapse";
|
|
||||||
client_secret_path = config.sops.secrets."synapse/oidc_client_secret".path;
|
|
||||||
scopes = [
|
|
||||||
"openid"
|
|
||||||
"profile"
|
|
||||||
];
|
|
||||||
allow_existing_users = true;
|
|
||||||
backchannel_logout_enabled = true;
|
|
||||||
user_mapping_provider.config = {
|
|
||||||
confirm_localpart = true;
|
|
||||||
localpart_template = "{{ user.preferred_username }}";
|
|
||||||
display_name_template = "{{ user.name }}";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.caddy = {
|
|
||||||
virtualHosts.${synapseUrl}.extraConfig = ''
|
|
||||||
header /.well-known/matrix/* Content-Type application/json
|
|
||||||
header /.well-known/matrix/* Access-Control-Allow-Origin *
|
|
||||||
respond /.well-known/matrix/server `{"m.server":"synapse.xiny.li:443"}`
|
|
||||||
respond /.well-known/matrix/client `{"m.homeserver":{"base_url":"${synapseDelegateUrl}"}}`
|
|
||||||
'';
|
|
||||||
virtualHosts.${synapseDelegateUrl}.extraConfig = ''
|
|
||||||
reverse_proxy /_matrix/* 127.0.0.1:${toString port-synapse}
|
|
||||||
reverse_proxy /_synapse/client/* 127.0.0.1:${toString port-synapse}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [
|
|
||||||
443
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
{ config, pkgs, ... }:
|
|
||||||
let
|
|
||||||
inherit (config.my-lib.settings) vaultwardenUrl;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
services.vaultwarden = {
|
|
||||||
enable = true;
|
|
||||||
dbBackend = "sqlite";
|
|
||||||
config = {
|
|
||||||
DOMAIN = "${vaultwardenUrl}";
|
|
||||||
SIGNUPS_ALLOWED = false;
|
|
||||||
|
|
||||||
ROCKET_ADDRESS = "127.0.0.1";
|
|
||||||
ROCKET_PORT = 8222;
|
|
||||||
|
|
||||||
ROCKET_LOG = "normal";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.caddy = {
|
|
||||||
virtualHosts.${vaultwardenUrl}.extraConfig = with config.services.vaultwarden.config; ''
|
|
||||||
reverse_proxy ${ROCKET_ADDRESS}:${toString ROCKET_PORT}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -16,7 +16,7 @@ in
|
||||||
];
|
];
|
||||||
|
|
||||||
commonSettings = {
|
commonSettings = {
|
||||||
# auth.enable = true;
|
auth.enable = true;
|
||||||
nix = {
|
nix = {
|
||||||
signing.enable = true;
|
signing.enable = true;
|
||||||
};
|
};
|
||||||
|
@ -51,6 +51,7 @@ in
|
||||||
};
|
};
|
||||||
# services.gnome.gnome-keyring.enable = lib.mkForce false;
|
# services.gnome.gnome-keyring.enable = lib.mkForce false;
|
||||||
security.pam.services.login.enableGnomeKeyring = lib.mkForce false;
|
security.pam.services.login.enableGnomeKeyring = lib.mkForce false;
|
||||||
|
services.ssh-tpm-agent.enable = true;
|
||||||
|
|
||||||
programs.ssh.agentPKCS11Whitelist = "${config.security.tpm2.pkcs11.package}/lib/libtpm_pkcs11.so";
|
programs.ssh.agentPKCS11Whitelist = "${config.security.tpm2.pkcs11.package}/lib/libtpm_pkcs11.so";
|
||||||
|
|
||||||
|
@ -65,7 +66,18 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
programs.vim.enable = true;
|
programs.oidc-agent.enable = true;
|
||||||
|
programs.oidc-agent.providers = [
|
||||||
|
{
|
||||||
|
issuer = "https://home.xinyang.life:9201";
|
||||||
|
pubclient = {
|
||||||
|
client_id = "xdXOt13JKxym1B1QcEncf2XDkLAexMBFwiT9j6EfhhHFJhs2KM9jbjTmf8JBXE69";
|
||||||
|
client_secret = "UBntmLjC2yYCeHwsyj73Uwo9TAaecAetRwMw0xYcvNL9yRdLSUi0hUAHfvCHFeFh";
|
||||||
|
scope = "openid offline_access profile email";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
programs.vim.defaultEditor = true;
|
programs.vim.defaultEditor = true;
|
||||||
|
|
||||||
# Keep this even if enabled in home manager
|
# Keep this even if enabled in home manager
|
||||||
|
@ -295,22 +307,23 @@ in
|
||||||
bitwarden
|
bitwarden
|
||||||
|
|
||||||
# Browser
|
# Browser
|
||||||
chromium
|
(chromium.override {
|
||||||
|
commandLineArgs = [
|
||||||
|
"--ozone-platform-hint=auto"
|
||||||
|
"--enable-wayland-ime"
|
||||||
|
];
|
||||||
|
})
|
||||||
|
brave
|
||||||
|
|
||||||
# Writting
|
# Writting
|
||||||
zotero
|
zotero
|
||||||
# onlyoffice-bin
|
# onlyoffice-bin
|
||||||
|
|
||||||
wemeet
|
config.nur.repos.linyinfeng.wemeet
|
||||||
|
|
||||||
virt-manager
|
virt-manager
|
||||||
wineWowPackages.waylandFull
|
|
||||||
winetricks
|
|
||||||
];
|
];
|
||||||
|
|
||||||
services.esphome.enable = true;
|
|
||||||
users.groups.dialout.members = [ "xin" ];
|
|
||||||
|
|
||||||
system.stateVersion = "22.05";
|
system.stateVersion = "22.05";
|
||||||
|
|
||||||
system.switch.enable = false;
|
system.switch.enable = false;
|
||||||
|
@ -339,16 +352,16 @@ in
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
# custom.forgejo-actions-runner = {
|
custom.forgejo-actions-runner = {
|
||||||
# enable = false;
|
enable = false;
|
||||||
# tokenFile = config.sops.secrets."gitea/envfile".path;
|
tokenFile = config.sops.secrets."gitea/envfile".path;
|
||||||
# settings = {
|
settings = {
|
||||||
# runner.capacity = 2;
|
runner.capacity = 2;
|
||||||
# runner.fetch_timeout = "120s";
|
runner.fetch_timeout = "120s";
|
||||||
# runner.fetch_interval = "30s";
|
runner.fetch_interval = "30s";
|
||||||
# };
|
};
|
||||||
# };
|
};
|
||||||
#
|
|
||||||
custom.prometheus = {
|
custom.prometheus = {
|
||||||
exporters.node.enable = true;
|
exporters.node.enable = true;
|
||||||
};
|
};
|
||||||
|
@ -366,12 +379,15 @@ in
|
||||||
# Fonts
|
# Fonts
|
||||||
fonts = {
|
fonts = {
|
||||||
packages = with pkgs; [
|
packages = with pkgs; [
|
||||||
nerd-fonts.ubuntu-sans
|
(nerdfonts.override {
|
||||||
nerd-fonts.ubuntu
|
fonts = [
|
||||||
nerd-fonts.fira-code
|
"FiraCode"
|
||||||
nerd-fonts.fira-mono
|
"FiraMono"
|
||||||
nerd-fonts.jetbrains-mono
|
"JetBrainsMono"
|
||||||
nerd-fonts.roboto-mono
|
"RobotoMono"
|
||||||
|
"Ubuntu"
|
||||||
|
];
|
||||||
|
})
|
||||||
noto-fonts
|
noto-fonts
|
||||||
noto-fonts-emoji
|
noto-fonts-emoji
|
||||||
liberation_ttf
|
liberation_ttf
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
{
|
{ config, pkgs, lib, ... }:
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [ ];
|
imports = [ ];
|
||||||
|
@ -29,9 +24,16 @@
|
||||||
|
|
||||||
services.dae.enable = true;
|
services.dae.enable = true;
|
||||||
services.dae.configFile = "/var/lib/dae/config.dae";
|
services.dae.configFile = "/var/lib/dae/config.dae";
|
||||||
systemd.services.dae.after = lib.mkIf (config.networking.networkmanager.enable) [
|
systemd.services.dae.after = lib.mkIf (config.networking.networkmanager.enable) [ "NetworkManager-wait-online.service" ];
|
||||||
"NetworkManager-wait-online.service"
|
|
||||||
];
|
custom.sing-box = {
|
||||||
|
enable = false;
|
||||||
|
configFile = {
|
||||||
|
urlFile = config.sops.secrets.sing_box_url.path;
|
||||||
|
hash = "6ca5bc8a16f8c413227690aceeee2c12c02cab09473c216b849af1e854b98588";
|
||||||
|
};
|
||||||
|
overrideSettings.experimental.clash_api.external_ui = "${config.nur.repos.linyinfeng.yacd}";
|
||||||
|
};
|
||||||
|
|
||||||
# Open ports in the firewall.
|
# Open ports in the firewall.
|
||||||
networking.firewall.enable = true;
|
networking.firewall.enable = true;
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
config = {
|
config = {
|
||||||
sops = {
|
sops = {
|
||||||
age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
||||||
defaultSopsFile = ./secrets/secrets.yaml;
|
|
||||||
secrets = {
|
secrets = {
|
||||||
wg_private_key = {
|
wg_private_key = {
|
||||||
owner = "root";
|
owner = "root";
|
||||||
|
@ -13,6 +12,14 @@
|
||||||
owner = "root";
|
owner = "root";
|
||||||
sopsFile = ./secrets + "/${config.networking.hostName}.yaml";
|
sopsFile = ./secrets + "/${config.networking.hostName}.yaml";
|
||||||
};
|
};
|
||||||
|
"sing-box/password" = {
|
||||||
|
owner = "root";
|
||||||
|
sopsFile = ./secrets/secrets.yaml;
|
||||||
|
};
|
||||||
|
"sing-box/uuid" = {
|
||||||
|
owner = "root";
|
||||||
|
sopsFile = ./secrets/secrets.yaml;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
swapDevices = [
|
swapDevices = [
|
||||||
|
@ -25,8 +32,6 @@
|
||||||
custom.prometheus.exporters = {
|
custom.prometheus.exporters = {
|
||||||
enable = true;
|
enable = true;
|
||||||
node.enable = true;
|
node.enable = true;
|
||||||
blackbox.enable = true;
|
|
||||||
v2ray.enable = true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
custom.monitoring = {
|
custom.monitoring = {
|
||||||
|
@ -39,11 +44,6 @@
|
||||||
auth.enable = true;
|
auth.enable = true;
|
||||||
proxyServer = {
|
proxyServer = {
|
||||||
enable = true;
|
enable = true;
|
||||||
users = [
|
|
||||||
"wyj"
|
|
||||||
"yhb"
|
|
||||||
"xin"
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,14 +1,6 @@
|
||||||
sing-box:
|
sing-box:
|
||||||
users:
|
password: ENC[AES256_GCM,data:qCc1v8nAL0oYisRinMDXGrBQA+r6XNoa,iv:eTxtad4kEdE28XqnrZEek8BtXNY1rNgLvGLxlMzRtl4=,tag:s/shWAkYE4DSnScpTY8ulQ==,type:str]
|
||||||
wyj:
|
uuid: ENC[AES256_GCM,data:lEpz15sLOVrGDzQwTJyS+tFJY0bMeO265bxocWAjB6qrvxYx,iv:lhk5jl/udUH3AZEuk5ffuvin/qhRUaOZ/3nk1Jaw+DI=,tag:4mKFIVKT+D47njfDsxe9iA==,type:str]
|
||||||
password: ENC[AES256_GCM,data:yp+T3eci9RiuZzdmRSq5nTjHaz8e/Rri,iv:hIPc+7YHUnaIdU9O8GGx3r7l3oBA6prQb+KBQV0G+8k=,tag:2GNiBP4PQy+KGHgLupKGSg==,type:str]
|
|
||||||
uuid: ENC[AES256_GCM,data:Qrgil6G7pjQAQzCCOlstDi27EqqmSuBMhs+RTl9++wrPrIgJ,iv:u+3Z17uX4I6li2qd9UP3y+WaKn7aKfbb3J6H1Pyc1QY=,tag:hSa4AB383/B58XMmZ8LIfQ==,type:str]
|
|
||||||
yhb:
|
|
||||||
password: ENC[AES256_GCM,data:TwRct68TePpcZcnpWIQpFaF23WGMre8=,iv:YU4mQNm0rt2u4ItJwQ8nZPEmJi0+lmEIPG2Kxh/nI58=,tag:ukZem38O/b42dEKM3CYa+w==,type:str]
|
|
||||||
uuid: ENC[AES256_GCM,data:6hVhEqWPLVrn8rCS4x/eapd+iL7JRaXtOGCj9uuPlkGjBTMK,iv:VZ27KWCY6/K5GoNwRNmaRWzqfV7+8iFjtias1vKeGfA=,tag:8mhmZPooxHaGNYdznuFhMQ==,type:str]
|
|
||||||
xin:
|
|
||||||
password: ENC[AES256_GCM,data:SRiPFO+Uwy/PT41SIg7eI68wk4AX6so=,iv:aXwP5wa1IrlnvFo/ZL+DYFFHDdWw2Z83de3ApHUTsXo=,tag:sxXoy1FnDxZBQCDeNxphzQ==,type:str]
|
|
||||||
uuid: ENC[AES256_GCM,data:7xK53SO4x0tOIEIYl6kmmAvnpdsR/tYQoG1t/ytsnO4QqWY3,iv:i694Fnu7g1OA3IGzSaoSGA5/eMPo+I/1TZbYuaQrgNA=,tag:4cUlioJn/IvsvZclgboOSA==,type:str]
|
|
||||||
sops:
|
sops:
|
||||||
kms: []
|
kms: []
|
||||||
gcp_kms: []
|
gcp_kms: []
|
||||||
|
@ -51,8 +43,8 @@ sops:
|
||||||
K1F1SzI2NFNIKzlreVBXSjAxaUxQd28KFaf1uu7OlqIe0TirJFgS3iPjhXPyfNDE
|
K1F1SzI2NFNIKzlreVBXSjAxaUxQd28KFaf1uu7OlqIe0TirJFgS3iPjhXPyfNDE
|
||||||
m2XUjzdXp+chJCzVOFvpYStqz+e08ADEc+jp3YsTLcxyqvXhQdyL/Q==
|
m2XUjzdXp+chJCzVOFvpYStqz+e08ADEc+jp3YsTLcxyqvXhQdyL/Q==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2024-12-06T04:35:52Z"
|
lastmodified: "2024-12-02T05:26:17Z"
|
||||||
mac: ENC[AES256_GCM,data:DAg4UTwNv+rs6hye2z5UUtA1a4yZbFaAWjLoKAXf87tKgBCZzK8C1q6gLyTQOqp07ptYQd5Q951kfE1a/35SFJsubREzJmu6haxznRgq7pO5HDGqgtjYEHsngsWZh3bUSX/aG2dLISdD81VY68nLzTO0r4h/SL6DNG36RzJgL8E=,iv:V0WhENNt/Szi5VWVD2t5AsWP1tOZUGjFjMNYPDq59XI=,tag:ThRstdzVNtSs6E7qlvKPOw==,type:str]
|
mac: ENC[AES256_GCM,data:K94zFWPWGUisLCqDjSLs17QxHXPH4tPU/98Sb4lCnt7IRAIn14x/T+BnInY/DK+DOVLLtzSfuN0kgzzGjSzwJx5Vq1G3MkhngRQQRT9dvODTCMAw6lPt98Ofw1CEEsFQnpYo9zIUlCGKg2YPKFLqE7OjkPxqw7VYvgzr5dDw58s=,iv:3xcJfNX5v/e9HgZt3UrHs2/C5ivaBV1rXKIBs9hKKFg=,tag:RQPQQ1cmZiOpQjUwqnzZQA==,type:str]
|
||||||
pgp: []
|
pgp: []
|
||||||
unencrypted_suffix: _unencrypted
|
unencrypted_suffix: _unencrypted
|
||||||
version: 3.9.1
|
version: 3.9.1
|
||||||
|
|
|
@ -15,9 +15,24 @@
|
||||||
defaultSopsFile = ./secrets.yaml;
|
defaultSopsFile = ./secrets.yaml;
|
||||||
age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
|
||||||
secrets = {
|
secrets = {
|
||||||
|
storage_box_mount = {
|
||||||
|
owner = "root";
|
||||||
|
};
|
||||||
gts_env = {
|
gts_env = {
|
||||||
owner = "gotosocial";
|
owner = "gotosocial";
|
||||||
};
|
};
|
||||||
|
hedgedoc_env = {
|
||||||
|
owner = "hedgedoc";
|
||||||
|
};
|
||||||
|
grafana_oauth_secret = {
|
||||||
|
owner = "grafana";
|
||||||
|
};
|
||||||
|
"miniflux/oauth2_secret" = {
|
||||||
|
owner = "root";
|
||||||
|
};
|
||||||
|
"forgejo/env" = {
|
||||||
|
owner = "forgejo";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,4 @@
|
||||||
{ pkgs, config, ... }:
|
{ config, lib, ... }:
|
||||||
let
|
|
||||||
inherit (config.my-lib.settings)
|
|
||||||
gotosocialUrl
|
|
||||||
minifluxUrl
|
|
||||||
hedgedocDomain
|
|
||||||
forgejoDomain
|
|
||||||
grafanaUrl
|
|
||||||
synapseDelegateUrl
|
|
||||||
;
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
services.kanidm.provision = {
|
services.kanidm.provision = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@ -55,9 +45,6 @@ in
|
||||||
miniflux-users = {
|
miniflux-users = {
|
||||||
members = [ "xin" ];
|
members = [ "xin" ];
|
||||||
};
|
};
|
||||||
synapse-users = {
|
|
||||||
members = [ "xin" ];
|
|
||||||
};
|
|
||||||
idm_people_self_mail_write = {
|
idm_people_self_mail_write = {
|
||||||
members = [ ];
|
members = [ ];
|
||||||
};
|
};
|
||||||
|
@ -86,8 +73,8 @@ in
|
||||||
systems.oauth2 = {
|
systems.oauth2 = {
|
||||||
forgejo = {
|
forgejo = {
|
||||||
displayName = "ForgeJo";
|
displayName = "ForgeJo";
|
||||||
originUrl = "https://${forgejoDomain}/user/oauth2/kanidm/callback";
|
originUrl = "https://git.xinyang.life/user/oauth2/kanidm/callback";
|
||||||
originLanding = "https://${forgejoDomain}/user/oauth2/kanidm";
|
originLanding = "https://git.xinyang.life/user/oauth2/kanidm";
|
||||||
allowInsecureClientDisablePkce = true;
|
allowInsecureClientDisablePkce = true;
|
||||||
scopeMaps = {
|
scopeMaps = {
|
||||||
forgejo-access = [
|
forgejo-access = [
|
||||||
|
@ -123,8 +110,8 @@ in
|
||||||
};
|
};
|
||||||
gotosocial = {
|
gotosocial = {
|
||||||
displayName = "GoToSocial";
|
displayName = "GoToSocial";
|
||||||
originUrl = "${gotosocialUrl}/auth/callback";
|
originUrl = "https://gts.xiny.li/auth/callback";
|
||||||
originLanding = "${gotosocialUrl}/auth/callback";
|
originLanding = "https://gts.xiny.li/auth/callback";
|
||||||
allowInsecureClientDisablePkce = true;
|
allowInsecureClientDisablePkce = true;
|
||||||
scopeMaps = {
|
scopeMaps = {
|
||||||
gts-users = [
|
gts-users = [
|
||||||
|
@ -160,8 +147,8 @@ in
|
||||||
|
|
||||||
hedgedoc = {
|
hedgedoc = {
|
||||||
displayName = "HedgeDoc";
|
displayName = "HedgeDoc";
|
||||||
originUrl = "https://${hedgedocDomain}/auth/oauth2/callback";
|
originUrl = "https://docs.xinyang.life/auth/oauth2/callback";
|
||||||
originLanding = "https://${hedgedocDomain}/auth/oauth2";
|
originLanding = "https://docs.xinyang.life/auth/oauth2";
|
||||||
allowInsecureClientDisablePkce = true;
|
allowInsecureClientDisablePkce = true;
|
||||||
scopeMaps = {
|
scopeMaps = {
|
||||||
hedgedoc-users = [
|
hedgedoc-users = [
|
||||||
|
@ -190,8 +177,9 @@ in
|
||||||
};
|
};
|
||||||
miniflux = {
|
miniflux = {
|
||||||
displayName = "Miniflux";
|
displayName = "Miniflux";
|
||||||
originUrl = "${minifluxUrl}/oauth2/oidc/callback";
|
originUrl = "https://rss.xinyang.life/oauth2/oidc/callback";
|
||||||
originLanding = "${minifluxUrl}/oauth2/oidc/redirect";
|
|
||||||
|
originLanding = "https://rss.xinyang.life/oauth2/oidc/redirect";
|
||||||
scopeMaps = {
|
scopeMaps = {
|
||||||
miniflux-users = [
|
miniflux-users = [
|
||||||
"openid"
|
"openid"
|
||||||
|
@ -202,8 +190,8 @@ in
|
||||||
};
|
};
|
||||||
grafana = {
|
grafana = {
|
||||||
displayName = "Grafana";
|
displayName = "Grafana";
|
||||||
originUrl = "${grafanaUrl}/login/generic_oauth";
|
originUrl = "https://grafana.xinyang.life/login/generic_oauth";
|
||||||
originLanding = "${grafanaUrl}/";
|
originLanding = "https://grafana.xinyang.life/";
|
||||||
scopeMaps = {
|
scopeMaps = {
|
||||||
grafana-users = [
|
grafana-users = [
|
||||||
"openid"
|
"openid"
|
||||||
|
@ -223,17 +211,6 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
synapse = {
|
|
||||||
displayName = "Synapse";
|
|
||||||
originUrl = "${synapseDelegateUrl}/_synapse/client/oidc/callback";
|
|
||||||
originLanding = "${synapseDelegateUrl}/";
|
|
||||||
scopeMaps = {
|
|
||||||
synapse-users = [
|
|
||||||
"openid"
|
|
||||||
"profile"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,26 @@ in
|
||||||
8448
|
8448
|
||||||
];
|
];
|
||||||
|
|
||||||
|
custom.vaultwarden = {
|
||||||
|
enable = true;
|
||||||
|
domain = "vaultwarden.xinyang.life";
|
||||||
|
};
|
||||||
|
|
||||||
|
custom.hedgedoc = {
|
||||||
|
enable = true;
|
||||||
|
caddy = true;
|
||||||
|
domain = "docs.xinyang.life";
|
||||||
|
mediaPath = "/mnt/storage/hedgedoc";
|
||||||
|
oidc = {
|
||||||
|
enable = true;
|
||||||
|
baseURL = "https://auth.xinyang.life/oauth2/openid/hedgedoc";
|
||||||
|
authorizationURL = "https://auth.xinyang.life/ui/oauth2";
|
||||||
|
tokenURL = "https://auth.xinyang.life/oauth2/token";
|
||||||
|
userProfileURL = "https://auth.xinyang.life/oauth2/openid/hedgedoc/userinfo";
|
||||||
|
};
|
||||||
|
environmentFile = config.sops.secrets.hedgedoc_env.path;
|
||||||
|
};
|
||||||
|
|
||||||
custom.monitoring = {
|
custom.monitoring = {
|
||||||
promtail.enable = true;
|
promtail.enable = true;
|
||||||
};
|
};
|
||||||
|
@ -46,6 +66,18 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.ntfy-sh = {
|
||||||
|
enable = true;
|
||||||
|
group = "caddy";
|
||||||
|
settings = {
|
||||||
|
listen-unix = "/var/run/ntfy-sh/ntfy.sock";
|
||||||
|
listen-unix-mode = 432; # octal 0660
|
||||||
|
base-url = "https://ntfy.xinyang.life";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.ntfy-sh.serviceConfig.RuntimeDirectory = "ntfy-sh";
|
||||||
|
|
||||||
services.kanidm = {
|
services.kanidm = {
|
||||||
package = pkgs.kanidm.withSecretProvisioning;
|
package = pkgs.kanidm.withSecretProvisioning;
|
||||||
enableServer = true;
|
enableServer = true;
|
||||||
|
@ -60,6 +92,40 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
custom.miniflux = {
|
||||||
|
enable = true;
|
||||||
|
environment = {
|
||||||
|
LOG_LEVEL = "debug";
|
||||||
|
LISTEN_ADDR = "127.0.0.1:58173";
|
||||||
|
BASE_URL = "https://rss.xinyang.life/";
|
||||||
|
OAUTH2_PROVIDER = "oidc";
|
||||||
|
OAUTH2_CLIENT_ID = "miniflux";
|
||||||
|
OAUTH2_REDIRECT_URL = "https://rss.xinyang.life/oauth2/oidc/callback";
|
||||||
|
OAUTH2_OIDC_DISCOVERY_ENDPOINT = "https://auth.xinyang.life/oauth2/openid/miniflux";
|
||||||
|
OAUTH2_USER_CREATION = 1;
|
||||||
|
};
|
||||||
|
oauth2SecretFile = config.sops.secrets."miniflux/oauth2_secret".path;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.matrix-conduit = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.matrix-conduit;
|
||||||
|
settings.global = {
|
||||||
|
server_name = "xinyang.life";
|
||||||
|
port = 6167;
|
||||||
|
# database_path = "/var/lib/matrix-conduit/";
|
||||||
|
max_concurrent_requests = 100;
|
||||||
|
log = "info";
|
||||||
|
database_backend = "rocksdb";
|
||||||
|
allow_registration = false;
|
||||||
|
|
||||||
|
well_known = {
|
||||||
|
client = "https://msg.xinyang.life";
|
||||||
|
server = "msg.xinyang.life:443";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
users.users.conduit = {
|
users.users.conduit = {
|
||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
group = "conduit";
|
group = "conduit";
|
||||||
|
@ -84,8 +150,128 @@ in
|
||||||
environmentFile = config.sops.secrets.gts_env.path;
|
environmentFile = config.sops.secrets.gts_env.path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.forgejo = {
|
||||||
|
enable = true;
|
||||||
|
# Use cutting edge instead of lts
|
||||||
|
package = pkgs.forgejo;
|
||||||
|
repositoryRoot = "/mnt/storage/forgejo/repositories";
|
||||||
|
lfs = {
|
||||||
|
enable = true;
|
||||||
|
contentDir = "/mnt/storage/forgejo/lfs";
|
||||||
|
};
|
||||||
|
settings = {
|
||||||
|
service.DISABLE_REGISTRATION = true;
|
||||||
|
server = {
|
||||||
|
ROOT_URL = "https://git.xinyang.life/";
|
||||||
|
START_SSH_SERVER = false;
|
||||||
|
SSH_USER = config.services.forgejo.user;
|
||||||
|
SSH_DOMAIN = "ssh.xinyang.life";
|
||||||
|
SSH_PORT = 22;
|
||||||
|
LFS_MAX_FILE_SIZE = 10737418240;
|
||||||
|
LANDING_PAGE = "/explore/repos";
|
||||||
|
};
|
||||||
|
repository = {
|
||||||
|
ENABLE_PUSH_CREATE_USER = true;
|
||||||
|
};
|
||||||
|
service = {
|
||||||
|
ENABLE_BASIC_AUTHENTICATION = false;
|
||||||
|
};
|
||||||
|
oauth2 = {
|
||||||
|
ENABLED = false; # Disable forgejo as oauth2 provider
|
||||||
|
};
|
||||||
|
oauth2_client = {
|
||||||
|
ACCOUNT_LINKING = "auto";
|
||||||
|
USERNAME = "email";
|
||||||
|
ENABLE_AUTO_REGISTRATION = true;
|
||||||
|
UPDATE_AVATAR = false;
|
||||||
|
OPENID_CONNECT_SCOPES = "openid profile email groups";
|
||||||
|
};
|
||||||
|
other = {
|
||||||
|
SHOW_FOOTER_VERSION = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.forgejo = {
|
||||||
|
serviceConfig = {
|
||||||
|
EnvironmentFile = config.sops.secrets."forgejo/env".path;
|
||||||
|
ExecStartPost = ''
|
||||||
|
${lib.getExe config.services.forgejo.package} admin auth update-oauth \
|
||||||
|
--id 1 \
|
||||||
|
--name kanidm \
|
||||||
|
--provider openidConnect \
|
||||||
|
--key forgejo \
|
||||||
|
--secret $CLIENT_SECRET \
|
||||||
|
--icon-url https://auth.xinyang.life/pkg/img/favicon.png \
|
||||||
|
--group-claim-name forgejo_role --admin-group Admin
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.grafana = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
server = {
|
||||||
|
http_addr = "127.0.0.1";
|
||||||
|
http_port = 3003;
|
||||||
|
root_url = "https://grafana.xinyang.life";
|
||||||
|
domain = "grafana.xinyang.life";
|
||||||
|
};
|
||||||
|
"auth.generic_oauth" = {
|
||||||
|
enabled = true;
|
||||||
|
name = "Kanidm";
|
||||||
|
client_id = "grafana";
|
||||||
|
scopes = "openid,profile,email,groups";
|
||||||
|
auth_url = "https://auth.xinyang.life/ui/oauth2";
|
||||||
|
token_url = "https://auth.xinyang.life/oauth2/token";
|
||||||
|
api_url = "https://auth.xinyang.life/oauth2/openid/grafana/userinfo";
|
||||||
|
use_pkce = true;
|
||||||
|
use_refresh_token = true;
|
||||||
|
allow_sign_up = true;
|
||||||
|
login_attribute_path = "preferred_username";
|
||||||
|
groups_attribute_path = "groups";
|
||||||
|
role_attribute_path = "contains(grafana_role[*], 'GrafanaAdmin') && 'GrafanaAdmin' || contains(grafana_role[*], 'Admin') && 'Admin' || contains(grafana_role[*], 'Editor') && 'Editor' || 'Viewer'";
|
||||||
|
allow_assign_grafana_admin = true;
|
||||||
|
auto_login = true;
|
||||||
|
};
|
||||||
|
"auth" = {
|
||||||
|
disable_login_form = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.grafana.serviceConfig.EnvironmentFile =
|
||||||
|
config.sops.secrets.grafana_oauth_secret.path;
|
||||||
|
|
||||||
|
users.users.git = {
|
||||||
|
isSystemUser = true;
|
||||||
|
useDefaultShell = true;
|
||||||
|
group = "git";
|
||||||
|
extraGroups = [ "forgejo" ];
|
||||||
|
};
|
||||||
|
users.groups.git = { };
|
||||||
|
|
||||||
|
users.users = {
|
||||||
|
${config.services.caddy.user}.extraGroups = [ config.services.ntfy-sh.group ];
|
||||||
|
};
|
||||||
|
|
||||||
services.caddy = {
|
services.caddy = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
virtualHosts."xinyang.life:443".extraConfig = ''
|
||||||
|
tls internal
|
||||||
|
encode zstd gzip
|
||||||
|
reverse_proxy /.well-known/matrix/* localhost:6167
|
||||||
|
reverse_proxy * http://localhost:8080 {
|
||||||
|
flush_interval -1
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
virtualHosts."https://msg.xinyang.life:443".extraConfig = ''
|
||||||
|
reverse_proxy /_matrix/* localhost:6167
|
||||||
|
'';
|
||||||
|
virtualHosts."https://git.xinyang.life:443".extraConfig = ''
|
||||||
|
reverse_proxy http://${config.services.gitea.settings.server.DOMAIN}:${toString config.services.gitea.settings.server.HTTP_PORT}
|
||||||
|
'';
|
||||||
|
|
||||||
virtualHosts."http://auth.xinyang.life:80".extraConfig = ''
|
virtualHosts."http://auth.xinyang.life:80".extraConfig = ''
|
||||||
reverse_proxy ${config.security.acme.certs."auth.xinyang.life".listenHTTP}
|
reverse_proxy ${config.security.acme.certs."auth.xinyang.life".listenHTTP}
|
||||||
'';
|
'';
|
||||||
|
@ -98,5 +284,27 @@ in
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
virtualHosts."https://rss.xinyang.life".extraConfig = ''
|
||||||
|
reverse_proxy ${config.custom.miniflux.environment.LISTEN_ADDR}
|
||||||
|
'';
|
||||||
|
|
||||||
|
virtualHosts."https://ntfy.xinyang.life".extraConfig = ''
|
||||||
|
reverse_proxy unix/${config.services.ntfy-sh.settings.listen-unix}
|
||||||
|
@httpget {
|
||||||
|
protocol http
|
||||||
|
method GET
|
||||||
|
path_regexp ^/([-_a-z0-9]{0,64}$|docs/|static/)
|
||||||
|
}
|
||||||
|
redir @httpget https://{host}{uri}
|
||||||
|
'';
|
||||||
|
|
||||||
|
virtualHosts."https://grafana.xinyang.life".extraConfig =
|
||||||
|
let
|
||||||
|
grafanaSettings = config.services.grafana.settings.server;
|
||||||
|
in
|
||||||
|
''
|
||||||
|
reverse_proxy http://${grafanaSettings.http_addr}:${toString grafanaSettings.http_port}
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,13 @@ in
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.postgresqlBackup = {
|
||||||
|
enable = true;
|
||||||
|
compression = "zstd";
|
||||||
|
compressionLevel = 9;
|
||||||
|
location = "/backup/postgresql";
|
||||||
|
};
|
||||||
|
|
||||||
services.restic.backups.${config.networking.hostName} = {
|
services.restic.backups.${config.networking.hostName} = {
|
||||||
extraBackupArgs = [
|
extraBackupArgs = [
|
||||||
"--limit-upload=1024"
|
"--limit-upload=1024"
|
||||||
|
|
|
@ -10,83 +10,74 @@ sops:
|
||||||
- recipient: age1uw059wcwfvd9xuj0hpqzqpeg7qemecspjrsatg37wc7rs2pumfdsgken0c
|
- recipient: age1uw059wcwfvd9xuj0hpqzqpeg7qemecspjrsatg37wc7rs2pumfdsgken0c
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5SjAzOEozUzh1bzVvaHgr
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwMHB1bFQ3dWJIU3NiOVVP
|
||||||
T2xsVUszTHVSdWIyM3B5TFhtUEFMeVZlYzNrCk5IOWFNbTErbTVkQnNlVllMZWlV
|
Yi9LZE1PTVdMY1BqS1JHV3VPLzZIY0hGK0NZClNlclVXKzBvNTBrTlhiR0VsaVoz
|
||||||
Q2lHZXRIdzBiRFRSZnNUVWd2NXVXVGcKLS0tIERhcjh3VVlqSGxHUHpnc1JzVksv
|
RlVLNVBEVDgzSXB5ZGxDd3hqNDh2V2MKLS0tIEhBZHFUY3c2VXJBVEVKamZ6TzBa
|
||||||
VXpQVVVCUC9xR3crWm9rTk13LzVhK1EKwiuvwx3ZhcDE+9w7/dR4PrZSSoJMvklT
|
MlFsNnVEV0xCdlJoRnBhUHF2MmswUEUKNYD9zssGBy9SaKeOMvTz71B6KMPW87cM
|
||||||
m7I32dMRk0o9zcl5KYU5L9Hwb+z+EBE34raoGKBF5K4aQcbZQUX3Cw==
|
tFJzgnQceEQF658lVa5cCzG1gzraCgBtQU15XzC7e8zWI9CHquRRlQ==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1ytwfqfeez3dqtazyjltn7mznccwx3ua8djhned7n8mxqhw4p6e5s97skfa
|
- recipient: age1ytwfqfeez3dqtazyjltn7mznccwx3ua8djhned7n8mxqhw4p6e5s97skfa
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5R1ZIRlN2b3M2OUQ0T2cw
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTTnZLTlZQRzc1enVEa1BN
|
||||||
eE5DTm9KY1NUY1p5eDhLNG4xMDVkVjRyWDNRClp3MTRWeGJMYTczcC9YQTNZdkxx
|
SHdoSi9oOXk4UTV0SlRZS2tLS2FFL3VjNzNNClVWTTNKekF6T0RTUzdEeWhLbHoz
|
||||||
ejJ3QnhjcUcyUldUNEVqVUh6Z2grd00KLS0tIDVvbDZWbmZPZVhDNHM1K1kzaE95
|
WFZKaHJEaVBWa04zRWRiVnJZRjU0YVEKLS0tIFJVL0FEemowS3V6MmsxbWJMU2I1
|
||||||
aHJqSU16dlJiRGl0VWNMVXVYMmhPb2MKMboq9ShGIJMFVENgLPlQdwdtTOjVb0CC
|
U2NnUnVKdFlRSGVzUFQ4ZFcwL0lWTlkKz1t3yqjgIdMWS/Nsy2nq3oCjOhGDP+UT
|
||||||
4ttM3xWnYkf8416a0OYFrda5l1kfJJzQakbk/tbGcTu1yTcd+6lOtA==
|
L+LAuFExJPV0qlsOG/kCGB/WtCJfnBvcp6vPDBLqjK8NllIX/iPI5g==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
|
||||||
- recipient: age17r3fxfmt6hgwe984w4lds9u0cnkf5ttq8hnqt800ayfmx7t8t5gqjddyml
|
|
||||||
enc: |
|
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVby8wYS9pa0szTlVUS3FI
|
|
||||||
VWhjaCtyUzNLbkw2VXRlWkVMZlRkeXJMZGlRCnBTWklnZ0Uzd2lTMGt1M2wxZ0px
|
|
||||||
NFl2RW5hSUZVdHI0aVFRMHJtMFQ3ODAKLS0tIFlYOHVRYVFGbkcvUWRmQitQQnI5
|
|
||||||
bG5vemMvcWdpOEtxNGRpS0doQmtuUFkK8Hxl//kOtbEw3jf96ZZ4G1Yb94f4Jeb4
|
|
||||||
TfPs7O/ESJY8ovNsoXRQEt99vOR5D1wBzyZBY9E3f2ZzY/uBmup0cw==
|
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1jle2auermhswqtehww9gqada8car5aczrx43ztzqf9wtcld0sfmqzaecta
|
- recipient: age1jle2auermhswqtehww9gqada8car5aczrx43ztzqf9wtcld0sfmqzaecta
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPSmRYMkNIdERJZVBxV1p1
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBETWpkcjhINktqeGxjdWxz
|
||||||
emlqOTBpN3l2WXkzNjRRcFI5NUZDZnQ1WXdnCkRVbm8xais5aGVCTmtSTGxaTXlT
|
UTVVNC9kalorcVJOdHpJSkZJNXlGUHZ2VUdrCjRCclBTZnJEZ3JGOVpqS1Y0b0dt
|
||||||
L2ZWQ0p5WFZNRWl5SWVkRUYwc2R3b1UKLS0tIEZEck4yMmJUQWVvNHRJQnpCQTBo
|
eldFMS91WUc2Y1FnWWZoN0grc01pT0UKLS0tIC96TjlEaVBGRkZhZ0hac2lmbEdI
|
||||||
cDJsaG83MTdXWVd2NUpLczhjWTBBZVUK5BxBIYVqkqVLw9LTbnJ8SQWN2i4USdI8
|
eHMzTFhsQ0FqY05uUEZSbExCcmdscEkKdxITlc0V5ayq+9fmj77SnEMFxKJhOOta
|
||||||
8m/hZFXTJ4GI0f795DEmbcZq9xET14aQqta0wSASqwP/5Ld1mo0a0w==
|
RfJhOQUv8g3nCN+SsuaOy0TitUCiDWh5XoB0DufEQPcS/kzGZN1Inw==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age12ng08vjx5jde5ncqutwkd5vm4ygfwy33mzhzwe0lkxzglulgpqusc89r96
|
- recipient: age12ng08vjx5jde5ncqutwkd5vm4ygfwy33mzhzwe0lkxzglulgpqusc89r96
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwSkhjRTdBWklZUEpUanM0
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBydlQ4S1duQU53Wk1nd21K
|
||||||
Wjl4b2c3K0g0ZUxxMlRrUFhhZzhNRXhPVnpvCmpNWVBNTXNYczV3aWhCd05FOGJ0
|
d2RqM1F0VDFJVXB2aGRTZ2hxczI2V1lndVdrCjArVlE2N0RGZ0htUEZYdVlQMlU5
|
||||||
YlNobFhWdStGbDRZV2NlUWV6ZFRVNEkKLS0tIGd1RUR4K21GOEQ0aWtqRi9RREpE
|
SWIwWHVCaWxaQTJMNzg3WC8xRS9IYzgKLS0tIDRvSS8ybVlrSy9zYjQ2NXBaMlZk
|
||||||
RXBXcXFYUDVXVzN4Q25zSklFU21wbFkKQuTHkgFC5HRPO7/PuVhJzbbHOTPaFXvN
|
Ulg4cUFBejRoS3VEWkRaZEUxMExUeWMKNeq6TN1gaBNU9vAitGttcU+8HmFQipdm
|
||||||
+Y31AK3OAVdUETMEuJ2mk50Bi5BiiUeOnnv1bZ6O+iX0o20ysUseTg==
|
LPwo4/toyf27emb4KGs0AV0Dm4Sxj9S3Xvrv1B+qvhfT638/RIUm2w==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1v5h946jfke6ae8pcgz52mhj26cacqcpl9dmmrrkf37x55rnq2v3szqctvv
|
- recipient: age1v5h946jfke6ae8pcgz52mhj26cacqcpl9dmmrrkf37x55rnq2v3szqctvv
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnc3NOZFRYT1VnaVZSaTRi
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4YXpyOXE3MFovWEQvMVRr
|
||||||
WnluSEk4d1U5TWx2REZRZ3VCRVp2ZzlKY0NvCjNlUnIwdWVqSnlQOWp1dlJ5THlW
|
TGVST3U0N2dCVDJGT1A3eUtlRis3bFEvTHlFClZHQ2xRWklMMCtER01QNEVHaVYr
|
||||||
c2xTNHhnaE94a2ZTeXJjQTVxeGRLTmsKLS0tIFV4c2NZK1ZnL2xtUlVvSksxNi9o
|
MC94V3R4MVdNdUU3eXQ2RGFFVGo4VFEKLS0tIDQ4b2ZuMy9URUswWUZqNHlxandU
|
||||||
L3dodkJXVjZrekVldTVsRFRxSFlrTmMKiokjgIRIsI8D2aFP/Qem4iGzC4yr5lm2
|
OFducVVzdGZGY0tnbFFBZDdjVzVkaUEKN8qAbbrd4pAHRGIN8O64fl7bQ6hx6Isr
|
||||||
ZwggC/UfD56ysTEqrVaDnR7f5fSqZLWdstPJn7I/vr5CwKRMbMPYSA==
|
Qx0xKeuhJCVXgtE8xc7xmnEhqrcONlflJ/XUnYV9jOkB71zSBJxruA==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1p2dlc8gfgyrvtta6mty2pezjycn244gmvh456qd3wvkfwesp253qnwyta9
|
- recipient: age1p2dlc8gfgyrvtta6mty2pezjycn244gmvh456qd3wvkfwesp253qnwyta9
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpN0llOTBJU1pNNVFxVWxt
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzczdPMDdWU1ZtckJRQm5j
|
||||||
aFdKdStKL1ZlZ0p6WFRQbHpGNnpmdlJXdG1FCkx5eDhZWWJvQ2xSWEJqWnZ6NmNt
|
UWJub0Yzd3NzOEh4YWdId01nYWI1YVY3dng0ClpEYXBJV2cvWEdjdXcwUFI3Y0NG
|
||||||
Y0MzNDg5QzVSbEZteW1LNlFyRFg5Q0EKLS0tIDBrT0dEZlBoTExYcGRNZjZ5Znpz
|
MDgvTmNZOXRQQndyVmRHamNRbzVaVU0KLS0tIGFKVTI4TkE2UjhDUSsxQTlNQ0Vk
|
||||||
cnE4YWRTMmRsTENhOTl5R2dYSzQwazAKvnTvZz842Mg5AVlIoYHI2BG+0/hO5zIv
|
QmFMNnlqbnhScC90T012K1QxRnRUOHcKAV7NxUn0CMcjKwK8zrocoLO1P9jc22uG
|
||||||
jRVJri98fgGterXADTPmeoY3p+fFQggTPhs/5s5GSQxd5aiX8vvvrA==
|
eG+vdJ6xzA99UX51aPxQOeEJgdFPEd3y1QJszQmRzThvid7y4lv0Cw==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age18u4mqrhqkrpcytxfxfex6aeap04u38emhy6u4wrp5k62sz2vae4qm5jj7s
|
- recipient: age18u4mqrhqkrpcytxfxfex6aeap04u38emhy6u4wrp5k62sz2vae4qm5jj7s
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPQWljdGg4VTlDdGhoblpk
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsVmpzenRvWE5EK2wzRFkx
|
||||||
LytxK2FnQVI1dzB2bnFaWUtoUVNGS3lpU3prCnRwUTNnZVVXTnZ6eCtScTk5YzI3
|
SERZV0s1Rkt0ZnZ1U3JQSFNhdGVvaWhWcTA4CjVxK0Z0MHI0ZnMrUS9YYWhTTG1z
|
||||||
TGM2MmNhaHQ3NXAzMk0rcnJoTlp5STQKLS0tIEp2U3YvUUhXTkt3VFczY3J1LzMv
|
L2lVS1Q2UkVQd2x5b1E1eWpQVGp2ZHMKLS0tIHNLOGhTYjkzWkFEM05wYkRZeXFQ
|
||||||
ZzM0VHpqamRIZVROS2lQdXFhQTNBekEKEySldC+VvZvPY398ZVkB5s73bT3QbuLh
|
SXNTSGZZSFE2bFhybXdIc1FUb1ZBd0kKkYzflPRk6GrE6t9oVGOzc8xcyZDxiIw8
|
||||||
IqTv+wbkbjlvZJUavVyycY5SwMXkSX3ge9W/64mt/RDs88gSXFS+Sw==
|
9SVXIgV0WVpY4lnFKYKH2i4+1sIm6tKOpizlQxTg5VgmmrTtfazWAA==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1fw2sqaa5s9c8ml6ncsexkj8ar4288387ju92ytjys4awf9aw6smqqz94dh
|
- recipient: age1fw2sqaa5s9c8ml6ncsexkj8ar4288387ju92ytjys4awf9aw6smqqz94dh
|
||||||
enc: |
|
enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4bGppem15NlVod2hCRkM5
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0NHpkOTFHaXRhVGNua0dV
|
||||||
MzY1aUZOdEVzRzdEYTRNakdMQWJlRkk0eEZzClRLSnRrQUoreU5MVG40KzRKSGcw
|
alRieWJ6WG5ZNzlvcTR2aTVUeWFBVGVVUUNZCnY2VUZUOWVlNGY1ZldyVGE2bkpi
|
||||||
bUU4ZnpLU0VtOWxXVllrSW5lN0NWb0kKLS0tIE1iemRlVVpieEhxRnlIb2dFUHZr
|
VXVtQ3IyK0kyV1cyMU5nN1lYaW1oOUkKLS0tIFRVRGFCNWlGendSVEhHY0w0QTl6
|
||||||
am04NVRtU2N6SThYZWdXVE5RZ1B2aE0KVcHvB5k2Gcu/St0P8WPFzlCtuZthZTKo
|
emJEQkQ3QlU0TFVWaW1uQytaUndmQlEKKahqJpX8vI+PASOzzod/sFvXSkQFnJ9O
|
||||||
hwVc0lC6Xxt25hriaUFinwnyvcjxrLCx0Nq7f9Zn16nJcza5kev1nQ==
|
YmnmiFxm5WZDPLHwkgVx8FgCq9RfAad4HybhsMjYPKXJ/fNa/WVZRA==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2024-11-30T06:31:42Z"
|
lastmodified: "2024-11-30T06:31:42Z"
|
||||||
mac: ENC[AES256_GCM,data:xh8x9IrQ01ZzdcCTIfBrifIGduMYVmSSP52BkTyr/bx7AgQAz2WeA7LFrccxIayCGHrQKfMQDLUKJ/EBamG/6p8AX6QqZBTfqFD688ZhmRfxgpj7fYR9jPYnhb/9XHI9R2jTaJWwrorXvu3pa+Gy/hWB3Kb+WZc3fslmIuKuLH0=,iv:GDrHSFZxPbpACdusVDPHXEjeEusYfk53N/KGHtdvrYo=,tag:ap38sCSTZVDQ0ZazXM3vlg==,type:str]
|
mac: ENC[AES256_GCM,data:xh8x9IrQ01ZzdcCTIfBrifIGduMYVmSSP52BkTyr/bx7AgQAz2WeA7LFrccxIayCGHrQKfMQDLUKJ/EBamG/6p8AX6QqZBTfqFD688ZhmRfxgpj7fYR9jPYnhb/9XHI9R2jTaJWwrorXvu3pa+Gy/hWB3Kb+WZc3fslmIuKuLH0=,iv:GDrHSFZxPbpACdusVDPHXEjeEusYfk53N/KGHtdvrYo=,tag:ap38sCSTZVDQ0ZazXM3vlg==,type:str]
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
{ config, ... }:
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./hardware-configurations.nix
|
./hardware-configurations.nix
|
||||||
./monitoring.nix
|
./monitoring.nix
|
||||||
./restic.nix
|
|
||||||
./ntfy.nix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
|
@ -31,10 +28,6 @@
|
||||||
443
|
443
|
||||||
];
|
];
|
||||||
|
|
||||||
services.tailscale.enable = true;
|
|
||||||
|
|
||||||
services.caddy.enable = true;
|
|
||||||
|
|
||||||
commonSettings = {
|
commonSettings = {
|
||||||
auth.enable = true;
|
auth.enable = true;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,20 +1,5 @@
|
||||||
{
|
{ config, my-lib, ... }:
|
||||||
config,
|
with my-lib;
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
with config.my-lib;
|
|
||||||
let
|
|
||||||
inherit (config.my-lib.settings)
|
|
||||||
minifluxUrl
|
|
||||||
gotosocialUrl
|
|
||||||
hedgedocDomain
|
|
||||||
grafanaUrl
|
|
||||||
ntfyUrl
|
|
||||||
;
|
|
||||||
removeHttps = s: lib.removePrefix "https://" s;
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
config = {
|
config = {
|
||||||
sops = {
|
sops = {
|
||||||
|
@ -29,23 +14,11 @@ in
|
||||||
|
|
||||||
custom.monitoring = {
|
custom.monitoring = {
|
||||||
grafana.enable = true;
|
grafana.enable = true;
|
||||||
loki = {
|
loki.enable = true;
|
||||||
enable = true;
|
|
||||||
rules = {
|
|
||||||
sshd_closed = {
|
|
||||||
expr = ''count_over_time({unit="sshd.service"} |~ "Connection closed by authenticating user" [15m]) > 25'';
|
|
||||||
description = "More then 25 login attemps in last 15 min without success";
|
|
||||||
};
|
|
||||||
unusual_log_volume = {
|
|
||||||
expr = ''sum by (unit) (rate({unit=~".+"}[5m])) > 80'';
|
|
||||||
description = "Unit {{ $labels.unit }} is logging at an unusually high rate";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
promtail.enable = true;
|
promtail.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
services.caddy.virtualHosts.${grafanaUrl}.extraConfig =
|
services.caddy.virtualHosts."https://grafana.xinyang.life".extraConfig =
|
||||||
with config.services.grafana.settings.server; ''
|
with config.services.grafana.settings.server; ''
|
||||||
reverse_proxy http://${http_addr}:${toString http_port}
|
reverse_proxy http://${http_addr}:${toString http_port}
|
||||||
'';
|
'';
|
||||||
|
@ -57,28 +30,19 @@ in
|
||||||
blackbox.enable = true;
|
blackbox.enable = true;
|
||||||
node.enable = true;
|
node.enable = true;
|
||||||
};
|
};
|
||||||
ruleModules =
|
ruleModules = (mkCaddyRules [ { host = "thorite"; } ]) ++ (mkNodeRules [ { host = "thorite"; } ]);
|
||||||
(mkCaddyRules [ { host = "thorite"; } ])
|
|
||||||
++ (mkNodeRules [ { host = "thorite"; } ])
|
|
||||||
++ (mkBlackboxRules [ { host = "thorite"; } ]);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
services.prometheus.scrapeConfigs =
|
services.prometheus.scrapeConfigs =
|
||||||
let
|
let
|
||||||
probeList = [
|
probeList = [
|
||||||
"la-00.video.namely.icu:8080"
|
"la-00.video.namely.icu:8080"
|
||||||
"fra-00.video.namely.icu:8080"
|
"fre-00.video.namely.icu:8080"
|
||||||
"hk-00.video.namely.icu:8080"
|
"hk-00.video.namely.icu:8080"
|
||||||
|
"49.13.13.122:443"
|
||||||
|
"45.142.178.32:22"
|
||||||
"home.xinyang.life:8000"
|
"home.xinyang.life:8000"
|
||||||
];
|
];
|
||||||
chinaTargets = [
|
|
||||||
"bj-cu-v4.ip.zstaticcdn.com:80"
|
|
||||||
"bj-cm-v4.ip.zstaticcdn.com:80"
|
|
||||||
"bj-ct-v4.ip.zstaticcdn.com:80"
|
|
||||||
"sh-cu-v4.ip.zstaticcdn.com:80"
|
|
||||||
"sh-cm-v4.ip.zstaticcdn.com:80"
|
|
||||||
"sh-ct-v4.ip.zstaticcdn.com:80"
|
|
||||||
];
|
|
||||||
passwordFile = config.sops.secrets."prometheus/metrics_password".path;
|
passwordFile = config.sops.secrets."prometheus/metrics_password".path;
|
||||||
in
|
in
|
||||||
(mkScrapes [
|
(mkScrapes [
|
||||||
|
@ -88,50 +52,32 @@ in
|
||||||
address = "weilite.coho-tet.ts.net";
|
address = "weilite.coho-tet.ts.net";
|
||||||
port = 8082;
|
port = 8082;
|
||||||
}
|
}
|
||||||
{
|
|
||||||
name = "restic_rest_server";
|
|
||||||
address = "backup.xinyang.life";
|
|
||||||
port = 8443;
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
inherit passwordFile;
|
inherit passwordFile;
|
||||||
name = "gotosocial";
|
name = "gotosocial";
|
||||||
address = removeHttps gotosocialUrl;
|
address = "xinyang.life";
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
inherit passwordFile;
|
inherit passwordFile;
|
||||||
name = "miniflux";
|
name = "miniflux";
|
||||||
address = removeHttps minifluxUrl;
|
address = "rss.xinyang.life";
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "hedgedoc";
|
|
||||||
address = hedgedocDomain;
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
name = "ntfy";
|
name = "ntfy";
|
||||||
address = removeHttps ntfyUrl;
|
address = "ntfy.xinyang.life";
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
name = "grafana-eu";
|
name = "grafana-eu";
|
||||||
address = removeHttps grafanaUrl;
|
address = "grafana.xinyang.life";
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "loki";
|
|
||||||
scheme = "http";
|
|
||||||
address = "thorite.coho-tet.ts.net";
|
|
||||||
port = 3100;
|
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
++ (mkCaddyScrapes [
|
++ (mkCaddyScrapes [
|
||||||
{ address = "thorite.coho-tet.ts.net"; }
|
{ address = "thorite.coho-tet.ts.net"; }
|
||||||
{ address = "biotite.coho-tet.ts.net"; }
|
|
||||||
{ address = "weilite.coho-tet.ts.net"; }
|
|
||||||
])
|
])
|
||||||
++ (mkNodeScrapes [
|
++ (mkNodeScrapes [
|
||||||
{ address = "thorite.coho-tet.ts.net"; }
|
{ address = "thorite.coho-tet.ts.net"; }
|
||||||
{ address = "massicot.coho-tet.ts.net"; }
|
{ address = "massicot.coho-tet.ts.net"; }
|
||||||
{ address = "weilite.coho-tet.ts.net"; }
|
{ address = "weilite.coho-tet.ts.net"; }
|
||||||
{ address = "biotite.coho-tet.ts.net"; }
|
|
||||||
{ address = "hk-00.coho-tet.ts.net"; }
|
{ address = "hk-00.coho-tet.ts.net"; }
|
||||||
{ address = "la-00.coho-tet.ts.net"; }
|
{ address = "la-00.coho-tet.ts.net"; }
|
||||||
{ address = "fra-00.coho-tet.ts.net"; }
|
{ address = "fra-00.coho-tet.ts.net"; }
|
||||||
|
@ -139,37 +85,20 @@ in
|
||||||
++ (mkBlackboxScrapes [
|
++ (mkBlackboxScrapes [
|
||||||
{
|
{
|
||||||
hostAddress = "thorite.coho-tet.ts.net";
|
hostAddress = "thorite.coho-tet.ts.net";
|
||||||
targetAddresses = probeList ++ [ "49.13.13.122:443" ];
|
targetAddresses = probeList;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
hostAddress = "massicot.coho-tet.ts.net";
|
hostAddress = "massicot.coho-tet.ts.net";
|
||||||
targetAddresses = probeList ++ [ "45.142.178.32:443" ];
|
targetAddresses = probeList;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
hostAddress = "weilite.coho-tet.ts.net";
|
hostAddress = "weilite.coho-tet.ts.net";
|
||||||
targetAddresses = [
|
targetAddresses = [
|
||||||
"la-00.video.namely.icu:8080"
|
"la-00.video.namely.icu:8080"
|
||||||
"fra-00.video.namely.icu:8080"
|
"fre-00.video.namely.icu:8080"
|
||||||
"hk-00.video.namely.icu:8080"
|
"hk-00.video.namely.icu:8080"
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
{
|
|
||||||
hostAddress = "la-00.coho-tet.ts.net";
|
|
||||||
targetAddresses = chinaTargets;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
hostAddress = "hk-00.coho-tet.ts.net";
|
|
||||||
targetAddresses = chinaTargets;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
hostAddress = "fra-00.coho-tet.ts.net";
|
|
||||||
targetAddresses = chinaTargets;
|
|
||||||
}
|
|
||||||
])
|
|
||||||
++ (mkV2rayScrapes [
|
|
||||||
{ address = "la-00.coho-tet.ts.net"; }
|
|
||||||
{ address = "hk-00.coho-tet.ts.net"; }
|
|
||||||
{ address = "fra-00.coho-tet.ts.net"; }
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
{ config, ... }:
|
|
||||||
let
|
|
||||||
inherit (config.my-lib.settings) ntfyUrl;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
|
|
||||||
services.ntfy-sh = {
|
|
||||||
enable = true;
|
|
||||||
group = "caddy";
|
|
||||||
settings = {
|
|
||||||
listen-unix = "/var/run/ntfy-sh/ntfy.sock";
|
|
||||||
listen-unix-mode = 432; # octal 0660
|
|
||||||
base-url = ntfyUrl;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.ntfy-sh.serviceConfig.RuntimeDirectory = "ntfy-sh";
|
|
||||||
|
|
||||||
services.caddy.virtualHosts.${ntfyUrl}.extraConfig = ''
|
|
||||||
reverse_proxy unix/${config.services.ntfy-sh.settings.listen-unix}
|
|
||||||
@httpget {
|
|
||||||
protocol http
|
|
||||||
method GET
|
|
||||||
path_regexp ^/([-_a-z0-9]{0,64}$|docs/|static/)
|
|
||||||
}
|
|
||||||
redir @httpget https://{host}{uri}
|
|
||||||
'';
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
sqliteBackup = fromPath: toPath: file: ''
|
|
||||||
mkdir -p ${toPath}
|
|
||||||
${lib.getExe pkgs.sqlite} ${fromPath} ".backup '${toPath}/${file}'"
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
{
|
|
||||||
sops.secrets = {
|
|
||||||
"restic/repo_url" = { };
|
|
||||||
"restic/repo_password" = { };
|
|
||||||
};
|
|
||||||
|
|
||||||
custom.restic = {
|
|
||||||
enable = true;
|
|
||||||
paths = [
|
|
||||||
"/backup/db"
|
|
||||||
"/backup/var/lib"
|
|
||||||
];
|
|
||||||
backupPrepareCommand = [
|
|
||||||
''
|
|
||||||
mkdir -p /backup/var
|
|
||||||
${pkgs.btrfs-progs}/bin/btrfs subvolume snapshot -r /var/lib /backup/var/lib
|
|
||||||
''
|
|
||||||
];
|
|
||||||
backupCleanupCommand = [
|
|
||||||
''
|
|
||||||
${pkgs.btrfs-progs}/bin/btrfs subvolume delete /backup/var/lib
|
|
||||||
''
|
|
||||||
];
|
|
||||||
btrfsRoots = [ ];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.postgresqlBackup = lib.mkIf config.services.postgresql.enable {
|
|
||||||
enable = true;
|
|
||||||
compression = "zstd";
|
|
||||||
compressionLevel = 9;
|
|
||||||
location = "/backup/db/postgresql";
|
|
||||||
};
|
|
||||||
|
|
||||||
services.restic.backups.${config.networking.hostName} = {
|
|
||||||
extraBackupArgs = [
|
|
||||||
"--limit-upload=1024"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,8 +1,5 @@
|
||||||
grafana:
|
grafana:
|
||||||
oauth_secret: ENC[AES256_GCM,data:angZR3sl8vGcbAXyKFBvCSm+YhF5OooCcxRiSxR2zBoXMz5wv5/uMJFynwOTRVI6,iv:hVpOlM89lNbK6AsGf4Is/tLv3xPfg/XdtA8vuEK52L8=,tag:zCER+IdRnTcG2WHQ/AhxZA==,type:str]
|
oauth_secret: ENC[AES256_GCM,data:angZR3sl8vGcbAXyKFBvCSm+YhF5OooCcxRiSxR2zBoXMz5wv5/uMJFynwOTRVI6,iv:hVpOlM89lNbK6AsGf4Is/tLv3xPfg/XdtA8vuEK52L8=,tag:zCER+IdRnTcG2WHQ/AhxZA==,type:str]
|
||||||
restic:
|
|
||||||
repo_url: ENC[AES256_GCM,data:tc7wYRN20sHxATTZYEBpf6tNafzq9vcvqdUHYJDmJIArxprNd6WiyqPXowzbksZcEi5JwSwwJH/MYminnPGtrR8erWZg8OB3,iv:/z7mF58tMAviscFWHd4NJw7UZlq7Bzz+LU88J+kE9qg=,tag:i97FP4SmmNXOuxylkHhYCA==,type:str]
|
|
||||||
repo_password: ENC[AES256_GCM,data:o3MbXJRwR5UE9uCELN2ejQ==,iv:cYPNjJAV7H2BNCuFLDJoJvPk+CFvagXJwW9LRAGc0G0=,tag:qF6Di2W+8kESCRAphC/c0g==,type:str]
|
|
||||||
sops:
|
sops:
|
||||||
kms: []
|
kms: []
|
||||||
gcp_kms: []
|
gcp_kms: []
|
||||||
|
@ -27,8 +24,8 @@ sops:
|
||||||
M2pqMUJoMGlBZnpBaVBUTFFRZUMzb2sKrlWy26Cv55/8XQEl9hee8P29uj582sIx
|
M2pqMUJoMGlBZnpBaVBUTFFRZUMzb2sKrlWy26Cv55/8XQEl9hee8P29uj582sIx
|
||||||
mUjaYE0U2qOP9bklXUQyyzQjfkBLWTLc1PTX9BjqOOsqXwkRQIYppA==
|
mUjaYE0U2qOP9bklXUQyyzQjfkBLWTLc1PTX9BjqOOsqXwkRQIYppA==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2024-12-03T08:18:54Z"
|
lastmodified: "2024-11-28T17:02:03Z"
|
||||||
mac: ENC[AES256_GCM,data:jqSt34avoMfL9g3LmvjrPTzW4xGLgX70CXI8qk4isaLbZ8FkxjVU8QY1ot9GZnFEQWUkReSuGD4gFxi8TjetlNdx0zDPcv6zGJUSfcYpyKDCqGdyL/2x8xnYtI2pWINBZxR/2XxT3cus39FJdXVcz3l7KX4DvYvm8t/D9+r4ef0=,iv:KY/OTbDOOD/bBDTIuIk1ck7wDxLogo2EKeSOfOe4j5o=,tag:B17iF5O32KDZfctubpXCng==,type:str]
|
mac: ENC[AES256_GCM,data:14FOUXuKP+8+sad1UlhBW37fWzmutpyn6d4q2qKtBiOyT5ivHunFHJfHrtX83X2fLDmUfiD42bXf+rYfdtKzVUmQ6vutCUQk+Hal8NElhjcq5Ns5kT4VZRKG7/ya9+eNEEkajtq/7OFEM5KOQKTKjyOBqBq/AdYQ+ni9r45c1sM=,iv:WrdWSfrZrGalZO4WGk3JpgACY7W0odt3vP+pRkMXHfA=,tag:jeRBfR2QYjLBylOLHxU3hQ==,type:str]
|
||||||
pgp: []
|
pgp: []
|
||||||
unencrypted_suffix: _unencrypted
|
unencrypted_suffix: _unencrypted
|
||||||
version: 3.9.1
|
version: 3.9.1
|
||||||
|
|
|
@ -52,8 +52,9 @@
|
||||||
owner = "caddy";
|
owner = "caddy";
|
||||||
mode = "400";
|
mode = "400";
|
||||||
};
|
};
|
||||||
"restic/localpass" = {
|
"immich/oauth_client_secret" = {
|
||||||
owner = "restic";
|
owner = "immich";
|
||||||
|
mode = "400";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -68,10 +69,6 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
custom.monitoring = {
|
|
||||||
promtail.enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.mounts = [
|
systemd.mounts = [
|
||||||
{
|
{
|
||||||
what = "immich";
|
what = "immich";
|
||||||
|
@ -108,6 +105,43 @@
|
||||||
2222
|
2222
|
||||||
];
|
];
|
||||||
|
|
||||||
|
services.immich = {
|
||||||
|
enable = true;
|
||||||
|
mediaLocation = "/mnt/XinPhotos/immich";
|
||||||
|
host = "127.0.0.1";
|
||||||
|
port = 3001;
|
||||||
|
openFirewall = true;
|
||||||
|
machine-learning.enable = true;
|
||||||
|
environment = {
|
||||||
|
IMMICH_MACHINE_LEARNING_ENABLED = "true";
|
||||||
|
};
|
||||||
|
database.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
custom.immich.jsonSettings = {
|
||||||
|
oauth = {
|
||||||
|
enabled = true;
|
||||||
|
issuerUrl = "https://auth.xinyang.life/oauth2/openid/immich/";
|
||||||
|
clientId = "immich";
|
||||||
|
clientSecret = {
|
||||||
|
_secret = config.sops.secrets."immich/oauth_client_secret".path;
|
||||||
|
};
|
||||||
|
scope = "openid email profile";
|
||||||
|
signingAlgorithm = "ES256";
|
||||||
|
storageLabelClaim = "email";
|
||||||
|
buttonText = "Login with Kanidm";
|
||||||
|
autoLaunch = true;
|
||||||
|
mobileOverrideEnabled = true;
|
||||||
|
mobileRedirectUri = "https://immich.xinyang.life:8000/api/oauth/mobile-redirect/";
|
||||||
|
};
|
||||||
|
passwordLogin = {
|
||||||
|
enabled = false;
|
||||||
|
};
|
||||||
|
newVersionCheck = {
|
||||||
|
enabled = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
services.dae = {
|
services.dae = {
|
||||||
enable = true;
|
enable = true;
|
||||||
configFile = "/var/lib/dae/config.dae";
|
configFile = "/var/lib/dae/config.dae";
|
||||||
|
|
|
@ -2,8 +2,6 @@ cloudflare_dns_token: ENC[AES256_GCM,data:m4euSkxxJmiMk9UPyeni/hwpl1W9A4MM0ssg71
|
||||||
dnspod_dns_token: ENC[AES256_GCM,data:uZfr3g103amywxh3NMU+AkwuYb61svzyavvQ4rxJijIMIbfPvERrVNcyivoOrFWYXHpPWkhZFdU=,iv:mArVAcebW9i+u26GmQmfmJTsFkR4ZRMIisTqjpMYan8=,tag:Zsmv1Wzfi3+PHigjReToHQ==,type:str]
|
dnspod_dns_token: ENC[AES256_GCM,data:uZfr3g103amywxh3NMU+AkwuYb61svzyavvQ4rxJijIMIbfPvERrVNcyivoOrFWYXHpPWkhZFdU=,iv:mArVAcebW9i+u26GmQmfmJTsFkR4ZRMIisTqjpMYan8=,tag:Zsmv1Wzfi3+PHigjReToHQ==,type:str]
|
||||||
immich:
|
immich:
|
||||||
oauth_client_secret: ENC[AES256_GCM,data:EFs2hPjGMj0idwY3oQVIDTOIWkdwoAoAVjDQE9Z2eAKzUDH3grmYpYE+33V8d/Ux,iv:A9cjwFr/ZqltG62/N8MQ1LhdDbSIVVAqIPVB492zYJw=,tag:VTTtE697BZTVsI32UF53/w==,type:str]
|
oauth_client_secret: ENC[AES256_GCM,data:EFs2hPjGMj0idwY3oQVIDTOIWkdwoAoAVjDQE9Z2eAKzUDH3grmYpYE+33V8d/Ux,iv:A9cjwFr/ZqltG62/N8MQ1LhdDbSIVVAqIPVB492zYJw=,tag:VTTtE697BZTVsI32UF53/w==,type:str]
|
||||||
restic:
|
|
||||||
localpass: ENC[AES256_GCM,data:GIQAmkpDmGu4+sSG5/b5yQ==,iv:dcu6F8NnVjeQzEG2vM3fOV5owI0PWc86ts20UP3vN18=,tag:vsG8x062FG1pH5YNcAajeg==,type:str]
|
|
||||||
sops:
|
sops:
|
||||||
kms: []
|
kms: []
|
||||||
gcp_kms: []
|
gcp_kms: []
|
||||||
|
@ -28,8 +26,8 @@ sops:
|
||||||
V0thRjU4WGpQRGFpcnoxSjZTZHhTTkUKzNMHh9p7GUY3hL5XZ9S4x20CwaItsXFV
|
V0thRjU4WGpQRGFpcnoxSjZTZHhTTkUKzNMHh9p7GUY3hL5XZ9S4x20CwaItsXFV
|
||||||
RKujsFVVBd8Kuq/jyOCBTRCscuHI4LW/wYeZYHFEZFSTK2liAqspgw==
|
RKujsFVVBd8Kuq/jyOCBTRCscuHI4LW/wYeZYHFEZFSTK2liAqspgw==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2024-12-03T05:59:51Z"
|
lastmodified: "2024-09-13T12:02:54Z"
|
||||||
mac: ENC[AES256_GCM,data:0dLbfkm7fJvH5Mmct0/qHulg2AtDCeeeOgWMXfeGRUaX3GlLDiLga0zW4uNPDuahVecdh6ofvYfBOxFaGUdBCHk9vq5GzrwrzBNhqObWQ3AqVuq5rjqSxEKoFM4Eb5qoqaOefFzT/9qC94NDETTsHhjiEeIgd4fgSr2dazNiFPE=,iv:Ggw0FHzkrhKh5Uzo3seHGwwHsWW/tTAgAl0iIq9PVk4=,tag:rJvUI5/wsLJ01XyKmkRghw==,type:str]
|
mac: ENC[AES256_GCM,data:c5p+B2mPCDyS/Q4QH4MkzCww6jFDhP8RfHqrKLf4e/8XuNEGfNmPKaeliZG26j1YQWRvFHiGQX3AMnQ3Q+fSRUQCVi5KV+KW7fADNIB3TiTT5hAFuynhiWWQSmIrWP0GGek3GDGi7OJ1PrFbxWP9bwaf+zBegiaUcWoTorJg7No=,iv:6MohNgPpq80eTUlf3RvPKsxdx69V0jl+/hrMxAPpPQE=,tag:BtWp1FChP2hdclbGl5W+vQ==,type:str]
|
||||||
pgp: []
|
pgp: []
|
||||||
unencrypted_suffix: _unencrypted
|
unencrypted_suffix: _unencrypted
|
||||||
version: 3.9.1
|
version: 3.9.0
|
||||||
|
|
|
@ -3,6 +3,5 @@
|
||||||
./ocis.nix
|
./ocis.nix
|
||||||
./restic.nix
|
./restic.nix
|
||||||
./media-download.nix
|
./media-download.nix
|
||||||
./immich.nix
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
user = config.systemd.services.immich-server.serviceConfig.User;
|
|
||||||
jsonSettings = {
|
|
||||||
oauth = {
|
|
||||||
enabled = true;
|
|
||||||
issuerUrl = "https://auth.xinyang.life/oauth2/openid/immich/";
|
|
||||||
clientId = "immich";
|
|
||||||
clientSecret = config.sops.placeholder."immich/oauth_client_secret";
|
|
||||||
scope = "openid email profile";
|
|
||||||
signingAlgorithm = "ES256";
|
|
||||||
storageLabelClaim = "email";
|
|
||||||
buttonText = "Login with Kanidm";
|
|
||||||
autoLaunch = true;
|
|
||||||
mobileOverrideEnabled = true;
|
|
||||||
mobileRedirectUri = "https://immich.xinyang.life:8000/api/oauth/mobile-redirect/";
|
|
||||||
};
|
|
||||||
passwordLogin = {
|
|
||||||
enabled = false;
|
|
||||||
};
|
|
||||||
image = {
|
|
||||||
extractEmbedded = true;
|
|
||||||
};
|
|
||||||
newVersionCheck = {
|
|
||||||
enabled = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
config = {
|
|
||||||
sops.secrets."immich/oauth_client_secret" = { };
|
|
||||||
|
|
||||||
sops.templates."immich/config.json" = {
|
|
||||||
owner = user; # Read when running
|
|
||||||
content = builtins.toJSON jsonSettings;
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.immich-server = {
|
|
||||||
serviceConfig = {
|
|
||||||
Environment = "IMMICH_CONFIG_FILE=${config.sops.templates."immich/config.json".path}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.immich = {
|
|
||||||
enable = true;
|
|
||||||
mediaLocation = "/mnt/XinPhotos/immich";
|
|
||||||
host = "127.0.0.1";
|
|
||||||
port = 3001;
|
|
||||||
openFirewall = true;
|
|
||||||
machine-learning.enable = true;
|
|
||||||
environment = {
|
|
||||||
IMMICH_MACHINE_LEARNING_ENABLED = "true";
|
|
||||||
};
|
|
||||||
database.enable = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
# https://github.com/NixOS/nixpkgs/pull/324127/files#r1723763510
|
|
||||||
services.immich.redis.host = "/run/redis-immich/redis.sock";
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -13,13 +13,6 @@
|
||||||
openFirewall = false;
|
openFirewall = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
nixpkgs.config.permittedInsecurePackages = [
|
|
||||||
"aspnetcore-runtime-6.0.36"
|
|
||||||
"aspnetcore-runtime-wrapped-6.0.36"
|
|
||||||
"dotnet-sdk-6.0.428"
|
|
||||||
"dotnet-sdk-wrapped-6.0.428"
|
|
||||||
];
|
|
||||||
|
|
||||||
services.sonarr = {
|
services.sonarr = {
|
||||||
enable = true;
|
enable = true;
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,8 +35,6 @@ in
|
||||||
services.restic.backups = builtins.listToAttrs [
|
services.restic.backups = builtins.listToAttrs [
|
||||||
(mkPrune "xin" "calcite")
|
(mkPrune "xin" "calcite")
|
||||||
(mkPrune "xin" "massicot")
|
(mkPrune "xin" "massicot")
|
||||||
(mkPrune "xin" "biotite")
|
|
||||||
(mkPrune "xin" "thorite")
|
|
||||||
];
|
];
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [ 8443 ];
|
networking.firewall.allowedTCPPorts = [ 8443 ];
|
||||||
|
|
|
@ -91,10 +91,6 @@ in
|
||||||
${pkgs.comma}/bin/comma $argv
|
${pkgs.comma}/bin/comma $argv
|
||||||
end
|
end
|
||||||
set -gx LS_COLORS (${lib.getExe pkgs.vivid} generate catppuccin-mocha)
|
set -gx LS_COLORS (${lib.getExe pkgs.vivid} generate catppuccin-mocha)
|
||||||
alias ctlsp="systemctl stop"
|
|
||||||
alias ctlst="systemctl start"
|
|
||||||
alias ctlrt="systemctl restart"
|
|
||||||
alias ctls="systemctl status"
|
|
||||||
''
|
''
|
||||||
else
|
else
|
||||||
"";
|
"";
|
||||||
|
|
|
@ -25,9 +25,8 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config = mkIf cfg.enable {
|
config = {
|
||||||
home.packages = [ pkgs.git-absorb ];
|
programs.git = mkIf cfg.enable {
|
||||||
programs.git = {
|
|
||||||
enable = true;
|
enable = true;
|
||||||
delta.enable = true;
|
delta.enable = true;
|
||||||
userName = "Xinyang Li";
|
userName = "Xinyang Li";
|
||||||
|
@ -43,10 +42,6 @@ in
|
||||||
signByDefault = true;
|
signByDefault = true;
|
||||||
key = cfg.signing.keyFile;
|
key = cfg.signing.keyFile;
|
||||||
};
|
};
|
||||||
extraConfig.absorb = {
|
|
||||||
oneFixupPerCommit = true;
|
|
||||||
maxStack = 20;
|
|
||||||
};
|
|
||||||
extraConfig.user = mkIf cfg.signing.enable { signingkey = cfg.signing.keyFile; };
|
extraConfig.user = mkIf cfg.signing.enable { signingkey = cfg.signing.keyFile; };
|
||||||
extraConfig.gpg = mkIf cfg.signing.enable { format = "ssh"; };
|
extraConfig.gpg = mkIf cfg.signing.enable { format = "ssh"; };
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,6 +9,8 @@ let
|
||||||
inherit (lib)
|
inherit (lib)
|
||||||
mkIf
|
mkIf
|
||||||
mkEnableOption
|
mkEnableOption
|
||||||
|
mkOption
|
||||||
|
types
|
||||||
;
|
;
|
||||||
|
|
||||||
cfg = config.commonSettings.auth;
|
cfg = config.commonSettings.auth;
|
||||||
|
@ -19,43 +21,25 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
services.kanidm = {
|
custom.kanidm-client = {
|
||||||
enableClient = true;
|
enable = true;
|
||||||
clientSettings = {
|
uri = "https://auth.xinyang.life";
|
||||||
uri = "https://auth.xinyang.life";
|
asSSHAuth = {
|
||||||
};
|
enable = true;
|
||||||
enablePam = true;
|
allowedGroups = [ "linux_users" ];
|
||||||
unixSettings = {
|
|
||||||
pam_allowed_login_groups = [ "linux_users" ];
|
|
||||||
default_shell = "/bin/sh";
|
|
||||||
};
|
};
|
||||||
|
sudoers = [ "xin@auth.xinyang.life" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
services.openssh = {
|
services.openssh = {
|
||||||
enable = true;
|
|
||||||
authorizedKeysCommand = "/etc/ssh/auth %u";
|
|
||||||
authorizedKeysCommandUser = "kanidm-ssh-runner";
|
|
||||||
settings = {
|
settings = {
|
||||||
PasswordAuthentication = false;
|
PasswordAuthentication = false;
|
||||||
KbdInteractiveAuthentication = false;
|
KbdInteractiveAuthentication = false;
|
||||||
PermitRootLogin = lib.mkForce "no";
|
PermitRootLogin = "no";
|
||||||
|
GSSAPIAuthentication = "no";
|
||||||
|
KerberosAuthentication = "no";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
environment.etc."ssh/auth" = {
|
|
||||||
mode = "0555";
|
|
||||||
text = ''
|
|
||||||
#!${pkgs.stdenv.shell}
|
|
||||||
${pkgs.kanidm}/bin/kanidm_ssh_authorizedkeys $1
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
users.groups.wheel.members = [ "xin@auth.xinyang.life" ];
|
|
||||||
users.groups.kanidm-ssh-runner = { };
|
|
||||||
users.users.kanidm-ssh-runner = {
|
|
||||||
isSystemUser = true;
|
|
||||||
group = "kanidm-ssh-runner";
|
|
||||||
};
|
|
||||||
|
|
||||||
services.fail2ban.enable = true;
|
services.fail2ban.enable = true;
|
||||||
|
|
||||||
security.sudo = {
|
security.sudo = {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
pkgs,
|
|
||||||
lib,
|
lib,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
@ -22,117 +21,106 @@ let
|
||||||
config.security.acme.certs.${config.deployment.targetHost}.directory + "/cert.pem";
|
config.security.acme.certs.${config.deployment.targetHost}.directory + "/cert.pem";
|
||||||
};
|
};
|
||||||
|
|
||||||
mkSingConfig = users: {
|
mkSingConfig =
|
||||||
log = {
|
{ uuid, password, ... }:
|
||||||
level = "warn";
|
{
|
||||||
};
|
log = {
|
||||||
inbounds =
|
level = "warn";
|
||||||
[
|
};
|
||||||
{
|
inbounds =
|
||||||
tag = "sg0";
|
|
||||||
type = "trojan";
|
|
||||||
listen = "::";
|
|
||||||
listen_port = cfg.trojan.port;
|
|
||||||
tcp_multi_path = true;
|
|
||||||
tcp_fast_open = true;
|
|
||||||
users = map (user: {
|
|
||||||
name = user.name;
|
|
||||||
password = {
|
|
||||||
_secret = user.passwordFile;
|
|
||||||
};
|
|
||||||
}) users;
|
|
||||||
tls = singTls;
|
|
||||||
}
|
|
||||||
]
|
|
||||||
++ lib.forEach (lib.range 6311 6314) (port: {
|
|
||||||
tag = "sg" + toString (port - 6310);
|
|
||||||
type = "tuic";
|
|
||||||
listen = "::";
|
|
||||||
listen_port = port;
|
|
||||||
congestion_control = "bbr";
|
|
||||||
users = map (user: {
|
|
||||||
name = user.name;
|
|
||||||
uuid = {
|
|
||||||
_secret = user.uuidFile;
|
|
||||||
};
|
|
||||||
password = {
|
|
||||||
_secret = user.passwordFile;
|
|
||||||
};
|
|
||||||
}) users;
|
|
||||||
tls = singTls;
|
|
||||||
});
|
|
||||||
outbounds =
|
|
||||||
# warp outbound goes first to make it default outbound
|
|
||||||
(lib.optionals (cfg.warp.onTuic or cfg.warp.onTrojan) [
|
|
||||||
{
|
|
||||||
type = "wireguard";
|
|
||||||
tag = "wg-out";
|
|
||||||
private_key = {
|
|
||||||
_secret = config.sops.secrets.wg_private_key.path;
|
|
||||||
};
|
|
||||||
local_address = [
|
|
||||||
"172.16.0.2/32"
|
|
||||||
{ _secret = config.sops.secrets.wg_ipv6_local_addr.path; }
|
|
||||||
];
|
|
||||||
peers = [
|
|
||||||
{
|
|
||||||
public_key = "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=";
|
|
||||||
allowed_ips = [
|
|
||||||
"0.0.0.0/0"
|
|
||||||
"::/0"
|
|
||||||
];
|
|
||||||
server = "162.159.192.1";
|
|
||||||
server_port = 500;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
])
|
|
||||||
++ [
|
|
||||||
|
|
||||||
{
|
|
||||||
type = "direct";
|
|
||||||
tag = "direct";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
route = {
|
|
||||||
rules =
|
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
inbound = "sg4";
|
tag = "sg0";
|
||||||
outbound = "direct";
|
type = "trojan";
|
||||||
|
listen = "::";
|
||||||
|
listen_port = cfg.trojan.port;
|
||||||
|
tcp_multi_path = true;
|
||||||
|
tcp_fast_open = true;
|
||||||
|
users = [
|
||||||
|
{
|
||||||
|
name = "proxy";
|
||||||
|
password = {
|
||||||
|
_secret = password;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
tls = singTls;
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
++ (lib.optionals (!cfg.warp.onTuic) (
|
++ lib.forEach (lib.range 6311 6314) (port: {
|
||||||
lib.forEach (lib.range 1 3) (i: {
|
tag = "sg" + toString (port - 6310);
|
||||||
inbound = "sg${toString i}";
|
type = "tuic";
|
||||||
outbound = "direct";
|
listen = "::";
|
||||||
})
|
listen_port = port;
|
||||||
))
|
congestion_control = "bbr";
|
||||||
++ (lib.optionals (!cfg.warp.onTrojan) [
|
users = [
|
||||||
|
{
|
||||||
|
name = "proxy";
|
||||||
|
uuid = {
|
||||||
|
_secret = uuid;
|
||||||
|
};
|
||||||
|
password = {
|
||||||
|
_secret = password;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
tls = singTls;
|
||||||
|
});
|
||||||
|
outbounds =
|
||||||
|
# warp outbound goes first to make it default outbound
|
||||||
|
(lib.optionals (cfg.warp.onTuic or cfg.warp.onTrojan) [
|
||||||
{
|
{
|
||||||
inbound = "sg0";
|
type = "wireguard";
|
||||||
outbound = "direct";
|
tag = "wg-out";
|
||||||
|
private_key = {
|
||||||
|
_secret = config.sops.secrets.wg_private_key.path;
|
||||||
|
};
|
||||||
|
local_address = [
|
||||||
|
"172.16.0.2/32"
|
||||||
|
{ _secret = config.sops.secrets.wg_ipv6_local_addr.path; }
|
||||||
|
];
|
||||||
|
peers = [
|
||||||
|
{
|
||||||
|
public_key = "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=";
|
||||||
|
allowed_ips = [
|
||||||
|
"0.0.0.0/0"
|
||||||
|
"::/0"
|
||||||
|
];
|
||||||
|
server = "162.159.192.1";
|
||||||
|
server_port = 500;
|
||||||
|
}
|
||||||
|
];
|
||||||
}
|
}
|
||||||
]);
|
])
|
||||||
};
|
++ [
|
||||||
experimental = {
|
|
||||||
v2ray_api = {
|
{
|
||||||
listen = "127.0.0.1:15175";
|
type = "direct";
|
||||||
stats = {
|
tag = "direct";
|
||||||
users = map (u: u.name) users;
|
}
|
||||||
enabled = true;
|
];
|
||||||
inbounds = map (p: "sg" + toString p) (lib.range 0 4);
|
route = {
|
||||||
};
|
rules =
|
||||||
|
[
|
||||||
|
{
|
||||||
|
inbound = "sg4";
|
||||||
|
outbound = "direct";
|
||||||
|
}
|
||||||
|
]
|
||||||
|
++ (lib.optionals (!cfg.warp.onTuic) (
|
||||||
|
lib.forEach (lib.range 1 3) (i: {
|
||||||
|
inbound = "sg${toString i}";
|
||||||
|
outbound = "direct";
|
||||||
|
})
|
||||||
|
))
|
||||||
|
++ (lib.optionals (!cfg.warp.onTrojan) [
|
||||||
|
{
|
||||||
|
inbound = "sg0";
|
||||||
|
outbound = "direct";
|
||||||
|
}
|
||||||
|
]);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
sing-box = pkgs.sing-box.overrideAttrs (
|
|
||||||
finalAttrs: previousAttrs: {
|
|
||||||
tags = previousAttrs.tags ++ [
|
|
||||||
"with_v2ray_api"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
);
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.commonSettings.proxyServer = {
|
options.commonSettings.proxyServer = {
|
||||||
|
@ -149,62 +137,40 @@ in
|
||||||
onTrojan = mkEnableOption "forward to warp in trojan";
|
onTrojan = mkEnableOption "forward to warp in trojan";
|
||||||
onTuic = mkEnableOption "forward to warp in first two port of tuic";
|
onTuic = mkEnableOption "forward to warp in first two port of tuic";
|
||||||
};
|
};
|
||||||
|
|
||||||
users = mkOption {
|
|
||||||
type = lib.types.listOf lib.types.str;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable (
|
config = mkIf cfg.enable {
|
||||||
{
|
boot.kernel.sysctl = {
|
||||||
boot.kernel.sysctl = {
|
"net.core.default_qdisc" = "fq";
|
||||||
"net.core.default_qdisc" = "fq";
|
"net.ipv4.tcp_congestion_control" = "bbr";
|
||||||
"net.ipv4.tcp_congestion_control" = "bbr";
|
};
|
||||||
|
|
||||||
|
networking.firewall.trustedInterfaces = [ "tun0" ];
|
||||||
|
|
||||||
|
security.acme = {
|
||||||
|
acceptTerms = true;
|
||||||
|
certs.${config.deployment.targetHost} = {
|
||||||
|
email = "me@namely.icu";
|
||||||
|
# Avoid port conflict
|
||||||
|
listenHTTP = if config.services.caddy.enable then ":30310" else ":80";
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
services.caddy.virtualHosts."http://${config.deployment.targetHost}:80".extraConfig = ''
|
||||||
|
reverse_proxy 127.0.0.1:30310
|
||||||
|
'';
|
||||||
|
|
||||||
networking.firewall.trustedInterfaces = [ "tun0" ];
|
networking.firewall.allowedTCPPorts = [
|
||||||
|
80
|
||||||
|
cfg.trojan.port
|
||||||
|
];
|
||||||
|
networking.firewall.allowedUDPPorts = [ ] ++ (lib.range 6311 6314);
|
||||||
|
|
||||||
security.acme = {
|
services.sing-box = {
|
||||||
acceptTerms = true;
|
enable = true;
|
||||||
certs.${config.deployment.targetHost} = {
|
settings = mkSingConfig {
|
||||||
email = "me@namely.icu";
|
uuid = config.sops.secrets."sing-box/uuid".path;
|
||||||
# Avoid port conflict
|
password = config.sops.secrets."sing-box/password".path;
|
||||||
listenHTTP = if config.services.caddy.enable then ":30310" else ":80";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
services.caddy.virtualHosts."http://${config.deployment.targetHost}:80".extraConfig = ''
|
};
|
||||||
reverse_proxy 127.0.0.1:30310
|
};
|
||||||
'';
|
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [
|
|
||||||
80
|
|
||||||
cfg.trojan.port
|
|
||||||
];
|
|
||||||
networking.firewall.allowedUDPPorts = [ ] ++ (lib.range 6311 6314);
|
|
||||||
|
|
||||||
services.sing-box = {
|
|
||||||
enable = true;
|
|
||||||
package = sing-box;
|
|
||||||
settings = (
|
|
||||||
mkSingConfig (
|
|
||||||
map (n: {
|
|
||||||
name = n;
|
|
||||||
uuidFile = config.sops.secrets."sing-box/users/${n}/uuid".path;
|
|
||||||
passwordFile = config.sops.secrets."sing-box/users/${n}/password".path;
|
|
||||||
}) cfg.users
|
|
||||||
)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// {
|
|
||||||
sops.secrets = (
|
|
||||||
builtins.foldl' (a: b: a // b) { } (
|
|
||||||
map (u: {
|
|
||||||
"sing-box/users/${u}/uuid" = { };
|
|
||||||
"sing-box/users/${u}/password" = { };
|
|
||||||
}) cfg.users
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,15 @@
|
||||||
./common-settings/mainland.nix
|
./common-settings/mainland.nix
|
||||||
./disk-partitions
|
./disk-partitions
|
||||||
./restic.nix
|
./restic.nix
|
||||||
|
./vaultwarden.nix
|
||||||
./monitor
|
./monitor
|
||||||
|
./hedgedoc.nix
|
||||||
|
./sing-box.nix
|
||||||
|
./kanidm-client.nix
|
||||||
|
./ssh-tpm-agent.nix # FIXME: Waiting for upstream merge
|
||||||
|
./forgejo-actions-runner.nix
|
||||||
|
./oidc-agent.nix
|
||||||
|
./miniflux.nix
|
||||||
|
./immich.nix
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
78
modules/nixos/hedgedoc.nix
Normal file
78
modules/nixos/hedgedoc.nix
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.custom.hedgedoc;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
custom.hedgedoc = {
|
||||||
|
enable = mkEnableOption "HedgeDoc Markdown Editor";
|
||||||
|
domain = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "docs.example.com";
|
||||||
|
description = "Domain name of the HedgeDoc server";
|
||||||
|
};
|
||||||
|
caddy = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = "Enable Caddy as reverse proxy";
|
||||||
|
};
|
||||||
|
mediaPath = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = /var/lib/hedgedoc/uploads;
|
||||||
|
description = "Directory for storing medias";
|
||||||
|
};
|
||||||
|
oidc = {
|
||||||
|
enable = mkEnableOption "OIDC support for HedgeDoc";
|
||||||
|
baseURL = mkOption { type = types.str; };
|
||||||
|
authorizationURL = mkOption { type = types.str; };
|
||||||
|
tokenURL = mkOption { type = types.str; };
|
||||||
|
userProfileURL = mkOption { type = types.str; };
|
||||||
|
};
|
||||||
|
environmentFile = mkOption { type = types.path; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
services.hedgedoc = {
|
||||||
|
enable = true;
|
||||||
|
environmentFile = cfg.environmentFile;
|
||||||
|
settings = {
|
||||||
|
domain = cfg.domain;
|
||||||
|
protocolUseSSL = cfg.caddy;
|
||||||
|
uploadsPath = cfg.mediaPath;
|
||||||
|
path = "/run/hedgedoc/hedgedoc.sock";
|
||||||
|
email = false;
|
||||||
|
allowEmailRegister = false;
|
||||||
|
oauth2 = mkIf cfg.oidc.enable {
|
||||||
|
baseURL = cfg.oidc.baseURL;
|
||||||
|
authorizationURL = cfg.oidc.authorizationURL;
|
||||||
|
tokenURL = cfg.oidc.tokenURL;
|
||||||
|
userProfileURL = cfg.oidc.userProfileURL;
|
||||||
|
userProfileEmailAttr = "email";
|
||||||
|
userProfileUsernameAttr = "name";
|
||||||
|
userProfileDisplayNameAttr = "preferred_name";
|
||||||
|
scope = "openid email profile";
|
||||||
|
clientID = "$HEDGEDOC_CLIENT_ID";
|
||||||
|
clientSecret = "$HEDGEDOC_CLIENT_SECRET";
|
||||||
|
};
|
||||||
|
allowAnonymous = false;
|
||||||
|
defaultPermission = "private";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
services.caddy = mkIf cfg.caddy {
|
||||||
|
enable = true;
|
||||||
|
virtualHosts."https://${cfg.domain}".extraConfig = ''
|
||||||
|
reverse_proxy unix/${config.services.hedgedoc.settings.path}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
users.users.caddy.extraGroups = mkIf cfg.caddy [ "hedgedoc" ];
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
60
modules/nixos/immich.nix
Normal file
60
modules/nixos/immich.nix
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
utils,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
cfg = config.custom.immich;
|
||||||
|
upstreamCfg = config.services.immich;
|
||||||
|
settingsFormat = pkgs.formats.json { };
|
||||||
|
user = config.systemd.services.immich-server.serviceConfig.User;
|
||||||
|
group = config.systemd.services.immich-server.serviceConfig.Group;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
custom.immich.jsonSettings = lib.mkOption {
|
||||||
|
type = lib.types.submodule {
|
||||||
|
freeformType = settingsFormat.type;
|
||||||
|
};
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
/*
|
||||||
|
LoadCredential happens before preStart. We need to ensure the
|
||||||
|
configuration file exist, otherwise LoadCredential will fail.
|
||||||
|
*/
|
||||||
|
systemd.tmpfiles.settings = lib.mkIf upstreamCfg.enable {
|
||||||
|
"10-etc-immich" = {
|
||||||
|
"/etc/immich" = {
|
||||||
|
d = {
|
||||||
|
inherit user group;
|
||||||
|
mode = "0700";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
"/etc/immich/config.json" = {
|
||||||
|
"f+" = {
|
||||||
|
inherit user group;
|
||||||
|
mode = "0600";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.immich-server = {
|
||||||
|
preStart = ''
|
||||||
|
umask 0077
|
||||||
|
${utils.genJqSecretsReplacementSnippet cfg.jsonSettings "/etc/immich/config.json"}
|
||||||
|
'';
|
||||||
|
serviceConfig = {
|
||||||
|
LoadCredential = "config:/etc/immich/config.json";
|
||||||
|
Environment = "IMMICH_CONFIG_FILE=%d/config";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# https://github.com/NixOS/nixpkgs/pull/324127/files#r1723763510
|
||||||
|
services.immich.redis.host = "/run/redis-immich/redis.sock";
|
||||||
|
};
|
||||||
|
}
|
134
modules/nixos/inbounds.nix
Normal file
134
modules/nixos/inbounds.nix
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
let
|
||||||
|
cfg = config.custom.sing-box-server;
|
||||||
|
|
||||||
|
secretFileType = lib.types.submodule { _secret = lib.types.path; };
|
||||||
|
singTls = {
|
||||||
|
enabled = true;
|
||||||
|
server_name = config.deployment.targetHost;
|
||||||
|
key_path = config.security.acme.certs.${config.deployment.targetHost}.directory + "/key.pem";
|
||||||
|
certificate_path =
|
||||||
|
config.security.acme.certs.${config.deployment.targetHost}.directory + "/cert.pem";
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
enable = lib.mkEnableOption "sing-box proxy server";
|
||||||
|
users = lib.types.listOf lib.types.submodule {
|
||||||
|
name = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "proxy";
|
||||||
|
};
|
||||||
|
password = lib.mkOption { type = secretFileType; };
|
||||||
|
uuid = lib.mkOption { type = secretFileType; };
|
||||||
|
};
|
||||||
|
wgOut = {
|
||||||
|
privKeyFile = lib.mkOption { type = lib.types.path; };
|
||||||
|
pubkey = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
inbounds = {
|
||||||
|
trojan = {
|
||||||
|
enable = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
tuic = {
|
||||||
|
enable = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
ports = lib.mkOption {
|
||||||
|
type = lib.types.listOf lib.types.int;
|
||||||
|
default = lib.range 6311 6313;
|
||||||
|
};
|
||||||
|
directPorts = lib.mkOption {
|
||||||
|
type = lib.types.listOf lib.types.int;
|
||||||
|
default = [ 6314 ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
services.sing-box = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
dns = {
|
||||||
|
servers = [
|
||||||
|
{
|
||||||
|
address = "1.1.1.1";
|
||||||
|
detour = "wg-out";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
inbounds =
|
||||||
|
[
|
||||||
|
# TODO: Trojan and tuic enable
|
||||||
|
{
|
||||||
|
tag = "trojan-in";
|
||||||
|
type = "trojan";
|
||||||
|
listen = "::";
|
||||||
|
listen_port = 8080;
|
||||||
|
users = map (u: removeAttrs u [ "uuid" ]) cfg.users;
|
||||||
|
tls = singTls;
|
||||||
|
}
|
||||||
|
]
|
||||||
|
++ lib.forEach (cfg.tuic.ports ++ cfg.tuic.directPorts) (port: {
|
||||||
|
tag = "tuic-in" + toString port;
|
||||||
|
type = "tuic";
|
||||||
|
listen = "::";
|
||||||
|
listen_port = port;
|
||||||
|
congestion_control = "bbr";
|
||||||
|
users = cfg.users;
|
||||||
|
tls = singTls;
|
||||||
|
});
|
||||||
|
outbounds = [
|
||||||
|
{
|
||||||
|
type = "wireguard";
|
||||||
|
tag = "wg-out";
|
||||||
|
private_key = cfg.wgOut.privKeyFile;
|
||||||
|
local_address = [
|
||||||
|
"172.16.0.2/32"
|
||||||
|
"2606:4700:110:82ed:a443:3c62:6cbc:b59b/128"
|
||||||
|
];
|
||||||
|
peers = [
|
||||||
|
{
|
||||||
|
public_key = cfg.wgOut.pubkey;
|
||||||
|
allowed_ips = [
|
||||||
|
"0.0.0.0/0"
|
||||||
|
"::/0"
|
||||||
|
];
|
||||||
|
server = "162.159.192.1";
|
||||||
|
server_port = 500;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
type = "direct";
|
||||||
|
tag = "direct-out";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
type = "dns";
|
||||||
|
tag = "dns-out";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
route = {
|
||||||
|
rules =
|
||||||
|
[
|
||||||
|
{
|
||||||
|
outbound = "dns-out";
|
||||||
|
protocol = "dns";
|
||||||
|
}
|
||||||
|
]
|
||||||
|
++ lib.forEach cfg.tuic.directPorts (port: {
|
||||||
|
inbound = "tuic-in" + toString port;
|
||||||
|
outbound = "direct-out";
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -59,6 +59,8 @@ in
|
||||||
PasswordAuthentication = false;
|
PasswordAuthentication = false;
|
||||||
KbdInteractiveAuthentication = false;
|
KbdInteractiveAuthentication = false;
|
||||||
PermitRootLogin = lib.mkForce "no";
|
PermitRootLogin = lib.mkForce "no";
|
||||||
|
GSSAPIAuthentication = "no";
|
||||||
|
KerberosAuthentication = "no";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
165
modules/nixos/miniflux.nix
Normal file
165
modules/nixos/miniflux.nix
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
inherit (lib)
|
||||||
|
mkEnableOption
|
||||||
|
mkPackageOption
|
||||||
|
mkOption
|
||||||
|
types
|
||||||
|
literalExpression
|
||||||
|
mkIf
|
||||||
|
mkDefault
|
||||||
|
;
|
||||||
|
cfg = config.custom.miniflux;
|
||||||
|
|
||||||
|
defaultAddress = "localhost:8080";
|
||||||
|
|
||||||
|
pgbin = "${config.services.postgresql.package}/bin";
|
||||||
|
preStart = pkgs.writeScript "miniflux-pre-start" ''
|
||||||
|
#!${pkgs.runtimeShell}
|
||||||
|
${pgbin}/psql "miniflux" -c "CREATE EXTENSION IF NOT EXISTS hstore"
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
custom.miniflux = {
|
||||||
|
enable = mkEnableOption "miniflux";
|
||||||
|
|
||||||
|
package = mkPackageOption pkgs "miniflux" { };
|
||||||
|
|
||||||
|
oauth2SecretFile = mkOption { type = types.path; };
|
||||||
|
|
||||||
|
environment = mkOption {
|
||||||
|
type =
|
||||||
|
with types;
|
||||||
|
attrsOf (oneOf [
|
||||||
|
int
|
||||||
|
str
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
createDatabaseLocally = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Whether a PostgreSQL database should be automatically created and
|
||||||
|
configured on the local host. If set to `false`, you need provision a
|
||||||
|
database yourself and make sure to create the hstore extension in it.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
services.miniflux.enable = false;
|
||||||
|
custom.miniflux.environment = {
|
||||||
|
LISTEN_ADDR = mkDefault defaultAddress;
|
||||||
|
RUN_MIGRATIONS = mkDefault 1;
|
||||||
|
DATABASE_URL = lib.mkIf cfg.createDatabaseLocally "user=miniflux host=/run/postgresql dbname=miniflux";
|
||||||
|
OAUTH2_CLIENT_SECRET_FILE = "%d/oauth2_secret";
|
||||||
|
WATCHDOG = mkDefault 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.postgresql = lib.mkIf cfg.createDatabaseLocally {
|
||||||
|
enable = true;
|
||||||
|
ensureUsers = [
|
||||||
|
{
|
||||||
|
name = "miniflux";
|
||||||
|
ensureDBOwnership = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
ensureDatabases = [ "miniflux" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.miniflux-dbsetup = lib.mkIf cfg.createDatabaseLocally {
|
||||||
|
description = "Miniflux database setup";
|
||||||
|
requires = [ "postgresql.service" ];
|
||||||
|
after = [
|
||||||
|
"network.target"
|
||||||
|
"postgresql.service"
|
||||||
|
];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
User = config.services.postgresql.superUser;
|
||||||
|
ExecStart = preStart;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.miniflux = {
|
||||||
|
description = "Miniflux service";
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
requires = lib.optional cfg.createDatabaseLocally "miniflux-dbsetup.service";
|
||||||
|
after =
|
||||||
|
[ "network.target" ]
|
||||||
|
++ lib.optionals cfg.createDatabaseLocally [
|
||||||
|
"postgresql.service"
|
||||||
|
"miniflux-dbsetup.service"
|
||||||
|
];
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "notify";
|
||||||
|
ExecStart = lib.getExe cfg.package;
|
||||||
|
User = "miniflux";
|
||||||
|
DynamicUser = true;
|
||||||
|
LoadCredential = [ "oauth2_secret:${cfg.oauth2SecretFile}" ];
|
||||||
|
RuntimeDirectory = "miniflux";
|
||||||
|
RuntimeDirectoryMode = "0750";
|
||||||
|
WatchdogSec = 60;
|
||||||
|
WatchdogSignal = "SIGKILL";
|
||||||
|
Restart = "always";
|
||||||
|
RestartSec = 5;
|
||||||
|
|
||||||
|
# Hardening
|
||||||
|
CapabilityBoundingSet = [ "" ];
|
||||||
|
DeviceAllow = [ "" ];
|
||||||
|
LockPersonality = true;
|
||||||
|
MemoryDenyWriteExecute = true;
|
||||||
|
PrivateDevices = true;
|
||||||
|
PrivateUsers = true;
|
||||||
|
ProcSubset = "pid";
|
||||||
|
ProtectClock = true;
|
||||||
|
ProtectControlGroups = true;
|
||||||
|
ProtectHome = true;
|
||||||
|
ProtectHostname = true;
|
||||||
|
ProtectKernelLogs = true;
|
||||||
|
ProtectKernelModules = true;
|
||||||
|
ProtectKernelTunables = true;
|
||||||
|
ProtectProc = "invisible";
|
||||||
|
RestrictAddressFamilies = [
|
||||||
|
"AF_INET"
|
||||||
|
"AF_INET6"
|
||||||
|
"AF_UNIX"
|
||||||
|
];
|
||||||
|
RestrictNamespaces = true;
|
||||||
|
RestrictRealtime = true;
|
||||||
|
RestrictSUIDSGID = true;
|
||||||
|
SystemCallArchitectures = "native";
|
||||||
|
SystemCallFilter = [
|
||||||
|
"@system-service"
|
||||||
|
"~@privileged"
|
||||||
|
];
|
||||||
|
UMask = "0077";
|
||||||
|
};
|
||||||
|
|
||||||
|
environment = lib.mapAttrs (_: toString) cfg.environment;
|
||||||
|
};
|
||||||
|
environment.systemPackages = [ cfg.package ];
|
||||||
|
|
||||||
|
security.apparmor.policies."bin.miniflux".profile = ''
|
||||||
|
include <tunables/global>
|
||||||
|
${cfg.package}/bin/miniflux {
|
||||||
|
include <abstractions/base>
|
||||||
|
include <abstractions/nameservice>
|
||||||
|
include <abstractions/ssl_certs>
|
||||||
|
include "${pkgs.apparmorRulesFromClosure { name = "miniflux"; } cfg.package}"
|
||||||
|
r ${cfg.package}/bin/miniflux,
|
||||||
|
r @{sys}/kernel/mm/transparent_hugepage/hpage_pmd_size,
|
||||||
|
rw /run/miniflux/**,
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
|
@ -11,7 +11,6 @@ let
|
||||||
mkMerge
|
mkMerge
|
||||||
types
|
types
|
||||||
;
|
;
|
||||||
inherit (config.my-lib.settings) ntfyUrl;
|
|
||||||
cfg = config.custom.prometheus;
|
cfg = config.custom.prometheus;
|
||||||
|
|
||||||
mkRulesOption = mkOption {
|
mkRulesOption = mkOption {
|
||||||
|
@ -57,13 +56,6 @@ in
|
||||||
default = "${config.networking.hostName}.coho-tet.ts.net";
|
default = "${config.networking.hostName}.coho-tet.ts.net";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
v2ray = {
|
|
||||||
enable = mkEnableOption "blackbox exporter";
|
|
||||||
listenAddress = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "${config.networking.hostName}.coho-tet.ts.net";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -89,9 +81,19 @@ in
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
(mkIf cfg.enable {
|
(mkIf cfg.enable {
|
||||||
services.caddy.virtualHosts."${config.networking.hostName}.coho-tet.ts.net".extraConfig = ''
|
|
||||||
reverse_proxy 127.0.0.1:${toString config.services.prometheus.port}
|
services.tailscale = {
|
||||||
'';
|
enable = true;
|
||||||
|
permitCertUid = config.services.caddy.user;
|
||||||
|
openFirewall = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.caddy = {
|
||||||
|
enable = true;
|
||||||
|
virtualHosts."${config.networking.hostName}.coho-tet.ts.net".extraConfig = ''
|
||||||
|
reverse_proxy 127.0.0.1:${toString config.services.prometheus.port}
|
||||||
|
'';
|
||||||
|
};
|
||||||
services.prometheus = mkIf cfg.enable {
|
services.prometheus = mkIf cfg.enable {
|
||||||
enable = true;
|
enable = true;
|
||||||
port = 9091;
|
port = 9091;
|
||||||
|
@ -119,11 +121,12 @@ in
|
||||||
name = "ntfy";
|
name = "ntfy";
|
||||||
webhook_configs = [
|
webhook_configs = [
|
||||||
{
|
{
|
||||||
url = "${ntfyUrl}/prometheus-alerts?tpl=yes&m=${lib.escapeURL ''
|
url = "https://ntfy.xinyang.life/prometheus-alerts?tpl=yes&m=${lib.escapeURL ''
|
||||||
{{range .alerts}}[{{ if eq .status "resolved" }}✅ RESOLVED{{ else }}{{ if eq .status "firing" }}🔥 FIRING{{end}}{{end}}]{{range $k,$v := .labels}}
|
Alert {{.status}}
|
||||||
|
{{range .alerts}}-----{{range $k,$v := .labels}}
|
||||||
{{$k}}={{$v}}{{end}}
|
{{$k}}={{$v}}{{end}}
|
||||||
|
{{end}}
|
||||||
{{end}}''}";
|
''}";
|
||||||
send_resolved = true;
|
send_resolved = true;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
|
@ -5,8 +5,7 @@
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
inherit (lib) mkIf concatStringsSep;
|
inherit (lib) mkIf;
|
||||||
inherit (config.my-lib.settings) prometheusCollectors;
|
|
||||||
cfg = config.custom.prometheus.exporters;
|
cfg = config.custom.prometheus.exporters;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
@ -47,13 +46,6 @@ in
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
services.prometheus.exporters.v2ray = mkIf cfg.v2ray.enable {
|
|
||||||
enable = true;
|
|
||||||
listenAddress = cfg.v2ray.listenAddress;
|
|
||||||
port = 9516;
|
|
||||||
v2rayEndpoint = config.services.sing-box.settings.experimental.v2ray_api.listen;
|
|
||||||
};
|
|
||||||
|
|
||||||
# gotosocial
|
# gotosocial
|
||||||
sops.templates."gotosocial_metrics.env" = {
|
sops.templates."gotosocial_metrics.env" = {
|
||||||
content = ''
|
content = ''
|
||||||
|
@ -79,7 +71,7 @@ in
|
||||||
|
|
||||||
services.restic.server.prometheus = true;
|
services.restic.server.prometheus = true;
|
||||||
|
|
||||||
# miniflux
|
# miniflux
|
||||||
sops.templates."miniflux_metrics_env" = {
|
sops.templates."miniflux_metrics_env" = {
|
||||||
content = ''
|
content = ''
|
||||||
METRICS_COLLECTOR=1
|
METRICS_COLLECTOR=1
|
||||||
|
@ -103,28 +95,8 @@ in
|
||||||
metrics
|
metrics
|
||||||
}
|
}
|
||||||
|
|
||||||
admin unix//var/run/caddy/admin.sock {
|
admin ${config.networking.hostName}.coho-tet.ts.net:2019 {
|
||||||
origins 127.0.0.1 ${config.networking.hostName}.coho-tet.ts.net:2019
|
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
systemd.services.caddy.serviceConfig = {
|
|
||||||
RuntimeDirectory = "caddy";
|
|
||||||
RuntimeDirectoryMode = "0700";
|
|
||||||
};
|
|
||||||
|
|
||||||
services.tailscale = {
|
|
||||||
permitCertUid = config.services.caddy.user;
|
|
||||||
openFirewall = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.caddy = {
|
|
||||||
virtualHosts."https://${config.networking.hostName}.coho-tet.ts.net:2019".extraConfig = ''
|
|
||||||
handle /metrics {
|
|
||||||
reverse_proxy unix//var/run/caddy/admin.sock
|
|
||||||
}
|
|
||||||
respond 403
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
let
|
let
|
||||||
inherit (config.my-lib.settings) grafanaUrl idpUrl;
|
|
||||||
cfg = config.custom.monitoring.grafana;
|
cfg = config.custom.monitoring.grafana;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
@ -14,17 +13,17 @@ in
|
||||||
server = {
|
server = {
|
||||||
http_addr = "127.0.0.1";
|
http_addr = "127.0.0.1";
|
||||||
http_port = 3003;
|
http_port = 3003;
|
||||||
root_url = grafanaUrl;
|
root_url = "https://grafana.xinyang.life";
|
||||||
domain = lib.removePrefix "https://" grafanaUrl;
|
domain = "grafana.xinyang.life";
|
||||||
};
|
};
|
||||||
"auth.generic_oauth" = {
|
"auth.generic_oauth" = {
|
||||||
enabled = true;
|
enabled = true;
|
||||||
name = "Kanidm";
|
name = "Kanidm";
|
||||||
client_id = "grafana";
|
client_id = "grafana";
|
||||||
scopes = "openid,profile,email,groups";
|
scopes = "openid,profile,email,groups";
|
||||||
auth_url = "${idpUrl}/ui/oauth2";
|
auth_url = "https://auth.xinyang.life/ui/oauth2";
|
||||||
token_url = "${idpUrl}/oauth2/token";
|
token_url = "https://auth.xinyang.life/oauth2/token";
|
||||||
api_url = "${idpUrl}/oauth2/openid/grafana/userinfo";
|
api_url = "https://auth.xinyang.life/oauth2/openid/grafana/userinfo";
|
||||||
use_pkce = true;
|
use_pkce = true;
|
||||||
use_refresh_token = true;
|
use_refresh_token = true;
|
||||||
allow_sign_up = true;
|
allow_sign_up = true;
|
||||||
|
|
|
@ -1,159 +1,68 @@
|
||||||
{
|
{
|
||||||
pkgs,
|
|
||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
inherit (lib)
|
inherit (lib)
|
||||||
mkOption
|
|
||||||
mkEnableOption
|
mkEnableOption
|
||||||
mkIf
|
mkIf
|
||||||
mkMerge
|
mkMerge
|
||||||
types
|
|
||||||
literalExpression
|
|
||||||
;
|
|
||||||
inherit (config.my-lib.settings)
|
|
||||||
alertmanagerPort
|
|
||||||
;
|
;
|
||||||
cfg = config.custom.monitoring;
|
cfg = config.custom.monitoring;
|
||||||
lokiPort = 3100;
|
port-loki = 3100;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options = {
|
options = {
|
||||||
custom.monitoring = {
|
custom.monitoring = {
|
||||||
loki = {
|
loki.enable = mkEnableOption "loki";
|
||||||
enable = mkEnableOption "loki";
|
|
||||||
rules = mkOption {
|
|
||||||
type = types.attrsOf (
|
|
||||||
types.submodule {
|
|
||||||
options = {
|
|
||||||
expr = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = ''
|
|
||||||
Loki alert expression.
|
|
||||||
'';
|
|
||||||
example = ''count_over_time({job=~"secure"} |="sshd[" |~": Failed|: Invalid|: Connection closed by authenticating user" | __error__="" [15m]) > 15'';
|
|
||||||
default = null;
|
|
||||||
};
|
|
||||||
description = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = ''
|
|
||||||
Loki alert message.
|
|
||||||
'';
|
|
||||||
example = "Prometheus encountered value {{ $value }} with {{ $labels }}";
|
|
||||||
default = null;
|
|
||||||
};
|
|
||||||
labels = mkOption {
|
|
||||||
type = types.nullOr (types.attrsOf types.str);
|
|
||||||
description = ''
|
|
||||||
Additional alert labels.
|
|
||||||
'';
|
|
||||||
example = literalExpression ''
|
|
||||||
{ severity = "page" };
|
|
||||||
'';
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
time = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = ''
|
|
||||||
Time until the alert is fired.
|
|
||||||
'';
|
|
||||||
example = "5m";
|
|
||||||
default = "2m";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
description = ''
|
|
||||||
Defines the loki rules.
|
|
||||||
'';
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
promtail.enable = mkEnableOption "promtail";
|
promtail.enable = mkEnableOption "promtail";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkMerge [
|
config = mkMerge [
|
||||||
(
|
(mkIf cfg.loki.enable {
|
||||||
let
|
services.loki = {
|
||||||
rulerConfig = {
|
enable = true;
|
||||||
groups = [
|
configuration = {
|
||||||
|
auth_enabled = false;
|
||||||
|
server.http_listen_address = "${config.networking.hostName}.coho-tet.ts.net";
|
||||||
|
server.http_listen_port = port-loki;
|
||||||
|
|
||||||
|
common = {
|
||||||
|
ring = {
|
||||||
|
instance_addr = "${config.networking.hostName}.coho-tet.ts.net";
|
||||||
|
kvstore.store = "inmemory";
|
||||||
|
};
|
||||||
|
replication_factor = 1;
|
||||||
|
path_prefix = "/var/lib/loki";
|
||||||
|
};
|
||||||
|
|
||||||
|
schema_config.configs = [
|
||||||
{
|
{
|
||||||
name = "alerting-rules";
|
from = "2024-12-01";
|
||||||
rules = lib.mapAttrsToList (name: opts: {
|
store = "boltdb-shipper";
|
||||||
alert = name;
|
object_store = "filesystem";
|
||||||
inherit (opts) expr labels;
|
schema = "v13";
|
||||||
for = opts.time;
|
index = {
|
||||||
annotations.description = opts.description;
|
prefix = "index_";
|
||||||
}) cfg.loki.rules;
|
period = "24h";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
|
||||||
rulerFile = pkgs.writeText "ruler.yml" (builtins.toJSON rulerConfig);
|
|
||||||
in
|
|
||||||
mkIf cfg.loki.enable {
|
|
||||||
services.loki = {
|
|
||||||
enable = true;
|
|
||||||
configuration = {
|
|
||||||
auth_enabled = false;
|
|
||||||
server.http_listen_address = "${config.networking.hostName}.coho-tet.ts.net";
|
|
||||||
server.http_listen_port = lokiPort;
|
|
||||||
|
|
||||||
common = {
|
storage_config = {
|
||||||
ring = {
|
filesystem.directory = "/var/lib/loki/chunks";
|
||||||
instance_addr = "${config.networking.hostName}.coho-tet.ts.net";
|
};
|
||||||
kvstore.store = "inmemory";
|
|
||||||
};
|
|
||||||
replication_factor = 1;
|
|
||||||
path_prefix = "/var/lib/loki";
|
|
||||||
};
|
|
||||||
|
|
||||||
schema_config.configs = [
|
limits_config = {
|
||||||
{
|
reject_old_samples = true;
|
||||||
from = "2024-12-01";
|
reject_old_samples_max_age = "168h";
|
||||||
store = "boltdb-shipper";
|
allow_structured_metadata = false;
|
||||||
object_store = "filesystem";
|
|
||||||
schema = "v13";
|
|
||||||
index = {
|
|
||||||
prefix = "index_";
|
|
||||||
period = "24h";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
storage_config = {
|
|
||||||
filesystem.directory = "/var/lib/loki/chunks";
|
|
||||||
};
|
|
||||||
|
|
||||||
limits_config = {
|
|
||||||
reject_old_samples = true;
|
|
||||||
reject_old_samples_max_age = "168h";
|
|
||||||
allow_structured_metadata = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
ruler = {
|
|
||||||
storage = {
|
|
||||||
type = "local";
|
|
||||||
local.directory = "${config.services.loki.dataDir}/rules";
|
|
||||||
};
|
|
||||||
rule_path = "${config.services.loki.dataDir}/rules-temp";
|
|
||||||
enable_api = true;
|
|
||||||
alertmanager_url = "http://127.0.0.1:${toString alertmanagerPort}";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
systemd.tmpfiles.rules = [
|
};
|
||||||
"d /var/lib/loki 0700 loki loki - -"
|
})
|
||||||
"d /var/lib/loki/rules-temp 0700 loki loki - -"
|
|
||||||
"d /var/lib/loki/rules 0700 loki loki - -"
|
|
||||||
"d /var/lib/loki/rules/fake 0700 loki loki - -"
|
|
||||||
"L /var/lib/loki/rules/fake/ruler.yml - - - - ${rulerFile}"
|
|
||||||
];
|
|
||||||
systemd.services.loki.restartTriggers = [ rulerFile ];
|
|
||||||
}
|
|
||||||
)
|
|
||||||
(mkIf cfg.promtail.enable {
|
(mkIf cfg.promtail.enable {
|
||||||
services.promtail = {
|
services.promtail = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@ -169,7 +78,7 @@ in
|
||||||
|
|
||||||
clients = [
|
clients = [
|
||||||
{
|
{
|
||||||
url = "http://thorite.coho-tet.ts.net:${toString lokiPort}/loki/api/v1/push";
|
url = "http://thorite.coho-tet.ts.net:${toString port-loki}/loki/api/v1/push";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -241,42 +150,17 @@ in
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
# {
|
# {
|
||||||
# job_name = "caddy";
|
# job_name = "caddy-access";
|
||||||
# static_configs = [
|
# file_sd_configs = {
|
||||||
# {
|
# files = [
|
||||||
# targets = [ "localhost" ];
|
# "/var/log/caddy/*.log"
|
||||||
# labels = {
|
# ];
|
||||||
# job = "caddy";
|
# refresh_interval = "5m";
|
||||||
# __path__ = "/var/log/caddy/*log";
|
# };
|
||||||
# agent = "caddy-promtail";
|
|
||||||
# };
|
|
||||||
# }
|
|
||||||
# ];
|
|
||||||
# pipeline_stages = [
|
|
||||||
# {
|
|
||||||
# json = {
|
|
||||||
# expressions = {
|
|
||||||
# duration = "duration";
|
|
||||||
# status = "status";
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
# }
|
|
||||||
# {
|
|
||||||
# labels = {
|
|
||||||
# duration = null;
|
|
||||||
# status = null;
|
|
||||||
# };
|
|
||||||
# }
|
|
||||||
# ];
|
|
||||||
# }
|
# }
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.caddy.logFormat = ''
|
|
||||||
format json
|
|
||||||
level INFO
|
|
||||||
'';
|
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ let
|
||||||
echo "Creating snapshot for ${rootDir}"
|
echo "Creating snapshot for ${rootDir}"
|
||||||
subvolumes=$(${pkgs.btrfs-progs}/bin/btrfs subvolume list -o "${rootDir}" | ${awk} '{print $NF}')
|
subvolumes=$(${pkgs.btrfs-progs}/bin/btrfs subvolume list -o "${rootDir}" | ${awk} '{print $NF}')
|
||||||
mkdir -p "${backupDir}"
|
mkdir -p "${backupDir}"
|
||||||
${pkgs.btrfs-progs}/bin/btrfs subvolume snapshot -r "${rootDir}" "${backupDir}/rootDirectory"
|
${pkgs.btrfs-progs}/bin/btrfs subvolume snapshot -r "${rootDir}" "${backupDir}/rootfs"
|
||||||
for subvol in $subvolumes; do
|
for subvol in $subvolumes; do
|
||||||
${continueIfInExclude}
|
${continueIfInExclude}
|
||||||
[[ /"$subvol" == "${backupDir}"* ]] && continue
|
[[ /"$subvol" == "${backupDir}"* ]] && continue
|
||||||
|
|
87
modules/nixos/sing-box.nix
Normal file
87
modules/nixos/sing-box.nix
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
utils,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
cfg = config.custom.sing-box;
|
||||||
|
settingsFormat = pkgs.formats.json { };
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
custom.sing-box = {
|
||||||
|
enable = lib.mkEnableOption "sing-box";
|
||||||
|
|
||||||
|
package = lib.mkPackageOption pkgs "sing-box" { };
|
||||||
|
|
||||||
|
stateDir = lib.mkOption {
|
||||||
|
type = lib.types.path;
|
||||||
|
default = "/var/lib/sing-box";
|
||||||
|
};
|
||||||
|
|
||||||
|
configFile = {
|
||||||
|
urlFile = lib.mkOption { type = lib.types.path; };
|
||||||
|
name = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "config.json";
|
||||||
|
};
|
||||||
|
hash = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
example = "9a304bcb87d4c3f1e50f6281f25dd78635255ebde06cd4d2555729ecda43aed4";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
overrideSettings = lib.mkOption {
|
||||||
|
type = lib.types.submodule {
|
||||||
|
freeformType = settingsFormat.type;
|
||||||
|
options = {
|
||||||
|
route = {
|
||||||
|
geoip.path = lib.mkOption {
|
||||||
|
type = lib.types.path;
|
||||||
|
default = "${pkgs.sing-geoip}/share/sing-box/geoip.db";
|
||||||
|
defaultText = lib.literalExpression "\${pkgs.sing-geoip}/share/sing-box/geoip.db";
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
The path to the sing-geoip database.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
geosite.path = lib.mkOption {
|
||||||
|
type = lib.types.path;
|
||||||
|
default = "${pkgs.sing-geosite}/share/sing-box/geosite.db";
|
||||||
|
defaultText = lib.literalExpression "\${pkgs.sing-geosite}/share/sing-box/geosite.db";
|
||||||
|
description = lib.mdDoc ''
|
||||||
|
The path to the sing-geosite database.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
networking.firewall.trustedInterfaces = [ "tun0" ];
|
||||||
|
|
||||||
|
systemd.packages = [ cfg.package ];
|
||||||
|
|
||||||
|
systemd.services.sing-box =
|
||||||
|
let
|
||||||
|
configFile = cfg.stateDir + "/${cfg.configFile.name}";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
preStart = ''
|
||||||
|
umask 0077
|
||||||
|
mkdir -p /etc/sing-box
|
||||||
|
if ! [ -e ${configFile} ]; then
|
||||||
|
${pkgs.curl}/bin/curl "$(${pkgs.coreutils}/bin/cat ${cfg.configFile.urlFile})" > '${configFile}'
|
||||||
|
test "${cfg.configFile.hash}" $(${pkgs.coreutils}/bin/sha256sum '${configFile}' | ${pkgs.coreutils}/bin/cut -d ' ' -f 1)
|
||||||
|
fi
|
||||||
|
${utils.genJqSecretsReplacementSnippet cfg.overrideSettings "/etc/sing-box/config.json"}
|
||||||
|
${cfg.package}/bin/sing-box merge -c '${configFile}' -c /etc/sing-box/config.json /etc/sing-box/config.json
|
||||||
|
'';
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
7
note.md
7
note.md
|
@ -1,10 +1,3 @@
|
||||||
# nix-tree
|
# nix-tree
|
||||||
|
|
||||||
Demonstrate disk usage by nix-store path.
|
Demonstrate disk usage by nix-store path.
|
||||||
|
|
||||||
## TODO
|
|
||||||
- [x] change caddy admin to unix socket
|
|
||||||
- [ ] admin config persist = false
|
|
||||||
- [x] synapse jmalloc
|
|
||||||
- [ ] backup all directories under /var/lib/forgejo
|
|
||||||
- [ ] collect caddy access logs with promtail (waiting for caddy v2.9.0 release after which log file mode can be set)
|
|
||||||
|
|
|
@ -1,11 +1,3 @@
|
||||||
{
|
{
|
||||||
mkSystemdDebug =
|
|
||||||
{ lib, pkgs }:
|
|
||||||
{
|
|
||||||
ExecStart = lib.mkForce "${pkgs.tmux}/bin/tmux -S /tmp/tmux.socket new-session -s my-session -d";
|
|
||||||
ExecStop = lib.mkForce "${pkgs.tmux}/bin/tmux -S /tmp/tmux.socket kill-session -t my-session";
|
|
||||||
Type = "forking";
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
// (import ./prometheus.nix)
|
// (import ./prometheus.nix)
|
||||||
// (import ./settings.nix)
|
|
||||||
|
|
|
@ -28,51 +28,17 @@ in
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
mkV2rayScrapes = targets: [
|
mkCaddyScrapes = mkFunction (
|
||||||
{
|
{
|
||||||
job_name = "v2ray-exporter";
|
address,
|
||||||
scheme = "http";
|
port ? 2019,
|
||||||
static_configs = map (
|
...
|
||||||
{
|
}:
|
||||||
address,
|
|
||||||
port ? 9516,
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
targets = [ "${address}${mkPort port}" ];
|
|
||||||
}
|
|
||||||
) targets;
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
job_name = "singbox_stat";
|
job_name = "caddy_${address}";
|
||||||
scheme = "http";
|
static_configs = [ { targets = [ "${address}${mkPort port}" ]; } ];
|
||||||
metrics_path = "/scrape";
|
|
||||||
static_configs = map (
|
|
||||||
{
|
|
||||||
address,
|
|
||||||
port ? 9516,
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
targets = [ "${address}${mkPort port}" ];
|
|
||||||
}
|
|
||||||
) targets;
|
|
||||||
}
|
}
|
||||||
];
|
);
|
||||||
|
|
||||||
mkCaddyScrapes = targets: [
|
|
||||||
{
|
|
||||||
job_name = "caddy";
|
|
||||||
scheme = "https";
|
|
||||||
static_configs = map (
|
|
||||||
{
|
|
||||||
address,
|
|
||||||
port ? 2019,
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
targets = [ "${address}${mkPort port}" ];
|
|
||||||
}
|
|
||||||
) targets;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
mkCaddyRules = mkFunction (
|
mkCaddyRules = mkFunction (
|
||||||
{
|
{
|
||||||
|
@ -97,20 +63,17 @@ in
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
mkNodeScrapes = targets: [
|
mkNodeScrapes = mkFunction (
|
||||||
{
|
{
|
||||||
job_name = "node_exporter";
|
address,
|
||||||
static_configs = map (
|
port ? 9100,
|
||||||
{
|
...
|
||||||
address,
|
}:
|
||||||
port ? 9100,
|
{
|
||||||
}:
|
job_name = "node_${address}";
|
||||||
{
|
static_configs = [ { targets = [ "${address}${mkPort port}" ]; } ];
|
||||||
targets = [ "${address}${mkPort port}" ];
|
|
||||||
}
|
|
||||||
) targets;
|
|
||||||
}
|
}
|
||||||
];
|
);
|
||||||
|
|
||||||
mkNodeRules = mkFunction (
|
mkNodeRules = mkFunction (
|
||||||
{
|
{
|
||||||
|
@ -146,9 +109,21 @@ in
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
alert = "NetworkTrafficExceedLimit";
|
alert = "HighTransmitTraffic";
|
||||||
expr = ''sum by(instance) (increase(node_network_transmit_bytes_total{device!="lo", device!~"tailscale.*", device!~"wg.*", device!~"br.*"}[30d])) > 322122547200'';
|
expr = "rate(node_network_transmit_bytes_total{device!=\"lo\"}[5m]) > 100000000";
|
||||||
for = "1m";
|
for = "1m";
|
||||||
|
labels = {
|
||||||
|
severity = "warning";
|
||||||
|
};
|
||||||
|
annotations = {
|
||||||
|
summary = "High network transmit traffic on {{ $labels.instance }} ({{ $labels.device }})";
|
||||||
|
description = "The network interface {{ $labels.device }} on {{ $labels.instance }} is transmitting data at a rate exceeding 100 MB/s for the last 1 minute.";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
alert = "NetworkTrafficExceedLimit";
|
||||||
|
expr = ''increase(node_network_transmit_bytes_total{device!="lo",device!~"tailscale.*",device!~"wg.*",device!~"br.*"}[30d]) > 322122547200'';
|
||||||
|
for = "0m";
|
||||||
labels = {
|
labels = {
|
||||||
severity = "critical";
|
severity = "critical";
|
||||||
};
|
};
|
||||||
|
@ -156,66 +131,6 @@ in
|
||||||
summary = "Outbound network traffic exceed 300GB for last 30 day";
|
summary = "Outbound network traffic exceed 300GB for last 30 day";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
{
|
|
||||||
alert = "HighDiskUsage";
|
|
||||||
expr = ''(1 - node_filesystem_free_bytes{fstype!~"vfat|ramfs"} / node_filesystem_size_bytes) * 100 > 85'';
|
|
||||||
for = "5m";
|
|
||||||
labels = {
|
|
||||||
severity = "warning";
|
|
||||||
};
|
|
||||||
annotations = {
|
|
||||||
summary = "High disk usage on {{ $labels.instance }}";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
alert = "DiskWillFull";
|
|
||||||
expr = ''predict_linear(node_filesystem_free_bytes{fstype!~"vfat|ramfs"}[1h], 12 * 3600) < (node_filesystem_size_bytes * 0.05)'';
|
|
||||||
|
|
||||||
for = "3m";
|
|
||||||
labels = {
|
|
||||||
severity = "critical";
|
|
||||||
};
|
|
||||||
annotations = {
|
|
||||||
summary = "Disk usage will exceed 95% in 12 hours on {{ $labels.instance }}";
|
|
||||||
description = "Disk {{ $labels.mountpoint }} is predicted to exceed 92% usage within 12 hours at current growth rate";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
alert = "HighSwapUsage";
|
|
||||||
expr = ''(1 - (node_memory_SwapFree_bytes / node_memory_SwapTotal_bytes)) * 100 > 80'';
|
|
||||||
for = "5m";
|
|
||||||
labels = {
|
|
||||||
severity = "warning";
|
|
||||||
};
|
|
||||||
annotations = {
|
|
||||||
summary = "High swap usage on {{ $labels.instance }}";
|
|
||||||
description = "Swap usage is above 80% for 5 minutes\n Current value: {{ $value }}%";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
alert = "OOMKillDetected";
|
|
||||||
expr = ''increase(node_vmstat_oom_kill[5m]) > 0'';
|
|
||||||
for = "1m";
|
|
||||||
labels = {
|
|
||||||
severity = "critical";
|
|
||||||
};
|
|
||||||
annotations = {
|
|
||||||
summary = "OOM kill detected on {{ $labels.instance }}";
|
|
||||||
description = "Out of memory killer was triggered in the last 5 minutes";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
alert = "HighMemoryUsage";
|
|
||||||
expr = ''(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 90'';
|
|
||||||
for = "5m";
|
|
||||||
labels = {
|
|
||||||
severity = "warning";
|
|
||||||
};
|
|
||||||
annotations = {
|
|
||||||
summary = "High memory usage on {{ $labels.instance }}";
|
|
||||||
description = "Memory usage is above 90% for 5 minutes\n Current value: {{ $value }}%";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -237,9 +152,6 @@ in
|
||||||
static_configs = [
|
static_configs = [
|
||||||
{
|
{
|
||||||
targets = targetAddresses;
|
targets = targetAddresses;
|
||||||
labels = {
|
|
||||||
from = hostAddress;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
relabel_configs = [
|
relabel_configs = [
|
||||||
|
@ -267,17 +179,6 @@ in
|
||||||
{
|
{
|
||||||
inherit name;
|
inherit name;
|
||||||
rules = [
|
rules = [
|
||||||
{
|
|
||||||
alert = "ProbeError";
|
|
||||||
expr = "probe_success != 1";
|
|
||||||
for = "3m";
|
|
||||||
labels = {
|
|
||||||
severity = "critical";
|
|
||||||
};
|
|
||||||
annotations = {
|
|
||||||
summary = "Probing {{ $labels.instance }} from {{ $labels.from }} failed";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
alert = "HighProbeLatency";
|
alert = "HighProbeLatency";
|
||||||
expr = "probe_duration_seconds > 0.5";
|
expr = "probe_duration_seconds > 0.5";
|
||||||
|
@ -286,25 +187,23 @@ in
|
||||||
severity = "warning";
|
severity = "warning";
|
||||||
};
|
};
|
||||||
annotations = {
|
annotations = {
|
||||||
summary = "High request latency from {{ $labels.from }} to {{ $labels.instance }}";
|
summary = "High request latency on {{ $labels.instance }}";
|
||||||
description = "Request latency is above 0.5 seconds for the last 2 minutes.";
|
description = "Request latency is above 0.5 seconds for the last 3 minutes.";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
alert = "VeryHighProbeLatency";
|
alert = "VeryHighProbeLatency";
|
||||||
expr = "probe_duration_seconds > 2";
|
expr = "probe_duration_seconds > 1";
|
||||||
for = "3m";
|
for = "3m";
|
||||||
labels = {
|
labels = {
|
||||||
severity = "critical";
|
severity = "critical";
|
||||||
};
|
};
|
||||||
annotations = {
|
annotations = {
|
||||||
summary = "Very high request latency from {{ $labels.from }} to {{ $labels.instance }}";
|
summary = "High request latency on {{ $labels.instance }}";
|
||||||
description = "Request latency is above 2 seconds for the last 2 minutes.";
|
description = "Request latency is above 0.5 seconds for the last 3 minutes.";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
# mkResticScrapes = mkFunction () ;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
{
|
|
||||||
settings = {
|
|
||||||
alertmanagerPort = 9093;
|
|
||||||
idpUrl = "https://auth.xinyang.life";
|
|
||||||
gotosocialUrl = "https://gts.xiny.li";
|
|
||||||
minifluxUrl = "https://rss.xiny.li";
|
|
||||||
hedgedocDomain = "docs.xiny.li";
|
|
||||||
forgejoDomain = "git.xiny.li";
|
|
||||||
forgejoGitDomain = "git.xiny.li";
|
|
||||||
vaultwardenUrl = "https://vaultwarden.xiny.li";
|
|
||||||
ntfyUrl = "https://ntfy.xiny.li";
|
|
||||||
grafanaUrl = "https://grafana.xiny.li";
|
|
||||||
synapseUrl = "https://xiny.li";
|
|
||||||
synapseDelegateUrl = "https://synapse.xiny.li";
|
|
||||||
|
|
||||||
prometheusCollectors = [
|
|
||||||
"thorite.coho-tet.ts.net"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
56
overlays/pkgs/oidc-agent/default.nix
Normal file
56
overlays/pkgs/oidc-agent/default.nix
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
stdenv,
|
||||||
|
fetchFromGitHub,
|
||||||
|
curl,
|
||||||
|
webkitgtk,
|
||||||
|
libmicrohttpd,
|
||||||
|
libsecret,
|
||||||
|
qrencode,
|
||||||
|
libsodium,
|
||||||
|
pkg-config,
|
||||||
|
help2man,
|
||||||
|
}:
|
||||||
|
|
||||||
|
stdenv.mkDerivation rec {
|
||||||
|
pname = "oidc-agent";
|
||||||
|
version = "5.1.0";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "indigo-dc";
|
||||||
|
repo = "oidc-agent";
|
||||||
|
rev = "v${version}";
|
||||||
|
sha256 = "sha256-cOK/rZ/jnyALLuhDM3+qvwwe4Fjkv8diQBkw7NfVo0c=";
|
||||||
|
};
|
||||||
|
|
||||||
|
buildInputs = [
|
||||||
|
pkg-config
|
||||||
|
help2man
|
||||||
|
];
|
||||||
|
nativeBuildInputs = [
|
||||||
|
curl
|
||||||
|
webkitgtk
|
||||||
|
libmicrohttpd
|
||||||
|
libsecret
|
||||||
|
qrencode
|
||||||
|
libsodium
|
||||||
|
];
|
||||||
|
enableParallelBuilding = true;
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
make -j $NIX_BUILD_CORES PREFIX=$out BIN_PATH=$out LIB_PATH=$out/lib \
|
||||||
|
install_bin install_lib install_conf
|
||||||
|
'';
|
||||||
|
postFixup = ''
|
||||||
|
# Override with patched binary to be used by help2man
|
||||||
|
cp -r $out/bin/* bin
|
||||||
|
make install_man PREFIX=$out
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "oidc-agent for managing OpenID Connect tokens on the command line";
|
||||||
|
homepage = "https://github.com/indigo-dc/oidc-agent";
|
||||||
|
maintainers = [ ];
|
||||||
|
license = licenses.mit;
|
||||||
|
};
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue