Compare changes

Choose any two refs to compare.

+63 -2
README.md
···
+
# NixOS Configuration
+
+
My personal Nix and NixOS configuration for reproducible, declarative systems and environments across multiple hosts.
+
This is a personal configuration with limited applicability to others, though some patterns may be useful for reference.
+
Common self-hosting services have been extracted to a separate project, [Eilean](https://github.com/RyanGibb/eilean-nix).
+
+
## Usage
+
+
### NixOS
+
+
See the [NixOS manual](https://nixos.org/manual/nixos/stable/#ch-installation) for how to install NixOS.
+
+
1. Clone this repository to `/etc/nixos/` on a NixOS system.
+
2. Set up the host configuration in `/etc/nixos/hosts/<hostname>/`.
+
3. Deploy the host with `nixos-rebuild switch`.
+
+
### Remote Deployment
+
+
[`deploy-rs`](https://github.com/serokell/deploy-rs) can be used to update remote hosts via SSH with `deploy .#hostname`.
+
+
### Home Manager
+
+
For non-NixOS systems, you can use Home Manager standalone:
+
+
1. Install [Nix](https://nixos.org/download/) and [enable flakes](https://nixos.wiki/wiki/flakes#Other_Distros.2C_without_Home-Manager).
+
2. Clone this repository and follow the [Home Manager manual](https://nix-community.github.io/home-manager/index.xhtml#sec-install-standalone).
+
3. Deploy the profile with `home-manager switch`.
+
+
### Nix-on-Droid
+
+
See [upstream](https://github.com/nix-community/nix-on-droid/).
+
+
## Repository Structure
-
My NixOS configs.
+
- [`flake.nix`](./flake.nix) - Entry point where inputs, outputs, and [overlays](https://nixos.org/manual/nixpkgs/stable/#chap-overlays) are defined.
+
The [`flake.lock`](./flake.lock) file locks these inputs for reproducibility.
+
- [`hosts/`](./hosts/) - Host-specific configurations where each subdirectory represents a separate machine.
+
- Hosts are named after animals, following a rough naming scheme where,
+
- Stationary hosts are mammals.
+
- Servers are even-toed ungulates ([Artiodactyls](https://en.wikipedia.org/wiki/Artiodactyl)), e.g. the [Network-Attached Storage (NAS) server](https://ryan.freumh.org/nas.html) [`elephant`](./hosts/elephant).
+
- SBCs are small mammals ([Eulipotyphla](https://en.wikipedia.org/wiki/Eulipotyphla)), e.g. the [Home Assistant](https://www.home-assistant.io/) server and [Zigbee](https://en.wikipedia.org/wiki/Zigbee) bridge [`shrew`](./hosts/shrew).
+
- Desktops are carnivores ([Carnivora](https://en.wikipedia.org/wiki/Carnivora)), e.g. the tower PC [`vulpine`](./hosts/vulpine).
+
- Mobile (battery powered) hosts are reptiles, e.g. the laptop [`gecko`](./hosts/gecko).
+
- Virtual hosts are birds, e.g. the virtual private server (VPS) [`owl`](./hosts/owl).
+
- Work-associated hosts are aquatic, e.g. the VPSs for [Eon](https://github.com/RyanGibb/eon) experiments [`duck`](./hosts/duck), and running the [EEG](https://www.cst.cam.ac.uk/research/eeg) infrastructure including using the federated [Shibboleth](https://www.shibboleth.net/) identity server to provision [Matrix](https://matrix.org/) accounts [`swan`](./hosts/swan).
+
- [`barnacle`](./hosts/barnacle/default.nix) builds an ISO image that can be written to media like a USB flash drive to create a read-only live USB that can be booted to provide the custom environment on all my other hosts and used to, for example, install an operating system, with the [`install.sh`](./hosts/barnacle/install.sh) script.
+
- Each host directory typically contains,
+
- `default.nix` - Main configuration entry point that imports other modules.
+
- `hardware-configuration.nix` - Hardware-specific configuration generated by `nixos-generate-config`.
+
- `minimal.nix` - A minimal configuration that can be useful when updating with insufficient disk space.
+
The minimal configuration can be build, the `default.nix` system garbage collected, and then the updated configuration built.
+
Note this precludes trivial rollback.
+
- Other modules separating functionality, such as `services.nix`.
+
- [`modules/`](./modules/) - NixOS modules of common functionality extracted into modular components which can be enabled by host configurations.
+
- [`pkgs/`](./pkgs/) - Custom package definitions for packages not available in nixpkgs or requiring modifications.
+
- [`home/`](./home/) - Home-manager NixOS modules configurations.
+
- [`secrets/`](./secrets/) - Encrypted secrets managed by agenix.
+
- [`scripts/`](./scripts/) - Miscellaneous scripts.
+
- [`nix-on-droid/`](./nix-on-droid/) - [Nix-on-Droid](./#nix-on-droid) configuration.
-
Uses flakes.
+
## Managing Secrets
+
+
Secrets are managed using [agenix](https://github.com/ryantm/agenix).
+
To add a new secret, update [secrets.nix](./secrets/secrets.nix) and run `cd secrets && agenix -e <secret-name>.age`.
+
To update an existing secret you need only do the latter.
+161 -107
flake.lock
···
"type": "gitlab"
}
},
-
"colour-guesser": {
-
"inputs": {
-
"flake-utils": "flake-utils_2",
-
"nix-filter": "nix-filter",
-
"nixpkgs": [
-
"nixpkgs"
-
]
-
},
-
"locked": {
-
"lastModified": 1713180220,
-
"narHash": "sha256-hTdD8t3/hvaexQXDFL2lsXgyxg93IrTFszXeCrBcmEY=",
-
"ref": "develop",
-
"rev": "6ecf853ca91af2e6ddcecd64e6eaa1214aaf87fa",
-
"revCount": 11,
-
"type": "git",
-
"url": "ssh://git@github.com/ryangibb/colour-guesser.git"
-
},
-
"original": {
-
"ref": "develop",
-
"type": "git",
-
"url": "ssh://git@github.com/ryangibb/colour-guesser.git"
-
}
-
},
"darwin": {
"inputs": {
"nixpkgs": [
···
"type": "github"
}
},
+
"disko": {
+
"inputs": {
+
"nixpkgs": [
+
"nixpkgs"
+
]
+
},
+
"locked": {
+
"lastModified": 1743598667,
+
"narHash": "sha256-ViE7NoFWytYO2uJONTAX35eGsvTYXNHjWALeHAg8OQY=",
+
"owner": "nix-community",
+
"repo": "disko",
+
"rev": "329d3d7e8bc63dd30c39e14e6076db590a6eabe6",
+
"type": "github"
+
},
+
"original": {
+
"owner": "nix-community",
+
"repo": "disko",
+
"type": "github"
+
}
+
},
"eilean": {
"inputs": {
"eon": [
···
]
},
"locked": {
-
"lastModified": 1734089719,
-
"narHash": "sha256-ZBh6KrIQXPGXhR7AWUIMdkY/99MFunfULoNqWpm+K6k=",
+
"lastModified": 1740855157,
+
"narHash": "sha256-qnKyiLva/VVWYTYWH2tN7xxj9jJ4dsl/jOxkpotlZIE=",
"owner": "RyanGibb",
"repo": "eilean-nix",
-
"rev": "e048d7e4fba2029f9e70c2a770b59c1f88575670",
+
"rev": "f68975d7d049ab10b7c26eeceb63a6ddd357bb30",
"type": "github"
},
"original": {
···
},
"eon": {
"inputs": {
-
"flake-utils": "flake-utils_3",
+
"flake-utils": "flake-utils_2",
"nixpkgs": [
"nixpkgs"
],
"opam-nix": "opam-nix"
},
"locked": {
-
"lastModified": 1735557697,
-
"narHash": "sha256-pb/gYk5Yl4osJGoH7wVKeIs211zHRRbMoa14VSF26c0=",
+
"lastModified": 1743149102,
+
"narHash": "sha256-pW24ij8CqAdU8m5OFD1amwNmovf25YRygl1bv+s390o=",
"owner": "RyanGibb",
"repo": "eon",
-
"rev": "ab24e3b9bc36a00b540eb89e77a7789804fd7005",
+
"rev": "81bdd51d1e2651c46df2a1ce38b7df5661e7eef1",
"type": "github"
},
"original": {
···
},
"flake-utils_2": {
"inputs": {
-
"systems": "systems_2"
-
},
-
"locked": {
-
"lastModified": 1681202837,
-
"narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=",
-
"owner": "numtide",
-
"repo": "flake-utils",
-
"rev": "cfacdce06f30d2b68473a46042957675eebb3401",
-
"type": "github"
-
},
-
"original": {
-
"id": "flake-utils",
-
"type": "indirect"
-
}
-
},
-
"flake-utils_3": {
-
"inputs": {
-
"systems": "systems_5"
+
"systems": "systems_4"
},
"locked": {
"lastModified": 1731533236,
···
"type": "github"
}
},
-
"flake-utils_4": {
+
"flake-utils_3": {
"locked": {
"lastModified": 1676283394,
"narHash": "sha256-XX2f9c3iySLCw54rJ/CZs+ZK6IQy7GXNY4nSOyu2QG4=",
···
"type": "indirect"
}
},
-
"flake-utils_5": {
+
"flake-utils_4": {
"inputs": {
-
"systems": "systems_6"
+
"systems": "systems_5"
},
"locked": {
"lastModified": 1694529238,
···
"type": "github"
}
},
-
"flake-utils_6": {
+
"flake-utils_5": {
"locked": {
"lastModified": 1638122382,
"narHash": "sha256-sQzZzAbvKEqN9s0bzWuYmRaA03v40gaJ4+iL1LXjaeI=",
···
"type": "github"
}
},
-
"flake-utils_7": {
+
"flake-utils_6": {
"inputs": {
-
"systems": "systems_7"
+
"systems": "systems_6"
},
"locked": {
"lastModified": 1692799911,
···
},
"fn06-website": {
"inputs": {
-
"flake-utils": "flake-utils_4",
+
"flake-utils": "flake-utils_3",
"nixpkgs": [
"nixpkgs"
]
···
"type": "github"
}
},
+
"gitignore": {
+
"inputs": {
+
"nixpkgs": [
+
"tangled",
+
"nixpkgs"
+
]
+
},
+
"locked": {
+
"lastModified": 1709087332,
+
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
+
"owner": "hercules-ci",
+
"repo": "gitignore.nix",
+
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
+
"type": "github"
+
},
+
"original": {
+
"owner": "hercules-ci",
+
"repo": "gitignore.nix",
+
"type": "github"
+
}
+
},
"gomod2nix": {
"inputs": {
"nixpkgs": [
···
]
},
"locked": {
-
"lastModified": 1736373539,
-
"narHash": "sha256-dinzAqCjenWDxuy+MqUQq0I4zUSfaCvN9rzuCmgMZJY=",
+
"lastModified": 1743387206,
+
"narHash": "sha256-24N3NAuZZbYqZ39NgToZgHUw6M7xHrtrAm18kv0+2Wo=",
"owner": "nix-community",
"repo": "home-manager",
-
"rev": "bd65bc3cde04c16755955630b344bc9e35272c56",
+
"rev": "15c5f9d04fabd176f30286c8f52bbdb2c853a146",
"type": "github"
},
"original": {
···
"type": "github"
}
},
+
"htmx-src": {
+
"flake": false,
+
"locked": {
+
"narHash": "sha256-nm6avZuEBg67SSyyZUhjpXVNstHHgUxrtBHqJgowU08=",
+
"type": "file",
+
"url": "https://unpkg.com/htmx.org@2.0.4/dist/htmx.min.js"
+
},
+
"original": {
+
"type": "file",
+
"url": "https://unpkg.com/htmx.org@2.0.4/dist/htmx.min.js"
+
}
+
},
"hyperbib-eeg": {
"inputs": {
-
"flake-utils": "flake-utils_5",
+
"flake-utils": "flake-utils_4",
"nixpkgs": [
"nixpkgs"
],
···
},
"i3-workspace-history": {
"inputs": {
-
"flake-utils": "flake-utils_7",
+
"flake-utils": "flake-utils_6",
"gomod2nix": "gomod2nix",
"nixpkgs": [
"nixpkgs"
···
"type": "github"
}
},
+
"ia-fonts-src": {
+
"flake": false,
+
"locked": {
+
"lastModified": 1686932517,
+
"narHash": "sha256-2T165nFfCzO65/PIHauJA//S+zug5nUwPcg8NUEydfc=",
+
"owner": "iaolo",
+
"repo": "iA-Fonts",
+
"rev": "f32c04c3058a75d7ce28919ce70fe8800817491b",
+
"type": "github"
+
},
+
"original": {
+
"owner": "iaolo",
+
"repo": "iA-Fonts",
+
"type": "github"
+
}
+
},
+
"indigo": {
+
"flake": false,
+
"locked": {
+
"lastModified": 1738491661,
+
"narHash": "sha256-+njDigkvjH4XmXZMog5Mp0K4x9mamHX6gSGJCZB9mE4=",
+
"owner": "oppiliappan",
+
"repo": "indigo",
+
"rev": "feb802f02a462ac0a6392ffc3e40b0529f0cdf71",
+
"type": "github"
+
},
+
"original": {
+
"owner": "oppiliappan",
+
"repo": "indigo",
+
"type": "github"
+
}
+
},
+
"lucide-src": {
+
"flake": false,
+
"locked": {
+
"lastModified": 1742302029,
+
"narHash": "sha256-OyPVtpnC4/AAmPq84Wt1r1Gcs48d9KG+UBCtZK87e9k=",
+
"type": "tarball",
+
"url": "https://github.com/lucide-icons/lucide/releases/download/0.483.0/lucide-icons-0.483.0.zip"
+
},
+
"original": {
+
"type": "tarball",
+
"url": "https://github.com/lucide-icons/lucide/releases/download/0.483.0/lucide-icons-0.483.0.zip"
+
}
+
},
"mirage-opam-overlays": {
"flake": false,
"locked": {
···
"original": {
"owner": "dune-universe",
"repo": "mirage-opam-overlays",
-
"type": "github"
-
}
-
},
-
"nix-filter": {
-
"locked": {
-
"lastModified": 1681154353,
-
"narHash": "sha256-MCJ5FHOlbfQRFwN0brqPbCunLEVw05D/3sRVoNVt2tI=",
-
"owner": "numtide",
-
"repo": "nix-filter",
-
"rev": "f529f42792ade8e32c4be274af6b6d60857fbee7",
-
"type": "github"
-
},
-
"original": {
-
"owner": "numtide",
-
"repo": "nix-filter",
"type": "github"
}
},
···
},
"nixos-hardware": {
"locked": {
-
"lastModified": 1737590910,
-
"narHash": "sha256-qM/y6Dtpu9Wmf5HqeZajQdn+cS0aljdYQQQnrvx+LJE=",
+
"lastModified": 1743420942,
+
"narHash": "sha256-b/exDDQSLmENZZgbAEI3qi9yHkuXAXCPbormD8CSJXo=",
"owner": "nixos",
"repo": "nixos-hardware",
-
"rev": "9368027715d8dde4b84c79c374948b5306fdd2db",
+
"rev": "de6fc5551121c59c01e2a3d45b277a6d05077bc4",
"type": "github"
},
"original": {
···
},
"nixpkgs-unstable": {
"locked": {
-
"lastModified": 1737469691,
-
"narHash": "sha256-nmKOgAU48S41dTPIXAq0AHZSehWUn6ZPrUKijHAMmIk=",
+
"lastModified": 1743448293,
+
"narHash": "sha256-bmEPmSjJakAp/JojZRrUvNcDX2R5/nuX6bm+seVaGhs=",
"owner": "nixos",
"repo": "nixpkgs",
-
"rev": "9e4d5190a9482a1fb9d18adf0bdb83c6e506eaab",
+
"rev": "77b584d61ff80b4cef9245829a6f1dfad5afdfa3",
"type": "github"
},
"original": {
···
},
"nixpkgs_2": {
"locked": {
-
"lastModified": 1737569578,
-
"narHash": "sha256-6qY0pk2QmUtBT9Mywdvif0i/CLVgpCjMUn6g9vB+f3M=",
+
"lastModified": 1743501102,
+
"narHash": "sha256-7PCBQ4aGVF8OrzMkzqtYSKyoQuU2jtpPi4lmABpe5X4=",
"owner": "nixos",
"repo": "nixpkgs",
-
"rev": "47addd76727f42d351590c905d9d1905ca895b82",
+
"rev": "02f2af8c8a8c3b2c05028936a1e84daefa1171d4",
"type": "github"
},
"original": {
···
"opam2json": "opam2json"
},
"locked": {
-
"lastModified": 1732617437,
-
"narHash": "sha256-jj25fziYrES8Ix6HkfSiLzrN6MZjiwlHUxFSIuLRjgE=",
+
"lastModified": 1741156005,
+
"narHash": "sha256-JBPvXe5g1V2xpmPVMlf5CP5+T1E+TCK73lqeqV89EJE=",
"owner": "tweag",
"repo": "opam-nix",
-
"rev": "ea8b9cb81fe94e1fc45c6376fcff15f17319c445",
+
"rev": "e71936b31658f0b039a7d26b0c9c7a461d949ba4",
"type": "github"
},
"original": {
···
"opam-nix_2": {
"inputs": {
"flake-compat": "flake-compat_4",
-
"flake-utils": "flake-utils_6",
+
"flake-utils": "flake-utils_5",
"mirage-opam-overlays": "mirage-opam-overlays_2",
"nixpkgs": [
"hyperbib-eeg",
···
"opam-repository": {
"flake": false,
"locked": {
-
"lastModified": 1732612513,
-
"narHash": "sha256-kju4NWEQo4xTxnKeBIsmqnyxIcCg6sNZYJ1FmG/gCDw=",
+
"lastModified": 1740730647,
+
"narHash": "sha256-6veU2WjUGcWDAzLDjoAI1L6GWZd0KIUq19sHcbJS+u8=",
"owner": "ocaml",
"repo": "opam-repository",
-
"rev": "3d52b66b04788999a23f22f0d59c2dfc831c4f32",
+
"rev": "f1f75fef5fbf1e8bd1cc9544e50b89ba59f625e2",
"type": "github"
},
"original": {
···
"inputs": {
"agenix": "agenix",
"alec-website": "alec-website",
-
"colour-guesser": "colour-guesser",
"deploy-rs": "deploy-rs",
+
"disko": "disko",
"eilean": "eilean",
"eon": "eon",
"fn06-website": "fn06-website",
···
"nixpkgs-sonarr": "nixpkgs-sonarr",
"nixpkgs-unstable": "nixpkgs-unstable",
"nur": "nur",
+
"tangled": "tangled",
"timewall": "timewall"
},
···
"type": "github"
},
-
"systems_7": {
+
"tangled": {
+
"inputs": {
+
"gitignore": "gitignore",
+
"htmx-src": "htmx-src",
+
"ia-fonts-src": "ia-fonts-src",
+
"indigo": "indigo",
+
"lucide-src": "lucide-src",
+
"nixpkgs": [
+
"nixpkgs"
+
]
+
},
"locked": {
-
"lastModified": 1681028828,
-
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
-
"owner": "nix-systems",
-
"repo": "default",
-
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
-
"type": "github"
+
"lastModified": 1743620557,
+
"narHash": "sha256-w7a9Qn/IUdCe+gk5cMvSUS+YKItK2iTiu2Qcq49a+zU=",
+
"ref": "refs/heads/master",
+
"rev": "19ee94f42ab259c218762e6f0ed87952f80b5162",
+
"revCount": 420,
+
"type": "git",
+
"url": "https://tangled.sh/@tangled.sh/core"
},
"original": {
-
"owner": "nix-systems",
-
"repo": "default",
-
"type": "github"
+
"type": "git",
+
"url": "https://tangled.sh/@tangled.sh/core"
},
"timewall": {
···
"rust-overlay": "rust-overlay"
},
"locked": {
-
"lastModified": 1737663538,
-
"narHash": "sha256-qrCHymJGE3hbLqxVZK98PNYvw03kQItelDAR2kkwA0o=",
+
"lastModified": 1743524557,
+
"narHash": "sha256-0rNcLtKWbjI0VqlusrqPMcpPgdkkZGkOIt9s3CnsCao=",
"owner": "bcyran",
"repo": "timewall",
-
"rev": "8c0a4bf755b714b41144bd830f8e718e5dee5afd",
+
"rev": "789befef40bf0d45e48285f17f512b41924cfeb7",
"type": "github"
},
"original": {
···
},
"utils": {
"inputs": {
-
"systems": "systems_3"
+
"systems": "systems_2"
},
"locked": {
"lastModified": 1701680307,
···
},
"utils_2": {
"inputs": {
-
"systems": "systems_4"
+
"systems": "systems_3"
},
"locked": {
"lastModified": 1709126324,
+6 -6
flake.nix
···
eilean.url = "github:RyanGibb/eilean-nix/main";
alec-website.url = "github:alexanderhthompson/website";
fn06-website.url = "github:RyanGibb/fn06";
-
colour-guesser.url = "git+ssh://git@github.com/ryangibb/colour-guesser.git?ref=develop";
i3-workspace-history.url = "github:RyanGibb/i3-workspace-history";
hyperbib-eeg.url = "github:RyanGibb/hyperbib?ref=nixify";
nix-rpi5.url = "gitlab:vriska/nix-rpi5?ref=main";
nur.url = "github:nix-community/NUR/e9e77b7985ef9bdeca12a38523c63d47555cc89b";
timewall.url = "github:bcyran/timewall/";
+
tangled.url = "git+https://tangled.sh/@tangled.sh/core";
+
disko.url = "github:nix-community/disko";
# deduplicate flake inputs
eilean.inputs.nixpkgs.follows = "nixpkgs";
···
alec-website.inputs.nixpkgs.follows = "nixpkgs";
fn06-website.inputs.nixpkgs.follows = "nixpkgs";
eon.inputs.nixpkgs.follows = "nixpkgs";
-
colour-guesser.inputs.nixpkgs.follows = "nixpkgs";
i3-workspace-history.inputs.nixpkgs.follows = "nixpkgs";
hyperbib-eeg.inputs.nixpkgs.follows = "nixpkgs";
nix-rpi5.inputs.nixpkgs.follows = "nixpkgs";
nur.inputs.nixpkgs.follows = "nixpkgs";
timewall.inputs.nixpkgs.follows = "nixpkgs";
+
tangled.inputs.nixpkgs.follows = "nixpkgs";
+
disko.inputs.nixpkgs.follows = "nixpkgs";
};
outputs =
···
(
{ config, ... }:
{
-
networking.hostName = "${host}";
+
networking.hostName = host-nixpkgs.lib.mkDefault "${host}";
# pin nix command's nixpkgs flake to the system flake to avoid unnecessary downloads
nix.registry.nixpkgs.flake = host-nixpkgs;
system.stateVersion = "24.05";
···
};
nixOnDroidConfigurations.default = inputs.nix-on-droid.lib.nixOnDroidConfiguration {
-
modules = [ ./nix-on-droid/default.nix ];
+
modules = [ (import ./nix-on-droid/default.nix inputs) ];
pkgs = import inputs.nixpkgs {
overlays = getSystemOverlays "aarch64-linux" { };
config.permittedInsecurePackages = [
···
formatter = inputs.nixpkgs.lib.genAttrs inputs.nixpkgs.lib.systems.flakeExposed (
system: inputs.nixpkgs.legacyPackages.${system}.nixfmt-rfc-style
);
-
-
templates.host.path = ./templates/host;
};
}
+4 -62
home/calendar.nix
···
options.custom.calendar.enable = lib.mkEnableOption "calendar";
config = lib.mkIf cfg.enable {
+
home.packages = with pkgs; [
+
vdirsyncer
+
];
+
programs = {
password-store.enable = true;
gpg.enable = true;
-
vdirsyncer.enable = true;
-
khal = {
-
enable = true;
-
locale = {
-
timeformat = "%I:%M%p";
-
dateformat = "%y-%m-%d";
-
longdateformat = "%Y-%m-%d";
-
datetimeformat = "%y-%m-%d %I:%M%p";
-
longdatetimeformat = "%Y-%m-%d %I:%M%p";
-
};
-
settings = {
-
default.default_calendar = "ryan_freumh_org";
-
keybindings.external_edit = "ctrl e";
-
keybindings.save = "ctrl s";
-
};
-
};
};
services = {
gpg-agent.enable = true;
-
};
-
-
accounts.calendar = {
-
basePath = "calendar";
-
accounts = {
-
"ryan_freumh_org" = {
-
khal = {
-
enable = true;
-
color = "white";
-
};
-
vdirsyncer = {
-
enable = true;
-
};
-
remote = {
-
type = "caldav";
-
url = "https://cal.freumh.org/ryan/f497c073-d027-2aa5-1e58-cbec1bf5a8c7/";
-
passwordCommand = [
-
"${pkgs.pass}/bin/pass"
-
"show"
-
"calendar/ryan@freumh.org"
-
];
-
userName = "ryan";
-
};
-
local = {
-
type = "filesystem";
-
fileExt = ".ics";
-
};
-
};
-
"srg" = {
-
khal = {
-
enable = true;
-
color = "#CC3333";
-
};
-
vdirsyncer = {
-
enable = true;
-
};
-
remote = {
-
type = "http";
-
url = "https://talks.cam.ac.uk/show/ics/8316.ics";
-
};
-
local = {
-
type = "filesystem";
-
fileExt = ".ics";
-
};
-
};
-
};
};
};
}
+49 -36
home/default.nix
···
}:
let
-
cfg = config.custom;
+
tmux-sessionizer = pkgs.writeScriptBin "tmux-sessionizer" ''
+
#!/usr/bin/env bash
+
+
hist_file=~/.cache/sessionizer.hist
+
+
if [[ $# -eq 1 ]]; then
+
selected=$1
+
else
+
selected=$((tac "$hist_file"
+
find ~/ ~/projects -mindepth 1 -maxdepth 1 -type d -not -path '*/[.]*'
+
awk '{print "ssh " $1}' ~/.ssh/known_hosts 2>/dev/null | sort -u
+
echo /etc/nixos) | awk '!seen[$0]++' | fzf --print-query | tail -n 1)
+
fi
+
+
if [[ -z $selected ]]; then
+
exit 0
+
fi
+
+
echo "$selected" >> $hist_file
+
+
selected_name=$(basename "$selected" | tr . _)
+
tmux_running=$(pgrep tmux)
+
+
if [[ $selected == ssh\ * ]]; then
+
if [[ -z $TMUX ]] && [[ -z $tmux_running ]]; then
+
tmux new-session -s "$selected_name" "$selected"
+
exit 0
+
fi
+
+
if ! tmux has-session -t="$selected_name" 2> /dev/null; then
+
tmux new-session -ds "$selected_name" "$selected"
+
fi
+
else
+
if [[ -z $TMUX ]] && [[ -z "$tmux_running" ]]; then
+
tmux new-session -s "$selected_name" -c "$selected"
+
exit 0
+
fi
+
+
if ! tmux has-session -t="$selected_name" 2> /dev/null; then
+
tmux new-session -ds "$selected_name" -c "$selected"
+
fi
+
fi
+
+
+
tmux switch-client -t "$selected_name"
+
'';
in
{
imports = [
···
dua
fd
ripgrep
+
tmux-sessionizer
];
home.shellAliases = {
···
tmux set-option status off
fi
'';
-
# https://github.com/ThePrimeagen/.dotfiles/blob/master/bin/.local/scripts/tmux-sessionizer
-
sessionizer = pkgs.writeScript "sessionizer.sh" ''
-
#!/usr/bin/env bash
-
-
if [[ $# -eq 1 ]]; then
-
selected=$1
-
else
-
selected=$(find ~ -not -path '*/.*' -maxdepth 2 -type d | fzf)
-
fi
-
-
if [[ -z $selected ]]; then
-
exit 0
-
fi
-
-
selected_name=$(basename "$selected" | tr . _)
-
tmux_running=$(pgrep tmux)
-
-
if [[ -z $TMUX ]] && [[ -z $tmux_running ]]; then
-
tmux new-session -s $selected_name -c $selected
-
exit 0
-
fi
-
-
if ! tmux has-session -t=$selected_name 2> /dev/null; then
-
tmux new-session -ds $selected_name -c $selected
-
fi
-
-
tmux switch-client -t $selected_name
-
'';
in
+
# https://github.com/ThePrimeagen/.dotfiles/blob/master/bin/.local/scripts/tmux-sessionizer
''
# alternative modifier
unbind C-b
set-option -g prefix C-a
bind-key C-a send-prefix
-
set-window-option -g mode-keys vi
set-option -g mouse on
set-option -g set-titles on
···
# https://stackoverflow.com/questions/62182401/neovim-screen-lagging-when-switching-mode-from-insert-to-normal
# locking
set -s escape-time 0
-
set -g lock-command ${pkgs.vlock}/bin/vlock
-
set -g lock-after-time 0 # Seconds; 0 = never
-
bind L lock-session
# for .zprofile display environment starting https://github.com/tmux/tmux/issues/3483
set-option -g update-environment XDG_VTNR
# Allow clipboard with OSC-52 work
···
bind -T copy-mode-vi v send-keys -X begin-selection
bind -T copy-mode-vi y send-keys -X copy-selection-and-cancel
# find
-
bind-key -r g run-shell "tmux neww ${sessionizer}"
+
bind-key -r f run-shell "tmux neww tmux-sessionizer"
# reload
bind-key r source-file ~/.config/tmux/tmux.conf
-
# kill unattached
-
bind-key K run-shell 'tmux ls | grep -v attached | cut -d: -f1 | xargs -I {} tmux kill-window -t {}'
'';
};
+1 -1
home/emacs/default.nix
···
let
cfg = config.custom.emacs;
-
emacs = (pkgs.emacsPackagesFor pkgs.emacs29-pgtk).emacsWithPackages (
+
emacs = (pkgs.emacsPackagesFor pkgs.emacs30-pgtk).emacsWithPackages (
epkgs: with epkgs; [
treesit-grammars.with-all-grammars
vterm
+2 -2
home/gui/default.nix
···
};
};
-
services.timewall = {
+
services.timewall = lib.mkIf (inputs ? timewall) {
enable = true;
config = {
-
geoclue.timeout = 300000;
+
geoclue.timeout = 1000;
setter = {
command = [
"${pkgs.bash}/bin/sh"
-1
home/gui/sway.nix
···
export MOZ_ENABLE_WAYLAND=1
export MOZ_DBUS_REMOTE=1
export QT_STYLE_OVERRIDE="Fusion"
-
export WLR_NO_HARDWARE_CURSORS=1
export NIXOS_OZONE_WL=1
# for intellij
+4 -4
home/gui/wm/config.d/bindings
···
bindsym $mod+Control+Shift+k resize shrink height 1px
bindsym $mod+Control+Shift+l resize grow width 1px
-
bindsym $mod+$alt+h focus output left
-
bindsym $mod+$alt+j focus output down
-
bindsym $mod+$alt+k focus output up
-
bindsym $mod+$alt+l focus output right
+
bindsym $mod+$alt+h focus output left ; exec st workspace -t 500
+
bindsym $mod+$alt+j focus output down ; exec st workspace -t 500
+
bindsym $mod+$alt+k focus output up ; exec st workspace -t 500
+
bindsym $mod+$alt+l focus output right ; exec st workspace -t 500
bindsym $mod+$alt+Shift+h move container to output left
bindsym $mod+$alt+Shift+j move container to output down
+2 -3
home/gui/wm/scripts/swayidle_suspend.sh
···
resume '@wmmsg@ "output * dpms on"'\
timeout 240 'loginctl lock-session'\
timeout 300 'systemctl suspend-then-hibernate'\
-
before-sleep 'playerctl -a pause; loginctl lock-session'\
-
after-resume 'pkill -x swaylock; timewall set; loginctl lock-session' # for timewall
-
+
resume 'timewall set'\
+
before-sleep 'playerctl -a pause; loginctl lock-session'
+13 -12
home/mail.nix
···
${pkgs.ugrep}/bin/ugrep -jPh -m 100 --color=never "$1" cat ${config.accounts.email.maildirBasePath}/addressbook/cam-ldap)
'';
sync-mail = pkgs.writeScriptBin "sync-mail" ''
-
${pkgs.isync}/bin/mbsync "$1" || exit 1
+
${pkgs.isync}/bin/mbsync "$@" || exit 1
${pkgs.procps}/bin/pkill -2 -x mu
${pkgs.coreutils}/bin/sleep 1
${pkgs.mu}/bin/mu index
···
mu.enable = true;
msmtp.enable = true;
aerc = {
-
enable = true;
+
# enable = true;
extraConfig = {
general.unsafe-accounts-conf = true;
general.default-save-path = "~/downloads";
···
extraBinds = import ./aerc-binds.nix { inherit pkgs; };
};
neomutt = {
-
enable = true;
+
# enable = true;
extraConfig = ''
# Macro to switch accounts
macro index,pager <F1> '"<change-folder> ${config.accounts.email.maildirBasePath}/ryan@freumh.org/Inbox<enter>"'
···
"mu find results"
'';
};
-
notmuch.enable = true;
};
services = {
···
macro index gt "<change-folder>=${folders.trash}<enter>"
'';
};
-
notmuch.enable = true;
};
"misc@freumh.org" = rec {
userName = "misc@freumh.org";
···
macro index gt "<change-folder>=${folders.trash}<enter>"
'';
};
-
notmuch.enable = true;
};
"ryan.gibb@cl.cam.ac.uk" = rec {
userName = "rtg24@fm.cl.cam.ac.uk";
···
};
imapnotify = {
enable = true;
-
boxes = [ "Inbox" ];
-
onNotify = "${sync-mail}/bin/sync-mail ryan.gibb@cl.cam.ac.uk:INBOX";
+
boxes = [
+
"Inbox"
+
"Sidebox"
+
];
+
onNotify = "${sync-mail}/bin/sync-mail ryan.gibb@cl.cam.ac.uk:INBOX ryan.gibb@cl.cam.ac.uk:Sidebox";
};
mbsync = {
enable = true;
···
macro index gt "<change-folder>=${folders.trash}<enter>"
'';
};
-
notmuch.enable = true;
};
"ryangibb321@gmail.com" = rec {
userName = "ryangibb321@gmail.com";
···
};
imapnotify = {
enable = true;
-
boxes = [ "Inbox" ];
-
onNotify = "${sync-mail}/bin/sync-mail ryangibb321@gmail.com:INBOX";
+
boxes = [
+
"Inbox"
+
"Sidebox"
+
];
+
onNotify = "${sync-mail}/bin/sync-mail ryangibb321@gmail.com:INBOX ryangibb321@gmail.com:Sidebox";
};
mbsync = {
enable = true;
···
macro index gt "<change-folder>=${folders.trash}<enter>"
'';
};
-
notmuch.enable = true;
};
search = {
maildir.path = "search";
+313 -314
home/nvim/default.nix
···
extraLuaConfig = builtins.readFile ./init.lua;
# undo transparent background
# + "colorscheme gruvbox";
-
plugins =
-
with pkgs.vimPlugins;
-
[
-
{
-
plugin = gruvbox-nvim;
-
type = "lua";
-
# TODO is there a better place to put this?
-
runtime =
-
let
-
ml-style = ''
-
setlocal expandtab
-
setlocal shiftwidth=2
-
setlocal tabstop=2
-
setlocal softtabstop=2
-
'';
-
in
-
{
-
"ftplugin/nix.vim".text = ml-style;
-
"ftplugin/ocaml.vim".text = ml-style;
-
"ftplugin/ledger.vim".text = ''
-
setlocal foldmethod=syntax
-
vnoremap <silent> <buffer> <Tab> :LedgerAlign<CR>
-
nnoremap <silent> <buffer> <Tab> :LedgerAlign<CR>
-
'';
-
};
-
}
+
plugins = with pkgs.vimPlugins; [
+
{
+
plugin = gruvbox-nvim;
+
type = "lua";
+
# TODO is there a better place to put this?
+
runtime =
+
let
+
ml-style = ''
+
setlocal expandtab
+
setlocal shiftwidth=2
+
setlocal tabstop=2
+
setlocal softtabstop=2
+
'';
+
in
+
{
+
"ftplugin/nix.vim".text = ml-style;
+
"ftplugin/ocaml.vim".text = ml-style;
+
"ftplugin/haskell.vim".text = ml-style;
+
"ftplugin/ledger.vim".text = ''
+
setlocal foldmethod=syntax
+
vnoremap <silent> <buffer> <Tab> :LedgerAlign<CR>
+
nnoremap <silent> <buffer> <Tab> :LedgerAlign<CR>
+
'';
+
};
+
}
+
+
{
+
plugin = telescope-nvim;
+
type = "lua";
+
config = builtins.readFile ./telescope-nvim.lua;
+
}
+
telescope-fzf-native-nvim
+
telescope-undo-nvim
+
telescope-file-browser-nvim
-
{
-
plugin = telescope-nvim;
-
type = "lua";
-
config = builtins.readFile ./telescope-nvim.lua;
-
}
-
telescope-fzf-native-nvim
-
telescope-undo-nvim
-
telescope-file-browser-nvim
+
{
+
plugin = gitsigns-nvim;
+
type = "lua";
+
config = ''
+
require('gitsigns').setup{
+
on_attach = function(bufnr)
+
local gitsigns = require('gitsigns')
-
{
-
plugin = gitsigns-nvim;
-
type = "lua";
-
config = ''
-
require('gitsigns').setup{
-
on_attach = function(bufnr)
-
local gitsigns = require('gitsigns')
+
local function map(mode, l, r, opts)
+
opts = opts or {}
+
opts.buffer = bufnr
+
vim.keymap.set(mode, l, r, opts)
+
end
-
local function map(mode, l, r, opts)
-
opts = opts or {}
-
opts.buffer = bufnr
-
vim.keymap.set(mode, l, r, opts)
+
map('n', ']c', function()
+
if vim.wo.diff then
+
vim.cmd.normal({']c', bang = true})
+
else
+
gitsigns.nav_hunk('next')
end
+
end, { desc = 'Git next hunk' })
-
map('n', ']c', function()
-
if vim.wo.diff then
-
vim.cmd.normal({']c', bang = true})
-
else
-
gitsigns.nav_hunk('next')
-
end
-
end, { desc = 'Git next hunk' })
-
-
map('n', '[c', function()
-
if vim.wo.diff then
-
vim.cmd.normal({'[c', bang = true})
-
else
-
gitsigns.nav_hunk('prev')
-
end
-
end, { desc = 'Git prev hunk' })
+
map('n', '[c', function()
+
if vim.wo.diff then
+
vim.cmd.normal({'[c', bang = true})
+
else
+
gitsigns.nav_hunk('prev')
+
end
+
end, { desc = 'Git prev hunk' })
-
map('n', '<leader>gs', gitsigns.stage_hunk, { desc = 'Git stage hunk' })
-
map('n', '<leader>gr', gitsigns.reset_hunk, { desc = 'Git reset hunk' })
-
map('v', '<leader>gs', function() gitsigns.stage_hunk {vim.fn.line('.'), vim.fn.line('v')} end, { desc = 'Git stage hunk' })
-
map('v', '<leader>gr', function() gitsigns.reset_hunk {vim.fn.line('.'), vim.fn.line('v')} end, { desc = 'Git reset hunk' })
-
map('n', '<leader>gS', gitsigns.stage_buffer, { desc = 'Git stage buffer' })
-
map('n', '<leader>gu', gitsigns.undo_stage_hunk, { desc = 'Git unstage hunk' })
-
map('n', '<leader>gR', gitsigns.reset_buffer, { desc = 'Git reset buffer' })
-
map('n', '<leader>gp', gitsigns.preview_hunk, { desc = 'Git preview hunk' })
-
map('n', '<leader>gb', function() gitsigns.blame_line{full=true} end, { desc = 'Git blame' })
-
map('n', '<leader>gtb', gitsigns.toggle_current_line_blame, { desc = 'Git toggle line blame' })
-
map('n', '<leader>gd', gitsigns.diffthis, { desc = 'Git diff index' })
-
map('n', '<leader>gD', function() gitsigns.diffthis('~') end, { desc = 'Git diff last' })
-
map('n', '<leader>gtd', gitsigns.toggle_deleted, { desc = 'Git toggle deleted' })
+
map('n', '<leader>gs', gitsigns.stage_hunk, { desc = 'Git stage hunk' })
+
map('n', '<leader>gr', gitsigns.reset_hunk, { desc = 'Git reset hunk' })
+
map('v', '<leader>gs', function() gitsigns.stage_hunk {vim.fn.line('.'), vim.fn.line('v')} end, { desc = 'Git stage hunk' })
+
map('v', '<leader>gr', function() gitsigns.reset_hunk {vim.fn.line('.'), vim.fn.line('v')} end, { desc = 'Git reset hunk' })
+
map('n', '<leader>gS', gitsigns.stage_buffer, { desc = 'Git stage buffer' })
+
map('n', '<leader>gu', gitsigns.undo_stage_hunk, { desc = 'Git unstage hunk' })
+
map('n', '<leader>gR', gitsigns.reset_buffer, { desc = 'Git reset buffer' })
+
map('n', '<leader>gp', gitsigns.preview_hunk, { desc = 'Git preview hunk' })
+
map('n', '<leader>gb', function() gitsigns.blame_line{full=true} end, { desc = 'Git blame' })
+
map('n', '<leader>gtb', gitsigns.toggle_current_line_blame, { desc = 'Git toggle line blame' })
+
map('n', '<leader>gd', gitsigns.diffthis, { desc = 'Git diff index' })
+
map('n', '<leader>gD', function() gitsigns.diffthis('~') end, { desc = 'Git diff last' })
+
map('n', '<leader>gtd', gitsigns.toggle_deleted, { desc = 'Git toggle deleted' })
-
-- vih
-
map({'o', 'x'}, 'ih', ':<C-U>Git select_hunk<CR>', { desc = 'Gitsigns select hunk' })
-
end
-
}
-
'';
-
}
-
{
-
plugin = pkgs.overlay-unstable.vimPlugins.neogit;
-
type = "lua";
-
config = ''
-
local neogit = require('neogit')
-
neogit.setup {}
-
'';
-
}
+
-- vih
+
map({'o', 'x'}, 'ih', ':<C-U>Git select_hunk<CR>', { desc = 'Gitsigns select hunk' })
+
end
+
}
+
'';
+
}
+
{
+
plugin = pkgs.overlay-unstable.vimPlugins.neogit;
+
type = "lua";
+
config = ''
+
local neogit = require('neogit')
+
neogit.setup {}
+
'';
+
}
-
plenary-nvim
-
pkgs.ripgrep
+
plenary-nvim
+
pkgs.ripgrep
-
{
-
plugin = nvim-cmp;
-
type = "lua";
-
config = builtins.readFile ./nvim-cmp.lua;
-
}
-
cmp-path
-
cmp-buffer
-
cmp-cmdline
-
{
-
plugin = cmp-dictionary;
-
type = "lua";
-
config = ''
-
require("cmp_dictionary").setup({
-
paths = { "${pkgs.scowl}/share/dict/words.txt" },
-
exact_length = 2,
-
first_case_insensitive = true,
-
})
-
'';
-
}
+
{
+
plugin = nvim-cmp;
+
type = "lua";
+
config = builtins.readFile ./nvim-cmp.lua;
+
}
+
cmp-path
+
cmp-buffer
+
cmp-cmdline
+
{
+
plugin = cmp-dictionary;
+
type = "lua";
+
config = ''
+
require("cmp_dictionary").setup({
+
paths = { "${pkgs.scowl}/share/dict/words.txt" },
+
exact_length = 2,
+
first_case_insensitive = true,
+
})
+
'';
+
}
-
{
-
plugin = luasnip;
-
type = "lua";
-
config = builtins.readFile ./luasnip.lua;
-
}
-
cmp_luasnip
-
pkgs.overlay-unstable.vimPlugins.friendly-snippets
+
{
+
plugin = luasnip;
+
type = "lua";
+
config = builtins.readFile ./luasnip.lua;
+
}
+
cmp_luasnip
+
pkgs.overlay-unstable.vimPlugins.friendly-snippets
-
{
-
plugin = nvim-treesitter.withAllGrammars;
-
type = "lua";
-
config = ''
-
require'nvim-treesitter.configs'.setup {
-
highlight = {
+
{
+
plugin = nvim-treesitter.withAllGrammars;
+
type = "lua";
+
config = ''
+
require'nvim-treesitter.configs'.setup {
+
highlight = {
+
enable = true,
+
-- :h vimtex-faq-treesitter
+
disable = { "latex" },
+
},
+
}
+
vim.opt.foldmethod = "expr"
+
vim.opt.foldexpr = "v:lua.vim.treesitter.foldexpr()"
+
vim.opt.foldenable = false
+
'';
+
}
+
{
+
plugin = nvim-treesitter-textobjects;
+
type = "lua";
+
config = ''
+
require'nvim-treesitter.configs'.setup {
+
textobjects = {
+
select = {
enable = true,
-
-- :h vimtex-faq-treesitter
-
disable = { "latex" },
+
lookahead = true,
+
keymaps = {
+
["af"] = "@function.outer",
+
["if"] = "@function.inner",
+
["ac"] = "@conditional.outer",
+
["ic"] = "@conditional.inner",
+
["al"] = "@loop.outer",
+
["il"] = "@loop.inner",
+
},
+
include_surrounding_whitespace = true,
},
-
}
-
vim.opt.foldmethod = "expr"
-
vim.opt.foldexpr = "v:lua.vim.treesitter.foldexpr()"
-
vim.opt.foldenable = false
-
'';
-
}
-
{
-
plugin = nvim-treesitter-textobjects;
-
type = "lua";
-
config = ''
-
require'nvim-treesitter.configs'.setup {
-
textobjects = {
-
select = {
-
enable = true,
-
lookahead = true,
-
keymaps = {
-
["af"] = "@function.outer",
-
["if"] = "@function.inner",
-
["ac"] = "@conditional.outer",
-
["ic"] = "@conditional.inner",
-
["al"] = "@loop.outer",
-
["il"] = "@loop.inner",
-
},
-
include_surrounding_whitespace = true,
+
swap = {
+
enable = true,
+
swap_next = {
+
["<leader>a"] = "@parameter.inner",
+
},
+
swap_previous = {
+
["<leader>A"] = "@parameter.inner",
+
},
+
},
+
move = {
+
enable = true,
+
set_jumps = true,
+
goto_next_start = {
+
["]m"] = "@function.outer",
+
},
+
goto_next_end = {
+
["]M"] = "@function.outer",
},
-
swap = {
-
enable = true,
-
swap_next = {
-
["<leader>a"] = "@parameter.inner",
-
},
-
swap_previous = {
-
["<leader>A"] = "@parameter.inner",
-
},
+
goto_previous_start = {
+
["[m"] = "@function.outer",
},
-
move = {
-
enable = true,
-
set_jumps = true,
-
goto_next_start = {
-
["]m"] = "@function.outer",
-
},
-
goto_next_end = {
-
["]M"] = "@function.outer",
-
},
-
goto_previous_start = {
-
["[m"] = "@function.outer",
-
},
-
goto_previous_end = {
-
["[M"] = "@function.outer",
-
},
+
goto_previous_end = {
+
["[M"] = "@function.outer",
},
},
-
}
-
-- could use some tweaking
-
vim.treesitter.query.set("ocaml", "textobjects", [[
-
((value_definition (let_binding)) @function.outer)
-
((let_binding body: (_) @function.inner))
-
]])
-
'';
-
}
+
},
+
}
+
-- could use some tweaking
+
vim.treesitter.query.set("ocaml", "textobjects", [[
+
((value_definition (let_binding)) @function.outer)
+
((let_binding body: (_) @function.inner))
+
]])
+
'';
+
}
-
{
-
plugin = vimtex;
-
type = "lua";
-
config = ''
-
vim.cmd("filetype plugin indent on")
-
vim.cmd("syntax enable")
-
vim.g.vimtex_quickfix_mode = 0
-
vim.g.vimtex_view_general_viewer = 'evince'
+
{
+
plugin = vimtex;
+
type = "lua";
+
config = ''
+
vim.cmd("filetype plugin indent on")
+
vim.cmd("syntax enable")
+
vim.g.vimtex_quickfix_mode = 0
+
vim.g.vimtex_view_general_viewer = 'evince'
+
'';
+
}
+
{
+
plugin = sved;
+
type = "lua";
+
runtime = {
+
"ftplugin/tex.lua".text = ''
+
vim.keymap.set('n', '<localleader>v', ':call SVED_Sync()<CR>')
'';
-
}
-
{
-
plugin = sved;
-
type = "lua";
-
runtime = {
-
"ftplugin/tex.lua".text = ''
-
vim.keymap.set('n', '<localleader>v', ':call SVED_Sync()<CR>')
-
'';
-
};
-
}
-
cmp-omni
+
};
+
}
+
cmp-omni
-
{
-
plugin = nvim-surround;
-
type = "lua";
-
config = ''
-
require('nvim-surround').setup({})
-
'';
-
}
-
{
-
plugin = comment-nvim;
-
type = "lua";
-
config = ''
-
require('Comment').setup()
-
'';
-
}
-
{
-
plugin = undotree;
-
type = "lua";
-
config = ''
-
vim.keymap.set('n', '<leader>u', vim.cmd.UndotreeToggle, { desc = 'Undotree toggle' })
-
'';
-
}
-
{
-
plugin = leap-nvim;
-
type = "lua";
-
config = ''
-
vim.keymap.set({'n', 'x', 'o'}, 's', '<Plug>(leap-forward)', { desc = "Leap forward"} )
-
vim.keymap.set({'n', 'x', 'o'}, 'S', '<Plug>(leap-backward)', { desc = "Leap backward"} )
-
vim.keymap.set({'n', 'x', 'o'}, 'gs', '<Plug>(leap-from-window)', { desc = "Leap from window"} )
-
'';
-
}
-
{
-
plugin = pkgs.overlay-unstable.vimPlugins.which-key-nvim;
-
type = "lua";
-
config = ''
-
local wk = require('which-key')
-
wk.setup({
-
plugins = {
-
spelling = {
-
enabled = false
-
},
+
{
+
plugin = nvim-surround;
+
type = "lua";
+
config = ''
+
require('nvim-surround').setup({})
+
'';
+
}
+
{
+
plugin = comment-nvim;
+
type = "lua";
+
config = ''
+
require('Comment').setup()
+
'';
+
}
+
{
+
plugin = undotree;
+
type = "lua";
+
config = ''
+
vim.keymap.set('n', '<leader>su', vim.cmd.UndotreeToggle, { desc = 'Undo history' })
+
'';
+
}
+
{
+
plugin = leap-nvim;
+
type = "lua";
+
config = ''
+
vim.keymap.set({'n', 'x', 'o'}, 's', '<Plug>(leap-forward)', { desc = "Leap forward"} )
+
vim.keymap.set({'n', 'x', 'o'}, 'S', '<Plug>(leap-backward)', { desc = "Leap backward"} )
+
vim.keymap.set({'n', 'x', 'o'}, 'gs', '<Plug>(leap-from-window)', { desc = "Leap from window"} )
+
'';
+
}
+
{
+
plugin = pkgs.overlay-unstable.vimPlugins.which-key-nvim;
+
type = "lua";
+
config = ''
+
local wk = require('which-key')
+
wk.setup({
+
plugins = {
+
spelling = {
+
enabled = false
},
-
icons = { mappings = false },
-
triggers = {
-
{ "<leader>", mode = { "n", "v" } },
-
{ "<auto>", mode = "nixsotc" },
-
},
-
delay = 1000,
-
})
-
wk.add({
-
{ "<leader>f", group = 'Find' },
-
{ "<leader>l", group = 'LSP' },
-
{ "<leader>;", group = 'DAP' },
-
{ "<leader>s", group = 'Session' },
-
{ "<leader>t", group = 'Tab' },
-
{ "<leader>h", group = 'Hunk' },
-
{ "<leader>x", group = 'Trouble' },
-
{ "<leader>g", group = 'Git' },
-
{ "<leader>i", group = 'Insert' },
-
})
-
'';
-
}
+
},
+
icons = { mappings = false },
+
triggers = {
+
{ "<leader>", mode = { "n", "v" } },
+
{ "<auto>", mode = "nixsotc" },
+
},
+
delay = 1000,
+
})
+
wk.add({
+
{ "<leader>f", group = 'Find' },
+
{ "<leader>c", group = 'Code' },
+
{ "<leader>;", group = 'DAP' },
+
{ "<leader>s", group = 'Search' },
+
{ "<leader>t", group = 'Tab' },
+
{ "<leader>h", group = 'Hunk' },
+
{ "<leader>x", group = 'Trouble' },
+
{ "<leader>g", group = 'Git' },
+
{ "<leader>i", group = 'Insert' },
+
})
+
'';
+
}
-
{
-
plugin = vim-ledger-2024-07-15;
-
type = "lua";
-
config = ''
-
vim.g.ledger_fuzzy_account_completion = true
-
vim.g.ledger_extra_options = '--pedantic'
-
vim.g.ledger_align_at = 50
-
vim.g.ledger_accounts_cmd = 'ledger accounts --add-budget'
+
{
+
plugin = vim-ledger-2024-07-15;
+
type = "lua";
+
config = ''
+
vim.g.ledger_fuzzy_account_completion = true
+
vim.g.ledger_extra_options = '--pedantic'
+
vim.g.ledger_align_at = 50
+
vim.g.ledger_accounts_cmd = 'ledger accounts --add-budget'
-
vim.g.ledger_date_format = '%Y-%m-%d'
+
vim.g.ledger_date_format = '%Y-%m-%d'
-
vim.cmd([[
-
autocmd FileType ledger nnoremap <buffer> <leader>e :call ledger#entry()<CR>
-
]])
-
'';
-
}
-
{
-
plugin = orgmode;
-
type = "lua";
-
config = ''
-
-- In any orgmode buffer press g? for help
-
require('orgmode').setup({
-
org_agenda_files = { '~/vault/*.org' },
-
org_default_notes_file = '~/vault/todo.org',
-
org_capture_templates = {
-
t = {
-
description = 'Task',
-
template = '* TODO %?\n %u',
-
},
+
vim.cmd([[
+
autocmd FileType ledger nnoremap <buffer> <leader>e :call ledger#entry()<CR>
+
]])
+
'';
+
}
+
{
+
plugin = orgmode;
+
type = "lua";
+
config = ''
+
-- In any orgmode buffer press g? for help
+
require('orgmode').setup({
+
org_agenda_files = { '~/vault/*.org' },
+
org_default_notes_file = '~/vault/todo.org',
+
org_capture_templates = {
+
t = {
+
description = 'Task',
+
template = '* TODO %?\n %u',
},
-
})
-
'';
-
}
+
},
+
})
+
'';
+
}
-
{
-
plugin = nvim-lspconfig;
-
type = "lua";
-
config = builtins.readFile ./lsp.lua;
-
runtime = {
-
"ftplugin/java.lua".text = ''
-
local project_name = vim.fn.fnamemodify(vim.fn.getcwd(), ':p:h:t')
-
local workspace_dir = '~/.cache/jdt/' .. project_name
-
require('jdtls').start_or_attach {
-
on_attach = On_attach,
-
capabilities = Capabilities,
-
cmd = { 'jdt-language-server', '-data', workspace_dir, },
-
root_dir = vim.fs.dirname(vim.fs.find({'gradlew', '.git', 'mvnw'}, { upward = true })[1]),
-
}
-
'';
-
};
-
}
-
{
-
plugin = nvim-dap;
-
type = "lua";
-
config = builtins.readFile ./dap.lua;
-
}
-
cmp-nvim-lsp
-
cmp-nvim-lsp-signature-help
-
ltex-ls-nvim
-
nvim-jdtls
-
];
+
{
+
plugin = nvim-lspconfig;
+
type = "lua";
+
config = builtins.readFile ./lsp.lua;
+
runtime = {
+
"ftplugin/java.lua".text = ''
+
local project_name = vim.fn.fnamemodify(vim.fn.getcwd(), ':p:h:t')
+
local workspace_dir = '~/.cache/jdt/' .. project_name
+
require('jdtls').start_or_attach {
+
on_attach = On_attach,
+
capabilities = Capabilities,
+
cmd = { 'jdt-language-server', '-data', workspace_dir, },
+
root_dir = vim.fs.dirname(vim.fs.find({'gradlew', '.git', 'mvnw'}, { upward = true })[1]),
+
}
+
'';
+
};
+
}
+
{
+
plugin = nvim-dap;
+
type = "lua";
+
config = builtins.readFile ./dap.lua;
+
}
+
cmp-nvim-lsp
+
cmp-nvim-lsp-signature-help
+
ltex-ls-nvim
+
nvim-jdtls
+
];
};
};
}
+1 -1
home/nvim/init.lua
···
vim.keymap.set('n', '!', ':term ', { desc = 'terminal' })
-
vim.keymap.set('n', '<leader>gg', ':Neogit', { desc = 'Neogit' })
+
vim.keymap.set('n', '<leader>gg', ':Neogit<CR>', { desc = 'Neogit' })
vim.keymap.set('n', '<leader>om', ':make<Enter>', { desc = 'Make' })
+3 -2
home/nvim/telescope-nvim.lua
···
vim.keymap.set('n', '<leader>ff', require('telescope.builtin').find_files, { desc = 'Find files' })
vim.keymap.set('n', '<leader><leader>', require('telescope.builtin').find_files, { desc = 'Find files' })
-
vim.keymap.set('n', '<leader>sd', require('telescope.builtin').live_grep, { desc = 'Find grep' })
+
vim.keymap.set('n', '<leader>sd', require('telescope.builtin').live_grep, { desc = 'Search directory' })
vim.keymap.set('n', '<leader>fv', require('telescope.builtin').git_files, { desc = 'Find version control' })
vim.keymap.set('n', '<leader>bb', function() require('telescope.builtin').buffers({ sort_mru = true }) end, { desc = 'Find buffer' })
vim.keymap.set('n', '<leader>h', require('telescope.builtin').help_tags, { desc = 'Find help' })
-
vim.keymap.set('n', '<leader>fq', require('telescope.builtin').command_history, { desc = 'Find command' })
+
vim.keymap.set('n', '<leader>fq', require('telescope.builtin').commands, { desc = 'Find command' })
+
vim.keymap.set('n', '<leader>fQ', require('telescope.builtin').command_history, { desc = 'Find command history' })
vim.keymap.set('n', '<leader>f/', require('telescope.builtin').search_history, { desc = 'Find search' })
vim.keymap.set('n', '<leader>fj', require('telescope.builtin').jumplist, { desc = 'Find jumplist' })
vim.keymap.set('n', '<leader>fm', require('telescope.builtin').marks, { desc = 'Find marks' })
+4
home/zsh.cfg
···
+
+
# https://www.emacswiki.org/emacs/TrampMode#h5o-9
+
[[ $TERM == "dumb" ]] && unsetopt zle && PS1='$ ' && return
setopt autocd nomatch notify interactive_comments inc_append_history
unsetopt beep extendedglob share_history
···
source /run/current-system/sw/share/bash-completion/completions/ledger.bash
fi
+
eval $(opam env)
-1
hosts/elephant/default.nix
···
# Video Acceleration API (VA-API) user mode driver
intel-media-driver
# Intel Video Processing Library (VPL) API runtime implementation
-
# replace with`onevpl-intel-gpu` after https://github.com/NixOS/nixpkgs/pull/264621
vpl-gpu-rt
];
};
+76 -8
hosts/elephant/services.nix
···
"nextcloud.vpn.freumh.org"
"owntracks.vpn.freumh.org"
"immich.vpn.freumh.org"
+
"calibre.freumh.org"
+
"audiobookshelf.vpn.freumh.org"
];
};
···
proxyPass = with config.services.immich; ''
http://${host}:${builtins.toString port}
'';
+
};
+
};
+
"calibre.freumh.org" = {
+
addSSL = true;
+
locations."/" = {
+
recommendedProxySettings = true;
+
proxyPass = ''
+
http://127.0.0.1:${builtins.toString config.services.calibre-web.listen.port}
+
'';
+
proxyWebsockets = true;
+
extraConfig = ''
+
proxy_buffer_size 128k;
+
proxy_buffers 4 256k;
+
proxy_busy_buffers_size 256k;
+
'';
+
};
+
};
+
"audiobookshelf.vpn.freumh.org" = {
+
onlySSL = true;
+
listenAddresses = [ "100.64.0.9" ];
+
locations."/" = {
+
proxyPass = ''
+
http://localhost:${builtins.toString config.services.audiobookshelf.port}
+
'';
+
proxyWebsockets = true;
};
};
};
···
config.services.transmission.user
config.services.nzbget.user
];
-
# services.calibre-server.enable = true;
+
+
services.calibre-web = {
+
enable = true;
+
listen = {
+
port = 8084;
+
ip = "127.0.0.1";
+
};
+
options = {
+
enableBookConversion = true;
+
enableBookUploading = true;
+
enableKepubify = true;
+
};
+
};
+
users.users.${config.services.calibre-web.user}.extraGroups = [
+
config.services.readarr.user
+
];
age.secrets.restic-owl.file = ../../secrets/restic-owl.age;
age.secrets.restic-gecko.file = ../../secrets/restic-gecko.age;
···
mediaLocation = "/tank/immich";
};
+
services.audiobookshelf = {
+
enable = true;
+
port = 8001;
+
};
+
users.users.${config.services.audiobookshelf.user}.extraGroups = [
+
config.services.readarr.user
+
];
+
services.fail2ban = {
enable = true;
bantime = "24h";
···
bantime = "86400";
findTime = "43200";
logPath = "/var/lib/jellyseerr/logs/overseerr.log";
+
};
+
# requires 'Enable Proxy Support' for jellyseerr
+
jails."calibre-web".settings = {
+
backend = "auto";
+
port = "80,443";
+
protocol = "tcp";
+
filter = "calibre-web";
+
maxRetry = 3;
+
bantime = "86400";
+
findTime = "43200";
+
logPath = "/var/lib/calibre-web/log";
};
};
environment.etc = {
···
[Definition]
failregex = ^.*\[warn\]\[Auth\]: Failed login attempt from user with incorrect Jellyfin credentials {"account":{"ip":"<HOST>","email":
'';
+
"fail2ban/filter.d/calibre-web.local".text = ''
+
[Definition]
+
failregex = ^(?:\[\])?\s*WARN \{[^\}]*\} Login failed for user "<F-USER>[^"]*</F-USER>" IP-address: <ADDR>
+
'';
};
systemd.services.ddns = {
···
serviceConfig = {
ExecStart = pkgs.writeShellScript "update-dns" ''
while true; do
-
IP="$(${pkgs.curl}/bin/curl https://ipinfo.io/ip 2> /dev/null)";
-
echo $IP;
+
IP="$(${pkgs.curl}/bin/curl https://ipinfo.io/ip 2> /dev/null)"
+
echo $IP
${config.services.eon.package}/bin/capc update /run/agenix/eon-freumh.org.cap \
-
-u remove/jellyfin.freumh.org/A \
-
-u remove/jellyseerr.freumh.org/A \
-
-u add/jellyfin.freumh.org/A/"$IP"/60 \
-
-u add/jellyseerr.freumh.org/A/"$IP"/60;
-
sleep 3600;
+
-u "remove|jellyfin.freumh.org|A" \
+
-u "remove|jellyseerr.freumh.org|A" \
+
-u "remove|calibre.freumh.org|A" \
+
-u "add|jellyfin.freumh.org|A|$IP|60" \
+
-u "add|jellyseerr.freumh.org|A|$IP|60" \
+
-u "add|calibre.freumh.org|A|$IP|60" \
+
;
+
sleep 3600
done
'';
Restart = "always";
+24 -5
hosts/gecko/default.nix
···
emacs.enable = true;
};
home.sessionVariables = {
-
LEDGER_FILE = "~/vault/finaces.ledger";
+
LEDGER_FILE = "$HOME/vault/finances.ledger";
+
CALENDAR_DIR = "$HOME/calendar";
};
programs.git.extraConfig.commit.gpgSign = true;
+
programs.direnv = {
+
enable = true;
+
enableZshIntegration = true;
+
enableBashIntegration = true;
+
};
};
boot.loader.grub = {
···
calibre
zotero
element-desktop
+
nheko
iamb
spotify
gimp
···
ocamlPackages.ocaml-lsp
ocamlPackages.ocamlformat
# rust
-
cargo
-
rustc
-
rust-analyzer
-
rustfmt
+
overlay-unstable.cargo
+
overlay-unstable.rustc
+
overlay-unstable.rust-analyzer
+
overlay-unstable.rustfmt
# haskell
cabal-install
ghc
···
# other
ltex-ls
typst-lsp
+
+
overlay-unstable.claude-code
];
services.gnome.gnome-keyring.enable = true;
···
# ddcutil
hardware.i2c.enable = true;
+
+
hardware.graphics = {
+
enable = true;
+
extraPackages = with pkgs; [
+
# Video Acceleration API (VA-API) user mode driver
+
intel-media-driver
+
# Intel Video Processing Library (VPL) API runtime implementation
+
vpl-gpu-rt
+
];
+
};
}
+31
hosts/hippo/default.nix
···
+
{
+
pkgs,
+
config,
+
lib,
+
disko,
+
...
+
}:
+
+
{
+
imports = [
+
./hardware-configuration.nix
+
disko.nixosModules.disko
+
./disk-config.nix
+
];
+
+
custom = {
+
enable = true;
+
autoUpgrade.enable = true;
+
homeManager.enable = true;
+
};
+
+
home-manager.users.${config.custom.username}.config.custom.machineColour = "blue";
+
+
networking.hostName = "iphito";
+
+
services.openssh.openFirewall = true;
+
+
users.users.root.openssh.authorizedKeys.keys = [
+
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA7UrJmBFWR3c7jVzpoyg4dJjON9c7t9bT9acfrj6G7i mtelvers"
+
];
+
}
+33
hosts/hippo/disk-config.nix
···
+
{ lib, ... }:
+
+
{
+
disko.devices = {
+
disk.disk1 = {
+
device = lib.mkDefault "/dev/sda";
+
type = "disk";
+
content = {
+
type = "gpt";
+
partitions = {
+
ESP = {
+
type = "EF00";
+
size = "500M";
+
content = {
+
type = "filesystem";
+
format = "vfat";
+
mountpoint = "/boot";
+
mountOptions = [ "umask=0077" ];
+
};
+
};
+
root = {
+
size = "100%";
+
content = {
+
type = "filesystem";
+
format = "ext4";
+
mountpoint = "/";
+
};
+
};
+
};
+
};
+
};
+
};
+
}
+40
hosts/hippo/hardware-configuration.nix
···
+
{
+
config,
+
lib,
+
pkgs,
+
modulesPath,
+
...
+
}:
+
+
{
+
imports = [
+
(modulesPath + "/installer/scan/not-detected.nix")
+
];
+
+
boot.initrd.availableKernelModules = [
+
"megaraid_sas"
+
"xhci_pci"
+
"nvme"
+
"ahci"
+
"sd_mod"
+
];
+
boot.initrd.kernelModules = [ "dm-snapshot" ];
+
boot.kernelModules = [ "kvm-amd" ];
+
boot.extraModulePackages = [ ];
+
+
networking.useDHCP = lib.mkDefault true;
+
+
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
+
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
+
+
boot.loader.grub = {
+
enable = true;
+
device = "nodev";
+
efiSupport = true;
+
efiInstallAsRemovable = true;
+
};
+
+
boot.kernelParams = [
+
"console=ttyS1,115200n8"
+
];
+
}
+5 -467
hosts/owl/default.nix
···
{
pkgs,
-
config,
lib,
-
eon,
...
}@inputs:
-
let
-
vpnRecords = [
-
{
-
name = "nix-cache.vpn.${config.networking.domain}.";
-
type = "A";
-
value = "100.64.0.9";
-
}
-
{
-
name = "jellyfin.vpn.${config.networking.domain}.";
-
type = "A";
-
value = "100.64.0.9";
-
}
-
{
-
name = "nextcloud.vpn.${config.networking.domain}.";
-
type = "A";
-
value = "100.64.0.9";
-
}
-
{
-
name = "transmission.vpn.${config.networking.domain}.";
-
type = "A";
-
value = "100.64.0.9";
-
}
-
{
-
name = "owntracks.vpn.${config.networking.domain}.";
-
type = "A";
-
value = "100.64.0.9";
-
}
-
{
-
name = "immich.vpn.${config.networking.domain}.";
-
type = "A";
-
value = "100.64.0.9";
-
}
-
];
-
in
{
imports = [
./hardware-configuration.nix
./minimal.nix
-
../../modules/colour-guesser.nix
+
./services.nix
../../modules/ryan-website.nix
../../modules/alec-website.nix
../../modules/fn06-website.nix
+
inputs.tangled.nixosModules.knotserver
];
-
age.secrets.eon-capnp = {
-
file = ../../secrets/eon-capnp.age;
-
mode = "770";
-
owner = "eon";
-
group = "eon";
-
};
-
age.secrets.eon-sirref-primary = {
-
file = ../../secrets/eon-sirref-primary.cap.age;
-
mode = "770";
-
owner = "eon";
-
group = "eon";
-
};
-
services.eon = {
-
capnpSecretKeyFile = config.age.secrets.eon-capnp.path;
-
primaries = [ config.age.secrets.eon-sirref-primary.path ];
-
prod = true;
-
capnpAddress = "135.181.100.27";
-
logLevel = 0;
-
};
-
-
security.acme-eon = {
-
acceptTerms = true;
-
package = eon.defaultPackage.${config.nixpkgs.hostPlatform.system};
-
defaults.email = "${config.custom.username}@${config.networking.domain}";
-
defaults.capFile = "/var/lib/eon/caps/domain/freumh.org.cap";
-
certs = {
-
"fn06.org".capFile = "/var/lib/eon/caps/domain/fn06.org.cap";
-
"capybara.fn06.org".capFile = "/var/lib/eon/caps/domain/fn06.org.cap";
-
};
-
};
-
-
eilean = {
-
username = config.custom.username;
-
serverIpv4 = "135.181.100.27";
-
serverIpv6 = "2a01:4f9:c011:87ad:0:0:0:0";
-
acme-eon = true;
-
fail2ban.enable = true;
-
};
-
networking.domain = lib.mkDefault "freumh.org";
-
eilean.publicInterface = "enp1s0";
-
eilean.mailserver.enable = true;
-
eilean.radicale = {
-
enable = true;
-
users = null;
-
};
-
age.secrets.matrix-shared-secret = {
-
file = ../../secrets/matrix-shared-secret.age;
-
mode = "770";
-
owner = "${config.systemd.services.matrix-synapse.serviceConfig.User}";
-
group = "${config.systemd.services.matrix-synapse.serviceConfig.Group}";
-
};
-
eilean.matrix = {
-
enable = true;
-
registrationSecretFile = config.age.secrets.matrix-shared-secret.path;
-
bridges.whatsapp = true;
-
bridges.signal = true;
-
bridges.instagram = true;
-
bridges.messenger = true;
-
};
-
eilean.turn.enable = true;
-
eilean.mastodon.enable = true;
-
eilean.headscale.enable = true;
-
#eilean.dns.enable = lib.mkForce false;
-
-
systemd.services.matrix-as-meta = {
-
# voice messages need `ffmpeg`
-
path = [ pkgs.ffmpeg ];
-
};
-
-
custom = {
-
freumh.enable = true;
-
rmfakecloud.enable = true;
-
website = {
-
ryan = {
-
enable = true;
-
cname = "vps";
-
};
-
alec = {
-
enable = true;
-
cname = "vps";
-
};
-
fn06 = {
-
enable = true;
-
cname = "vps";
-
domain = "fn06.org";
-
};
-
colour-guesser = {
-
# enable = true;
-
cname = "vps";
-
};
-
};
-
};
-
-
eilean.dns.nameservers = [ "ns1" ];
-
eilean.services.dns.zones = {
-
${config.networking.domain} = {
-
ttl = 300;
-
soa = {
-
serial = 2018011660;
-
refresh = 300;
-
};
-
records = [
-
{
-
name = "@";
-
type = "TXT";
-
value = "google-site-verification=rEvwSqf7RYKRQltY412qMtTuoxPp64O3L7jMotj9Jnc";
-
}
-
{
-
name = "_atproto.ryan";
-
type = "TXT";
-
value = "did=did:plc:3lfhu6ehlynzjgehef6alnvg";
-
}
-
-
{
-
name = "teapot";
-
type = "CNAME";
-
value = "vps";
-
}
-
-
{
-
name = "@";
-
type = "NS";
-
value = "ns1.sirref.org.";
-
}
-
-
{
-
name = "@";
-
type = "A";
-
value = config.eilean.serverIpv4;
-
}
-
{
-
name = "@";
-
type = "AAAA";
-
value = config.eilean.serverIpv6;
-
}
-
{
-
name = "vps";
-
type = "A";
-
value = config.eilean.serverIpv4;
-
}
-
{
-
name = "vps";
-
type = "AAAA";
-
value = config.eilean.serverIpv6;
-
}
-
-
{
-
name = "@";
-
type = "LOC";
-
value = "52 12 40.4 N 0 5 31.9 E 22m 10m 10m 10m";
-
}
-
-
{
-
name = "ns.cl";
-
type = "A";
-
value = "128.232.113.136";
-
}
-
{
-
name = "cl";
-
type = "NS";
-
value = "ns.cl";
-
}
-
-
{
-
name = "ns1.eilean";
-
type = "A";
-
value = "65.109.10.223";
-
}
-
{
-
name = "eilean";
-
type = "NS";
-
value = "ns1.eilean";
-
}
-
-
{
-
name = "shrew";
-
type = "CNAME";
-
value = "vps";
-
}
-
-
# generate with
-
# sudo openssl x509 -in /var/lib/acme/mail.freumh.org/fullchain.pem -pubkey -noout | openssl pkey -pubin -outform der | sha256sum | awk '{print "3 1 1", $1}'
-
{
-
name = "_25._tcp.mail";
-
type = "TLSA";
-
value = "3 1 1 2f0fd413f063c75141937dd196a9f4ab66139d599e0dcf2a7ce6d557647e26a6";
-
}
-
# generate with
-
# for i in r3 e1 r4-cross-signed e2
-
# openssl x509 -in ~/downloads/lets-encrypt-$i.pem -pubkey -noout | openssl pkey -pubin -outform der | sha256sum | awk '{print "2 1 1", $1}'
-
# LE R3
-
{
-
name = "_25._tcp.mail";
-
type = "TLSA";
-
value = "2 1 1 8d02536c887482bc34ff54e41d2ba659bf85b341a0a20afadb5813dcfbcf286d";
-
}
-
# LE E1
-
{
-
name = "_25._tcp.mail";
-
type = "TLSA";
-
value = "2 1 1 276fe8a8c4ec7611565bf9fce6dcace9be320c1b5bea27596b2204071ed04f10";
-
}
-
# LE R4
-
{
-
name = "_25._tcp.mail";
-
type = "TLSA";
-
value = "2 1 1 e5545e211347241891c554a03934cde9b749664a59d26d615fe58f77990f2d03";
-
}
-
# LE E2
-
{
-
name = "_25._tcp.mail";
-
type = "TLSA";
-
value = "2 1 1 bd936e72b212ef6f773102c6b77d38f94297322efc25396bc3279422e0c89270";
-
}
-
] ++ vpnRecords;
-
};
-
"fn06.org" = {
-
soa.serial = 1706745602;
-
records = [
-
{
-
name = "@";
-
type = "NS";
-
value = "ns1";
-
}
-
{
-
name = "@";
-
type = "NS";
-
value = "ns2";
-
}
-
-
{
-
name = "ns1";
-
type = "A";
-
value = config.eilean.serverIpv4;
-
}
-
{
-
name = "ns1";
-
type = "AAAA";
-
value = config.eilean.serverIpv6;
-
}
-
{
-
name = "ns2";
-
type = "A";
-
value = config.eilean.serverIpv4;
-
}
-
{
-
name = "ns2";
-
type = "AAAA";
-
value = config.eilean.serverIpv6;
-
}
-
-
{
-
name = "@";
-
type = "A";
-
value = config.eilean.serverIpv4;
-
}
-
{
-
name = "@";
-
type = "AAAA";
-
value = config.eilean.serverIpv6;
-
}
-
-
{
-
name = "www.fn06.org.";
-
type = "CNAME";
-
value = "fn06.org.";
-
}
-
-
{
-
name = "@";
-
type = "LOC";
-
value = "52 12 40.4 N 0 5 31.9 E 22m 10m 10m 10m";
-
}
-
-
{
-
name = "capybara.fn06.org.";
-
type = "CNAME";
-
value = "fn06.org.";
-
}
-
-
{
-
name = "jellyfin.${config.networking.domain}.";
-
type = "AAAA";
-
value = "2a00:23c6:aa22:e401:8dff:9b9a:cb3c:3fcb";
-
}
-
{
-
name = "jellyseerr.${config.networking.domain}.";
-
type = "AAAA";
-
value = "2a00:23c6:aa22:e401:8dff:9b9a:cb3c:3fcb";
-
}
-
];
-
};
-
};
-
services.bind.zones.${config.networking.domain}.extraConfig =
-
''
-
dnssec-policy default;
-
inline-signing yes;
-
journal "${config.services.bind.directory}/${config.networking.domain}.signed.jnl";
-
''
-
+
-
# dig ns org +short | xargs dig +short
-
# replace with `checkds true;` in bind 9.20
-
''
-
parental-agents {
-
199.19.56.1;
-
199.249.112.1;
-
199.19.54.1;
-
199.249.120.1;
-
199.19.53.1;
-
199.19.57.1;
-
};
-
'';
-
-
services.nginx.commonHttpConfig = ''
-
add_header Strict-Transport-Security max-age=31536000 always;
-
add_header X-Frame-Options SAMEORIGIN always;
-
add_header X-Content-Type-Options nosniff always;
-
add_header Content-Security-Policy "default-src 'self' 'unsafe-inline' 'unsafe-eval' blob:; base-uri 'self'; frame-src 'self'; frame-ancestors 'self'; form-action 'self';" always;
-
add_header Referrer-Policy 'same-origin';
-
'';
-
services.nginx.virtualHosts."teapot.${config.networking.domain}" = {
-
extraConfig = ''
-
return 418;
-
'';
-
};
-
age.secrets.website-phd = {
-
file = ../../secrets/website-phd.age;
-
mode = "770";
-
owner = "${config.systemd.services.nginx.serviceConfig.User}";
-
group = "${config.systemd.services.nginx.serviceConfig.Group}";
-
};
-
services.nginx.virtualHosts."${config.custom.website.ryan.domain}" = {
-
locations."/phd/" = {
-
basicAuthFile = config.age.secrets.website-phd.path;
-
};
-
};
-
-
security.acme-eon.nginxCerts = [
-
"capybara.fn06.org"
-
"shrew.freumh.org"
+
environment.systemPackages = with pkgs; [
+
nixd
+
nixfmt-rfc-style
];
-
services.nginx.virtualHosts."capybara.fn06.org" = {
-
forceSSL = true;
-
locations."/" = {
-
proxyPass = ''
-
http://100.64.0.10:8123
-
'';
-
proxyWebsockets = true;
-
};
-
};
-
services.nginx.virtualHosts."shrew.freumh.org" = {
-
forceSSL = true;
-
locations."/" = {
-
# need to specify ip or there's a bootstrap problem with headscale
-
proxyPass = ''
-
http://100.64.0.6:8123
-
'';
-
proxyWebsockets = true;
-
};
-
};
-
-
services.mastodon = {
-
webProcesses = lib.mkForce 1;
-
webThreads = lib.mkForce 1;
-
sidekiqThreads = lib.mkForce 1;
-
streamingProcesses = lib.mkForce 1;
-
};
-
-
boot.kernel.sysctl = {
-
"net.ipv4.ip_forward" = 1;
-
"net.ipv6.conf.all.forwarding" = 1;
-
};
-
-
services.headscale.settings.dns = {
-
extra_records = vpnRecords;
-
base_domain = "vpn.freumh.org";
-
nameservers.global = config.networking.nameservers;
-
};
-
-
age.secrets.restic-owl.file = ../../secrets/restic-owl.age;
-
services.restic.backups.${config.networking.hostName} = {
-
repository = "rest:http://100.64.0.9:8000/${config.networking.hostName}/";
-
passwordFile = config.age.secrets.restic-owl.path;
-
initialize = true;
-
paths = [
-
"/var/"
-
"/run/"
-
"/etc/"
-
];
-
timerConfig = {
-
OnCalendar = "03:00";
-
randomizedDelaySec = "1hr";
-
};
-
};
nix = {
gc = {
···
options = lib.mkForce "--delete-older-than 2d";
};
};
-
-
age.secrets.email-ryan.file = ../../secrets/email-ryan.age;
-
age.secrets.email-system.file = ../../secrets/email-system.age;
-
eilean.mailserver.systemAccountPasswordFile = config.age.secrets.email-system.path;
-
mailserver.loginAccounts = {
-
"${config.eilean.username}@${config.networking.domain}" = {
-
passwordFile = config.age.secrets.email-ryan.path;
-
aliases = [
-
"dns@${config.networking.domain}"
-
"postmaster@${config.networking.domain}"
-
];
-
sieveScript = ''
-
require ["fileinto", "mailbox"];
-
-
if header :contains ["to", "cc"] ["~rjarry/aerc-discuss@lists.sr.ht"] {
-
fileinto :create "lists.aerc";
-
stop;
-
}
-
'';
-
};
-
"misc@${config.networking.domain}" = {
-
passwordFile = config.age.secrets.email-ryan.path;
-
catchAll = [ "${config.networking.domain}" ];
-
};
-
"system@${config.networking.domain}" = {
-
aliases = [ "nas@${config.networking.domain}" ];
-
};
-
};
-
-
services.minecraft-server = {
-
enable = true;
-
package = pkgs.overlay-unstable.minecraft-server;
-
eula = true;
-
openFirewall = true;
-
};
-
-
networking.firewall.allowedTCPPorts = [ 7001 ];
services.openssh.openFirewall = true;
}
-3
hosts/owl/minimal.nix
···
{
-
pkgs,
config,
-
lib,
-
eilean,
...
}:
+518
hosts/owl/services.nix
···
+
{
+
pkgs,
+
config,
+
lib,
+
eon,
+
...
+
}:
+
+
let
+
vpnRecords = [
+
{
+
name = "nix-cache.vpn.${config.networking.domain}.";
+
type = "A";
+
value = "100.64.0.9";
+
}
+
{
+
name = "jellyfin.vpn.${config.networking.domain}.";
+
type = "A";
+
value = "100.64.0.9";
+
}
+
{
+
name = "nextcloud.vpn.${config.networking.domain}.";
+
type = "A";
+
value = "100.64.0.9";
+
}
+
{
+
name = "transmission.vpn.${config.networking.domain}.";
+
type = "A";
+
value = "100.64.0.9";
+
}
+
{
+
name = "owntracks.vpn.${config.networking.domain}.";
+
type = "A";
+
value = "100.64.0.9";
+
}
+
{
+
name = "immich.vpn.${config.networking.domain}.";
+
type = "A";
+
value = "100.64.0.9";
+
}
+
{
+
name = "audiobookshelf.vpn.${config.networking.domain}.";
+
type = "A";
+
value = "100.64.0.9";
+
}
+
];
+
in
+
{
+
# eilean
+
networking.domain = lib.mkDefault "freumh.org";
+
eilean = {
+
username = config.custom.username;
+
serverIpv4 = "135.181.100.27";
+
serverIpv6 = "2a01:4f9:c011:87ad:0:0:0:0";
+
publicInterface = "enp1s0";
+
fail2ban.enable = true;
+
};
+
+
# eon
+
age.secrets.eon-capnp = {
+
file = ../../secrets/eon-capnp.age;
+
mode = "660";
+
owner = "eon";
+
group = "eon";
+
};
+
age.secrets.eon-sirref-primary = {
+
file = ../../secrets/eon-sirref-primary.cap.age;
+
mode = "660";
+
owner = "eon";
+
group = "eon";
+
};
+
services.eon = {
+
capnpSecretKeyFile = config.age.secrets.eon-capnp.path;
+
primaries = [ config.age.secrets.eon-sirref-primary.path ];
+
prod = true;
+
capnpAddress = "135.181.100.27";
+
logLevel = 0;
+
};
+
+
# certificates
+
eilean.acme-eon = true;
+
security.acme-eon = {
+
acceptTerms = true;
+
package = eon.defaultPackage.${config.nixpkgs.hostPlatform.system};
+
defaults.email = "${config.custom.username}@${config.networking.domain}";
+
defaults.capFile = "/var/lib/eon/caps/domain/freumh.org.cap";
+
certs = {
+
"fn06.org".capFile = "/var/lib/eon/caps/domain/fn06.org.cap";
+
"capybara.fn06.org".capFile = "/var/lib/eon/caps/domain/fn06.org.cap";
+
};
+
};
+
security.acme-eon.nginxCerts = [
+
"capybara.fn06.org"
+
"shrew.freumh.org"
+
"knot.freumh.org"
+
"enki.freumh.org"
+
];
+
+
# VPN
+
eilean.headscale.enable = true;
+
services.headscale.settings.dns = {
+
extra_records = vpnRecords;
+
base_domain = "vpn.freumh.org";
+
nameservers.global = config.networking.nameservers;
+
};
+
boot.kernel.sysctl = {
+
"net.ipv4.ip_forward" = 1;
+
"net.ipv6.conf.all.forwarding" = 1;
+
};
+
+
# websites
+
custom = {
+
freumh.enable = true;
+
rmfakecloud.enable = true;
+
website = {
+
ryan = {
+
enable = true;
+
cname = "vps";
+
};
+
alec = {
+
enable = true;
+
cname = "vps";
+
};
+
fn06 = {
+
enable = true;
+
cname = "vps";
+
domain = "fn06.org";
+
};
+
};
+
};
+
services.nginx.commonHttpConfig = ''
+
add_header Strict-Transport-Security max-age=31536000 always;
+
add_header X-Frame-Options SAMEORIGIN always;
+
add_header X-Content-Type-Options nosniff always;
+
add_header Content-Security-Policy "default-src 'self' 'unsafe-inline' 'unsafe-eval' blob:; base-uri 'self'; frame-src 'self'; frame-ancestors 'self'; form-action 'self';" always;
+
add_header Referrer-Policy 'same-origin';
+
'';
+
services.nginx.virtualHosts."teapot.${config.networking.domain}" = {
+
extraConfig = ''
+
return 418;
+
'';
+
};
+
+
# mailserver
+
eilean.mailserver.enable = true;
+
age.secrets.email-ryan.file = ../../secrets/email-ryan.age;
+
age.secrets.email-system.file = ../../secrets/email-system.age;
+
eilean.mailserver.systemAccountPasswordFile = config.age.secrets.email-system.path;
+
mailserver.loginAccounts = {
+
"${config.eilean.username}@${config.networking.domain}" = {
+
passwordFile = config.age.secrets.email-ryan.path;
+
aliases = [
+
"dns@${config.networking.domain}"
+
"postmaster@${config.networking.domain}"
+
];
+
sieveScript = ''
+
require ["fileinto", "mailbox"];
+
+
if header :contains ["to", "cc"] ["ai-control@ietf.org"] {
+
fileinto :create "lists.aietf";
+
stop;
+
}
+
'';
+
};
+
"misc@${config.networking.domain}" = {
+
passwordFile = config.age.secrets.email-ryan.path;
+
catchAll = [ "${config.networking.domain}" ];
+
};
+
"system@${config.networking.domain}" = {
+
aliases = [ "nas@${config.networking.domain}" ];
+
};
+
};
+
+
# CalDAV calendar server
+
eilean.radicale = {
+
enable = true;
+
users = null;
+
};
+
+
# matrix
+
age.secrets.matrix-shared-secret = {
+
file = ../../secrets/matrix-shared-secret.age;
+
mode = "770";
+
owner = "${config.systemd.services.matrix-synapse.serviceConfig.User}";
+
group = "${config.systemd.services.matrix-synapse.serviceConfig.Group}";
+
};
+
eilean.matrix = {
+
enable = true;
+
registrationSecretFile = config.age.secrets.matrix-shared-secret.path;
+
bridges.whatsapp = true;
+
bridges.signal = true;
+
bridges.instagram = true;
+
bridges.messenger = true;
+
};
+
eilean.turn.enable = true;
+
systemd.services.matrix-as-meta = {
+
path = [ pkgs.ffmpeg ];
+
};
+
+
# mastodon
+
eilean.mastodon.enable = true;
+
services.mastodon = {
+
webProcesses = lib.mkForce 1;
+
webThreads = lib.mkForce 1;
+
sidekiqThreads = lib.mkForce 1;
+
streamingProcesses = lib.mkForce 1;
+
};
+
+
# restic
+
age.secrets.restic-owl.file = ../../secrets/restic-owl.age;
+
services.restic.backups.${config.networking.hostName} = {
+
repository = "rest:http://100.64.0.9:8000/${config.networking.hostName}/";
+
passwordFile = config.age.secrets.restic-owl.path;
+
initialize = true;
+
paths = [
+
"/var/"
+
"/run/"
+
"/etc/"
+
];
+
timerConfig = {
+
OnCalendar = "03:00";
+
randomizedDelaySec = "1hr";
+
};
+
};
+
+
# reverse proxy
+
services.nginx.virtualHosts."capybara.fn06.org" = {
+
forceSSL = true;
+
locations."/" = {
+
proxyPass = ''
+
http://100.64.0.10:8123
+
'';
+
proxyWebsockets = true;
+
};
+
};
+
services.nginx.virtualHosts."shrew.freumh.org" = {
+
forceSSL = true;
+
locations."/" = {
+
proxyPass = ''
+
http://100.64.0.6:8123
+
'';
+
proxyWebsockets = true;
+
};
+
};
+
+
# tangled
+
age.secrets.tangled = {
+
file = ../../secrets/tangled.age;
+
mode = "660";
+
owner = "git";
+
group = "git";
+
};
+
services.tangled-knotserver = {
+
enable = true;
+
repo.mainBranch = "master";
+
server.hostname = "knot.freumh.org";
+
server = {
+
secretFile = config.age.secrets.tangled.path;
+
listenAddr = "127.0.0.1:5555";
+
internalListenAddr = "127.0.0.1:5444";
+
};
+
};
+
services.nginx.virtualHosts."knot.freumh.org" = {
+
forceSSL = true;
+
locations."/" = {
+
proxyPass = ''
+
http://${config.services.tangled-knotserver.server.listenAddr}
+
'';
+
proxyWebsockets = true;
+
};
+
};
+
+
services.nginx.virtualHosts."enki.freumh.org" = {
+
forceSSL = true;
+
locations."/" = {
+
proxyPass = ''
+
http://localhost:8000
+
'';
+
proxyWebsockets = true;
+
extraConfig = ''
+
# SSE-specific settings
+
proxy_buffering off;
+
proxy_read_timeout 3600s;
+
proxy_send_timeout 3600s;
+
proxy_connect_timeout 60s;
+
+
# Forward headers
+
proxy_set_header Connection "";
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+
proxy_set_header X-Forwarded-Proto $scheme;
+
proxy_set_header Host $host;
+
'';
+
};
+
};
+
+
# minecraft server
+
services.minecraft-server = {
+
enable = true;
+
package = pkgs.overlay-unstable.minecraft-server;
+
eula = true;
+
openFirewall = true;
+
};
+
+
# DNS records
+
eilean.dns.nameservers = [ "ns1" ];
+
eilean.services.dns.zones = {
+
${config.networking.domain} = {
+
ttl = 300;
+
soa = {
+
serial = 2018011660;
+
refresh = 300;
+
};
+
records = [
+
{
+
name = "@";
+
type = "TXT";
+
value = "google-site-verification=rEvwSqf7RYKRQltY412qMtTuoxPp64O3L7jMotj9Jnc";
+
}
+
{
+
name = "_atproto.ryan";
+
type = "TXT";
+
value = "did=did:plc:3lfhu6ehlynzjgehef6alnvg";
+
}
+
+
{
+
name = "teapot";
+
type = "CNAME";
+
value = "vps";
+
}
+
+
{
+
name = "@";
+
type = "ns";
+
value = "ns1.sirref.org.";
+
}
+
+
{
+
name = "vps";
+
type = "A";
+
value = config.eilean.serverIpv4;
+
}
+
{
+
name = "vps";
+
type = "AAAA";
+
value = config.eilean.serverIpv6;
+
}
+
+
{
+
name = "@";
+
type = "LOC";
+
value = "52 12 40.4 N 0 5 31.9 E 22m 10m 10m 10m";
+
}
+
+
{
+
name = "ns.cl";
+
type = "A";
+
value = "128.232.113.136";
+
}
+
{
+
name = "cl";
+
type = "NS";
+
value = "ns.cl";
+
}
+
+
{
+
name = "ns1.eilean";
+
type = "A";
+
value = "65.109.10.223";
+
}
+
{
+
name = "eilean";
+
type = "NS";
+
value = "ns1.eilean";
+
}
+
+
{
+
name = "shrew";
+
type = "CNAME";
+
value = "vps";
+
}
+
+
{
+
name = "knot";
+
type = "CNAME";
+
value = "vps";
+
}
+
+
{
+
name = "enki";
+
type = "CNAME";
+
value = "vps";
+
}
+
+
{
+
name = "hippo";
+
type = "A";
+
value = "128.232.124.251";
+
}
+
+
# generate with
+
# sudo openssl x509 -in /var/lib/acme/mail.freumh.org/fullchain.pem -pubkey -noout | openssl pkey -pubin -outform der | sha256sum | awk '{print "3 1 1", $1}'
+
{
+
name = "_25._tcp.mail";
+
type = "TLSA";
+
value = "3 1 1 2f0fd413f063c75141937dd196a9f4ab66139d599e0dcf2a7ce6d557647e26a6";
+
}
+
# generate with
+
# for i in r3 e1 r4-cross-signed e2
+
# openssl x509 -in ~/downloads/lets-encrypt-$i.pem -pubkey -noout | openssl pkey -pubin -outform der | sha256sum | awk '{print "2 1 1", $1}'
+
# LE R3
+
{
+
name = "_25._tcp.mail";
+
type = "TLSA";
+
value = "2 1 1 8d02536c887482bc34ff54e41d2ba659bf85b341a0a20afadb5813dcfbcf286d";
+
}
+
# LE E1
+
{
+
name = "_25._tcp.mail";
+
type = "TLSA";
+
value = "2 1 1 276fe8a8c4ec7611565bf9fce6dcace9be320c1b5bea27596b2204071ed04f10";
+
}
+
# LE R4
+
{
+
name = "_25._tcp.mail";
+
type = "TLSA";
+
value = "2 1 1 e5545e211347241891c554a03934cde9b749664a59d26d615fe58f77990f2d03";
+
}
+
# LE E2
+
{
+
name = "_25._tcp.mail";
+
type = "TLSA";
+
value = "2 1 1 bd936e72b212ef6f773102c6b77d38f94297322efc25396bc3279422e0c89270";
+
}
+
+
{
+
name = "jellyfin";
+
type = "AAAA";
+
value = "2a00:23c6:aa22:e401:8dff:9b9a:cb3c:3fcb";
+
}
+
{
+
name = "jellyseerr";
+
type = "AAAA";
+
value = "2a00:23c6:aa22:e401:8dff:9b9a:cb3c:3fcb";
+
}
+
{
+
name = "calibre";
+
type = "AAAA";
+
value = "2a00:23c6:aa22:e401:8dff:9b9a:cb3c:3fcb";
+
}
+
] ++ vpnRecords;
+
};
+
"fn06.org" = {
+
soa.serial = 1706745602;
+
records = [
+
{
+
name = "@";
+
type = "NS";
+
value = "ns1";
+
}
+
{
+
name = "@";
+
type = "NS";
+
value = "ns2";
+
}
+
+
{
+
name = "ns1";
+
type = "A";
+
value = config.eilean.serverIpv4;
+
}
+
{
+
name = "ns1";
+
type = "AAAA";
+
value = config.eilean.serverIpv6;
+
}
+
{
+
name = "ns2";
+
type = "A";
+
value = config.eilean.serverIpv4;
+
}
+
{
+
name = "ns2";
+
type = "AAAA";
+
value = config.eilean.serverIpv6;
+
}
+
+
{
+
name = "@";
+
type = "A";
+
value = config.eilean.serverIpv4;
+
}
+
{
+
name = "@";
+
type = "AAAA";
+
value = config.eilean.serverIpv6;
+
}
+
+
{
+
name = "www.fn06.org.";
+
type = "CNAME";
+
value = "fn06.org.";
+
}
+
+
{
+
name = "@";
+
type = "LOC";
+
value = "52 12 40.4 N 0 5 31.9 E 22m 10m 10m 10m";
+
}
+
+
{
+
name = "capybara.fn06.org.";
+
type = "CNAME";
+
value = "fn06.org.";
+
}
+
];
+
};
+
};
+
}
+2 -11
hosts/vulpine/default.nix
···
services.kdeconnect.enable = true;
custom = {
machineColour = "magenta";
-
mail.enable = true;
calendar.enable = true;
battery.enable = true;
};
home.sessionVariables = {
-
LEDGER_FILE = "~/vault/finaces.ledger";
+
LEDGER_FILE = "~/vault/finances.ledger";
};
};
···
Defaults !tty_tickets
'';
-
services = {
-
syncthing = {
-
enable = true;
-
user = config.custom.username;
-
dataDir = "/home/ryan/syncthing";
-
configDir = "/home/ryan/.config/syncthing";
-
};
-
};
-
services.avahi.enable = true;
programs.steam.enable = true;
specialisation.nvidia.configuration = {
services.xserver.videoDrivers = [ "nvidia" ];
+
hardware.nvidia.open = false;
};
}
-57
modules/colour-guesser.nix
···
-
{
-
pkgs,
-
config,
-
lib,
-
options,
-
colour-guesser,
-
...
-
}:
-
-
let
-
cfg = config.custom.website.colour-guesser;
-
in
-
{
-
options = {
-
custom.website.colour-guesser = {
-
enable = lib.mkEnableOption "Colour Guesser";
-
domain = lib.mkOption {
-
type = lib.types.str;
-
default = "colour-guesser.${config.networking.domain}";
-
};
-
cname = lib.mkOption {
-
type = lib.types.str;
-
default = null;
-
description = ''
-
CNAME to create DNS records for.
-
Ignored if null
-
'';
-
};
-
};
-
};
-
-
config = lib.mkIf cfg.enable {
-
security.acme-eon.nginxCerts = [ cfg.domain ];
-
services.nginx = {
-
enable = true;
-
recommendedProxySettings = true;
-
virtualHosts."${cfg.domain}" = {
-
forceSSL = true;
-
root = "${colour-guesser.packages.${pkgs.stdenv.hostPlatform.system}.default}";
-
};
-
};
-
-
# requires dns module
-
eilean.services.dns.zones.${config.networking.domain}.records = [
-
{
-
name = "${cfg.domain}.";
-
type = "CNAME";
-
value = cfg.cname;
-
}
-
{
-
name = "www.${cfg.domain}.";
-
type = "CNAME";
-
value = cfg.cname;
-
}
-
];
-
};
-
}
+2 -2
modules/ryan-website.nix
···
{
-
pkgs,
config,
lib,
-
ryan-website,
...
}:
···
"${cfg.domain}" = {
forceSSL = true;
root = "/var/www/ryan.freumh.org/";
+
locations."/".index = "home.html index.html";
locations."/teapot".extraConfig = ''
return 418;
'';
+
locations."/var/".alias = "/var/www/var/";
extraConfig = ''
error_page 403 =404 /404.html;
error_page 404 /404.html;
+8 -1
nix-on-droid/default.nix
···
+
# TODO there has to be a better way of getting this in here
+
inputs:
+
{
pkgs,
config,
···
home-manager = {
useGlobalPkgs = true;
+
extraSpecialArgs = {
+
i3-workspace-history = inputs.i3-workspace-history;
+
timewall = inputs.timewall;
+
};
config =
{ pkgs, lib, ... }:
{
···
};
home.sessionVariables = {
-
LEDGER_FILE = "~/storage/Documents/vault/finaces.ledger";
+
LEDGER_FILE = "~/storage/Documents/vault/finances.ledger";
};
home.stateVersion = "22.05";
+1
secrets/secrets.nix
···
owl
];
"eon-sirref-primary.cap.age".publicKeys = user ++ [ owl ];
+
"tangled.age".publicKeys = user ++ [ owl ];
}
+7
secrets/tangled.age
···
+
age-encryption.org/v1
+
-> ssh-ed25519 2wDnOw Ttbl5LTzHDAP3kG7kbRErJr+ayerVYZIWZeLPmZmD0U
+
Uvon5zchwp3jwP/wHJ5/jIrmDhSVOxGKEhLGPtnQj9w
+
-> ssh-ed25519 suwb0g N+Z7lyQailIdkJMiCuFapSN3LhYphejMvB0x4Au1zBI
+
dC6ju3bdhzyLB19/WFwgmr+HxTG9vd2fO/EB/WYjodM
+
--- s2WjTwvpTi8jhAn0/yqBcTmzh77wbpYulovyEdGE7KQ
+
G๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ}w๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ{๏ฟฝ n๏ฟฝod&i,V๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝU๏ฟฝ๏ฟฝ%๏ฟฝ'!R46๏ฟฝ{>๏ฟฝ )>to๏ฟฝ]Hh๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝ2F๏ฟฝ๏ฟฝA๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝTv๏ฟฝ!๏ฟฝ;๏ฟฝ๏ฟฝ๏ฟฝ)R๏ฟฝlM%U=|W"?*๏ฟฝ๏ฟฝe๏ฟฝ๏ฟฝ"๏ฟฝ๏ฟฝ๏ฟฝ๏ฟฝi๏ฟฝKB๏ฟฝF
-43
templates/host/default.nix
···
-
{
-
pkgs,
-
lib,
-
config,
-
...
-
}:
-
-
{
-
imports = [
-
./hardware-configuration.nix
-
];
-
-
boot.loader.grub = {
-
enable = true;
-
device = "nodev";
-
efiSupport = true;
-
};
-
boot.loader.efi.canTouchEfiVariables = true;
-
-
custom = {
-
enable = true;
-
#tailscale = true;
-
#laptop = true;
-
#gui.i3 = true;
-
#gui.sway = true;
-
#workstation = true;
-
#autoUpgrade.enable = true;
-
homeManager.enable = true;
-
};
-
-
home-manager.users.${config.custom.username} = {
-
custom = {
-
machineColour = "blue";
-
};
-
};
-
-
environment.systemPackages = with pkgs; [
-
coreutils
-
];
-
-
networking.networkmanager.enable = true;
-
# services.openssh.openFirewall = true;
-
}