Compare commits

...
Sign in to create a new pull request.

62 commits

Author SHA1 Message Date
sid
0290c05845 Merge pull request 'zsh: add fr function' (#56) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 7s
Reviewed-on: #56
2026-05-31 21:05:20 +02:00
sid
eac3b0c3ea zsh: add fr function
All checks were successful
Build tests / build-hosts (pull_request) Successful in 27s
Flake check / flake-check (pull_request) Successful in 37s
2026-05-31 21:01:15 +02:00
sid
09ad548f97 Merge pull request 'develop' (#55) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 26s
Reviewed-on: #55
2026-05-31 20:34:50 +02:00
sid
cd7ea0fab9 docs: fix external links
All checks were successful
Build tests / build-hosts (pull_request) Successful in 24s
Flake check / flake-check (pull_request) Successful in 37s
2026-05-31 20:33:37 +02:00
sid
c8fdc514a7 docs: fix urls 2026-05-31 20:17:20 +02:00
sid
21f9d16df7 Merge pull request 'ci: run build-tests and deploy-docs on any release branch' (#54) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 6s
Reviewed-on: #54
2026-05-31 20:10:43 +02:00
sid
36d28a6a4b ci: run build-tests and deploy-docs on any release branch
All checks were successful
Build tests / build-hosts (pull_request) Successful in 24s
Flake check / flake-check (pull_request) Successful in 37s
2026-05-31 20:09:19 +02:00
sid
ea830ce9a8 Merge pull request 'yamllint: exclude stylix scheme files' (#53) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 6s
Reviewed-on: #53
2026-05-31 19:58:47 +02:00
sid
7224a47b04 yamllint: exclude stylix scheme files
All checks were successful
Build tests / build-hosts (pull_request) Successful in 24s
Flake check / flake-check (pull_request) Successful in 37s
2026-05-31 19:57:25 +02:00
sid
a9abe2dcde Merge pull request 'udpdate flake. update some pkgs' (#52) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 32s
Reviewed-on: #52
2026-05-31 19:10:18 +02:00
sid
c32466f078 fix arxiv overlay
All checks were successful
Flake check / flake-check (pull_request) Successful in 40s
Build tests / build-hosts (pull_request) Successful in 4m2s
2026-05-31 19:05:30 +02:00
sid
f546b9a865 lib: access util functions under lib.utils
Some checks failed
Flake check / flake-check (pull_request) Failing after 40s
Build tests / build-hosts (pull_request) Successful in 10m50s
2026-05-31 18:58:33 +02:00
sid
ecf5132cbb enforce new flake schema. formatting.
Some checks failed
Build tests / build-hosts (pull_request) Failing after 3s
Flake check / flake-check (pull_request) Failing after 13s
2026-05-31 18:50:41 +02:00
sid
4b0a90e00d fix arxiv-mcp-server sha
Some checks failed
Build tests / build-hosts (pull_request) Successful in 24s
Flake check / flake-check (pull_request) Failing after 29s
2026-05-27 19:47:33 +02:00
sid
998444f8f7 udpdate flake. update some pkgs
Some checks failed
Flake check / flake-check (pull_request) Failing after 1m2s
Build tests / build-hosts (pull_request) Successful in 2m3s
2026-05-27 19:26:41 +02:00
sid
1ab817090f Merge pull request 'librechat: add configFile option' (#50) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 5s
Reviewed-on: #50
2026-05-19 22:29:49 +02:00
sid
86afbb213c librechat: add configFile option
All checks were successful
Build tests / build-hosts (pull_request) Successful in 24s
Flake check / flake-check (pull_request) Successful in 24s
2026-05-19 22:23:23 +02:00
sid
b6546f3ab0 Merge pull request 'librechat: listen on 0.0.0.0' (#49) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 6s
Reviewed-on: #49
2026-05-19 21:25:47 +02:00
sid
0fc3d4da92 librechat: listen on 0.0.0.0
All checks were successful
Build tests / build-hosts (pull_request) Successful in 23s
Flake check / flake-check (pull_request) Successful in 24s
2026-05-19 21:25:29 +02:00
sid
a7daa3b9f3 Merge pull request 'librechat: add meilisearch' (#48) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 6s
Reviewed-on: #48
2026-05-19 20:54:21 +02:00
sid
dd7fea5711 librechat: new images api
All checks were successful
Build tests / build-hosts (pull_request) Successful in 24s
Flake check / flake-check (pull_request) Successful in 24s
2026-05-19 20:41:37 +02:00
sid
7613e6cb6b librechat: add meilisearch
All checks were successful
Build tests / build-hosts (pull_request) Successful in 24s
Flake check / flake-check (pull_request) Successful in 24s
2026-05-19 20:01:53 +02:00
sid
fe6b0d6c47 Merge pull request 'librechat: fix image ref' (#47) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 5s
Reviewed-on: #47
2026-05-19 19:32:26 +02:00
sid
fc83c6652d librechat: fix image ref
All checks were successful
Build tests / build-hosts (pull_request) Successful in 24s
Flake check / flake-check (pull_request) Successful in 25s
2026-05-19 19:31:30 +02:00
sid
da86a8eb57 Merge pull request 'add nerdlog package' (#46) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 6s
Reviewed-on: #46
2026-05-19 13:26:00 +02:00
sid
e8f2000053 add nerdlog package
All checks were successful
Build tests / build-hosts (pull_request) Successful in 25s
Flake check / flake-check (pull_request) Successful in 25s
2026-05-19 13:13:02 +02:00
sid
7d73c46b94 Merge pull request 'mcpo: fix port in ExecStart' (#45) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 5s
Reviewed-on: #45
2026-05-18 18:45:23 +02:00
sid
179a02731b mcpo: fix port in ExecStart
All checks were successful
Build tests / build-hosts (pull_request) Successful in 23s
Flake check / flake-check (pull_request) Successful in 23s
2026-05-18 18:44:30 +02:00
sid
8967439585 Merge pull request 'librechat-oci' (#44) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 5s
Reviewed-on: #44
2026-05-18 18:41:52 +02:00
sid
2323c97d89 mcpo: add port option
All checks were successful
Build tests / build-hosts (pull_request) Successful in 23s
Flake check / flake-check (pull_request) Successful in 23s
2026-05-18 18:41:07 +02:00
sid
529ca4d572 Merge pull request 'librechat-oci: nixos module and test' (#41) from feature/librechat-oci into develop
All checks were successful
Build tests / build-hosts (pull_request) Successful in 23s
Flake check / flake-check (pull_request) Successful in 23s
Reviewed-on: #41
2026-05-18 17:16:49 +02:00
sid
5e963c26ec Merge pull request 'bitwarden' (#43) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 19s
Reviewed-on: #43
2026-05-18 16:39:54 +02:00
sid
fff1263c85 add bitwarden app to hyprland
All checks were successful
Build tests / build-hosts (pull_request) Successful in 2m0s
Flake check / flake-check (pull_request) Successful in 2m47s
2026-05-18 16:33:15 +02:00
sid
49c93c82e0 fix pass2bw 2026-05-18 16:08:01 +02:00
sid
fd68579042 pass2bw: fix PATH 2026-05-18 13:36:52 +02:00
sid
b3fda57098 Merge pull request 'rebuild no longer produces result symlinks' (#42) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 6s
Reviewed-on: #42
2026-05-13 13:45:36 +02:00
sid
dad762369c rebuild no longer produces result symlinks
All checks were successful
Flake check / flake-check (pull_request) Successful in 1m37s
Build tests / build-hosts (pull_request) Successful in 2m5s
2026-05-13 13:44:09 +02:00
sid
d953dd7f8a Merge pull request 'develop' (#40) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 17s
Reviewed-on: #40
2026-05-10 23:39:18 +02:00
sid
93cadc467a Merge pull request 'rebuild: rm dix and nom. add env var support' (#39) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 5s
Reviewed-on: #39
2026-05-10 16:37:00 +02:00
sid
b9736a5f50 Merge pull request 'fix CVE-2026-43500' (#38) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 5s
Reviewed-on: #38
2026-05-09 09:02:10 +02:00
sid
a43fa6440b Merge pull request 'stm32: fix template dir' (#37) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 20s
Reviewed-on: #37
2026-05-07 22:37:41 +02:00
sid
d31510c64c Merge pull request 'add stm32 dev template' (#36) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 5s
Reviewed-on: #36
2026-05-07 18:59:06 +02:00
sid
f7a032864c Merge pull request 'add package for openmv-ide' (#35) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 5s
Reviewed-on: #35
2026-05-07 11:10:08 +02:00
sid
8ad8b1f633 Merge pull request 'remove mkVirtualHost from rss-bridge' (#34) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 6s
Reviewed-on: #34
2026-05-05 23:25:48 +02:00
sid
15cbf5d4ff Merge pull request 'nixvim: add diffview, gitsigns, which-key. re-enable treesitter. document some keymaps' (#33) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 6s
Reviewed-on: #33
2026-05-05 21:18:20 +02:00
sid
4683cb1136 Merge pull request 'update flake. update some package versions' (#32) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 27s
Reviewed-on: #32
2026-05-04 17:43:44 +02:00
sid
5f6ad9ecf5 Merge pull request 'fix CVE-2026-31431' (#31) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 5s
Reviewed-on: #31
2026-05-02 23:11:14 +02:00
sid
e76a05b512 Merge pull request 'add jirafeau-cli' (#30) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 5s
Reviewed-on: #30
2026-05-02 22:15:23 +02:00
sid
a0a39253f4 Merge pull request 'nixvim: fix spellfiles' (#29) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 42s
Reviewed-on: #29
2026-05-02 21:31:03 +02:00
sid
a42c91f99e Merge pull request 'develop' (#28) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 6s
Reviewed-on: #28
2026-05-02 20:42:50 +02:00
sid
5aebc805a6 Merge pull request 'remove tailcsale docs' (#27) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 6s
Reviewed-on: #27
2026-05-02 19:15:25 +02:00
sid
e801c318a7 Merge pull request 'tailscale: add support for multiple tailnets' (#26) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 11s
Reviewed-on: #26
2026-05-02 19:01:43 +02:00
sid
c114c6da0a Merge pull request 'develop' (#20) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 11s
Reviewed-on: #20
2026-04-23 22:17:57 +02:00
sid
0c13e9dabd Merge pull request 'update flake. update pkgs. new hp api' (#18) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 30s
Reviewed-on: #18
2026-04-15 22:28:56 +02:00
sid
cff8f40bb0 Merge pull request 'stylix: use image to generate color scheme with scheme = 'generate-from-image'' (#17) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 20s
Reviewed-on: #17
2026-04-03 17:36:34 +02:00
sid
7a3ecf1545 Merge pull request 'develop' (#16) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 5s
Reviewed-on: #16
2026-04-03 16:46:17 +02:00
sid
7e5a951877 Merge pull request 'develop' (#15) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 6s
Reviewed-on: #15
2026-03-30 22:12:04 +02:00
sid
d093bc3dc6 Merge pull request 'develop' (#5) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 19s
Reviewed-on: #5
2026-03-07 14:10:10 +01:00
sid
aa1d2bbe48 Merge pull request 'develop' (#4) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 19s
Reviewed-on: #4
2026-03-07 07:57:51 +01:00
sid
31f195ff89 Merge pull request 'open-webui-oci: replace version with image option' (#3) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 5s
Reviewed-on: #3
2026-03-01 16:14:41 +01:00
sid
aea241d610 Merge pull request 'open-webui: removed network service. add version option' (#2) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 5s
Reviewed-on: #2
2026-02-27 22:12:38 +01:00
sid
a5e0b2b117 Merge pull request 'flake update' (#1) from develop into release-25.11
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 27s
Reviewed-on: #1
2026-02-26 23:15:56 +01:00
171 changed files with 2024 additions and 1679 deletions

1
.envrc
View file

@ -1 +1,2 @@
# shellcheck shell=bash
use flake use flake

View file

@ -1,9 +1,10 @@
---
name: Build tests name: Build tests
on: on:
pull_request: pull_request:
branches: branches:
- release-25.11 - release-*
jobs: jobs:
build-hosts: build-hosts:

View file

@ -1,3 +1,4 @@
---
name: Deploy docs name: Deploy docs
on: on:
@ -18,5 +19,8 @@ jobs:
STORE_PATH=$(nix build .#synix-docs --print-out-paths --no-link) STORE_PATH=$(nix build .#synix-docs --print-out-paths --no-link)
echo "STORE_PATH=$STORE_PATH" >> $GITHUB_ENV echo "STORE_PATH=$STORE_PATH" >> $GITHUB_ENV
- name: Check external links
run: nix run nixpkgs#lychee -- --exclude-loopback docs/
- name: Update symlink - name: Update symlink
run: ln -sfn ${{ env.STORE_PATH }} /var/www/doc run: ln -sfn ${{ env.STORE_PATH }} /var/www/doc

View file

@ -1,6 +1,8 @@
---
name: Flake check name: Flake check
on: [pull_request] on:
pull_request:
jobs: jobs:
flake-check: flake-check:
@ -11,5 +13,8 @@ jobs:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Check formatting
run: nix fmt -- --check
- name: Run flake check - name: Run flake check
run: nix flake check --impure run: nix flake check --impure --all-systems

View file

@ -11,9 +11,6 @@ HOSTNAME=""
# Templates with Home Manager configurations # Templates with Home Manager configurations
HM_CONFIGS=("hyprland") HM_CONFIGS=("hyprland")
# This will get overwritten by the derivation
TEMPLATES_DIR=""
# Print usage information # Print usage information
usage() { usage() {
cat <<EOF cat <<EOF

View file

@ -1,3 +1,4 @@
#!/usr/bin/env bash
# NixOS and standalone Home Manager rebuild script # NixOS and standalone Home Manager rebuild script
# Defaults # Defaults
@ -60,7 +61,7 @@ Rebuild_nixos() {
[[ -n "$TARGET_HOST" || -n "$BUILD_HOST" ]] && CMD+=("--ask-sudo-password") [[ -n "$TARGET_HOST" || -n "$BUILD_HOST" ]] && CMD+=("--ask-sudo-password")
# Build config first so we can diff it # Build config first so we can diff it
local BUILD_CMD=("nixos-rebuild" "build" "--flake" "$FLAKE") local BUILD_CMD=("nixos-rebuild" "build" "--no-build-output" "--flake" "$FLAKE")
[ "$SHOW_TRACE" = 1 ] && BUILD_CMD+=("--show-trace") [ "$SHOW_TRACE" = 1 ] && BUILD_CMD+=("--show-trace")
[ -n "$BUILD_HOST" ] && BUILD_CMD+=("--build-host" "$BUILD_HOST") [ -n "$BUILD_HOST" ] && BUILD_CMD+=("--build-host" "$BUILD_HOST")
@ -101,7 +102,7 @@ Rebuild_home() {
# Build config first so we can diff it # Build config first so we can diff it
if [ "$ROLLBACK" = 0 ]; then if [ "$ROLLBACK" = 0 ]; then
local BUILD_CMD=("home-manager" "build" "--flake" "$FLAKE") local BUILD_CMD=("home-manager" "build" "--no-out-link" "--flake" "$FLAKE")
[ "$SHOW_TRACE" = 1 ] && BUILD_CMD+=("--show-trace") [ "$SHOW_TRACE" = 1 ] && BUILD_CMD+=("--show-trace")
_status "Building Home Manager configuration '$FLAKE'..." _status "Building Home Manager configuration '$FLAKE'..."
_status "Executing command: ${BUILD_CMD[*]}" _status "Executing command: ${BUILD_CMD[*]}"

View file

@ -1,3 +1,4 @@
#!/usr/bin/env bash
SYSTEM="x86_64-linux" SYSTEM="x86_64-linux"
IGNORE_PACKAGES=( IGNORE_PACKAGES=(
"pyman" "pyman"

View file

@ -1,6 +1,6 @@
# Add NixOS and Home Manager configurations # Add NixOS and Home Manager configurations
Choose a configuration template from [this list](https://git.sid.ovh/sid/synix/tree/master/apps/create/templates). Choose a configuration template from [this list](https://git.sid.ovh/sid/synix/src/branch/release-25.11/templates/nix-configs).
Run the `create` script to add your desired configuration template to your nix-config flake: Run the `create` script to add your desired configuration template to your nix-config flake:
@ -14,7 +14,7 @@ nix --experimental-features "nix-command flakes" run git+https://git.sid.ovh/sid
-f ~/.config/nixos -f ~/.config/nixos
``` ```
> Change the architecture if needed. Supported architectures are listet under `supportedSystems` inside [`flake.nix`](https://git.sid.ovh/sid/synix/blob/master/flake.nix). > Change the architecture if needed. Supported architectures are listet under `supportedSystems` inside [`flake.nix`](https://git.sid.ovh/sid/synix/src/branch/release-25.11/flake.nix).
See the script's help page for reference: See the script's help page for reference:

View file

@ -1,6 +1,6 @@
# Create your own nix-config flake # Create your own nix-config flake
Create an empty directory and apply a [nix-config template](https://git.sid.ovh/sid/synix/tree/master/templates/nix-config) to it: Create an empty directory and apply a [nix-config template](https://git.sid.ovh/sid/synix/src/branch/release-25.11/templates/nix-configs) to it:
```bash ```bash
mkdir -p ~/.config/nixos mkdir -p ~/.config/nixos

View file

@ -1,6 +1,6 @@
# Installation Guide # Installation Guide
This guide will walk you through installing NixOS using the provided installation script [`install.sh`](https://git.sid.ovh/sid/synix/blob/master/apps/install/install.sh). This guide will walk you through installing NixOS using the provided installation script [`install.sh`](https://git.sid.ovh/sid/synix/src/branch/release-25.11/apps/install/install.sh).
## Prerequisites ## Prerequisites
@ -114,7 +114,8 @@ git clone YOUR_GIT_REPO_URL ~/.config/nixos
Home Manager is not installed by default. Enter the development shell to apply the configuration: Home Manager is not installed by default. Enter the development shell to apply the configuration:
```bash ```bash
nix-shell ~/.config/nixos/shell.nix --run 'rebuild home' nix --experimental-features "nix-command flakes" develop git+https://git.sid.ovh/sid/synix#devShells.x86_64-linux.install-hm \
--command "rebuild home"
``` ```
### 8. Reboot your System ### 8. Reboot your System

View file

@ -2,7 +2,7 @@
`bemenu` is a dynamic menu library and client program inspired by dmenu. `bemenu` is a dynamic menu library and client program inspired by dmenu.
View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/home/bemenu). View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/home/bemenu).
If you use this repository's [Hyprland module](./hyprland.md), it is enabled by default. If you use this repository's [Hyprland module](./hyprland.md), it is enabled by default.
## References ## References

View file

@ -2,7 +2,7 @@
The common module sets some opinionated defaults. The common module sets some opinionated defaults.
View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/home/common). View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/home/common).
It is recommended to import it in your Home Manager configuration as some synix modules may depend on it: It is recommended to import it in your Home Manager configuration as some synix modules may depend on it:

View file

@ -1,65 +0,0 @@
# Gemini CLI
An open-source AI agent that brings the power of Gemini directly into your terminal.
View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/home/gemini-cli).
## References
- [GitHub](https://github.com/google-gemini/gemini-cli)
- [CLI Docs](https://github.com/google-gemini/gemini-cli/tree/main/docs/cli)
## Setup
The package must be set by you. Easiest option is to use the synix overlay:
```nix
{ inputs, pkgs, ... }:
{
imports = [
inputs.synix.homeModules.gemini-cli
];
programs.gemini-cli = {
enable = true;
package = pkgs.synix.gemini-cli;
};
}
```
Gemini CLI reads environment variables, such as your API key, from `~/.gemini/.env`. You can manage it with sops-nix:
```nix
{ config, ... }:
{
sops.secrets.gemini-api-key = { };
sops.templates.gemini-cli-env = {
content = ''
GEMINI_API_KEY=${config.sops.placeholder.gemini-api-key}
'';
path = config.home.homeDirectory + "/.gemini/.env";
};
}
```
Set `gemini-api-key` in your `secrets.yaml`:
> Replace `abc123` with your Gemini API key.
```yaml
gemini-api-key: abc123
```
## Troubleshooting
These are some common warnings and errors you might encounter when using Gemini CLI:
### Error saving user settings file
```
Error saving user settings file: Error: EROFS: read-only file system, open '/home/you/.gemini/settings.json'
```
This is intended behavior.

View file

@ -2,7 +2,7 @@
This module sets some defaults for gpg, mainly to let your gpg-agent handle ssh keys. This module sets some defaults for gpg, mainly to let your gpg-agent handle ssh keys.
View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/home/gpg). View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/home/gpg).
## SSH Setup ## SSH Setup

View file

@ -6,17 +6,17 @@ This module extends the options of and sets some defaults for [Hyprland](https:/
- XDG mime support and user directories - XDG mime support and user directories
- enable Waybar as status bar - enable Waybar as status bar
- enable dunst as notification service - enable dunst as notification service
- some [packages](https://git.sid.ovh/sid/synix/blob/master/modules/home/hyprland/packages.nix) - some [packages](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/home/hyprland/packages.nix)
- [keybindings](https://git.sid.ovh/sid/synix/blob/master/modules/home/hyprland/binds/default.nix) - [keybindings](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/home/hyprland/binds/default.nix)
- manage default applications via the new `applications` option - manage default applications via the new `applications` option
> Always import both NixOS and Home Manager modules from `synix` when using Hyprland. > Always import both NixOS and Home Manager modules from `synix` when using Hyprland.
View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/home/hyprland). View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/home/hyprland).
## Keybindings ## Keybindings
The ["Master Layout"](https://wiki.hyprland.org/Configuring/Master-Layout/) is the only supported window layout. The ["Master Layout"](https://wiki.hypr.land/Configuring/Layouts/Master-Layout/) is the only supported window layout.
> `$mod`, `modifier` or `SUPER` refer to the same key which is the Windows key by default. > `$mod`, `modifier` or `SUPER` refer to the same key which is the Windows key by default.
@ -59,7 +59,7 @@ Keybinding | Function
`SUPER LMB` | Move window by dragging `SUPER LMB` | Move window by dragging
`SUPER RMB` | Resize window by dragging `SUPER RMB` | Resize window by dragging
Some [media keys](https://git.sid.ovh/sid/synix/blob/master/modules/home/hyprland/binds/mediakeys.nix) are also supported. Some [media keys](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/home/hyprland/binds/mediakeys.nix) are also supported.
## Default applications ## Default applications
@ -73,7 +73,7 @@ To add default applications to Hyprland, you need to do the following steps:
### 1. Look for an existing category ### 1. Look for an existing category
Check if a fitting category for your application exists in [`applications/default.nix`](https://git.sid.ovh/sid/synix/blob/master/modules/home/hyprland/applications/default.nix). Check if a fitting category for your application exists in [`applications/default.nix`](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/home/hyprland/applications/default.nix).
Categories are listed under `options.wayland.windowManager.hyprland.applications`, for example: Categories are listed under `options.wayland.windowManager.hyprland.applications`, for example:
```nix ```nix
@ -133,13 +133,13 @@ in
} }
``` ```
> The function [`genMimeAssociations`](https://git.sid.ovh/sid/synix/blob/master/modules/home/hyprland/applications/genMimeAssociations.nix) might be useful here. See [`feh`'s config](https://git.sid.ovh/sid/synix/blob/master/modules/home/hyprland/applications/feh/default.nix) as an example. > The function [`genMimeAssociations`](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/home/hyprland/applications/genMimeAssociations.nix) might be useful here. See [`feh`'s config](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/home/hyprland/applications/feh/default.nix) as an example.
> Available MIME types can be found [here](https://www.iana.org/assignments/media-types/media-types.xhtml). > Available MIME types can be found [here](https://www.iana.org/assignments/media-types/media-types.xhtml).
### 3. Import the directory ### 3. Import the directory
You then need to import this directory in [`applications/default.nix`](https://git.sid.ovh/sid/synix/blob/master/modules/home/hyprland/applications/default.nix). You then need to import this directory in [`applications/default.nix`](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/home/hyprland/applications/default.nix).
Look for the comment `# add your application directories here`: Look for the comment `# add your application directories here`:
```nix ```nix

View file

@ -2,7 +2,7 @@
`kitty` is a cross-platform, fast, feature-rich, GPU based terminal emulator. `kitty` is a cross-platform, fast, feature-rich, GPU based terminal emulator.
View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/home/kitty). View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/home/kitty).
If you use this repository's [Hyprland module](./hyprland.md), it is enabled by default. If you use this repository's [Hyprland module](./hyprland.md), it is enabled by default.
## References ## References

View file

@ -1,11 +0,0 @@
# lf
> Note: This module is not actively maintained. Expect things to break!
`lf` is a terminal file manager.
View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/home/lf).
## References
- [GitHub](https://github.com/gokcehan/lf)

View file

@ -2,7 +2,7 @@
networkmanager-dmenu allows you to control NetworkManager via dmenu. networkmanager-dmenu allows you to control NetworkManager via dmenu.
View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/home/networkmanager-dmenu). View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/home/networkmanager-dmenu).
If you use this repository's [Hyprland module](./hyprland.md), it is enabled by default. If you use this repository's [Hyprland module](./hyprland.md), it is enabled by default.
## References ## References

View file

@ -1,75 +0,0 @@
# Nextcloud sync client
Because every other client sucks.
View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/home/nextcloud-sync).
## Setup
This is an example home config:
```nix
{ inputs, config, ... }:
{
imports = [
inputs.synix.homeModules.nextcloud-sync
];
services.nextcloud-sync = {
enable = true;
remote = "cloud.sid.ovh"; # just the URL without `https://`
passwordFile = config.sops.secrets.nextcloud.path;
connections = [ # absolute paths without trailing /
{
local = "/home/sid/aud";
remote = "/aud";
}
{
local = "/home/sid/doc";
remote = "/doc";
}
{
local = "/home/sid/img";
remote = "/img";
}
{
local = "/home/sid/vid";
remote = "/vid";
}
];
};
}
```
## Usage
You can manually sync by running:
```bash
nextcloud-sync-all
```
This will synchronize all defined connections.
## Troubleshooting
Each listed connection spawns a systemd user service and timer. Using the example above, we get:
```plaintext
nextcloud-sync-aud.service
nextcloud-sync-aud.timer
nextcloud-sync-doc.service
nextcloud-sync-doc.timer
nextcloud-sync-img.service
nextcloud-sync-img.timer
nextcloud-sync-vid.service
nextcloud-sync-vid.timer
```
Check their status to know what might go wrong:
```bash
systemctl --user status nextcloud-sync-doc.service
journalctl --user -xeu nextcloud-sync-doc.service
```

View file

@ -2,7 +2,7 @@
This module provides some defaults to quickly set up Nixvim with some plugins. This module provides some defaults to quickly set up Nixvim with some plugins.
View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/home/nixvim). View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/home/nixvim).
## Config ## Config
@ -88,7 +88,7 @@ key | action
`<C-A-K>` | next quickfix item `<C-A-K>` | next quickfix item
`<leader>ca` | apply code action `<leader>ca` | apply code action
See [keymaps.nix](https://git.sid.ovh/sid/synix/blob/master/modules/home/nixvim/keymaps.nix) and [plugins](https://git.sid.ovh/sid/synix/blob/master/modules/home/nixvim/plugins/) for more details. See [keymaps.nix](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/home/nixvim/keymaps.nix) and [plugins](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/home/nixvim/plugins/) for more details.
These commands do not have keymaps yet but might be useful anyway: These commands do not have keymaps yet but might be useful anyway:

View file

@ -2,7 +2,7 @@
This module will automatically install [`pass`](https://www.passwordstore.org/) as your password manager. It also provides a custom version of [`passmenu`](https://git.zx2c4.com/password-store/tree/contrib/dmenu/passmenu) using `bemenu` for Wayland sessions called `passmenu-bemenu` and configures [passff](https://codeberg.org/PassFF/passff) for your web browser. This module will automatically install [`pass`](https://www.passwordstore.org/) as your password manager. It also provides a custom version of [`passmenu`](https://git.zx2c4.com/password-store/tree/contrib/dmenu/passmenu) using `bemenu` for Wayland sessions called `passmenu-bemenu` and configures [passff](https://codeberg.org/PassFF/passff) for your web browser.
View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/home/password-manager). View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/home/password-manager).
## Setup ## Setup

View file

@ -4,7 +4,7 @@ For more information on how to use this module, see the [Sops NixOS module docum
For extensive documentation, read the [Readme on GitHub](https://github.com/Mic92/sops-nix/blob/master/README.md). For extensive documentation, read the [Readme on GitHub](https://github.com/Mic92/sops-nix/blob/master/README.md).
View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/home/sops). View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/home/sops).
## 1. Generate an age key ## 1. Generate an age key

View file

@ -2,7 +2,7 @@
This module wraps [stylix](https://github.com/nix-community/stylix), a theming framework for NixOS, Home Manager, nix-darwin, and Nix-on-Droid. This module wraps [stylix](https://github.com/nix-community/stylix), a theming framework for NixOS, Home Manager, nix-darwin, and Nix-on-Droid.
View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/home/stylix). View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/home/stylix).
## References ## References
@ -30,11 +30,11 @@ stylix = {
}; };
``` ```
Replace `SCHEME` with the name of your scheme. Available schemes are listed as `validSchemes` in [our stylix module](https://git.sid.ovh/sid/synix/tree/master/modules/home/stylix/default.nix). Replace `SCHEME` with the name of your scheme. Available schemes are listed as `validSchemes` in [our stylix module](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/home/stylix/default.nix).
## Create a scheme ## Create a scheme
You can create your own scheme in `schemes/<scheme>.yaml`. To make it available via `stylix.scheme`, you need to add it to `validSchemes` and `customSchemes` in [the module's `default.nix`](https://git.sid.ovh/sid/synix/tree/master/modules/home/stylix/default.nix). Make sure that the resulting scheme name is a valid [colorscheme in nixvim](https://github.com/nix-community/nixvim/tree/main/plugins/colorschemes). You can create your own scheme in `schemes/<scheme>.yaml`. To make it available via `stylix.scheme`, you need to add it to `validSchemes` and `customSchemes` in [the module's `default.nix`](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/home/stylix/default.nix). Make sure that the resulting scheme name is a valid [colorscheme in nixvim](https://github.com/nix-community/nixvim/tree/main/colorschemes).
It is recommended to set colors according to their purpose / name. This means that `base00` should always be a rather dark color for the background and `base08` a reddish color. It is recommended to set colors according to their purpose / name. This means that `base00` should always be a rather dark color for the background and `base08` a reddish color.

View file

@ -2,7 +2,7 @@
Home Manager module to go with the [Virtualisation NixOS module](../nixos/virtualisation.md). Home Manager module to go with the [Virtualisation NixOS module](../nixos/virtualisation.md).
View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/home/virtualisation). View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/home/virtualisation).
## Setup ## Setup

View file

@ -2,7 +2,7 @@
Waybar is a highly customizable Wayland bar for Sway and Wlroots based compositors. Waybar is a highly customizable Wayland bar for Sway and Wlroots based compositors.
View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/home/waybar). View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/home/waybar).
If you use this repository's [Hyprland module](./hyprland.md), it is enabled by default. If you use this repository's [Hyprland module](./hyprland.md), it is enabled by default.
## References ## References

View file

@ -2,7 +2,7 @@
Terminal file manager written in Rust. Terminal file manager written in Rust.
View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/home/yazi). View the [*synix* Home Manager module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/home/hyprland/applications/yazi).
If you use this repository's [Hyprland module](./hyprland.md), it is enabled by default. If you use this repository's [Hyprland module](./hyprland.md), it is enabled by default.
## References ## References

View file

@ -2,7 +2,7 @@
PipeWire is a server for handling audio, video streams, and hardware on Linux. PipeWire is a server for handling audio, video streams, and hardware on Linux.
View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/audio). View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/nixos/audio).
## References ## References

View file

@ -2,7 +2,7 @@
Baibot is a Matrix AI bot. Baibot is a Matrix AI bot.
View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/baibot). View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/nixos/baibot).
## References ## References

View file

@ -4,7 +4,7 @@
This module allows you to automount cifs shares after the login of the specified user. The remote has to have a running samba server. This module allows you to automount cifs shares after the login of the specified user. The remote has to have a running samba server.
View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/cifsMount). View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/nixos/cifsMount).
## Config ## Config

View file

@ -2,7 +2,7 @@
The common module sets some opinionated defaults. The common module sets some opinionated defaults.
View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/common). View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/nixos/common).
It is recommended to import it in your NixOS configuration as some synix modules may depend on it: It is recommended to import it in your NixOS configuration as some synix modules may depend on it:

View file

@ -2,7 +2,7 @@
This module lets you set some defaults for a device type. This module lets you set some defaults for a device type.
View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/device). View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/nixos/device).
Available devices are: Available devices are:

View file

@ -4,4 +4,4 @@
This module sets up a simple ftp web server behind a reverse proxy (`ftp.domain.tld` by default). This module sets up a simple ftp web server behind a reverse proxy (`ftp.domain.tld` by default).
View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/ftp-webserver). View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/nixos/ftp-webserver).

View file

@ -2,7 +2,7 @@
A feature-complete Web UI for Headscale. A feature-complete Web UI for Headscale.
View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/headplane). View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/nixos/headplane).
## References ## References

View file

@ -2,7 +2,7 @@
Headscale is an open source, self-hosted implementation of the Tailscale control server. Headscale is an open source, self-hosted implementation of the Tailscale control server.
View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/headscale). View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/nixos/headscale).
## References ## References

View file

@ -2,7 +2,7 @@
I2P is an End-to-End encrypted and anonymous Internet. I2P is an End-to-End encrypted and anonymous Internet.
View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/i2pd). View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/nixos/i2pd).
## References ## References

View file

@ -2,7 +2,7 @@
Jellyfin is a free and open-source media server and suite of multimedia applications. Jellyfin is a free and open-source media server and suite of multimedia applications.
View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/jellyfin). View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/nixos/jellyfin).
## References ## References

View file

@ -2,8 +2,8 @@
Jirafeau is a project that allows "one-click filesharing", making it easy to upload a file and give it a unique link. Jirafeau is a project that allows "one-click filesharing", making it easy to upload a file and give it a unique link.
View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/jirafeau). View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/nixos/jirafeau).
## References ## References
- [docs](https://github.com/Newlode/jirafeauhttps://github.com/Newlode/jirafeau) - [docs](https://github.com/Newlode/jirafeau)

View file

@ -2,7 +2,7 @@
A simple NixOS mailserver. A simple NixOS mailserver.
View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/mailserver). View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/nixos/mailserver).
## References ## References

View file

@ -2,7 +2,7 @@
Synapse is a [Matrix](https://matrix.org/) homeserver. Matrix is an open network for secure, decentralised communication. Synapse is a [Matrix](https://matrix.org/) homeserver. Matrix is an open network for secure, decentralised communication.
View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/matrix-synapse). View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/nixos/matrix-synapse).
## References ## References
@ -40,7 +40,7 @@ nix-shell -p livekit --run "livekit-server generate-keys | tail -1 | awk '{print
## Config ## Config
[Coturn has its own module](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/matrix-synapse), making it easy to outsource to a small VPS with a static IPv4 address. [Coturn has its own module](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/nixos/matrix-synapse), making it easy to outsource to a small VPS with a static IPv4 address.
If you do so, both machines need the secret `coturn/static-auth-secret`. If you do so, both machines need the secret `coturn/static-auth-secret`.
In the following example, both services run on the same machine: In the following example, both services run on the same machine:

View file

@ -4,7 +4,7 @@ A plugin-based Matrix bot system.
> Warning: Maubot uses [deprecated `libolm`](https://github.com/mautrix/go/issues/262). > Warning: Maubot uses [deprecated `libolm`](https://github.com/mautrix/go/issues/262).
View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/maubot). View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/nixos/maubot).
## References ## References

View file

@ -2,7 +2,7 @@
A simple MCP-to-OpenAPI proxy server. A simple MCP-to-OpenAPI proxy server.
View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/mcpo). View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/nixos/mcpo).
## References ## References
@ -10,7 +10,7 @@ View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/ma
## Configuration ## Configuration
You have to provide a package, for example from [synix](https://git.sid.ovh/sid/synix/tree/master/pkgs/mcpo/default.nix). You have to provide a package, for example from [synix](https://git.sid.ovh/sid/synix/src/branch/release-25.11/pkgs/mcpo/default.nix).
Setting `mcpServers` is required. The following example runs a NixOS MCP server using [mcp-nixos](https://github.com/utensils/mcp-nixos). Setting `mcpServers` is required. The following example runs a NixOS MCP server using [mcp-nixos](https://github.com/utensils/mcp-nixos).
@ -43,6 +43,6 @@ Each tool will be accessible under its own unique route `127.0.0.1:8000/<mcp-ser
## Open WebUI Integration ## Open WebUI Integration
Follow the [official Open WebUI integration documentation starting at *Step 2*](https://docs.openwebui.com/openapi-servers/open-webui/#step-2-connect-tool-server-in-open-webui). Follow the [official Open WebUI integration documentation starting at *Step 2*](https://docs.openwebui.com/features/extensibility/plugin/tools/openapi-servers/open-webui#step-2-connect-tool-server-in-open-webui).
In Open WebUI, users have to set *Function Calling* to *Native* in *Settings* > *General* > *Advanced Parameters*. Then, they can enable MCP servers in a chat by clicking *More* (the plus sign) in the bottom left of the prompt window. In Open WebUI, users have to set *Function Calling* to *Native* in *Settings* > *General* > *Advanced Parameters*. Then, they can enable MCP servers in a chat by clicking *More* (the plus sign) in the bottom left of the prompt window.

View file

@ -2,7 +2,7 @@
Miniflux is a minimalist and opinionated feed reader. Miniflux is a minimalist and opinionated feed reader.
View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/miniflux). View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/nixos/miniflux).
## References ## References

View file

@ -2,7 +2,7 @@
This module automates user creation for normal users. This module automates user creation for normal users.
View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/normalUsers). View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/nixos/normalUsers).
## Config ## Config

View file

@ -4,7 +4,7 @@ NixOS module that configures your Nvidia GPU with proprietary drivers.
> Tested on Turing and Ampere. Should work with most modern Nvidia GPUs. > Tested on Turing and Ampere. Should work with most modern Nvidia GPUs.
View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/nvidia). View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/nixos/nvidia).
## Setup ## Setup

View file

@ -2,13 +2,13 @@
Open WebUI is an extensible, self-hosted AI interface that adapts to your workflow, all while operating entirely offline. Open WebUI is an extensible, self-hosted AI interface that adapts to your workflow, all while operating entirely offline.
View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/open-webui-oci). View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/nixos/open-webui-oci).
## References ## References
- [Homepage](https://openwebui.com/) - [Homepage](https://openwebui.com/)
- [GitHub](https://github.com/open-webui/open-webui) - [GitHub](https://github.com/open-webui/open-webui)
- [Environment Configuration](https://docs.openwebui.com/getting-started/env-configuration/) - [Environment Configuration](https://docs.openwebui.com/reference/env-configuration/)
- [Nixpkgs Docker tools](https://github.com/NixOS/nixpkgs/blob/master/doc/build-helpers/images/dockertools.section.md) - [Nixpkgs Docker tools](https://github.com/NixOS/nixpkgs/blob/master/doc/build-helpers/images/dockertools.section.md)
## Configuration ## Configuration

View file

@ -4,4 +4,4 @@
This module sets up a printing server with a web interface. This module sets up a printing server with a web interface.
View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/print-server). View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/nixos/print-server).

View file

@ -2,7 +2,7 @@
A simple CalDAV and CardDAV server. A simple CalDAV and CardDAV server.
View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/radicale). View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/nixos/radicale).
## References ## References

View file

@ -2,7 +2,7 @@
RSS-Bridge is a PHP web application. It generates web feeds for websites that don't have one. RSS-Bridge is a PHP web application. It generates web feeds for websites that don't have one.
View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/rss-bridge). View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/nixos/rss-bridge).
## References ## References

View file

@ -2,7 +2,7 @@
Atomic secret provisioning for NixOS based on sops. Atomic secret provisioning for NixOS based on sops.
View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/sops). View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/nixos/sops).
## References ## References

View file

@ -2,7 +2,7 @@
Virtualisation using QEMU via libvirt and managed through Virt-manager with VFIO support. Virtualisation using QEMU via libvirt and managed through Virt-manager with VFIO support.
View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/virtualisation). View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/nixos/virtualisation).
## Overview ## Overview

View file

@ -2,4 +2,4 @@
A very simple module to serve a static web page behind a reverse proxy using nginx. A very simple module to serve a static web page behind a reverse proxy using nginx.
View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/webPage). View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/nixos/webPage).

View file

@ -2,7 +2,7 @@
Windows inside a Docker container. Windows inside a Docker container.
View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/tree/master/modules/nixos/windows-oci). View the [*synix* NixOS module on Forgejo](https://git.sid.ovh/sid/synix/src/branch/release-25.11/modules/nixos/windows-oci).
## References ## References

30
flake.lock generated
View file

@ -258,11 +258,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1776796298, "lastModified": 1778507602,
"narHash": "sha256-PcRvlWayisPSjd0UcRQbhG8Oqw78AcPE6x872cPRHN8=", "narHash": "sha256-kTwur1wV+01SdqskVMSo6JMEpg71ps3HpbFY2GsflKs=",
"owner": "cachix", "owner": "cachix",
"repo": "git-hooks.nix", "repo": "git-hooks.nix",
"rev": "3cfd774b0a530725a077e17354fbdb87ea1c4aad", "rev": "61ab0e80d9c7ab14c256b5b453d8b3fb0189ba0a",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -349,11 +349,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1777851538, "lastModified": 1779506708,
"narHash": "sha256-Gp8qwTEYNoy2yvmErVGlvLOQvrtEECCAKbonW7VJef8=", "narHash": "sha256-QOD/CNm196nCJRheux/URi4/HE66fthdOMqCJoPP1Y0=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "cc09c0f9b7eaa95c2d9827338a5eb03d32505ca5", "rev": "3ee51fbdac8c8bdfe1e7e1fcaba6520a563f394f",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -465,11 +465,11 @@
}, },
"nixpkgs_2": { "nixpkgs_2": {
"locked": { "locked": {
"lastModified": 1777673416, "lastModified": 1779467186,
"narHash": "sha256-5c2POKPOjU40Kh0MirOdScBLG0bu9TAuPYAtPRNZMBs=", "narHash": "sha256-nOesoDCiXcUftqbRBMz9tt4blI5PvljMWbm3kuCA+0s=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "26ef669cffa904b6f6832ab57b77892a37c1a671", "rev": "b77b3de8775677f84492abe84635f87b0e153f0f",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -511,11 +511,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1777906128, "lastModified": 1779900588,
"narHash": "sha256-ei9g+4pCXhacUwnYuljs9v75hwfTqnfU+J6s6s8hfvc=", "narHash": "sha256-b/yda4uMmjpw4uhXI4d0JNv09WtGoXis2JjD5l1Qbts=",
"owner": "nix-community", "owner": "nix-community",
"repo": "NUR", "repo": "NUR",
"rev": "c278c296b010e2a32838c8d4539a2d72c1686d4d", "rev": "dd8bdde89853bfb3eae0eb28e3d3a9320b3b8a3c",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -605,11 +605,11 @@
"tinted-zed": "tinted-zed" "tinted-zed": "tinted-zed"
}, },
"locked": { "locked": {
"lastModified": 1777581180, "lastModified": 1778680496,
"narHash": "sha256-JcDBTZkkz68WlZKYDoD+MZG8b3dnIJXqMvyuVx3Wkdg=", "narHash": "sha256-tUq1WASV0dHLv3j18log8V6Esq0NYkXuzNH2EHsstcg=",
"owner": "nix-community", "owner": "nix-community",
"repo": "stylix", "repo": "stylix",
"rev": "a2538cd28ae2140ffce9cee9108b8d569a9c4fed", "rev": "fc5bec2e44678eeaa221d566d447a0257a884737",
"type": "github" "type": "github"
}, },
"original": { "original": {

214
flake.nix
View file

@ -3,7 +3,6 @@
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11"; nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11";
nix.url = "github:DeterminateSystems/nix-src/flake-schemas"; nix.url = "github:DeterminateSystems/nix-src/flake-schemas";
flake-schemas.url = "github:DeterminateSystems/flake-schemas"; flake-schemas.url = "github:DeterminateSystems/flake-schemas";
git-hooks.url = "github:cachix/git-hooks.nix"; git-hooks.url = "github:cachix/git-hooks.nix";
@ -29,50 +28,69 @@
... ...
}@inputs: }@inputs:
let let
supportedSystems = [ inherit (self) outputs;
systems = [
"x86_64-linux" "x86_64-linux"
"aarch64-linux" # For testing only. Use at your own risk. "aarch64-linux" # For testing only. Use at your own risk.
]; ];
forAllSystems = nixpkgs.lib.genAttrs supportedSystems; lib = nixpkgs.lib.extend (_final: _prev: { inherit (self.lib) utils; });
nixpkgsFor = forAllSystems ( mkPkgs =
system: {
system,
config ? { },
}:
import nixpkgs { import nixpkgs {
inherit system; inherit system;
inherit config;
overlays = [ overlays = [
self.overlays.default self.overlays.modifications
self.overlays.additions
inputs.nix.overlays.default inputs.nix.overlays.default
(final: prev: { synix = self.overlays.additions final prev; })
]; ];
}
);
test = {
system = "x86_64-linux";
lib = nixpkgs.lib.extend (final: prev: self.outputs.lib or { });
inputs = inputs // {
synix = self;
}; };
outputs = { };
overlays = [ forAllSystems =
self.overlays.default function:
self.overlays.additions lib.genAttrs systems (
self.overlays.modifications system:
(final: prev: { synix = self.packages."${final.system}"; }) function (mkPkgs {
]; inherit system;
}; })
);
mkNixosConfiguration =
system: modules:
nixpkgs.lib.nixosSystem {
inherit system modules;
specialArgs = {
inherit inputs outputs lib;
};
};
mkHomeConfiguration =
system: modules:
inputs.home-manager.lib.homeManagerConfiguration {
pkgs = mkPkgs { inherit system; };
inherit modules;
extraSpecialArgs = {
inherit inputs outputs;
};
};
in in
{ {
inherit (inputs.flake-schemas) schemas; inherit (inputs.flake-schemas) schemas;
apps = forAllSystems ( apps = forAllSystems (
system: pkgs:
let let
pkgs = nixpkgs.legacyPackages.${system}; mkApp = name: description: {
mkApp = name: desc: {
type = "app"; type = "app";
program = pkgs.lib.getExe (pkgs.callPackage ./apps/${name} { }); program = pkgs.lib.getExe (pkgs.callPackage ./apps/${name} { });
meta.description = desc; meta.description = description;
}; };
in in
{ {
@ -86,13 +104,17 @@
); );
lib = { lib = {
utils = import ./lib/utils.nix { lib = nixpkgs.lib; }; utils = import ./lib/utils.nix { inherit (nixpkgs) lib; };
helpers = {
inherit mkPkgs;
};
}; };
packages = forAllSystems ( packages = forAllSystems (
system: pkgs:
let let
allArchs = import ./pkgs { pkgs = nixpkgs.legacyPackages.${system}; }; inherit (pkgs.stdenv.hostPlatform) system;
allArchs = import ./pkgs { inherit pkgs; };
x64only = x64only =
if system == "x86_64-linux" then if system == "x86_64-linux" then
{ {
@ -111,109 +133,93 @@
# test configs # test configs
nixosConfigurations = { nixosConfigurations = {
nixos-hyprland = nixpkgs.lib.nixosSystem { nixos-hyprland = mkNixosConfiguration "x86_64-linux" [ ./tests/build/nixos-hyprland ];
inherit (test) system; nixos-server = mkNixosConfiguration "x86_64-linux" [ ./tests/build/nixos-server ];
modules = [
./tests/build/nixos-hyprland
{ nixpkgs.overlays = test.overlays; }
];
specialArgs = {
inherit (test) inputs outputs lib;
};
};
nixos-server = nixpkgs.lib.nixosSystem {
inherit (test) system;
modules = [
./tests/build/nixos-server
{ nixpkgs.overlays = test.overlays; }
];
specialArgs = {
inherit (test) inputs outputs lib;
};
};
}; };
homeConfigurations = { homeConfigurations = {
hm-hyprland = inputs.home-manager.lib.homeManagerConfiguration { hm-hyprland = mkHomeConfiguration "x86_64-linux" [ ./tests/build/hm-hyprland ];
pkgs = import nixpkgs {
inherit (test) overlays system;
};
extraSpecialArgs = {
inherit (test) inputs outputs;
};
modules = [
./tests/build/hm-hyprland
];
};
}; };
devShells = forAllSystems ( devShells = forAllSystems (
system: pkgs:
let let
pkgs = nixpkgsFor.${system}; inherit (pkgs.stdenv.hostPlatform) system;
inherit (self.checks.${system}.pre-commit-check) shellHook enabledPackages;
in in
{ {
default = default = pkgs.mkShell {
let inherit shellHook;
inherit (self.checks.${system}.pre-commit-check) shellHook enabledPackages; nativeBuildInputs = [
in enabledPackages
pkgs.mkShell { pkgs.nix
inherit shellHook; pkgs.lychee
nativeBuildInputs = [ ]
enabledPackages ++ (with pkgs; [
pkgs.nix (python313.withPackages (
] p: with p; [
++ (with pkgs; [ mkdocs
(python313.withPackages ( mkdocs-material
p: with p; [ mkdocs-material-extensions
mkdocs pygments
mkdocs-material ]
mkdocs-material-extensions ))
pygments ]);
] };
)) nix-config = pkgs.mkShell {
]); inherit shellHook;
}; nativeBuildInputs = [ enabledPackages ];
};
install-hm = pkgs.mkShell {
NIX_CONFIG = "extra-experimental-features = nix-command flakes";
nativeBuildInputs = [ pkgs.home-manager ];
};
} }
); );
formatter = forAllSystems ( formatter = forAllSystems (
system: pkgs:
let let
pkgs = nixpkgs.legacyPackages.${system}; inherit (pkgs.stdenv.hostPlatform) system;
config = self.checks.${system}.pre-commit-check.config; inherit (self.checks.${system}.pre-commit-check.config) package configFile;
inherit (config) package configFile;
script = ''
${pkgs.lib.getExe package} run --all-files --config ${configFile}
'';
in in
pkgs.writeShellScriptBin "pre-commit-run" script pkgs.writeShellScriptBin "pre-commit-run" "${pkgs.lib.getExe package} run --all-files --config ${configFile}"
); );
checks = forAllSystems ( checks = forAllSystems (
system: pkgs:
let let
pkgs = nixpkgs.legacyPackages.${system}; inherit (pkgs.stdenv.hostPlatform) system;
flakePkgs = self.packages.${system};
overlaidPkgs = import nixpkgs {
inherit system;
overlays = [ self.overlays.modifications ];
};
in in
{ {
pre-commit-check = inputs.git-hooks.lib.${system}.run { pre-commit-check = inputs.git-hooks.lib.${system}.run {
src = ./.; src = ./.;
hooks = { hooks = {
nixfmt.enable = true; actionlint.enable = true;
nixfmt = {
enable = true;
settings.width = 120;
};
shellcheck.enable = true;
statix.enable = true;
yamllint = {
enable = true;
excludes = [
"secrets.yaml"
"modules/home/stylix/schemes/*.yaml"
];
settings.configData = "{rules: {line-length: {max: 120}}}";
};
}; };
}; };
build-packages = pkgs.linkFarm "flake-packages-${system}" flakePkgs;
build-overlays = pkgs.linkFarm "flake-overlays-${system}" { build-additions = pkgs.linkFarm "added-packages-${system}" self.packages.${system};
kicad = overlaidPkgs.kicad; build-modifications = pkgs.linkFarm "modified-packages-${system}" (
}; lib.filterAttrs (_: v: lib.isDerivation v) (self.overlays.modifications pkgs pkgs)
);
synapse-test = synapse-test =
let let
testPkgs = import nixpkgs { testPkgs = mkPkgs {
inherit system; inherit system;
config.permittedInsecurePackages = [ "olm-3.2.16" ]; config.permittedInsecurePackages = [ "olm-3.2.16" ];
}; };

View file

@ -1,3 +1,4 @@
---
site_name: synix docs site_name: synix docs
repo_url: https://git.sid.ovh/sid/synix repo_url: https://git.sid.ovh/sid/synix
site_url: https://doc.sid.ovh/synix site_url: https://doc.sid.ovh/synix
@ -20,7 +21,7 @@ markdown_extensions:
- pymdownx.superfences - pymdownx.superfences
nav: nav:
- Home: index.md # do not change - Home: index.md # do not change
- Introduction to Nix: - Introduction to Nix:
- Overview: introduction-to-nix/overview.md - Overview: introduction-to-nix/overview.md
- Install Nix: introduction-to-nix/install-nix.md - Install Nix: introduction-to-nix/install-nix.md
@ -67,7 +68,6 @@ nav:
- hyprland: modules/home/hyprland.md - hyprland: modules/home/hyprland.md
- kitty: modules/home/kitty.md - kitty: modules/home/kitty.md
- networkmanager-dmenu: modules/home/networkmanager-dmenu.md - networkmanager-dmenu: modules/home/networkmanager-dmenu.md
- nextcloud-sync: modules/home/nextcloud-sync.md
- nixvim: modules/home/nixvim.md - nixvim: modules/home/nixvim.md
- password-manager: modules/home/password-manager.md - password-manager: modules/home/password-manager.md
- sops: modules/home/sops.md - sops: modules/home/sops.md

View file

@ -1,3 +1,4 @@
#!/usr/bin/env bash
# change directory with fzf # change directory with fzf
# Usage: cdf [optional_relative_path] # Usage: cdf [optional_relative_path]
# - If no argument, searches from $HOME. # - If no argument, searches from $HOME.
@ -67,7 +68,8 @@ function cdf() {
"--preview=tree -C {} | head -50" "--preview=tree -C {} | head -50"
"--preview-window=right:50%:wrap" "--preview-window=right:50%:wrap"
) )
local selected=$(find "${find_args[@]}" 2>/dev/null | fzf "${fzf_args[@]}") local selected
selected=$(find "${find_args[@]}" 2>/dev/null | fzf "${fzf_args[@]}")
if [[ -n "$selected" ]]; then if [[ -n "$selected" ]]; then
cd "$selected" || echo "Failed to cd into '$selected'" cd "$selected" || echo "Failed to cd into '$selected'"

View file

@ -0,0 +1,7 @@
#!/usr/bin/env bash
# find and replace strings with rg
# Usage: fr OLD NEW
fr() {
rg -lF "$1" | xargs sed -i "s|$1|$2|g"
}

View file

@ -12,6 +12,7 @@ in
PROMPT='%F{green}%n%f@%F{blue}%m%f %B%1~%b > ' PROMPT='%F{green}%n%f@%F{blue}%m%f %B%1~%b > '
RPROMPT='[%F{yellow}%?%f]' RPROMPT='[%F{yellow}%?%f]'
'' ''
+ builtins.readFile ./cdf.sh; + builtins.readFile ./cdf.sh
+ builtins.readFile ./fr.sh;
}; };
} }

View file

@ -0,0 +1,48 @@
{
inputs,
config,
lib,
pkgs,
...
}:
let
cfg = config.wayland.windowManager.hyprland;
app = cfg.applications.password-manager.default;
inherit (lib) mkDefault mkIf;
in
{
imports = [ ../../../rofi-rbw ];
config = mkIf (cfg.enable && app == "rofi-rbw") {
programs = {
rbw = {
enable = true;
settings = {
# email = "you@example.tld"; # You have to set this in your config
pinentry = mkDefault pkgs.pinentry-gnome3;
lock_timeout = mkDefault 3600;
};
};
rofi-rbw = {
enable = true;
package = mkDefault pkgs.rofi-rbw-wayland;
settings = {
selector = mkDefault "bemenu";
selector-args = mkDefault "-i -l 20";
action = mkDefault "copy";
typing-key-delay = mkDefault 0;
};
};
librewolf = mkIf config.programs.librewolf.enable {
profiles.default.extensions.packages =
with inputs.nur.legacyPackages."${pkgs.stdenv.hostPlatform.system}".repos.rycee.firefox-addons; [
bitwarden
];
};
};
};
}

View file

@ -22,7 +22,7 @@ let
{ {
default = mkOption { default = mkOption {
type = types.str; type = types.str;
default = default; inherit default;
description = "The default application to use for the ${default}."; description = "The default application to use for the ${default}.";
}; };
bind = mkOption { bind = mkOption {
@ -38,12 +38,8 @@ let
}; };
# generate lists of all binds and window rules and remove empty strings # generate lists of all binds and window rules and remove empty strings
binds = filter (s: s != "") ( binds = filter (s: s != "") (builtins.concatLists (map (app: app.bind or [ "" ]) (attrValues apps)));
builtins.concatLists (map (app: app.bind or [ "" ]) (attrValues apps)) windowrules = filter (s: s != "") (builtins.concatLists (map (app: app.windowrule or [ "" ]) (attrValues apps)));
);
windowrules = filter (s: s != "") (
builtins.concatLists (map (app: app.windowrule or [ "" ]) (attrValues apps))
);
inherit (lib) inherit (lib)
attrValues attrValues
@ -56,6 +52,7 @@ let
in in
{ {
imports = [ imports = [
./bitwarden
./bemenu ./bemenu
./dmenu-bluetooth ./dmenu-bluetooth
./dunst-toggle ./dunst-toggle

View file

@ -5,7 +5,7 @@ let
pkill = "${pkgs.procps}/bin/pkill"; pkill = "${pkgs.procps}/bin/pkill";
signal = "${toString config.programs.waybar.settings.mainBar."custom/notifications".signal}"; signal = "${toString config.programs.waybar.settings.mainBar."custom/notifications".signal}";
in in
(pkgs.writeShellScriptBin "dunst-toggle" '' pkgs.writeShellScriptBin "dunst-toggle" ''
${dunst} set-paused toggle ${dunst} set-paused toggle
${pkill} -RTMIN+${signal} waybar ${pkill} -RTMIN+${signal} waybar
'') ''

View file

@ -9,7 +9,7 @@ let
cfg = config.wayland.windowManager.hyprland; cfg = config.wayland.windowManager.hyprland;
app = cfg.applications.rssreader.default; app = cfg.applications.rssreader.default;
reloadTime = "${toString config.programs.newsboat.reloadTime}"; reloadTime = "${toString config.programs.newsboat.reloadTime}";
newsboat-reload = (import ./newsboat-reload.nix { inherit config pkgs; }); newsboat-reload = import ./newsboat-reload.nix { inherit config pkgs; };
inherit (lib) mkIf; inherit (lib) mkIf;
in in
@ -27,9 +27,11 @@ in
timers.newsboat-reload = { timers.newsboat-reload = {
Unit.Description = "Reload newsboat every ${reloadTime} minutes"; Unit.Description = "Reload newsboat every ${reloadTime} minutes";
Timer.OnBootSec = "10sec"; Timer = {
Timer.OnUnitActiveSec = "${reloadTime}min"; OnBootSec = "10sec";
Timer.Unit = "newsboat-reload.service"; OnUnitActiveSec = "${reloadTime}min";
Unit = "newsboat-reload.service";
};
Install.WantedBy = [ "timers.target" ]; Install.WantedBy = [ "timers.target" ];
}; };

View file

@ -5,6 +5,6 @@ let
notify = "${pkgs.libnotify}/bin/notify-send"; notify = "${pkgs.libnotify}/bin/notify-send";
signal = "${toString config.programs.waybar.settings.mainBar."custom/newsboat".signal}"; signal = "${toString config.programs.waybar.settings.mainBar."custom/newsboat".signal}";
in in
(pkgs.writeShellScriptBin "newsboat-reload" '' pkgs.writeShellScriptBin "newsboat-reload" ''
${notify} -u low 'Newsboat' 'Reloading RSS feeds...' && ${newsboat} -x reload && ${notify} -u low 'Newsboat' 'RSS feeds reloaded.' && pkill -RTMIN+${signal} waybar ${notify} -u low 'Newsboat' 'Reloading RSS feeds...' && ${newsboat} -x reload && ${notify} -u low 'Newsboat' 'RSS feeds reloaded.' && pkill -RTMIN+${signal} waybar
'') ''

View file

@ -14,9 +14,7 @@ in
{ {
config = mkIf (cfg.enable && app == "presentation-mode-bemenu") { config = mkIf (cfg.enable && app == "presentation-mode-bemenu") {
home.packages = [ home.packages = [
(pkgs.writeShellScriptBin "presentation-mode-bemenu" ( (pkgs.writeShellScriptBin "presentation-mode-bemenu" (builtins.readFile ./presentation-mode-bemenu.sh))
builtins.readFile ./presentation-mode-bemenu.sh
))
]; ];
}; };
} }

View file

@ -1,5 +1,6 @@
#!/usr/bin/env bash
# Variables # Variables
DISPLAYS=( $(hyprctl monitors | grep -E '^Monitor' | awk '{print $2}') ) mapfile -t DISPLAYS < <(hyprctl monitors | grep -E '^Monitor' | awk '{print $2}')
EXTEND_RIGHT="Extend to right of main" EXTEND_RIGHT="Extend to right of main"
EXTEND_LEFT="Extend to left of main" EXTEND_LEFT="Extend to left of main"
MIRROR="Mirror main" MIRROR="Mirror main"

View file

@ -5,7 +5,7 @@
let let
screenshotDir = "${config.xdg.userDirs.pictures}/screenshots"; screenshotDir = "${config.xdg.userDirs.pictures}/screenshots";
in in
(pkgs.writeShellScriptBin "screenshot" '' pkgs.writeShellScriptBin "screenshot" ''
mkdir -p ${screenshotDir} mkdir -p ${screenshotDir}
${pkgs.hyprshot}/bin/hyprshot --mode $1 --output-folder ${screenshotDir} --filename screenshot_$(date +"%Y-%m-%d_%H-%M-%S").png ${pkgs.hyprshot}/bin/hyprshot --mode $1 --output-folder ${screenshotDir} --filename screenshot_$(date +"%Y-%m-%d_%H-%M-%S").png
'') ''

View file

@ -27,7 +27,7 @@ in
wayland.windowManager.hyprland = { wayland.windowManager.hyprland = {
settings = { settings = {
bind = binds; bind = binds;
bindm = (import ./mouse.nix); bindm = import ./mouse.nix;
}; };
}; };
}; };

View file

@ -9,17 +9,19 @@ let
inherit (lib) mkForce; inherit (lib) mkForce;
in in
{ {
home.pointerCursor = { home = {
name = mkForce "Bibata-Original-Ice"; pointerCursor = {
size = mkForce 24; name = mkForce "Bibata-Original-Ice";
package = mkForce pkgs.bibata-cursors; size = mkForce 24;
}; package = mkForce pkgs.bibata-cursors;
};
home.packages = [ pkgs.hyprcursor ]; packages = [ pkgs.hyprcursor ];
home.sessionVariables = { sessionVariables = {
HYPRCURSOR_THEME = config.home.pointerCursor.name; HYPRCURSOR_THEME = config.home.pointerCursor.name;
HYPRCURSOR_SIZE = toString config.home.pointerCursor.size; HYPRCURSOR_SIZE = toString config.home.pointerCursor.size;
};
}; };
# wayland.windowManager.hyprland.cursor.no_hardware_cursors = true; # wayland.windowManager.hyprland.cursor.no_hardware_cursors = true;

View file

@ -78,12 +78,6 @@ in
# auto discover fonts in `home.packages` # auto discover fonts in `home.packages`
fonts.fontconfig.enable = true; fonts.fontconfig.enable = true;
# notifications
services.dunst = {
enable = mkDefault true;
waylandDisplay = config.home.sessionVariables.WAYLAND_DISPLAY;
};
# install some applications # install some applications
home.packages = import ./packages.nix { inherit pkgs; }; # use programs.PACKAGE or services.SERVICE when possible home.packages = import ./packages.nix { inherit pkgs; }; # use programs.PACKAGE or services.SERVICE when possible
@ -94,11 +88,19 @@ in
fi fi
''; '';
services.udiskie = { # notifications
enable = mkDefault true; services = {
tray = mkDefault "never"; dunst = {
}; enable = mkDefault true;
waylandDisplay = config.home.sessionVariables.WAYLAND_DISPLAY;
};
services.network-manager-applet.enable = mkDefault true; udiskie = {
enable = mkDefault true;
tray = mkDefault "never";
};
network-manager-applet.enable = mkDefault true;
};
}; };
} }

View file

@ -20,8 +20,10 @@ in
enable = mkDefault true; enable = mkDefault true;
createDirectories = mkDefault true; createDirectories = mkDefault true;
}; };
portal.enable = mkDefault true; portal = {
portal.extraPortals = [ portal ]; enable = mkDefault true;
portal.configPackages = [ portal ]; extraPortals = [ portal ];
configPackages = [ portal ];
};
}; };
} }

View file

@ -19,13 +19,13 @@ let
in in
{ {
urls = [ { template = engine.url; } ]; urls = [ { template = engine.url; } ];
icon = engine.icon; inherit (engine) icon;
updateInterval = if (isUrl engine.icon) then every_day else null; updateInterval = if (isUrl engine.icon) then every_day else null;
definedAliases = optional (engine ? alias) engine.alias; definedAliases = optional (engine ? alias) engine.alias;
}; };
transformedEngines = mapAttrs' (name: engine: { transformedEngines = mapAttrs' (name: engine: {
name = name; inherit name;
value = transformEngine engine; value = transformEngine engine;
}) engines; }) engines;
@ -79,7 +79,7 @@ in
profiles.default.search.engines = mapAttrs (_: name: transformedEngines.${name}) ( profiles.default.search.engines = mapAttrs (_: name: transformedEngines.${name}) (
listToAttrs ( listToAttrs (
map (name: { map (name: {
name = name; inherit name;
value = name; value = name;
}) cfg.searchEngines }) cfg.searchEngines
) )

View file

@ -16,17 +16,19 @@ in
{ {
config = { config = {
programs.nixvim = { programs.nixvim = {
plugins.treesitter = { plugins = {
enable = mkDefault true; treesitter = {
nixvimInjections = mkDefault true; enable = mkDefault true;
settings = { nixvimInjections = mkDefault true;
folding.enable = mkDefault true; settings = {
highlight.enable = mkDefault true; folding.enable = mkDefault true;
indent.enable = mkDefault true; highlight.enable = mkDefault true;
indent.enable = mkDefault true;
};
}; };
treesitter-context = mkIf plugin.enable { enable = mkDefault true; };
treesitter-textobjects = mkIf plugin.enable { enable = mkDefault true; };
}; };
plugins.treesitter-context = mkIf plugin.enable { enable = mkDefault true; };
plugins.treesitter-textobjects = mkIf plugin.enable { enable = mkDefault true; };
}; };
# Fix for: ERROR `cc` executable not found. # Fix for: ERROR `cc` executable not found.

View file

@ -9,7 +9,7 @@
let let
cfg = config.programs.passwordManager; cfg = config.programs.passwordManager;
passmenuScript = pkgs.writeShellScriptBin "passmenu-bemenu" (builtins.readFile ./passmenu); # TODO: override original passmenu script coming from pass itself passmenuScript = pkgs.writeShellScriptBin "passmenu-bemenu" (builtins.readFile ./passmenu); # TODO: override original passmenu script coming from pass itself
passff-host = pkgs.passff-host; inherit (pkgs) passff-host;
inherit (lib) inherit (lib)
mkDefault mkDefault

View file

@ -29,8 +29,7 @@ let
"moonfly" "moonfly"
"oxocarbon" "oxocarbon"
]; ];
schemeName = schemeName = if builtins.elem cfg.scheme needsSuffix then "${cfg.scheme}-${cfg.polarity}" else cfg.scheme;
if builtins.elem cfg.scheme needsSuffix then "${cfg.scheme}-${cfg.polarity}" else cfg.scheme;
inherit (lib) inherit (lib)
mkDefault mkDefault

View file

@ -10,13 +10,13 @@ let
let let
newsboat = "${pkgs.newsboat}/bin/newsboat"; newsboat = "${pkgs.newsboat}/bin/newsboat";
in in
(pkgs.writeShellScriptBin "newsboat-print-unread" '' pkgs.writeShellScriptBin "newsboat-print-unread" ''
UNREAD=$(${newsboat} -x print-unread | awk '{print $1}') UNREAD=$(${newsboat} -x print-unread | awk '{print $1}')
if [[ $UNREAD -gt 0 ]]; then if [[ $UNREAD -gt 0 ]]; then
printf " %i" "$UNREAD" printf " %i" "$UNREAD"
fi fi
''); '';
inherit (lib) mkDefault; inherit (lib) mkDefault;
in in

View file

@ -1,3 +1,4 @@
#!/usr/bin/env bash
TIMER_FILE="/tmp/timer" # file to store the current time TIMER_FILE="/tmp/timer" # file to store the current time
SIGNAL=11 # signal number to send to status bar SIGNAL=11 # signal number to send to status bar
STATUS_BAR="waybar" # Support for more status bars? STATUS_BAR="waybar" # Support for more status bars?
@ -16,7 +17,7 @@ start_timer() {
notify-send "Timer Started" "Your countdown timer has been started." notify-send "Timer Started" "Your countdown timer has been started."
trap "exit" INT TERM trap "exit" INT TERM
trap "rm -f -- '$TIMER_FILE'" EXIT trap 'rm -f -- "$TIMER_FILE"' EXIT
while [ $total_seconds -gt 0 ]; do while [ $total_seconds -gt 0 ]; do
hours=$(( total_seconds / 3600 )) hours=$(( total_seconds / 3600 ))
@ -62,7 +63,7 @@ if [ "$1" = "start" ]; then
MINUTES=${MINUTES:-0} MINUTES=${MINUTES:-0}
SECONDS=${SECONDS:-0} SECONDS=${SECONDS:-0}
start_timer $HOURS $MINUTES $SECONDS start_timer "$HOURS" "$MINUTES" "$SECONDS"
elif [ "$1" = "stop" ]; then elif [ "$1" = "stop" ]; then
notify-send "Timer Stopped" "Your countdown timer has been stopped." notify-send "Timer Stopped" "Your countdown timer has been stopped."

View file

@ -4,10 +4,16 @@ let
inherit (lib) mkDefault; inherit (lib) mkDefault;
in in
{ {
hardware.bluetooth.enable = mkDefault true; hardware = {
hardware.bluetooth.powerOnBoot = mkDefault false; bluetooth = {
hardware.bluetooth.settings.General.Enable = mkDefault "Source,Sink,Media,Socket"; enable = mkDefault true;
hardware.bluetooth.settings.General.Experimental = mkDefault true; powerOnBoot = mkDefault false;
settings.General = {
Enable = mkDefault "Source,Sink,Media,Socket";
Experimental = mkDefault true;
};
};
};
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
blueman blueman

View file

@ -84,8 +84,6 @@ in
) { } cfg.remotes; ) { } cfg.remotes;
# Ensure that all cifs-mount services are started with the graphical session # Ensure that all cifs-mount services are started with the graphical session
systemd.user.targets.graphical-session.wants = map ( systemd.user.targets.graphical-session.wants = map (remote: "cifs-mount-${remote.shareName}.service") cfg.remotes;
remote: "cifs-mount-${remote.shareName}.service"
) cfg.remotes;
}; };
} }

View file

@ -1,20 +1,20 @@
{ lib, pkgs, ... }: { lib, pkgs, ... }:
{ {
# fix CVE-2026-31431 boot = {
boot.kernelPackages = lib.mkIf (lib.versionOlder pkgs.linux.version "6.18.22") ( # fix CVE-2026-31431
lib.mkDefault pkgs.linuxPackages_6_18 kernelPackages = lib.mkIf (lib.versionOlder pkgs.linux.version "6.18.22") (lib.mkDefault pkgs.linuxPackages_6_18);
);
# fix CVE-2026-43500 # fix CVE-2026-43500
boot.extraModprobeConfig = '' extraModprobeConfig = ''
install esp4 ${pkgs.coreutils}/bin/false install esp4 ${pkgs.coreutils}/bin/false
install esp6 ${pkgs.coreutils}/bin/false install esp6 ${pkgs.coreutils}/bin/false
install rxrpc ${pkgs.coreutils}/bin/false install rxrpc ${pkgs.coreutils}/bin/false
''; '';
boot.blacklistedKernelModules = [ blacklistedKernelModules = [
"esp4" "esp4"
"esp6" "esp6"
"rxrpc" "rxrpc"
]; ];
};
} }

View file

@ -9,55 +9,59 @@ let
inherit (lib) mkDefault optionals; inherit (lib) mkDefault optionals;
in in
{ {
environment.systemPackages = environment = {
with pkgs; systemPackages =
[ with pkgs;
cryptsetup [
curl cryptsetup
dig curl
dnsutils dig
fzf dnsutils
gptfdisk fzf
iproute2 gptfdisk
jq iproute2
lm_sensors jq
lsof lm_sensors
netcat-openbsd lsof
nettools netcat-openbsd
nixos-container nettools
nmap nixos-container
nurl nmap
p7zip nurl
pciutils p7zip
psmisc pciutils
rclone psmisc
rsync rclone
tcpdump rsync
tmux tcpdump
tree tmux
unzip tree
usbutils unzip
wget usbutils
xxd wget
zip xxd
zip
(callPackage ../../../apps/rebuild { }) (callPackage ../../../apps/rebuild { })
] ]
++ optionals (pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform) [ ++ optionals (pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform) [
pkgs.kitty.terminfo pkgs.kitty.terminfo
]; ];
environment.shellAliases = { shellAliases = {
l = "ls -lh"; l = "ls -lh";
ll = "ls -lAh"; ll = "ls -lAh";
ports = "ss -tulpn"; ports = "ss -tulpn";
publicip = "curl ifconfig.me/all"; publicip = "curl ifconfig.me/all";
sudo = "sudo "; # make aliases work with `sudo` sudo = "sudo "; # make aliases work with `sudo`
};
# saves one instance of nixpkgs.
ldso32 = null;
}; };
# saves one instance of nixpkgs. boot = {
environment.ldso32 = null; tmp.cleanOnBoot = mkDefault true;
initrd.systemd.enable = mkDefault (!config.boot.swraid.enable && !config.boot.isContainer);
boot.tmp.cleanOnBoot = mkDefault true; };
boot.initrd.systemd.enable = mkDefault (!config.boot.swraid.enable && !config.boot.isContainer);
} }

View file

@ -2,16 +2,13 @@
# avoid TOFU MITM # avoid TOFU MITM
programs.ssh.knownHosts = { programs.ssh.knownHosts = {
"github.com".hostNames = [ "github.com" ]; "github.com".hostNames = [ "github.com" ];
"github.com".publicKey = "github.com".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl";
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl";
"gitlab.com".hostNames = [ "gitlab.com" ]; "gitlab.com".hostNames = [ "gitlab.com" ];
"gitlab.com".publicKey = "gitlab.com".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf";
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf";
"git.sr.ht".hostNames = [ "git.sr.ht" ]; "git.sr.ht".hostNames = [ "git.sr.ht" ];
"git.sr.ht".publicKey = "git.sr.ht".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMZvRd4EtM7R+IHVMWmDkVU3VLQTSwQDSAvW0t2Tkj60";
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMZvRd4EtM7R+IHVMWmDkVU3VLQTSwQDSAvW0t2Tkj60";
}; };
# TODO: add synix # TODO: add synix
} }

View file

@ -42,12 +42,8 @@ in
static-auth-secret-file = mkIf cfg.sops config.sops.secrets."coturn/static-auth-secret".path; static-auth-secret-file = mkIf cfg.sops config.sops.secrets."coturn/static-auth-secret".path;
realm = mkDefault "turn.${config.networking.domain}"; realm = mkDefault "turn.${config.networking.domain}";
cert = cert = mkIf (!cfg.no-tls && cfg.sops) "${config.security.acme.certs.${cfg.realm}.directory}/full.pem";
mkIf (!cfg.no-tls && cfg.sops) pkey = mkIf (!cfg.no-tls && cfg.sops) "${config.security.acme.certs.${cfg.realm}.directory}/key.pem";
"${config.security.acme.certs.${cfg.realm}.directory}/full.pem";
pkey =
mkIf (!cfg.no-tls && cfg.sops)
"${config.security.acme.certs.${cfg.realm}.directory}/key.pem";
extraConfig = '' extraConfig = ''
# ban private IP ranges # ban private IP ranges

View file

@ -33,11 +33,13 @@ in
fonts.fontconfig.enable = mkDefault false; fonts.fontconfig.enable = mkDefault false;
xdg.autostart.enable = mkDefault false; xdg = {
xdg.icons.enable = mkDefault false; autostart.enable = mkDefault false;
xdg.menus.enable = mkDefault false; icons.enable = mkDefault false;
xdg.mime.enable = mkDefault false; menus.enable = mkDefault false;
xdg.sounds.enable = mkDefault false; mime.enable = mkDefault false;
sounds.enable = mkDefault false;
};
programs.git.package = mkDefault pkgs.gitMinimal; programs.git.package = mkDefault pkgs.gitMinimal;
@ -48,22 +50,25 @@ in
viAlias = mkDefault true; viAlias = mkDefault true;
}; };
# emergency mode is useless on headless machines systemd = {
systemd.enableEmergencyMode = false; # emergency mode is useless on headless machines
enableEmergencyMode = false;
sleep.extraConfig = ''
AllowSuspend=no
AllowHibernation=no
'';
# force reboots
settings.Manager = {
RuntimeWatchdogSec = mkDefault "15s";
RebootWatchdogSec = mkDefault "30s";
KExecWatchdogSec = mkDefault "1m";
};
};
boot.initrd.systemd.suppressedUnits = mkIf config.systemd.enableEmergencyMode [ boot.initrd.systemd.suppressedUnits = mkIf config.systemd.enableEmergencyMode [
"emergency.service" "emergency.service"
"emergency.target" "emergency.target"
]; ];
systemd.sleep.extraConfig = ''
AllowSuspend=no
AllowHibernation=no
'';
# force reboots
systemd.settings.Manager = {
RuntimeWatchdogSec = mkDefault "15s";
RebootWatchdogSec = mkDefault "30s";
KExecWatchdogSec = mkDefault "1m";
};
} }

View file

@ -4,7 +4,9 @@ let
inherit (lib) mkDefault; inherit (lib) mkDefault;
in in
{ {
services.qemuGuest.enable = mkDefault true; services = {
services.spice-vdagentd.enable = mkDefault true; qemuGuest.enable = mkDefault true;
services.spice-webdavd.enable = mkDefault true; spice-vdagentd.enable = mkDefault true;
spice-webdavd.enable = mkDefault true;
};
} }

View file

@ -2,9 +2,9 @@
let let
cfg = config.services.ftp-webserver; cfg = config.services.ftp-webserver;
domain = config.networking.domain; inherit (config.networking) domain;
fqdn = if (cfg.subdomain != "") then "${cfg.subdomain}.${domain}" else domain; fqdn = if (cfg.subdomain != "") then "${cfg.subdomain}.${domain}" else domain;
nginx = config.services.nginx; inherit (config.services) nginx;
inherit (lib) inherit (lib)
mkEnableOption mkEnableOption
@ -35,7 +35,7 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.nginx.virtualHosts."${fqdn}" = { services.nginx.virtualHosts."${fqdn}" = {
root = cfg.root; inherit (cfg) root;
locations."/" = { locations."/" = {
extraConfig = '' extraConfig = ''
autoindex on; autoindex on;
@ -43,7 +43,7 @@ in
autoindex_localtime on; autoindex_localtime on;
''; '';
}; };
forceSSL = cfg.forceSSL; inherit (cfg) forceSSL;
enableACME = cfg.forceSSL; enableACME = cfg.forceSSL;
sslCertificate = mkIf cfg.forceSSL "${config.security.acme.certs."${fqdn}".directory}/cert.pem"; sslCertificate = mkIf cfg.forceSSL "${config.security.acme.certs."${fqdn}".directory}/cert.pem";
sslCertificateKey = mkIf cfg.forceSSL "${config.security.acme.certs."${fqdn}".directory}/key.pem"; sslCertificateKey = mkIf cfg.forceSSL "${config.security.acme.certs."${fqdn}".directory}/key.pem";

View file

@ -7,10 +7,10 @@
let let
cfg = config.services.headplane; cfg = config.services.headplane;
domain = config.networking.domain; inherit (config.networking) domain;
subdomain = cfg.reverseProxy.subdomain; inherit (cfg.reverseProxy) subdomain;
fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain; fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain;
headscale = config.services.headscale; inherit (config.services) headscale;
inherit (lib) inherit (lib)
mkDefault mkDefault
@ -55,7 +55,7 @@ in
services.nginx.virtualHosts = mkIf cfg.reverseProxy.enable { services.nginx.virtualHosts = mkIf cfg.reverseProxy.enable {
"${fqdn}" = mkVirtualHost { "${fqdn}" = mkVirtualHost {
port = cfg.settings.server.port; inherit (cfg.settings.server) port;
ssl = cfg.reverseProxy.forceSSL; ssl = cfg.reverseProxy.forceSSL;
}; };
}; };
@ -63,7 +63,7 @@ in
sops.secrets = sops.secrets =
let let
owner = headscale.user; owner = headscale.user;
group = headscale.group; inherit (headscale) group;
mode = "0400"; mode = "0400";
in in
{ {

View file

@ -6,8 +6,8 @@
let let
cfg = config.services.headscale; cfg = config.services.headscale;
domain = config.networking.domain; inherit (config.networking) domain;
subdomain = cfg.reverseProxy.subdomain; inherit (cfg.reverseProxy) subdomain;
fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain; fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain;
acl = "headscale/acl.hujson"; acl = "headscale/acl.hujson";

View file

@ -8,23 +8,9 @@ in
programs.dconf.enable = true; # fixes nixvim hm module programs.dconf.enable = true; # fixes nixvim hm module
services.flatpak.enable = true; services = {
flatpak.enable = true;
xdg.portal = { gnome.gnome-keyring.enable = true;
enable = true; udisks2.enable = mkDefault true;
extraPortals = with pkgs; [
xdg-desktop-portal-gtk
];
config.common.default = "gtk";
}; };
services.gnome.gnome-keyring.enable = true;
security.pam.services = {
login = {
enableGnomeKeyring = true;
};
hyprlock = { };
};
services.udisks2.enable = mkDefault true;
} }

View file

@ -7,8 +7,8 @@
let let
cfg = config.services.jellyfin; cfg = config.services.jellyfin;
domain = config.networking.domain; inherit (config.networking) domain;
subdomain = cfg.reverseProxy.subdomain; inherit (cfg.reverseProxy) subdomain;
fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain; fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain;
inherit (lib) inherit (lib)
@ -48,9 +48,7 @@ in
]; ];
systemd.tmpfiles.rules = systemd.tmpfiles.rules =
(map ( (map (library: "d ${cfg.dataDir}/libraries/${library} 0770 ${cfg.user} ${cfg.group} -") cfg.libraries)
library: "d ${cfg.dataDir}/libraries/${library} 0770 ${cfg.user} ${cfg.group} -"
) cfg.libraries)
++ [ ++ [
"z ${cfg.dataDir} 0770 ${cfg.user} ${cfg.group} -" "z ${cfg.dataDir} 0770 ${cfg.user} ${cfg.group} -"
"Z ${cfg.dataDir}/libraries 0770 ${cfg.user} ${cfg.group} -" "Z ${cfg.dataDir}/libraries 0770 ${cfg.user} ${cfg.group} -"

View file

@ -2,8 +2,8 @@
let let
cfg = config.services.jirafeau; cfg = config.services.jirafeau;
domain = config.networking.domain; inherit (config.networking) domain;
subdomain = cfg.reverseProxy.subdomain; inherit (cfg.reverseProxy) subdomain;
fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain; fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain;
inherit (lib) inherit (lib)

View file

@ -8,75 +8,351 @@
let let
cfg = config.services.librechat-oci; cfg = config.services.librechat-oci;
image = pkgs.dockerTools.pullImage { defaultImages = {
imageName = "ghcr.io/danny-avila/librechat"; librechat = pkgs.dockerTools.pullImage {
imageDigest = "sha256:a46254938507971e0d4f7ed3f9d116bd9b118f4810b5b75eb716baf575645068"; imageName = "ghcr.io/danny-avila/librechat";
hash = "sha256-zevUN6vrs3hymwCGFmk/YXlUzYjN37H+EO5aLxYchyc="; imageDigest = "sha256:a46254938507971e0d4f7ed3f9d116bd9b118f4810b5b75eb716baf575645068";
finalImageName = "ghcr.io/danny-avila/librechat"; hash = "sha256-zevUN6vrs3hymwCGFmk/YXlUzYjN37H+EO5aLxYchyc=";
finalImageTag = "v0.8.5"; finalImageName = "ghcr.io/danny-avila/librechat";
finalImageTag = "v0.8.5";
};
meilisearch = pkgs.dockerTools.pullImage {
imageName = "getmeili/meilisearch";
imageDigest = "sha256:b839a48d008d4e67e57f78dcff5b21d5e8b8fa066bacd11f97824d6307abb0dd";
hash = "sha256-+hypvjFDSdnnWAO4tARTnjNd/6HlF6pMg1L6UUffdYM=";
finalImageName = "getmeili/meilisearch";
finalImageTag = "v1.44.0";
};
mongodb = pkgs.dockerTools.pullImage {
imageName = "mongo";
imageDigest = "sha256:098862b1339f031900ca66cf8fef799e616d6324fa41b9a263f2ec899552c1ef";
hash = "sha256-XuWnvcqAAkAGshdQtnngKOOJP2Bd33FXTbGHTRX3nUc=";
finalImageName = "mongo";
finalImageTag = "8.0.20";
};
vectordb = pkgs.dockerTools.pullImage {
imageName = "pgvector/pgvector";
imageDigest = "sha256:8809cfffff0082cf260c9ac752f1dd1afc77f6f0a55c4e6411321e78efc3d9a5";
hash = "sha256-rc6gQLMzv8UOZVLmWKGUESNIo+iPf5DR7T79AmbzWc4=";
finalImageName = "pgvector/pgvector";
finalImageTag = "0.8.0-pg15-trixie";
};
ragApi = pkgs.dockerTools.pullImage {
imageName = "registry.librechat.ai/danny-avila/librechat-rag-api-dev-lite";
imageDigest = "sha256:6dfb6832661ff9c26fa329c823ce266059e33567670a763e9ecb9b566b8daa68";
hash = "sha256-k8pkEgbqT4NU2+2ZjdRFlfFvMUk/1p+pkysbELh95pM=";
finalImageName = "registry.librechat.ai/danny-avila/librechat-rag-api-dev-lite";
finalImageTag = "latest";
};
}; };
defaultEnv = { defaultEnv = {
# Server
HOST = "0.0.0.0"; HOST = "0.0.0.0";
PORT = "3080"; PORT = toString cfg.port;
NO_INDEX = "true"; NO_INDEX = "true";
DEBUG_LOGGING = "false"; TRUST_PROXY = "1";
# Logging
CONSOLE_JSON = "false"; CONSOLE_JSON = "false";
ALLOW_REGISTRATION = "true"; DEBUG_LOGGING = "true";
ALLOW_EMAIL_LOGIN = "true"; DEBUG_CONSOLE = "false";
AGENT_DEBUG_LOGGING = "false";
DEBUG_OPENAI = "false";
# Node
NODE_MAX_OLD_SPACE_SIZE = "6144";
# Search
SEARCH = "true"; SEARCH = "true";
MEILI_NO_ANALYTICS = "true"; MEILI_NO_ANALYTICS = "true";
# Moderation
OPENAI_MODERATION = "false";
BAN_VIOLATIONS = "true";
BAN_DURATION = "1000 * 60 * 60 * 2";
BAN_INTERVAL = "20";
LOGIN_VIOLATION_SCORE = "1";
REGISTRATION_VIOLATION_SCORE = "1";
CONCURRENT_VIOLATION_SCORE = "1";
MESSAGE_VIOLATION_SCORE = "1";
NON_BROWSER_VIOLATION_SCORE = "20";
TTS_VIOLATION_SCORE = "0";
STT_VIOLATION_SCORE = "0";
FORK_VIOLATION_SCORE = "0";
IMPORT_VIOLATION_SCORE = "0";
FILE_UPLOAD_VIOLATION_SCORE = "0";
LOGIN_MAX = "7";
LOGIN_WINDOW = "5";
REGISTER_MAX = "5";
REGISTER_WINDOW = "60";
LIMIT_CONCURRENT_MESSAGES = "true";
CONCURRENT_MESSAGE_MAX = "2";
LIMIT_MESSAGE_IP = "true";
MESSAGE_IP_MAX = "40";
MESSAGE_IP_WINDOW = "1";
LIMIT_MESSAGE_USER = "false";
MESSAGE_USER_MAX = "40";
MESSAGE_USER_WINDOW = "1";
ILLEGAL_MODEL_REQ_SCORE = "5";
# Registration and login
ALLOW_EMAIL_LOGIN = "true";
ALLOW_REGISTRATION = "false";
ALLOW_SOCIAL_LOGIN = "false";
ALLOW_SOCIAL_REGISTRATION = "false";
ALLOW_PASSWORD_RESET = "false";
ALLOW_UNVERIFIED_EMAIL_LOGIN = "true";
SESSION_EXPIRY = "1000 * 60 * 15";
REFRESH_TOKEN_EXPIRY = "(1000 * 60 * 60 * 24) * 7";
# OpenID
OPENID_SCOPE = "openid profile email";
OPENID_CALLBACK_URL = "/oauth/openid/callback";
OPENID_AUTO_REDIRECT = "false";
OPENID_USE_PKCE = "false";
OPENID_ON_BEHALF_FLOW_USERINFO_SCOPE = "user.read";
# OAuth callback URLs
DISCORD_CALLBACK_URL = "/oauth/discord/callback";
FACEBOOK_CALLBACK_URL = "/oauth/facebook/callback";
GITHUB_CALLBACK_URL = "/oauth/github/callback";
GOOGLE_CALLBACK_URL = "/oauth/google/callback";
APPLE_CALLBACK_URL = "/oauth/apple/callback";
SAML_CALLBACK_URL = "/oauth/saml/callback";
# Entra ID
USE_ENTRA_ID_FOR_PEOPLE_SEARCH = "false";
ENTRA_ID_INCLUDE_OWNERS_AS_MEMBERS = "false";
OPENID_GRAPH_SCOPES = "User.Read,People.Read,GroupMember.Read.All";
# Shared links
ALLOW_SHARED_LINKS = "true";
ALLOW_SHARED_LINKS_PUBLIC = "false";
# UI
APP_TITLE = "LibreChat";
HELP_AND_FAQ_URL = "https://librechat.ai";
# Flux
FLUX_API_BASE_URL = "https://api.us1.bfl.ai";
# Email
EMAIL_PORT = "25";
EMAIL_FROM = "noreply@librechat.ai";
# Azure Blob Storage
AZURE_STORAGE_PUBLIC_ACCESS = "false";
AZURE_CONTAINER_NAME = "files";
}; };
mkImageOption =
name: description:
mkOption {
type = types.package;
default = defaultImages.${name};
inherit description;
};
inherit (lib) inherit (lib)
literalExpression literalExpression
mkEnableOption mkEnableOption
mkIf mkIf
mkOption mkOption
mkOverride mkOverride
optional
types types
; ;
in in
{ {
options.services.librechat-oci = { options.services.librechat-oci = {
enable = mkEnableOption "LibreChat container with Podman."; enable = mkEnableOption "LibreChat container with Podman.";
image = mkOption {
type = types.package; images = {
default = image; librechat = mkImageOption "librechat" "The LibreChat Docker image (`pkgs.dockerTools.pullImage`).";
description = "The Docker image to use (`pkgs.dockerTools.pullImage`)."; meilisearch = mkImageOption "meilisearch" "The Meilisearch Docker image (`pkgs.dockerTools.pullImage`).";
mongodb = mkImageOption "mongodb" "The MongoDB Docker image (`pkgs.dockerTools.pullImage`).";
vectordb = mkImageOption "vectordb" "The pgvector Docker image (`pkgs.dockerTools.pullImage`).";
ragApi = mkImageOption "ragApi" "The LibreChat RAG API Docker image (`pkgs.dockerTools.pullImage`).";
}; };
configFile = mkOption {
type = types.nullOr types.path;
default = null;
example = literalExpression "./librechat.yaml";
description = "Path to the `librechat.yaml` configuration file.";
};
externalUrl = mkOption { externalUrl = mkOption {
type = types.nullOr types.str; type = types.nullOr types.str;
default = null; default = null;
example = literalExpression "http://${config.networking.domain}"; example = literalExpression ''"https://chat.example.com"'';
description = "Public URL to configure for LibreChat."; description = "Public URL to configure for LibreChat (sets DOMAIN_CLIENT and DOMAIN_SERVER).";
}; };
port = mkOption { port = mkOption {
type = types.port; type = types.port;
default = 3080; default = 3080;
description = "Which port the LibreChat server listens to."; description = "Which port the LibreChat server listens on.";
}; };
meiliPort = mkOption {
type = types.port;
default = 7700;
description = "Which port Meilisearch listens on.";
};
ragPort = mkOption {
type = types.port;
default = 8000;
description = "Which port the RAG API listens on.";
};
environment = mkOption { environment = mkOption {
default = { }; default = { };
type = types.attrsOf types.str; type = types.attrsOf types.str;
description = '' description = ''
Extra environment variables for LibreChat. Extra environment variables for LibreChat.
For more details see <https://docs.librechat.ai/docs/configuration/dotenv> These are merged on top of the defaults and can override them.
For secrets use <option>environmentFile</option> instead.
See <https://docs.librechat.ai/docs/configuration/dotenv>.
''; '';
}; };
environmentFile = mkOption { environmentFile = mkOption {
description = "Environment file to be passed to the LibreChat container.";
type = types.nullOr types.path; type = types.nullOr types.path;
default = null; default = null;
example = "config.sops.templates.librechat-env.path"; example = literalExpression "config.sops.templates.librechat-env.path";
description = ''
Environment file passed to the LibreChat, Meilisearch, and RAG API
containers. Use this for secrets such as JWT_SECRET, CREDS_KEY,
MEILI_MASTER_KEY, and API keys.
'';
}; };
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
virtualisation.podman = { virtualisation = {
enable = true; podman = {
autoPrune.enable = true; enable = true;
dockerCompat = true; autoPrune.enable = true;
dockerCompat = true;
};
oci-containers = {
backend = "podman";
containers = {
librechat-mongodb = {
image = with cfg.images.mongodb; "${imageName}:${imageTag}";
imageFile = cfg.images.mongodb;
cmd = [
"mongod"
"--noauth"
];
volumes = [
"librechat_mongodb_data:/data/db:rw"
];
log-driver = "journald";
extraOptions = [
"--network-alias=mongodb"
"--network=librechat_default"
];
};
librechat-meilisearch = {
image = with cfg.images.meilisearch; "${imageName}:${imageTag}";
imageFile = cfg.images.meilisearch;
environment = {
MEILI_NO_ANALYTICS = "true";
MEILI_HOST = "http://meilisearch:${toString cfg.meiliPort}";
};
environmentFiles = optional (cfg.environmentFile != null) cfg.environmentFile;
volumes = [
"librechat_meili_data:/meili_data:rw"
];
log-driver = "journald";
extraOptions = [
"--network-alias=meilisearch"
"--network=librechat_default"
];
};
librechat-vectordb = {
image = with cfg.images.vectordb; "${imageName}:${imageTag}";
imageFile = cfg.images.vectordb;
environment = {
POSTGRES_DB = "mydatabase";
POSTGRES_USER = "myuser";
POSTGRES_PASSWORD = "mypassword";
};
volumes = [
"librechat_pgdata:/var/lib/postgresql/data:rw"
];
log-driver = "journald";
extraOptions = [
"--network-alias=vectordb"
"--network=librechat_default"
];
};
librechat-rag-api = {
image = with cfg.images.ragApi; "${imageName}:${imageTag}";
imageFile = cfg.images.ragApi;
environment = {
DB_HOST = "vectordb";
RAG_PORT = toString cfg.ragPort;
};
environmentFiles = optional (cfg.environmentFile != null) cfg.environmentFile;
dependsOn = [ "librechat-vectordb" ];
log-driver = "journald";
extraOptions = [
"--network-alias=rag_api"
"--network=librechat_default"
];
};
librechat = {
image = with cfg.images.librechat; "${imageName}:${imageTag}";
imageFile = cfg.images.librechat;
environment =
defaultEnv
// {
MONGO_URI = "mongodb://mongodb:27017/LibreChat";
MEILI_HOST = "http://meilisearch:${toString cfg.meiliPort}";
RAG_PORT = toString cfg.ragPort;
RAG_API_URL = "http://rag_api:${toString cfg.ragPort}";
DOMAIN_CLIENT = if cfg.externalUrl != null then cfg.externalUrl else "http://localhost:${toString cfg.port}";
DOMAIN_SERVER = if cfg.externalUrl != null then cfg.externalUrl else "http://localhost:${toString cfg.port}";
}
// cfg.environment;
environmentFiles = optional (cfg.environmentFile != null) cfg.environmentFile;
volumes = [
"librechat_images:/app/client/public/images:rw"
"librechat_uploads:/app/uploads:rw"
"librechat_logs:/app/logs:rw"
]
++ optional (cfg.configFile != null) "${cfg.configFile}:/app/librechat.yaml:ro";
ports = [
"0.0.0.0:${toString cfg.port}:${toString cfg.port}/tcp"
];
dependsOn = [
"librechat-mongodb"
"librechat-rag-api"
];
log-driver = "journald";
extraOptions = [
"--network-alias=api"
"--network=librechat_default"
];
};
};
};
}; };
networking.firewall.interfaces = networking.firewall.interfaces =
@ -87,161 +363,173 @@ in
"${matchAll}".allowedUDPPorts = [ 53 ]; "${matchAll}".allowedUDPPorts = [ 53 ];
}; };
virtualisation.oci-containers.backend = "podman"; systemd = {
services = {
podman-librechat-mongodb = {
serviceConfig.Restart = mkOverride 90 "always";
after = [
"podman-network-librechat_default.service"
"podman-volume-librechat_mongodb_data.service"
];
requires = [
"podman-network-librechat_default.service"
"podman-volume-librechat_mongodb_data.service"
];
partOf = [ "podman-compose-librechat-root.target" ];
wantedBy = [ "podman-compose-librechat-root.target" ];
};
virtualisation.oci-containers.containers."librechat-mongodb" = { podman-librechat-meilisearch = {
image = "mongo:7.0"; serviceConfig.Restart = mkOverride 90 "always";
environment = { after = [
MONGO_INITDB_ROOT_USERNAME = "root"; "podman-network-librechat_default.service"
MONGO_INITDB_ROOT_PASSWORD = "librechat"; "podman-volume-librechat_meili_data.service"
MONGO_INITDB_DATABASE = "LibreChat"; ];
requires = [
"podman-network-librechat_default.service"
"podman-volume-librechat_meili_data.service"
];
partOf = [ "podman-compose-librechat-root.target" ];
wantedBy = [ "podman-compose-librechat-root.target" ];
};
podman-librechat-vectordb = {
serviceConfig.Restart = mkOverride 90 "always";
after = [
"podman-network-librechat_default.service"
"podman-volume-librechat_pgdata.service"
];
requires = [
"podman-network-librechat_default.service"
"podman-volume-librechat_pgdata.service"
];
partOf = [ "podman-compose-librechat-root.target" ];
wantedBy = [ "podman-compose-librechat-root.target" ];
};
podman-librechat-rag-api = {
serviceConfig.Restart = mkOverride 90 "always";
after = [
"podman-network-librechat_default.service"
"podman-librechat-vectordb.service"
];
requires = [
"podman-network-librechat_default.service"
"podman-librechat-vectordb.service"
];
partOf = [ "podman-compose-librechat-root.target" ];
wantedBy = [ "podman-compose-librechat-root.target" ];
};
podman-librechat = {
serviceConfig.Restart = mkOverride 90 "always";
after = [
"podman-network-librechat_default.service"
"podman-volume-librechat_images.service"
"podman-volume-librechat_uploads.service"
"podman-volume-librechat_logs.service"
"podman-librechat-mongodb.service"
"podman-librechat-meilisearch.service"
"podman-librechat-rag-api.service"
];
requires = [
"podman-network-librechat_default.service"
"podman-volume-librechat_images.service"
"podman-volume-librechat_uploads.service"
"podman-volume-librechat_logs.service"
"podman-librechat-mongodb.service"
"podman-librechat-meilisearch.service"
"podman-librechat-rag-api.service"
];
partOf = [ "podman-compose-librechat-root.target" ];
wantedBy = [ "podman-compose-librechat-root.target" ];
};
podman-network-librechat_default = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStop = "podman network rm -f librechat_default";
};
script = ''
podman network inspect librechat_default || podman network create librechat_default
'';
partOf = [ "podman-compose-librechat-root.target" ];
wantedBy = [ "podman-compose-librechat-root.target" ];
};
podman-volume-librechat_mongodb_data = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = "podman volume inspect librechat_mongodb_data || podman volume create librechat_mongodb_data";
partOf = [ "podman-compose-librechat-root.target" ];
wantedBy = [ "podman-compose-librechat-root.target" ];
};
podman-volume-librechat_meili_data = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = "podman volume inspect librechat_meili_data || podman volume create librechat_meili_data";
partOf = [ "podman-compose-librechat-root.target" ];
wantedBy = [ "podman-compose-librechat-root.target" ];
};
podman-volume-librechat_pgdata = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = "podman volume inspect librechat_pgdata || podman volume create librechat_pgdata";
partOf = [ "podman-compose-librechat-root.target" ];
wantedBy = [ "podman-compose-librechat-root.target" ];
};
podman-volume-librechat_images = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = "podman volume inspect librechat_images || podman volume create librechat_images";
partOf = [ "podman-compose-librechat-root.target" ];
wantedBy = [ "podman-compose-librechat-root.target" ];
};
podman-volume-librechat_uploads = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = "podman volume inspect librechat_uploads || podman volume create librechat_uploads";
partOf = [ "podman-compose-librechat-root.target" ];
wantedBy = [ "podman-compose-librechat-root.target" ];
};
podman-volume-librechat_logs = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = "podman volume inspect librechat_logs || podman volume create librechat_logs";
partOf = [ "podman-compose-librechat-root.target" ];
wantedBy = [ "podman-compose-librechat-root.target" ];
};
}; };
volumes = [
"librechat_mongodb_data:/data/db:rw"
];
log-driver = "journald";
extraOptions = [
"--network=host"
];
};
virtualisation.oci-containers.containers.librechat = { targets.podman-compose-librechat-root = {
image = toString cfg.image; unitConfig.Description = "Root target generated by compose2nix.";
environment = wantedBy = [ "multi-user.target" ];
defaultEnv
// {
MONGO_URI = "mongodb://root:librechat@localhost:27017/LibreChat?authSource=admin";
}
// cfg.environment;
volumes = [
"librechat_data:/app/client/data:rw"
"librechat_images:/app/client/public/images:rw"
"librechat_uploads:/app/api/server/files/uploads:rw"
"librechat_logs:/app/logs:rw"
];
ports = [
"${toString cfg.port}:${toString cfg.port}"
];
log-driver = "journald";
extraOptions = [
"--network=host"
];
};
systemd.services."podman-librechat-mongodb" = {
serviceConfig = {
Restart = mkOverride 90 "always";
}; };
after = [
"podman-volume-librechat_mongodb_data.service"
];
requires = [
"podman-volume-librechat_mongodb_data.service"
];
partOf = [
"podman-compose-librechat-root.target"
];
wantedBy = [
"podman-compose-librechat-root.target"
];
};
systemd.services."podman-librechat" = {
serviceConfig = {
Restart = mkOverride 90 "always";
};
after = [
"podman-volume-librechat_data.service"
"podman-volume-librechat_images.service"
"podman-volume-librechat_uploads.service"
"podman-volume-librechat_logs.service"
"podman-librechat-mongodb.service"
];
requires = [
"podman-volume-librechat_data.service"
"podman-volume-librechat_images.service"
"podman-volume-librechat_uploads.service"
"podman-volume-librechat_logs.service"
"podman-librechat-mongodb.service"
];
partOf = [
"podman-compose-librechat-root.target"
];
wantedBy = [
"podman-compose-librechat-root.target"
];
};
systemd.services."podman-volume-librechat_data" = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
podman volume inspect librechat_data || podman volume create librechat_data
'';
partOf = [ "podman-compose-librechat-root.target" ];
wantedBy = [ "podman-compose-librechat-root.target" ];
};
systemd.services."podman-volume-librechat_images" = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
podman volume inspect librechat_images || podman volume create librechat_images
'';
partOf = [ "podman-compose-librechat-root.target" ];
wantedBy = [ "podman-compose-librechat-root.target" ];
};
systemd.services."podman-volume-librechat_uploads" = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
podman volume inspect librechat_uploads || podman volume create librechat_uploads
'';
partOf = [ "podman-compose-librechat-root.target" ];
wantedBy = [ "podman-compose-librechat-root.target" ];
};
systemd.services."podman-volume-librechat_logs" = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
podman volume inspect librechat_logs || podman volume create librechat_logs
'';
partOf = [ "podman-compose-librechat-root.target" ];
wantedBy = [ "podman-compose-librechat-root.target" ];
};
systemd.services."podman-volume-librechat_mongodb_data" = {
path = [ pkgs.podman ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
podman volume inspect librechat_mongodb_data || podman volume create librechat_mongodb_data
'';
partOf = [ "podman-compose-librechat-root.target" ];
wantedBy = [ "podman-compose-librechat-root.target" ];
};
systemd.targets."podman-compose-librechat-root" = {
unitConfig = {
Description = "Root target generated by compose2nix.";
};
wantedBy = [ "multi-user.target" ];
}; };
}; };
} }

View file

@ -8,7 +8,7 @@
let let
cfg = config.mailserver; cfg = config.mailserver;
domain = config.networking.domain; inherit (config.networking) domain;
fqdn = "${cfg.subdomain}.${domain}"; fqdn = "${cfg.subdomain}.${domain}";
inherit (lib) inherit (lib)
@ -74,7 +74,7 @@ in
nameValuePair "${user}@${domain}" { nameValuePair "${user}@${domain}" {
name = "${user}@${domain}"; name = "${user}@${domain}";
aliases = map (alias: "${alias}@${domain}") (accConf.aliases or [ ]); aliases = map (alias: "${alias}@${domain}") (accConf.aliases or [ ]);
sendOnly = accConf.sendOnly; inherit (accConf) sendOnly;
quota = mkDefault "5G"; quota = mkDefault "5G";
hashedPasswordFile = config.sops.secrets."mailserver/accounts/${user}".path; hashedPasswordFile = config.sops.secrets."mailserver/accounts/${user}".path;
} }

View file

@ -23,7 +23,7 @@ let
services."mautrix-${name}" = { services."mautrix-${name}" = {
enable = true; enable = true;
package = cfg.bridges.${name}.package; inherit (cfg.bridges.${name}) package;
environmentFile = mkIf cfg.sops config.sops.templates."mautrix-${name}/env-file".path; environmentFile = mkIf cfg.sops config.sops.templates."mautrix-${name}/env-file".path;
settings = { settings = {
bridge = { bridge = {
@ -71,33 +71,29 @@ let
mode = "0400"; mode = "0400";
in in
{ {
secrets."mautrix-${name}/encryption-pickle-key" = { secrets = {
inherit owner group mode; "mautrix-${name}/encryption-pickle-key" = {
}; inherit owner group mode;
secrets."mautrix-${name}/provisioning-shared-secret" = { };
inherit owner group mode; "mautrix-${name}/provisioning-shared-secret" = {
}; inherit owner group mode;
secrets."mautrix-${name}/public-media-signing-key" = { };
inherit owner group mode; "mautrix-${name}/public-media-signing-key" = {
}; inherit owner group mode;
secrets."mautrix-${name}/direct-media-server-key" = { };
inherit owner group mode; "mautrix-${name}/direct-media-server-key" = {
inherit owner group mode;
};
}; };
templates."mautrix-${name}/env-file" = { templates."mautrix-${name}/env-file" = {
inherit owner group mode; inherit owner group mode;
content = '' content = ''
MAUTRIX_${toUpper name}_ENCRYPTION_PICKLE_KEY=${ MAUTRIX_${toUpper name}_ENCRYPTION_PICKLE_KEY=${config.sops.placeholder."mautrix-${name}/encryption-pickle-key"}
config.sops.placeholder."mautrix-${name}/encryption-pickle-key"
}
MAUTRIX_${toUpper name}_PROVISIONING_SHARED_SECRET=${ MAUTRIX_${toUpper name}_PROVISIONING_SHARED_SECRET=${
config.sops.placeholder."mautrix-${name}/provisioning-shared-secret" config.sops.placeholder."mautrix-${name}/provisioning-shared-secret"
} }
MAUTRIX_${toUpper name}_PUBLIC_MEDIA_SIGNING_KEY=${ MAUTRIX_${toUpper name}_PUBLIC_MEDIA_SIGNING_KEY=${config.sops.placeholder."mautrix-${name}/public-media-signing-key"}
config.sops.placeholder."mautrix-${name}/public-media-signing-key" MAUTRIX_${toUpper name}_DIRECT_MEDIA_SERVER_KEY=${config.sops.placeholder."mautrix-${name}/direct-media-server-key"}
}
MAUTRIX_${toUpper name}_DIRECT_MEDIA_SERVER_KEY=${
config.sops.placeholder."mautrix-${name}/direct-media-server-key"
}
''; '';
}; };
} }

View file

@ -84,77 +84,74 @@ in
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.postgresql = { services = {
enable = true; postgresql = {
initialScript = pkgs.writeText "synapse-init.sql" '' enable = true;
CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse'; initialScript = pkgs.writeText "synapse-init.sql" ''
CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse" CREATE ROLE "matrix-synapse" WITH LOGIN PASSWORD 'synapse';
TEMPLATE template0 CREATE DATABASE "matrix-synapse" WITH OWNER "matrix-synapse"
LC_COLLATE = 'C' TEMPLATE template0
LC_CTYPE = 'C'; LC_COLLATE = 'C'
''; LC_CTYPE = 'C';
}; '';
};
services.matrix-synapse = mkMerge [ matrix-synapse = mkMerge [
{ {
settings = { settings = {
registration_shared_secret_path = registration_shared_secret_path = mkIf cfg.sops config.sops.secrets."matrix/registration-shared-secret".path;
mkIf cfg.sops server_name = config.networking.domain;
config.sops.secrets."matrix/registration-shared-secret".path; public_baseurl = baseUrl;
server_name = config.networking.domain; listeners = [
public_baseurl = baseUrl; {
listeners = [ inherit (cfg) port;
{ bind_addresses = [ "127.0.0.1" ];
inherit (cfg) port; resources = [
bind_addresses = [ "127.0.0.1" ]; {
resources = [ compress = true;
{ names = [ "client" ];
compress = true; }
names = [ "client" ]; {
} compress = false;
{ names = [ "federation" ];
compress = false; }
names = [ "federation" ]; ];
} tls = false;
]; type = "http";
tls = false; x_forwarded = true;
type = "http"; }
x_forwarded = true; ];
} };
]; }
(mkIf cfg.coturn.enable {
settings = {
turn_uris = with cfg.coturn; [
"turn:${realm}:${toString listening-port}?transport=udp"
"turn:${realm}:${toString listening-port}?transport=tcp"
"turn:${realm}:${toString tls-listening-port}?transport=udp"
"turn:${realm}:${toString tls-listening-port}?transport=tcp"
"turn:${realm}:${toString alt-listening-port}?transport=udp"
"turn:${realm}:${toString alt-listening-port}?transport=tcp"
"turn:${realm}:${toString alt-tls-listening-port}?transport=udp"
"turn:${realm}:${toString alt-tls-listening-port}?transport=tcp"
];
extraConfigFiles = mkIf cfg.sops [ config.sops.templates."coturn/static-auth-secret.env".path ];
turn_user_lifetime = "1h";
};
})
];
nginx.virtualHosts."${cfg.settings.server_name}" = {
enableACME = true;
forceSSL = true;
locations = {
"= /.well-known/matrix/server".extraConfig = mkWellKnown serverConfig;
"= /.well-known/matrix/client".extraConfig = mkWellKnown clientConfig;
"/_matrix".proxyPass = "http://127.0.0.1:${toString cfg.port}";
"/_synapse".proxyPass = "http://127.0.0.1:${toString cfg.port}";
}; };
} };
(mkIf cfg.coturn.enable {
settings = {
turn_uris = with cfg.coturn; [
"turn:${realm}:${toString listening-port}?transport=udp"
"turn:${realm}:${toString listening-port}?transport=tcp"
"turn:${realm}:${toString tls-listening-port}?transport=udp"
"turn:${realm}:${toString tls-listening-port}?transport=tcp"
"turn:${realm}:${toString alt-listening-port}?transport=udp"
"turn:${realm}:${toString alt-listening-port}?transport=tcp"
"turn:${realm}:${toString alt-tls-listening-port}?transport=udp"
"turn:${realm}:${toString alt-tls-listening-port}?transport=tcp"
];
extraConfigFiles = mkIf cfg.sops [ config.sops.templates."coturn/static-auth-secret.env".path ];
turn_user_lifetime = "1h";
};
})
];
environment.shellAliases = mkIf cfg.sops {
register_new_matrix_user = "${cfg.package}/bin/register_new_matrix_user -k $(sudo cat ${cfg.settings.registration_shared_secret_path})";
};
services.nginx.virtualHosts."${cfg.settings.server_name}" = {
enableACME = true;
forceSSL = true;
locations."= /.well-known/matrix/server".extraConfig = mkWellKnown serverConfig;
locations."= /.well-known/matrix/client".extraConfig = mkWellKnown clientConfig;
locations."/_matrix".proxyPass = "http://127.0.0.1:${toString cfg.port}";
locations."/_synapse".proxyPass = "http://127.0.0.1:${toString cfg.port}";
}; };
sops = mkIf cfg.sops { sops = mkIf cfg.sops {

View file

@ -6,51 +6,53 @@
let let
cfg = config.services.matrix-synapse; cfg = config.services.matrix-synapse;
domain = config.networking.domain; inherit (config.networking) domain;
inherit (lib) mkIf mkDefault; inherit (lib) mkIf mkDefault;
in in
{ {
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.livekit = { services = {
enable = true; livekit = {
settings.port = mkDefault 7880; enable = true;
settings.room.auto_create = mkDefault false; settings.port = mkDefault 7880;
openFirewall = mkDefault true; settings.room.auto_create = mkDefault false;
keyFile = mkIf cfg.sops config.sops.templates."livekit/key".path; openFirewall = mkDefault true;
}; keyFile = mkIf cfg.sops config.sops.templates."livekit/key".path;
};
services.lk-jwt-service = { lk-jwt-service = {
enable = true; enable = true;
port = mkDefault 8080; port = mkDefault 8080;
livekitUrl = "wss://${domain}/livekit/sfu"; livekitUrl = "wss://${domain}/livekit/sfu";
keyFile = mkIf cfg.sops config.sops.templates."livekit/key".path; keyFile = mkIf cfg.sops config.sops.templates."livekit/key".path;
}; };
systemd.services.lk-jwt-service.environment.LIVEKIT_FULL_ACCESS_HOMESERVERS = domain; nginx.virtualHosts = {
"${domain}".locations = {
services.nginx.virtualHosts = { "^~ /livekit/jwt/" = {
"${domain}".locations = { priority = 400;
"^~ /livekit/jwt/" = { proxyPass = "http://127.0.0.1:${toString config.services.lk-jwt-service.port}/";
priority = 400; };
proxyPass = "http://127.0.0.1:${toString config.services.lk-jwt-service.port}/"; "^~ /livekit/sfu/" = {
}; priority = 400;
"^~ /livekit/sfu/" = { proxyPass = "http://127.0.0.1:${toString config.services.livekit.settings.port}/";
priority = 400; proxyWebsockets = true;
proxyPass = "http://127.0.0.1:${toString config.services.livekit.settings.port}/"; extraConfig = ''
proxyWebsockets = true; proxy_send_timeout 120;
extraConfig = '' proxy_read_timeout 120;
proxy_send_timeout 120; proxy_buffering off;
proxy_read_timeout 120; proxy_set_header Accept-Encoding gzip;
proxy_buffering off; proxy_set_header Upgrade $http_upgrade;
proxy_set_header Accept-Encoding gzip; proxy_set_header Connection "upgrade";
proxy_set_header Upgrade $http_upgrade; '';
proxy_set_header Connection "upgrade"; };
'';
}; };
}; };
}; };
systemd.services.lk-jwt-service.environment.LIVEKIT_FULL_ACCESS_HOMESERVERS = domain;
sops = mkIf cfg.sops { sops = mkIf cfg.sops {
secrets."livekit/key" = { }; secrets."livekit/key" = { };
templates."livekit/key".content = '' templates."livekit/key".content = ''

View file

@ -76,7 +76,7 @@ in
sops = mkIf cfg.sops ( sops = mkIf cfg.sops (
let let
owner = user.name; owner = user.name;
group = user.group; inherit (user) group;
mode = "0400"; mode = "0400";
in in
{ {
@ -98,9 +98,7 @@ in
'' ''
admins: admins:
'' ''
+ concatLines ( + concatLines (map (admin: " ${admin}: ${config.sops.placeholder."maubot/admins/${admin}"}") cfg.admins)
map (admin: " ${admin}: ${config.sops.placeholder."maubot/admins/${admin}"}") cfg.admins
)
); );
}; };
} }

View file

@ -28,6 +28,12 @@ in
default = null; default = null;
}; };
port = mkOption {
type = types.port;
default = 8000;
description = "Port on which the mcpo service should listen.";
};
user = mkOption { user = mkOption {
type = types.str; type = types.str;
description = "The user the mcpo service will run as."; description = "The user the mcpo service will run as.";
@ -90,7 +96,7 @@ in
users.users."${cfg.user}" = { users.users."${cfg.user}" = {
isSystemUser = true; isSystemUser = true;
group = cfg.group; inherit (cfg) group;
}; };
users.groups."${cfg.group}" = { }; users.groups."${cfg.group}" = { };
@ -100,7 +106,7 @@ in
after = [ "network.target" ]; after = [ "network.target" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
serviceConfig = { serviceConfig = {
ExecStart = "${getExe cfg.package} --config ${configFile}"; ExecStart = "${getExe cfg.package} --port ${toString cfg.port} --config ${configFile}";
Restart = "on-failure"; Restart = "on-failure";
User = cfg.user; User = cfg.user;
Group = cfg.group; Group = cfg.group;

View file

@ -6,8 +6,8 @@
let let
cfg = config.services.miniflux; cfg = config.services.miniflux;
domain = config.networking.domain; inherit (config.networking) domain;
subdomain = cfg.reverseProxy.subdomain; inherit (cfg.reverseProxy) subdomain;
fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain; fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain;
port = 8085; port = 8085;

View file

@ -50,8 +50,7 @@ in
"1.1.1.1" "1.1.1.1"
"2606:4700:4700::1111" "2606:4700:4700::1111"
]; ];
resolvers = resolvers = if config.networking.nameservers == [ ] then cloudflare else config.networking.nameservers;
if config.networking.nameservers == [ ] then cloudflare else config.networking.nameservers;
in in
map escapeIPv6 resolvers; map escapeIPv6 resolvers;
@ -60,7 +59,7 @@ in
virtualHosts = { virtualHosts = {
"${config.networking.domain}" = mkDefault { "${config.networking.domain}" = mkDefault {
enableACME = cfg.forceSSL; enableACME = cfg.forceSSL;
forceSSL = cfg.forceSSL; inherit (cfg) forceSSL;
}; };
}; };
}; };

View file

@ -21,7 +21,7 @@ in
types.submodule { types.submodule {
options = { options = {
extraGroups = mkOption { extraGroups = mkOption {
type = (types.listOf types.str); type = types.listOf types.str;
default = [ ]; default = [ ];
description = "Extra groups for the user"; description = "Extra groups for the user";
example = [ "wheel" ]; example = [ "wheel" ];
@ -37,7 +37,7 @@ in
description = "Initial password for the user"; description = "Initial password for the user";
}; };
sshKeyFiles = mkOption { sshKeyFiles = mkOption {
type = (types.listOf types.path); type = types.listOf types.path;
default = [ ]; default = [ ];
description = "SSH key files for the user"; description = "SSH key files for the user";
example = [ "/path/to/id_rsa.pub" ]; example = [ "/path/to/id_rsa.pub" ];

Some files were not shown because too many files have changed in this diff Show more