Compare commits
No commits in common. "master" and "feat/mcentire-crowdsec" have entirely different histories.
master
...
feat/mcent
84 changed files with 990 additions and 3231 deletions
74
.gitignore
vendored
74
.gitignore
vendored
|
|
@ -1,74 +0,0 @@
|
||||||
### Linux gitignore ###
|
|
||||||
*~
|
|
||||||
|
|
||||||
# temporary files which can be created if a process still has a handle open of a deleted file
|
|
||||||
.fuse_hidden*
|
|
||||||
|
|
||||||
# Metadata left by Dolphin file manager, which comes with KDE Plasma
|
|
||||||
.directory
|
|
||||||
|
|
||||||
# Linux trash folder which might appear on any partition or disk
|
|
||||||
.Trash-*
|
|
||||||
|
|
||||||
# .nfs files are created when an open file is removed but is still being accessed
|
|
||||||
.nfs*
|
|
||||||
|
|
||||||
# Log files created by default by the nohup command
|
|
||||||
nohup.out
|
|
||||||
|
|
||||||
### MacOS gitignore ###
|
|
||||||
# General
|
|
||||||
.DS_Store
|
|
||||||
__MACOSX/
|
|
||||||
.AppleDouble
|
|
||||||
.LSOverride
|
|
||||||
Icon[]
|
|
||||||
|
|
||||||
# Thumbnails
|
|
||||||
._*
|
|
||||||
|
|
||||||
# Files that might appear in the root of a volume
|
|
||||||
.DocumentRevisions-V100
|
|
||||||
.fseventsd
|
|
||||||
.Spotlight-V100
|
|
||||||
.TemporaryItems
|
|
||||||
.Trashes
|
|
||||||
.VolumeIcon.icns
|
|
||||||
.com.apple.timemachine.donotpresent
|
|
||||||
|
|
||||||
# Directories potentially created on remote AFP share
|
|
||||||
.AppleDB
|
|
||||||
.AppleDesktop
|
|
||||||
Network Trash Folder
|
|
||||||
Temporary Items
|
|
||||||
.apdisk
|
|
||||||
|
|
||||||
### Nix gitignore ###
|
|
||||||
# Ignore build outputs from performing a nix-build or `nix build` command
|
|
||||||
result
|
|
||||||
result-*
|
|
||||||
|
|
||||||
# Ignore automatically generated direnv output
|
|
||||||
.direnv
|
|
||||||
|
|
||||||
### Vim gitignore ###
|
|
||||||
# Swap
|
|
||||||
[._]*.s[a-v][a-z]
|
|
||||||
# comment out the next line if you don't need vector files
|
|
||||||
!*.svg
|
|
||||||
[._]*.sw[a-p]
|
|
||||||
[._]s[a-rt-v][a-z]
|
|
||||||
[._]ss[a-gi-z]
|
|
||||||
[._]sw[a-p]
|
|
||||||
|
|
||||||
# Session
|
|
||||||
Session.vim
|
|
||||||
Sessionx.vim
|
|
||||||
|
|
||||||
# Temporary
|
|
||||||
.netrwhist
|
|
||||||
*~
|
|
||||||
# Auto-generated tag files
|
|
||||||
tags
|
|
||||||
# Persistent undo
|
|
||||||
[._]*.un~
|
|
||||||
157
README.md
157
README.md
|
|
@ -1,157 +0,0 @@
|
||||||
# nix-dotfiles
|
|
||||||
|
|
||||||
System and home configurations for my machines.
|
|
||||||
|
|
||||||
| Machine | Role | OS | Arch | System config tool | Home config tool |
|
|
||||||
| -------- | --------------- | ------ | ------- | --------------------------- | ---------------- |
|
|
||||||
| anderson | server | linux | x86_64 | dpkg/Docker (not this repo) | home-manager |
|
|
||||||
| bosephus | server | linux | x86_64 | NixOS | home-manager |
|
|
||||||
| mcentire | server | linux | x86_64 | NixOS | home-manager |
|
|
||||||
| corianne | MacBook | darwin | aarch64 | nix-darwin | home-manager |
|
|
||||||
| odyssey | workstation | linux | x86_64 | Ansible | home-manager |
|
|
||||||
|
|
||||||
## Quickstart
|
|
||||||
|
|
||||||
### Home dotfiles
|
|
||||||
|
|
||||||
> ![WARNING]
|
|
||||||
> Fedora systems will set this up automagically via Ansible. Follow the
|
|
||||||
[Fedora quickstart] instructions.
|
|
||||||
|
|
||||||
Ensure Nix is installed, with the `nix` command and flakes enabled. I try to use
|
|
||||||
the [Determinate Nix installer] (with upstream Nix) to install Nix with these
|
|
||||||
options turned on by default.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -fsSL https://install.determinate.systems/nix | sh -s -- install
|
|
||||||
```
|
|
||||||
|
|
||||||
Once Nix is installed, clone the repository to `~/.config/home-manager` and
|
|
||||||
initiate home-manager.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://code.millironx.com/millironx/nix-dotfiles.git ~/.config/home-manager
|
|
||||||
nix run home-manager -- switch --flake ~/.config/home-manager#$USER@$(hostname -s)
|
|
||||||
```
|
|
||||||
|
|
||||||
In the case that the host has not been assigned a configuration within this repo
|
|
||||||
yet, pick a hostname with the same system OS, arch, and role as the target
|
|
||||||
system to get temporary dotfiles up and running.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
nix run home-manager -- switch --flake ~/.config/home-manager#millironx@anderson
|
|
||||||
```
|
|
||||||
|
|
||||||
Once an SSH (with or without GPG) key has been setup and added to the authorized
|
|
||||||
keys of the git server, switch the upstream to track an authorized (i.e.
|
|
||||||
read/write) version of the repo.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd ~/.config/home-manager
|
|
||||||
git remote set-url origin git@code.millironx.com:millironx/nix-dotfiles.git
|
|
||||||
cd -
|
|
||||||
```
|
|
||||||
|
|
||||||
### NixOS
|
|
||||||
|
|
||||||
Switching to a flake-based config requires running as root. All of the following
|
|
||||||
commands are assumed to be running as root.
|
|
||||||
|
|
||||||
Ensure that the `nix` command and flakes are enabled.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sed -i '/^}/i nix.settings.experimental-features = [ "nix-command" "flakes" ];' /etc/nixos/configuration.nix
|
|
||||||
nixos-rebuild switch
|
|
||||||
```
|
|
||||||
|
|
||||||
> ![NOTE]
|
|
||||||
> To allow secret decryption in the system, the *machine*-specific SSH key must
|
|
||||||
> be added to the publicKeys attribute of all applicable secrets, and the
|
|
||||||
> `hardware-configuration.nix` file must be added to git. Copying arbitrary
|
|
||||||
> strings like SSH keys or disk UUIDs between systems can be painful, so it might
|
|
||||||
> be worth setting up the [home dotfiles] immediately after enabling flakes,
|
|
||||||
> then running these steps on the same machine to avoid typos. Alternatively, I
|
|
||||||
> might someday be smart enough to create an installer CD that automagically
|
|
||||||
> sets this up for me.
|
|
||||||
|
|
||||||
Get the machine-specific public SSH key.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cat /etc/ssh/ssh_host_ed25519_key.pub
|
|
||||||
```
|
|
||||||
|
|
||||||
On a separate machine, add the machine's SSH key to `./secrets.nix` and assign
|
|
||||||
it to any secrets it would need.
|
|
||||||
|
|
||||||
```nix
|
|
||||||
let
|
|
||||||
bosephus-host =
|
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIxTfeg+GZsfmG8TuEV1xW1gXknAIKzZ3UjZ3guRY+EW root@nixos";
|
|
||||||
bosephus-millironx =
|
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKaDPqRJHoqgY2pseh/mnhjaGWXprHk2s5I52LhHpHcF millironx@bosephus";
|
|
||||||
odyssey-millironx =
|
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN9Aj7BtQp1Roa0tgopDrUo7g2am5WJ43lO1d1fDUz45 millironx@odyssey";
|
|
||||||
|
|
||||||
system-administrators = [
|
|
||||||
bosephus-millironx
|
|
||||||
odyssey-millironx
|
|
||||||
];
|
|
||||||
in {
|
|
||||||
"secrets/network-information.age".publicKeys = system-administrators
|
|
||||||
++ [ bosephus-host ];
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Rekey the secrets, and push the updated secrets to the upstream repo.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
nix run github:ryantm/agenix -- --rekey
|
|
||||||
git add secrets.nix secrets/*
|
|
||||||
git commit -m "added $NEW_HOST to secrets"
|
|
||||||
git push
|
|
||||||
```
|
|
||||||
|
|
||||||
Copy the target machine's `hardware-configuration.nix` file to this repo's
|
|
||||||
`./systems/linux/hardware-configuration/$NEW_HOST.nix`, and be sure to update
|
|
||||||
the configuration to import its own `hardware-configuration`.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cp /etc/nixos/hardware-configuration.nix ./systems/linux/hardware-configuration/$NEW_HOST.nix
|
|
||||||
```
|
|
||||||
|
|
||||||
```nix
|
|
||||||
{ config, pkgs, ... }: {
|
|
||||||
imports = [
|
|
||||||
./hardware-configuration/bosephus.nix
|
|
||||||
];
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Commit and push the hardware configuration to the upstream repo.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git add systems/linux/*
|
|
||||||
git commit -m "added $NEW_HOST hardware configuration"
|
|
||||||
git push
|
|
||||||
```
|
|
||||||
|
|
||||||
Now switch to the flake by pulling and switching in one step.
|
|
||||||
|
|
||||||
|
|
||||||
```bash
|
|
||||||
nixos-rebuild switch --flake git+https://code.millironx.com/millironx/nix-dotfiles#$(hostname -s)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Fedora
|
|
||||||
|
|
||||||
Fedora systems are managed using Ansible.
|
|
||||||
|
|
||||||
TODO
|
|
||||||
|
|
||||||
## Home settings
|
|
||||||
|
|
||||||
TODO
|
|
||||||
|
|
||||||
[determinate nix installer]: https://github.com/DeterminateSystems/nix-installer
|
|
||||||
[fedora quickstart]: #fedora
|
|
||||||
[home dotfiles]: #home-dotfiles
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
#!/usr/bin/env julia
|
|
||||||
using TOML: TOML
|
|
||||||
|
|
||||||
@show ENV["PATH"]
|
|
||||||
|
|
||||||
function remove_podman_secrets()
|
|
||||||
run(`podman secret rm --all`)
|
|
||||||
return nothing
|
|
||||||
end #function
|
|
||||||
|
|
||||||
function create_podman_secret(name, secret)
|
|
||||||
run(
|
|
||||||
addenv(
|
|
||||||
`podman secret create --env=true --replace $name SECRET`,
|
|
||||||
Dict("SECRET" => secret),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
return nothing
|
|
||||||
end #function
|
|
||||||
|
|
||||||
function parse_toml_secrets(file)
|
|
||||||
foreach(f -> create_podman_secret(f[1], f[2]), TOML.parsefile(file))
|
|
||||||
return nothing
|
|
||||||
end #function
|
|
||||||
|
|
||||||
function main()
|
|
||||||
remove_podman_secrets()
|
|
||||||
foreach(parse_toml_secrets, ARGS)
|
|
||||||
return 0
|
|
||||||
end #function
|
|
||||||
|
|
||||||
main()
|
|
||||||
|
|
@ -1,159 +0,0 @@
|
||||||
# Translated from <https://github.com/Chocobozzz/PeerTube/blob/v8.1.4/support/nginx/peertube>
|
|
||||||
@api_resumable <<CEL
|
|
||||||
path_regexp('^/api/v1/videos/(upload-resumable|([^/]+/source/replace-resumable))$')
|
|
||||||
|| path_regexp('^/api/v1/users/[^/]+/imports/import-resumable$')
|
|
||||||
CEL
|
|
||||||
|
|
||||||
handle @api_resumable {
|
|
||||||
reverse_proxy http://127.0.0.1:{$MILLIRONX_PEERTUBE_PORT} {
|
|
||||||
header_up X-Real-IP {remote_host}
|
|
||||||
flush_interval -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@api_video_upload_wrong_method <<CEL
|
|
||||||
path_regexp('^/api/v1/videos/(upload|([^/]+/studio/edit))$')
|
|
||||||
&& !method('POST', 'HEAD')
|
|
||||||
CEL
|
|
||||||
handle @api_video_upload_wrong_method {
|
|
||||||
header Allow "POST,HEAD"
|
|
||||||
respond 405
|
|
||||||
}
|
|
||||||
|
|
||||||
@api_video_upload <<CEL
|
|
||||||
path_regexp('^/api/v1/videos/(upload|([^/]+/studio/edit))$')
|
|
||||||
&& method('POST', 'HEAD')
|
|
||||||
CEL
|
|
||||||
handle @api_video_upload {
|
|
||||||
request_body {
|
|
||||||
max_size 12G
|
|
||||||
}
|
|
||||||
|
|
||||||
reverse_proxy http://127.0.0.1:{$MILLIRONX_PEERTUBE_PORT} {
|
|
||||||
flush_interval -1
|
|
||||||
header_up X-File-Maximum-Size 8G
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@api_jobs path_regexp ^/api/v1/runners/jobs/[^/]+/(update|success)$
|
|
||||||
handle @api_jobs {
|
|
||||||
reverse_proxy http://127.0.0.1:{$MILLIRONX_PEERTUBE_PORT} {
|
|
||||||
flush_interval -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@api_videos path_regexp ^/api/v1/(videos|video-playlists|video-channels|users/me)
|
|
||||||
handle @api_videos {
|
|
||||||
request_body {
|
|
||||||
max_size 12M
|
|
||||||
}
|
|
||||||
|
|
||||||
reverse_proxy http://127.0.0.1:{$MILLIRONX_PEERTUBE_PORT} {
|
|
||||||
header_up X-File-Maximum-Size 8M
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@websocket_socket_plugins <<CEL
|
|
||||||
path('/socket.io')
|
|
||||||
|| path_regexp('^/plugins/[^/]+(/[^/]+)?/ws/')
|
|
||||||
CEL
|
|
||||||
handle @websocket_socket_plugins {
|
|
||||||
reverse_proxy http://127.0.0.1:{$MILLIRONX_PEERTUBE_PORT} {
|
|
||||||
header_up X-Real-IP {remote_host}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handle /tracker/socket {
|
|
||||||
reverse_proxy http://127.0.0.1:{$MILLIRONX_PEERTUBE_PORT} {
|
|
||||||
header_up X-Real-IP {remote_host}
|
|
||||||
transport http {
|
|
||||||
read_timeout 15m
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@client_overridable_assets {
|
|
||||||
path_regexp asset_path ^/client/(assets/images/(default-playlist\.jpg|default-avatar-account\.png|default-avatar-account-48x48\.png|default-avatar-video-channel\.png|default-avatar-video-channel-48x48\.png))$
|
|
||||||
}
|
|
||||||
handle @client_overridable_assets {
|
|
||||||
root * {$MILLIRONX_PEERTUBE_ASSETS_DIR}
|
|
||||||
header Cache-Control "public, max-age=31536000, immutable"
|
|
||||||
|
|
||||||
@try_override file {
|
|
||||||
try_files storage/client-overrides/{re.asset_path.1}
|
|
||||||
}
|
|
||||||
handle @try_override {
|
|
||||||
rewrite * storage/client-overrides/{re.asset_path.1}
|
|
||||||
file_server
|
|
||||||
}
|
|
||||||
|
|
||||||
@try_dist file {
|
|
||||||
try_files {re.asset_path.1}
|
|
||||||
}
|
|
||||||
handle @try_dist {
|
|
||||||
rewrite * {re.asset_path.1}
|
|
||||||
file_server
|
|
||||||
}
|
|
||||||
|
|
||||||
reverse_proxy http://127.0.0.1:{$MILLIRONX_PEERTUBE_PORT}
|
|
||||||
}
|
|
||||||
|
|
||||||
@client_static {
|
|
||||||
path_regexp asset_path ^/client/(.*\.(js|css|png|svg|woff2|otf|ttf|woff|eot))$
|
|
||||||
}
|
|
||||||
handle @client_static {
|
|
||||||
root * {$MILLIRONX_PEERTUBE_ASSETS_DIR}
|
|
||||||
header Cache-Control "public, max-age=31536000, immutable"
|
|
||||||
rewrite * {re.asset_path.1}
|
|
||||||
file_server
|
|
||||||
}
|
|
||||||
|
|
||||||
@static_downloads {
|
|
||||||
path_regexp dl_path ^/static/(webseed|web-videos|redundancy|streaming-playlists)/
|
|
||||||
}
|
|
||||||
handle @static_downloads {
|
|
||||||
@options method OPTIONS
|
|
||||||
handle @options {
|
|
||||||
header Access-Control-Allow-Origin "*"
|
|
||||||
header Access-Control-Allow-Methods "GET,OPTIONS"
|
|
||||||
header Access-Control-Allow-Headers "Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type"
|
|
||||||
header Access-Control-Max-Age 1728000
|
|
||||||
header Content-Type 'text/plain; charset=UTF-8'
|
|
||||||
header Content-Length 0
|
|
||||||
|
|
||||||
respond 204
|
|
||||||
}
|
|
||||||
|
|
||||||
@get method GET
|
|
||||||
handle @get {
|
|
||||||
header Access-Control-Allow-Origin "*"
|
|
||||||
header Access-Control-Allow-Methods "GET,OPTIONS"
|
|
||||||
header Access-Control-Allow-Headers "Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type"
|
|
||||||
|
|
||||||
uri path_regexp ^/static/webseed/(.*)$ /web-videos/$1
|
|
||||||
uri path_regexp ^/static/(.*)$ /$1
|
|
||||||
|
|
||||||
root * {$MILLIRONX_PEERTUBE_STORAGE_DIR}
|
|
||||||
|
|
||||||
@file_exists file {
|
|
||||||
try_files {path}
|
|
||||||
}
|
|
||||||
handle @file_exists {
|
|
||||||
file_server
|
|
||||||
}
|
|
||||||
|
|
||||||
reverse_proxy http://127.0.0.1:{$MILLIRONX_PEERTUBE_PORT} {
|
|
||||||
header_up X-Real-IP {remote_host}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handle {
|
|
||||||
request_body {
|
|
||||||
max_size 100KB
|
|
||||||
}
|
|
||||||
|
|
||||||
reverse_proxy http://127.0.0.1:{$MILLIRONX_PEERTUBE_PORT} {
|
|
||||||
header_up X-Real-IP {remote_host}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
24
dotfiles/dolphinrc
Normal file
24
dotfiles/dolphinrc
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
MenuBar=Disabled
|
||||||
|
|
||||||
|
[DetailsMode]
|
||||||
|
PreviewSize=16
|
||||||
|
|
||||||
|
[General]
|
||||||
|
BrowseThroughArchives=true
|
||||||
|
EditableUrl=true
|
||||||
|
GlobalViewProps=false
|
||||||
|
ShowFullPath=true
|
||||||
|
ShowStatusBar=FullWidth
|
||||||
|
ShowZoomSlider=true
|
||||||
|
Version=202
|
||||||
|
|
||||||
|
|
||||||
|
[KFileDialog Settings]
|
||||||
|
Places Icons Auto-resize=false
|
||||||
|
Places Icons Static Size=22
|
||||||
|
|
||||||
|
[MainWindow]
|
||||||
|
MenuBar=Disabled
|
||||||
|
|
||||||
|
[PreviewSettings]
|
||||||
|
Plugins=audiothumbnail,avif,blenderthumbnail,comicbookthumbnail,cursorthumbnail,djvuthumbnail,ebookthumbnail,exrthumbnail,directorythumbnail,fontthumbnail,imagethumbnail,jpegthumbnail,jxl,kraorathumbnail,windowsexethumbnail,windowsimagethumbnail,mobithumbnail,opendocumentthumbnail,gsthumbnail,rawthumbnail,svgthumbnail,gdk-pixbuf-thumbnailer,ffmpegthumbs,gsf-office
|
||||||
9
dotfiles/konsolerc
Normal file
9
dotfiles/konsolerc
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
DefaultProfile=My Default.profile
|
||||||
|
|
||||||
|
[MainWindow]
|
||||||
|
StatusBar=Disabled
|
||||||
|
ToolBarsMovable=Disabled
|
||||||
|
|
||||||
|
[UiSettings]
|
||||||
|
ColorScheme=Default
|
||||||
143
flake.lock
generated
143
flake.lock
generated
|
|
@ -14,11 +14,11 @@
|
||||||
"systems": "systems"
|
"systems": "systems"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1770165109,
|
"lastModified": 1754433428,
|
||||||
"narHash": "sha256-9VnK6Oqai65puVJ4WYtCTvlJeXxMzAp/69HhQuTdl/I=",
|
"narHash": "sha256-NA/FT2hVhKDftbHSwVnoRTFhes62+7dxZbxj5Gxvghs=",
|
||||||
"owner": "ryantm",
|
"owner": "ryantm",
|
||||||
"repo": "agenix",
|
"repo": "agenix",
|
||||||
"rev": "b027ee29d959fda4b60b57566d64c98a202e0feb",
|
"rev": "9edb1787864c4f59ae5074ad498b6272b3ec308d",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -27,6 +27,27 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"crowdsec": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1752497357,
|
||||||
|
"narHash": "sha256-9epXn1+T6U4Kfyw8B9zMzbERxDB3VfaPXhVebtai6CE=",
|
||||||
|
"ref": "refs/heads/main",
|
||||||
|
"rev": "84db7dcea77f7f477d79e69e35fb0bb560232667",
|
||||||
|
"revCount": 42,
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://codeberg.org/kampka/nix-flake-crowdsec.git"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://codeberg.org/kampka/nix-flake-crowdsec.git"
|
||||||
|
}
|
||||||
|
},
|
||||||
"flake-parts": {
|
"flake-parts": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs-lib": [
|
"nixpkgs-lib": [
|
||||||
|
|
@ -48,6 +69,23 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"flake-utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems_2"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1731533236,
|
||||||
|
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "flake-utils",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
"home-manager": {
|
"home-manager": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
|
|
@ -55,16 +93,16 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772985280,
|
"lastModified": 1756679287,
|
||||||
"narHash": "sha256-FdrNykOoY9VStevU4zjSUdvsL9SzJTcXt4omdEDZDLk=",
|
"narHash": "sha256-Xd1vOeY9ccDf5VtVK12yM0FS6qqvfUop8UQlxEB+gTQ=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "8f736f007139d7f70752657dff6a401a585d6cbc",
|
"rev": "07fc025fe10487dd80f2ec694f1cd790e752d0e8",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"ref": "release-25.11",
|
"ref": "release-25.05",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
|
@ -76,79 +114,59 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772129556,
|
"lastModified": 1757432263,
|
||||||
"narHash": "sha256-Utk0zd8STPsUJPyjabhzPc5BpPodLTXrwkpXBHYnpeg=",
|
"narHash": "sha256-qHn+/0+IOz5cG68BZUwL9BV3EO/e9eNKCjH3+N7wMdI=",
|
||||||
"owner": "LnL7",
|
"owner": "LnL7",
|
||||||
"repo": "nix-darwin",
|
"repo": "nix-darwin",
|
||||||
"rev": "ebec37af18215214173c98cf6356d0aca24a2585",
|
"rev": "1fef4404de4d1596aa5ab2bd68078370e1b9dcdb",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "LnL7",
|
"owner": "LnL7",
|
||||||
"ref": "nix-darwin-25.11",
|
"ref": "nix-darwin-25.05",
|
||||||
"repo": "nix-darwin",
|
"repo": "nix-darwin",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nix-rosetta-builder": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"nixpkgs-darwin"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1770491098,
|
|
||||||
"narHash": "sha256-ZfhynJqgV3A9hEivcgOEZa+TZnJPc26lIUjzKsSchgI=",
|
|
||||||
"owner": "cpick",
|
|
||||||
"repo": "nix-rosetta-builder",
|
|
||||||
"rev": "50e6070082e0b4fbaf67dd8f346892a1a9ed685c",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "cpick",
|
|
||||||
"repo": "nix-rosetta-builder",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772822230,
|
"lastModified": 1757545623,
|
||||||
"narHash": "sha256-yf3iYLGbGVlIthlQIk5/4/EQDZNNEmuqKZkQssMljuw=",
|
"narHash": "sha256-mCxPABZ6jRjUQx3bPP4vjA68ETbPLNz9V2pk9tO7pRQ=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "71caefce12ba78d84fe618cf61644dce01cf3a96",
|
"rev": "8cd5ce828d5d1d16feff37340171a98fc3bf6526",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"ref": "nixos-25.11",
|
"ref": "nixos-25.05",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs-darwin": {
|
"nixpkgs-darwin": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1766129819,
|
"lastModified": 1757590060,
|
||||||
"narHash": "sha256-crNRwvsbH2XSV8IwBjX6Tm+uWmYwhYyRuNVJ9/ZwlmA=",
|
"narHash": "sha256-EWwwdKLMZALkgHFyKW7rmyhxECO74+N+ZO5xTDnY/5c=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "eedcb27bf99430e51f83d896cd1149b828290d20",
|
"rev": "0ef228213045d2cdb5a169a95d63ded38670b293",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
|
"ref": "nixpkgs-25.05-darwin",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "eedcb27bf99430e51f83d896cd1149b828290d20",
|
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs-unstable": {
|
"nixpkgs-unstable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772771118,
|
"lastModified": 1757034884,
|
||||||
"narHash": "sha256-xWzaTvmmACR/SRWtABgI/Z97lcqwJAeoSd5QW1KdK1s=",
|
"narHash": "sha256-PgLSZDBEWUHpfTRfFyklmiiLBE1i1aGCtz4eRA3POao=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "e38213b91d3786389a446dfce4ff5a8aaf6012f2",
|
"rev": "ca77296380960cd497a765102eeb1356eb80fed0",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -166,11 +184,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1773029295,
|
"lastModified": 1757647720,
|
||||||
"narHash": "sha256-xmHhVHbaA5hR3dCEoGwqAgL6HTTJ0KEMRUTLdJuVtGM=",
|
"narHash": "sha256-qf/utP3d1qBDl5R4yWUCt7E7CHTkw2NY8BEsS7lJ0dc=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "NUR",
|
"repo": "NUR",
|
||||||
"rev": "bf45b24de2134f1488f7a6c135f4b0420ccec6fe",
|
"rev": "ef767aa25f9f917fe25d3848051f0e54ae42349f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -189,11 +207,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772361940,
|
"lastModified": 1756632588,
|
||||||
"narHash": "sha256-B1Cz+ydL1iaOnGlwOFld/C8lBECPtzhiy/pP93/CuyY=",
|
"narHash": "sha256-ydam6eggXf3ZwRutyCABwSbMAlX+5lW6w1SVZQ+kfSo=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "plasma-manager",
|
"repo": "plasma-manager",
|
||||||
"rev": "a4b33606111c9c5dcd10009042bb710307174f51",
|
"rev": "d47428e5390d6a5a8f764808a4db15929347cd77",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -204,11 +222,11 @@
|
||||||
},
|
},
|
||||||
"quadlet-nix": {
|
"quadlet-nix": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1770606362,
|
"lastModified": 1754008153,
|
||||||
"narHash": "sha256-6pOOPOQr4rtgShBtkLkSDTql5rRqcUgTRz8O+axK2eM=",
|
"narHash": "sha256-MYT1mDtSkiVg343agxgBFsnuNU3xS8vRy399JXX1Vw0=",
|
||||||
"owner": "SEIAROTg",
|
"owner": "SEIAROTg",
|
||||||
"repo": "quadlet-nix",
|
"repo": "quadlet-nix",
|
||||||
"rev": "f4ae60350ea6015b6560cbd0e1f11f7e195c993d",
|
"rev": "1b2d27d460d8c7e4da5ba44ede463b427160b5c4",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -220,9 +238,9 @@
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"agenix": "agenix",
|
"agenix": "agenix",
|
||||||
|
"crowdsec": "crowdsec",
|
||||||
"home-manager": "home-manager",
|
"home-manager": "home-manager",
|
||||||
"nix-darwin": "nix-darwin",
|
"nix-darwin": "nix-darwin",
|
||||||
"nix-rosetta-builder": "nix-rosetta-builder",
|
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
"nixpkgs-darwin": "nixpkgs-darwin",
|
"nixpkgs-darwin": "nixpkgs-darwin",
|
||||||
"nixpkgs-unstable": "nixpkgs-unstable",
|
"nixpkgs-unstable": "nixpkgs-unstable",
|
||||||
|
|
@ -240,11 +258,11 @@
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"dir": "pkgs/firefox-addons",
|
"dir": "pkgs/firefox-addons",
|
||||||
"lastModified": 1773028978,
|
"lastModified": 1757591399,
|
||||||
"narHash": "sha256-4BjOTYhHP8ljHShQyZ1gUIdwgSLjvaGN2ueKfqp6CQk=",
|
"narHash": "sha256-OlvNzfsqDok0y5PDY+2dK5T53GsxAdm1YGdYHjxAiHM=",
|
||||||
"owner": "rycee",
|
"owner": "rycee",
|
||||||
"repo": "nur-expressions",
|
"repo": "nur-expressions",
|
||||||
"rev": "a6ed037ffc0b50a9bd0c92e20e31f270a03ca1e3",
|
"rev": "b7d4f61ce9db44ba82859e15f6e1c175959948e3",
|
||||||
"type": "gitlab"
|
"type": "gitlab"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -268,6 +286,21 @@
|
||||||
"repo": "default",
|
"repo": "default",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"systems_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": "root",
|
"root": "root",
|
||||||
|
|
|
||||||
53
flake.nix
53
flake.nix
|
|
@ -3,10 +3,8 @@
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
# Specify the source of Home Manager and Nixpkgs.
|
# Specify the source of Home Manager and Nixpkgs.
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11";
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05";
|
||||||
# Revert to a cached version of Julia for aarch64-darwin
|
nixpkgs-darwin.url = "github:nixos/nixpkgs/nixpkgs-25.05-darwin";
|
||||||
nixpkgs-darwin.url =
|
|
||||||
"github:nixos/nixpkgs/eedcb27bf99430e51f83d896cd1149b828290d20";
|
|
||||||
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
||||||
|
|
||||||
# Inputs for both darwin and linux systems
|
# Inputs for both darwin and linux systems
|
||||||
|
|
@ -19,7 +17,7 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
home-manager = {
|
home-manager = {
|
||||||
url = "github:nix-community/home-manager/release-25.11";
|
url = "github:nix-community/home-manager/release-25.05";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
nur = {
|
nur = {
|
||||||
|
|
@ -32,6 +30,10 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
# Linux-specific inputs
|
# Linux-specific inputs
|
||||||
|
crowdsec = {
|
||||||
|
url = "git+https://codeberg.org/kampka/nix-flake-crowdsec.git";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
plasma-manager = {
|
plasma-manager = {
|
||||||
url = "github:nix-community/plasma-manager";
|
url = "github:nix-community/plasma-manager";
|
||||||
inputs = {
|
inputs = {
|
||||||
|
|
@ -43,28 +45,23 @@
|
||||||
|
|
||||||
# Darwin-specific inputs
|
# Darwin-specific inputs
|
||||||
nix-darwin = {
|
nix-darwin = {
|
||||||
url = "github:LnL7/nix-darwin/nix-darwin-25.11";
|
url = "github:LnL7/nix-darwin/nix-darwin-25.05";
|
||||||
inputs.nixpkgs.follows = "nixpkgs-darwin";
|
|
||||||
};
|
|
||||||
nix-rosetta-builder = {
|
|
||||||
url = "github:cpick/nix-rosetta-builder";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs-darwin";
|
inputs.nixpkgs.follows = "nixpkgs-darwin";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nix-darwin, nixpkgs, nixpkgs-darwin, nixpkgs-unstable
|
outputs = { self, nix-darwin, nixpkgs, nixpkgs-darwin, nixpkgs-unstable
|
||||||
, home-manager, agenix, rycee-nurpkgs, nur, plasma-manager, quadlet-nix
|
, home-manager, agenix, rycee-nurpkgs, nur, crowdsec, plasma-manager
|
||||||
, nix-rosetta-builder, ... }:
|
, quadlet-nix, ... }:
|
||||||
let
|
let
|
||||||
mkHomeConfiguration = { hostname, arch ? "x86_64", os ? "linux"
|
mkHomeConfiguration = { hostname, arch ? "x86_64", os ? "linux"
|
||||||
, desktop ? false, extraModules ? [ ] }:
|
, desktop ? false, extraModules ? [ ] }:
|
||||||
let
|
let
|
||||||
system = "${arch}-${os}";
|
system = "${arch}-${os}";
|
||||||
syspkg = if os == "darwin" then nixpkgs-darwin else nixpkgs;
|
pkgs = import nixpkgs {
|
||||||
pkgs = import syspkg {
|
|
||||||
inherit system;
|
inherit system;
|
||||||
config.allowUnfree = true;
|
config.allowUnfree = true;
|
||||||
overlays = [ nur.overlays.default agenix.overlays.default ];
|
overlays = [ nur.overlays.default ];
|
||||||
};
|
};
|
||||||
pkgs-unstable = import nixpkgs-unstable {
|
pkgs-unstable = import nixpkgs-unstable {
|
||||||
inherit system;
|
inherit system;
|
||||||
|
|
@ -83,8 +80,7 @@
|
||||||
] ++ (if desktop then [ ./homes/desktop.nix ] else [ ])
|
] ++ (if desktop then [ ./homes/desktop.nix ] else [ ])
|
||||||
++ (if (desktop && os == "linux") then [
|
++ (if (desktop && os == "linux") then [
|
||||||
./homes/linux-desktop.nix
|
./homes/linux-desktop.nix
|
||||||
plasma-manager.homeModules.plasma-manager
|
plasma-manager.homeManagerModules.plasma-manager
|
||||||
quadlet-nix.homeManagerModules.quadlet
|
|
||||||
] else
|
] else
|
||||||
[ ]) ++ extraModules;
|
[ ]) ++ extraModules;
|
||||||
extraSpecialArgs = {
|
extraSpecialArgs = {
|
||||||
|
|
@ -92,7 +88,6 @@
|
||||||
inherit firefox-addons;
|
inherit firefox-addons;
|
||||||
inherit buildFirefoxXpiAddon;
|
inherit buildFirefoxXpiAddon;
|
||||||
inherit custom-pkgs;
|
inherit custom-pkgs;
|
||||||
inherit hostname;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
|
|
@ -106,12 +101,16 @@
|
||||||
|
|
||||||
"millironx@anderson" = mkHomeConfiguration { hostname = "anderson"; };
|
"millironx@anderson" = mkHomeConfiguration { hostname = "anderson"; };
|
||||||
|
|
||||||
"millironx@mcentire" = mkHomeConfiguration { hostname = "mcentire"; };
|
|
||||||
|
|
||||||
"millironx@bosephus" = mkHomeConfiguration { hostname = "bosephus"; };
|
"millironx@bosephus" = mkHomeConfiguration { hostname = "bosephus"; };
|
||||||
|
|
||||||
"tchristensen@beocat" = mkHomeConfiguration { hostname = "beocat"; };
|
"tchristensen@beocat" = mkHomeConfiguration { hostname = "beocat"; };
|
||||||
|
|
||||||
|
"millironx@harmony" = mkHomeConfiguration {
|
||||||
|
hostname = "harmony";
|
||||||
|
arch = "aarch64";
|
||||||
|
desktop = true;
|
||||||
|
};
|
||||||
|
|
||||||
"millironx@odyssey" = mkHomeConfiguration {
|
"millironx@odyssey" = mkHomeConfiguration {
|
||||||
hostname = "odyssey";
|
hostname = "odyssey";
|
||||||
desktop = true;
|
desktop = true;
|
||||||
|
|
@ -127,11 +126,8 @@
|
||||||
};
|
};
|
||||||
agenix = agenix;
|
agenix = agenix;
|
||||||
};
|
};
|
||||||
modules = [
|
modules =
|
||||||
./systems/darwin/corianne.nix
|
[ ./systems/darwin/corianne.nix agenix.darwinModules.default ];
|
||||||
agenix.darwinModules.default
|
|
||||||
nix-rosetta-builder.darwinModules.default
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
nixosConfigurations = {
|
nixosConfigurations = {
|
||||||
|
|
@ -146,14 +142,13 @@
|
||||||
|
|
||||||
"mcentire" = nixpkgs.lib.nixosSystem {
|
"mcentire" = nixpkgs.lib.nixosSystem {
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
specialArgs = {
|
|
||||||
home-manager-quadlet-nix = quadlet-nix.homeManagerModules.quadlet;
|
|
||||||
};
|
|
||||||
modules = [
|
modules = [
|
||||||
./systems/linux/mcentire.nix
|
./systems/linux/mcentire.nix
|
||||||
agenix.nixosModules.default
|
agenix.nixosModules.default
|
||||||
home-manager.nixosModules.home-manager
|
|
||||||
quadlet-nix.nixosModules.quadlet
|
quadlet-nix.nixosModules.quadlet
|
||||||
|
crowdsec.nixosModules.crowdsec
|
||||||
|
crowdsec.nixosModules.crowdsec-firewall-bouncer
|
||||||
|
{ nixpkgs.overlays = [ crowdsec.overlays.default ]; }
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,13 @@
|
||||||
{ config, pkgs, ... }: {
|
{ config, lib, pkgs, pkgs-unstable, ... }:
|
||||||
|
let
|
||||||
|
runic_version = "1.5.0";
|
||||||
|
runic = pkgs.fetchFromGitHub {
|
||||||
|
owner = "fredrikekre";
|
||||||
|
repo = "Runic.jl";
|
||||||
|
rev = "v${runic_version}";
|
||||||
|
hash = "sha256-y+kiBA94vUMHH0fEEBg7+c9PEgzjGqh6nCuSRnawhQI=";
|
||||||
|
};
|
||||||
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
./../programs/shells.nix
|
./../programs/shells.nix
|
||||||
./../programs/bat.nix
|
./../programs/bat.nix
|
||||||
|
|
@ -6,15 +15,22 @@
|
||||||
./../programs/git.nix
|
./../programs/git.nix
|
||||||
./../programs/lsd.nix
|
./../programs/lsd.nix
|
||||||
./../programs/neovim.nix
|
./../programs/neovim.nix
|
||||||
./../programs/ssh.nix
|
|
||||||
./../programs/starship.nix
|
./../programs/starship.nix
|
||||||
./../programs/tmux.nix
|
|
||||||
./../programs/yt-dlp.nix
|
./../programs/yt-dlp.nix
|
||||||
];
|
];
|
||||||
home = {
|
home = {
|
||||||
stateVersion = "23.11";
|
stateVersion = "23.11";
|
||||||
|
file = {
|
||||||
|
".local/bin/runic" = {
|
||||||
|
source = runic + "/bin/runic";
|
||||||
|
executable = true;
|
||||||
|
};
|
||||||
|
".local/bin/git-runic" = {
|
||||||
|
source = runic + "/bin/git-runic";
|
||||||
|
executable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
packages = with pkgs; [
|
packages = with pkgs; [
|
||||||
agenix
|
|
||||||
btop
|
btop
|
||||||
cowsay
|
cowsay
|
||||||
figlet
|
figlet
|
||||||
|
|
@ -28,12 +44,14 @@
|
||||||
jq
|
jq
|
||||||
julia-bin
|
julia-bin
|
||||||
lynx
|
lynx
|
||||||
mamba-cpp
|
micromamba
|
||||||
most
|
most
|
||||||
|
nextflow
|
||||||
p7zip
|
p7zip
|
||||||
pdfgrep
|
pdfgrep
|
||||||
pipx
|
pipx
|
||||||
python3
|
python3
|
||||||
|
zulu17
|
||||||
];
|
];
|
||||||
sessionVariables = {
|
sessionVariables = {
|
||||||
PAGER = "most";
|
PAGER = "most";
|
||||||
|
|
@ -65,10 +83,24 @@
|
||||||
"tailscale set --exit-node=$(tailscale exit-node suggest | awk '{print $4}' | head -n1)";
|
"tailscale set --exit-node=$(tailscale exit-node suggest | awk '{print $4}' | head -n1)";
|
||||||
# tsed - TailScale Exit node Disconnect
|
# tsed - TailScale Exit node Disconnect
|
||||||
tsed = "tailscale set --exit-node=";
|
tsed = "tailscale set --exit-node=";
|
||||||
micromamba = "mamba";
|
|
||||||
conda = "mamba";
|
|
||||||
};
|
};
|
||||||
sessionPath = [ "$HOME/.local/bin" ];
|
sessionPath = [ "$HOME/.local/bin" ];
|
||||||
|
activation = {
|
||||||
|
recordHmGitHash = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||||
|
cd "$HOME/.config/home-manager" || exit 1
|
||||||
|
if [ -z "$(${pkgs.git}/bin/git status --porcelain --untracked-files=no)" ]; then
|
||||||
|
run echo "$(${pkgs.git}/bin/git rev-parse HEAD)" | tee $HOME/.cache/hm-git-hash
|
||||||
|
else
|
||||||
|
run echo '*' | tee $HOME/.cache/hm-git-hash
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
installRunic = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||||
|
run ${pkgs.julia-bin}/bin/julia --project=@runic --startup-file=no -e 'using Pkg; Pkg.add(name="Runic", version="${runic_version}")'
|
||||||
|
'';
|
||||||
|
installJuliaFormatter = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||||
|
run ${pkgs.julia-bin}/bin/julia --project=@JuliaFormatter --startup-file=no -e 'using Pkg; Pkg.add(name="JuliaFormatter", version="2.1.6")'
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
programs = {
|
programs = {
|
||||||
home-manager.enable = true;
|
home-manager.enable = true;
|
||||||
|
|
|
||||||
110
homes/darwin.nix
110
homes/darwin.nix
|
|
@ -7,7 +7,7 @@
|
||||||
];
|
];
|
||||||
home = {
|
home = {
|
||||||
packages = with pkgs; [
|
packages = with pkgs; [
|
||||||
macpm
|
asitop
|
||||||
pinentry_mac
|
pinentry_mac
|
||||||
(pkgs.writeShellScriptBin "uq" ''
|
(pkgs.writeShellScriptBin "uq" ''
|
||||||
xattr -rdv com.apple.quarantine "/Applications/$1.app"
|
xattr -rdv com.apple.quarantine "/Applications/$1.app"
|
||||||
|
|
@ -31,6 +31,114 @@
|
||||||
tailscale = "/Applications/Tailscale.app/Contents/MacOS/Tailscale";
|
tailscale = "/Applications/Tailscale.app/Contents/MacOS/Tailscale";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
launchd = {
|
||||||
|
enable = true;
|
||||||
|
agents = {
|
||||||
|
ollama = {
|
||||||
|
enable = true;
|
||||||
|
config = {
|
||||||
|
Label = "local.home-manager.ollama";
|
||||||
|
ProgramArguments = [ "${pkgs.ollama}/bin/ollama" "serve" ];
|
||||||
|
RunAtLoad = true;
|
||||||
|
KeepAlive = true;
|
||||||
|
StandardOutPath =
|
||||||
|
"${config.home.homeDirectory}/Library/Logs/ollama.log";
|
||||||
|
StandardErrorPath =
|
||||||
|
"${config.home.homeDirectory}/Library/Logs/ollama-error.log";
|
||||||
|
EnvironmentVariables = {
|
||||||
|
PATH = "${lib.makeBinPath [ pkgs.ollama ]}:$PATH";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
freetube-sync = {
|
||||||
|
enable = true;
|
||||||
|
config = {
|
||||||
|
Label = "local.home-manager.freetube-sync";
|
||||||
|
ProgramArguments = [
|
||||||
|
"/bin/sh"
|
||||||
|
"-c"
|
||||||
|
''
|
||||||
|
FREETUBE_CONFIG_DIR="$HOME/Library/Application Support/FreeTube"
|
||||||
|
NEXTCLOUD_DIR="$HOME/Nextcloud/Settings/FreeTube"
|
||||||
|
|
||||||
|
# Create directories if they don't exist
|
||||||
|
mkdir -p "$FREETUBE_CONFIG_DIR"
|
||||||
|
mkdir -p "$NEXTCLOUD_DIR"
|
||||||
|
|
||||||
|
# List of database files to sync
|
||||||
|
DB_FILES=("settings.db" "history.db" "playlists.db" "subscriptions.db" "profiles.db")
|
||||||
|
|
||||||
|
# Initial sync if Nextcloud has db files but FreeTube doesn't
|
||||||
|
if [ -n "$(ls $NEXTCLOUD_DIR/*.db 2>/dev/null)" ] && [ ! -n "$(ls $FREETUBE_CONFIG_DIR/*.db 2>/dev/null)" ]; then
|
||||||
|
echo "Performing initial sync from Nextcloud to FreeTube"
|
||||||
|
for DB_FILE in "''${DB_FILES[@]}"; do
|
||||||
|
if [ -f "$NEXTCLOUD_DIR/$DB_FILE" ]; then
|
||||||
|
rsync -av --checksum "$NEXTCLOUD_DIR/$DB_FILE" "$FREETUBE_CONFIG_DIR/$DB_FILE"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
# If Nextcloud is empty but FreeTube has db files, copy to Nextcloud
|
||||||
|
elif [ ! -n "$(ls $NEXTCLOUD_DIR/*.db 2>/dev/null)" ] && [ -n "$(ls $FREETUBE_CONFIG_DIR/*.db 2>/dev/null)" ]; then
|
||||||
|
echo "Performing initial sync from FreeTube to Nextcloud"
|
||||||
|
for DB_FILE in "''${DB_FILES[@]}"; do
|
||||||
|
if [ -f "$FREETUBE_CONFIG_DIR/$DB_FILE" ]; then
|
||||||
|
rsync -av --checksum "$FREETUBE_CONFIG_DIR/$DB_FILE" "$NEXTCLOUD_DIR/$DB_FILE"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
# Process each database file individually
|
||||||
|
for DB_FILE in "''${DB_FILES[@]}"; do
|
||||||
|
FT_PATH="$FREETUBE_CONFIG_DIR/$DB_FILE"
|
||||||
|
NC_PATH="$NEXTCLOUD_DIR/$DB_FILE"
|
||||||
|
|
||||||
|
# Skip if neither file exists
|
||||||
|
if [ ! -f "$FT_PATH" ] && [ ! -f "$NC_PATH" ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If only one exists, copy it
|
||||||
|
if [ -f "$FT_PATH" ] && [ ! -f "$NC_PATH" ]; then
|
||||||
|
echo "Copying $DB_FILE from FreeTube to Nextcloud"
|
||||||
|
rsync -av "$FT_PATH" "$NC_PATH"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$FT_PATH" ] && [ -f "$NC_PATH" ]; then
|
||||||
|
echo "Copying $DB_FILE from Nextcloud to FreeTube"
|
||||||
|
rsync -av "$NC_PATH" "$FT_PATH"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Both files exist, check which is newer
|
||||||
|
if [ "$FT_PATH" -nt "$NC_PATH" ]; then
|
||||||
|
echo "Syncing newer $DB_FILE from FreeTube to Nextcloud"
|
||||||
|
rsync -av --update "$FT_PATH" "$NC_PATH"
|
||||||
|
elif [ "$NC_PATH" -nt "$FT_PATH" ]; then
|
||||||
|
echo "Syncing newer $DB_FILE from Nextcloud to FreeTube"
|
||||||
|
rsync -av --update "$NC_PATH" "$FT_PATH"
|
||||||
|
else
|
||||||
|
# Same modification time, compare checksums
|
||||||
|
echo "Verifying $DB_FILE with checksum comparison"
|
||||||
|
rsync -av --checksum "$NC_PATH" "$FT_PATH"
|
||||||
|
rsync -av --checksum "$FT_PATH" "$NC_PATH"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
''
|
||||||
|
];
|
||||||
|
RunAtLoad = true;
|
||||||
|
StartInterval = 300; # Run every 5 minutes (300 seconds)
|
||||||
|
StandardOutPath =
|
||||||
|
"${config.home.homeDirectory}/Library/Logs/freetube-sync.log";
|
||||||
|
StandardErrorPath =
|
||||||
|
"${config.home.homeDirectory}/Library/Logs/freetube-sync-error.log";
|
||||||
|
EnvironmentVariables = {
|
||||||
|
PATH = "${lib.makeBinPath [ pkgs.rsync pkgs.findutils ]}:$PATH";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
programs = {
|
programs = {
|
||||||
bash = {
|
bash = {
|
||||||
profileExtra = ''
|
profileExtra = ''
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
./../programs/firefox.nix
|
./../programs/firefox.nix
|
||||||
|
./../programs/ghostty.nix
|
||||||
./../programs/zed.nix
|
./../programs/zed.nix
|
||||||
./../services/gpg-agent.nix
|
./../services/gpg-agent.nix
|
||||||
./../services/syncthing.nix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
home = {
|
home = {
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
nil
|
nil
|
||||||
nixd
|
nixd
|
||||||
nixfmt-classic
|
nixfmt-classic
|
||||||
nixos-rebuild
|
ollama
|
||||||
quarto
|
quarto
|
||||||
roboto-slab
|
roboto-slab
|
||||||
shellcheck
|
shellcheck
|
||||||
|
|
@ -31,8 +31,6 @@
|
||||||
woodpecker-cli
|
woodpecker-cli
|
||||||
(texlive.combine { inherit (texlive) scheme-basic latex-bin latexmk; })
|
(texlive.combine { inherit (texlive) scheme-basic latex-bin latexmk; })
|
||||||
custom-pkgs.ark
|
custom-pkgs.ark
|
||||||
custom-pkgs.jlfmt
|
|
||||||
custom-pkgs.runic
|
|
||||||
];
|
];
|
||||||
shellAliases = {
|
shellAliases = {
|
||||||
code = "codium";
|
code = "codium";
|
||||||
|
|
|
||||||
95
homes/harmony.nix
Normal file
95
homes/harmony.nix
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
{ config, lib, pkgs, pkgs-unstable, ... }: {
|
||||||
|
# harmony is an Asahi Fedora box
|
||||||
|
# I don't use NixOS, so there are some programs that don't interact well with
|
||||||
|
# the base system (or won't even install) when installed from Nix.
|
||||||
|
# There is no uniform way to trigger dnf package installs from Nix, so I'm
|
||||||
|
# just going to list my packages here. I hope to create a custom script that
|
||||||
|
# mimics the ideas of a Brewfile someday
|
||||||
|
# TODO: Create a Brewfile equivalent for dnf
|
||||||
|
|
||||||
|
# dnf repos:
|
||||||
|
# https://github.com/terrapkg/packages?tab=readme-ov-file
|
||||||
|
# https://pkgs.tailscale.com/stable/fedora/tailscale.repo
|
||||||
|
# https://packagecloud.io/filips/FirefoxPWA
|
||||||
|
|
||||||
|
# copr repos:
|
||||||
|
# iucar/rstudio
|
||||||
|
|
||||||
|
# dnf packages:
|
||||||
|
# apptainer
|
||||||
|
# chromium
|
||||||
|
# firefoxpwa - The nix version installs an "immutable" runtime, which simply launches extra browser windows on non-NixOS
|
||||||
|
# inkscape
|
||||||
|
# kate
|
||||||
|
# kdiff3
|
||||||
|
# krita
|
||||||
|
# lutris
|
||||||
|
# musescore
|
||||||
|
# nextcloud-client
|
||||||
|
# nextcloud-client-dolphin
|
||||||
|
# obs-studio
|
||||||
|
# podman-compose
|
||||||
|
# podman-docker
|
||||||
|
# qownnotes
|
||||||
|
# qt
|
||||||
|
# rssguard
|
||||||
|
# rstudio-desktop
|
||||||
|
# steam
|
||||||
|
# supertuxkart
|
||||||
|
# tailscale
|
||||||
|
# thunderbird
|
||||||
|
# vlc
|
||||||
|
# vorta - The vorta package is aarch64 compatible, but you cannot see any icons, and it cannot access local ssh keys, so we have to use the dnf package instead
|
||||||
|
# yakuake
|
||||||
|
# zed
|
||||||
|
# zsh
|
||||||
|
# R
|
||||||
|
# https://downloads.sourceforge.net/project/mscorefonts2/rpms/msttcore-fonts-installer-2.6-1.noarch.rpm
|
||||||
|
home = {
|
||||||
|
username = "millironx";
|
||||||
|
homeDirectory = "/home/millironx";
|
||||||
|
# Signal desktop is not available in any other package repository for aarch64 linux
|
||||||
|
# Similarly, Bitwarden is non-functional in all other forms using a 16k page size
|
||||||
|
packages = with pkgs; [
|
||||||
|
trayscale
|
||||||
|
veracrypt
|
||||||
|
pkgs-unstable.signal-desktop
|
||||||
|
pkgs.bitwarden-desktop
|
||||||
|
];
|
||||||
|
};
|
||||||
|
programs = {
|
||||||
|
git = {
|
||||||
|
signing = {
|
||||||
|
key = "0x37A3041D1C8C4524!";
|
||||||
|
signByDefault = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
services = {
|
||||||
|
gpg-agent = { sshKeys = [ "207D13371E19752A67AA2686C16354D9963821DB" ]; };
|
||||||
|
};
|
||||||
|
xdg = {
|
||||||
|
configFile = {
|
||||||
|
"nextflow.config".text = ''
|
||||||
|
params {
|
||||||
|
config_profile_description = 'harmony Asahi Linux local profile'
|
||||||
|
config_profile_contact = 'Thomas A. Christensen II <25492070+MillironX@users.noreply.github.com>'
|
||||||
|
config_profile_url = null
|
||||||
|
|
||||||
|
max_memory = 12.GB
|
||||||
|
max_cpus = 12
|
||||||
|
max_time = 7.d
|
||||||
|
}
|
||||||
|
|
||||||
|
apptainer {
|
||||||
|
enabled = true
|
||||||
|
autoMounts = true
|
||||||
|
}
|
||||||
|
|
||||||
|
process {
|
||||||
|
executor = 'local'
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -18,16 +18,115 @@ in {
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
systemd.user = {
|
||||||
|
services = {
|
||||||
|
freetube-sync = {
|
||||||
|
Unit = {
|
||||||
|
Description = "Sync FreeTube settings with Nextcloud";
|
||||||
|
After = [ "network.target" ];
|
||||||
|
};
|
||||||
|
Service = {
|
||||||
|
Type = "oneshot";
|
||||||
|
ExecStart = "${pkgs.writeShellScript "freetube-sync.sh" ''
|
||||||
|
FREETUBE_CONFIG_DIR="$HOME/.var/app/io.freetubeapp.FreeTube/config/FreeTube"
|
||||||
|
NEXTCLOUD_DIR="$HOME/Nextcloud/Settings/FreeTube"
|
||||||
|
|
||||||
|
# Create directories if they don't exist
|
||||||
|
mkdir -p "$FREETUBE_CONFIG_DIR"
|
||||||
|
mkdir -p "$NEXTCLOUD_DIR"
|
||||||
|
|
||||||
|
# List of database files to sync
|
||||||
|
DB_FILES=("settings.db" "history.db" "playlists.db" "subscriptions.db" "profiles.db")
|
||||||
|
|
||||||
|
# Initial sync if Nextcloud has db files but FreeTube doesn't
|
||||||
|
if [ -n "$(ls -A $NEXTCLOUD_DIR/*.db 2>/dev/null)" ] && [ ! -n "$(ls -A $FREETUBE_CONFIG_DIR/*.db 2>/dev/null)" ]; then
|
||||||
|
echo "Performing initial sync from Nextcloud to FreeTube"
|
||||||
|
for DB_FILE in "''${DB_FILES[@]}"; do
|
||||||
|
if [ -f "$NEXTCLOUD_DIR/$DB_FILE" ]; then
|
||||||
|
rsync -av --checksum "$NEXTCLOUD_DIR/$DB_FILE" "$FREETUBE_CONFIG_DIR/$DB_FILE"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
# If Nextcloud is empty but FreeTube has db files, copy to Nextcloud
|
||||||
|
elif [ ! -n "$(ls -A $NEXTCLOUD_DIR/*.db 2>/dev/null)" ] && [ -n "$(ls -A $FREETUBE_CONFIG_DIR/*.db 2>/dev/null)" ]; then
|
||||||
|
echo "Performing initial sync from FreeTube to Nextcloud"
|
||||||
|
for DB_FILE in "''${DB_FILES[@]}"; do
|
||||||
|
if [ -f "$FREETUBE_CONFIG_DIR/$DB_FILE" ]; then
|
||||||
|
rsync -av --checksum "$FREETUBE_CONFIG_DIR/$DB_FILE" "$NEXTCLOUD_DIR/$DB_FILE"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
# Process each database file individually
|
||||||
|
for DB_FILE in "''${DB_FILES[@]}"; do
|
||||||
|
FT_PATH="$FREETUBE_CONFIG_DIR/$DB_FILE"
|
||||||
|
NC_PATH="$NEXTCLOUD_DIR/$DB_FILE"
|
||||||
|
|
||||||
|
# Skip if neither file exists
|
||||||
|
if [ ! -f "$FT_PATH" ] && [ ! -f "$NC_PATH" ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If only one exists, copy it
|
||||||
|
if [ -f "$FT_PATH" ] && [ ! -f "$NC_PATH" ]; then
|
||||||
|
echo "Copying $DB_FILE from FreeTube to Nextcloud"
|
||||||
|
rsync -av "$FT_PATH" "$NC_PATH"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$FT_PATH" ] && [ -f "$NC_PATH" ]; then
|
||||||
|
echo "Copying $DB_FILE from Nextcloud to FreeTube"
|
||||||
|
rsync -av "$NC_PATH" "$FT_PATH"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Both files exist, check which is newer
|
||||||
|
if [ "$FT_PATH" -nt "$NC_PATH" ]; then
|
||||||
|
echo "Syncing newer $DB_FILE from FreeTube to Nextcloud"
|
||||||
|
rsync -av --update "$FT_PATH" "$NC_PATH"
|
||||||
|
elif [ "$NC_PATH" -nt "$FT_PATH" ]; then
|
||||||
|
echo "Syncing newer $DB_FILE from Nextcloud to FreeTube"
|
||||||
|
rsync -av --update "$NC_PATH" "$FT_PATH"
|
||||||
|
else
|
||||||
|
# Same modification time, compare checksums
|
||||||
|
echo "Verifying $DB_FILE with checksum comparison"
|
||||||
|
rsync -av --checksum "$NC_PATH" "$FT_PATH"
|
||||||
|
rsync -av --checksum "$FT_PATH" "$NC_PATH"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
''}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
timers = {
|
||||||
|
freetube-sync = {
|
||||||
|
Unit = { Description = "Timer for FreeTube settings sync"; };
|
||||||
|
Timer = {
|
||||||
|
OnBootSec = "1m";
|
||||||
|
OnUnitActiveSec = "5m";
|
||||||
|
};
|
||||||
|
Install = { WantedBy = [ "timers.target" ]; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
xdg = {
|
xdg = {
|
||||||
configFile = {
|
configFile = {
|
||||||
"plasma-workspace/env/ZED_WINDOW_DECORATIONS.sh".text =
|
"plasma-workspace/env/ZED_WINDOW_DECORATIONS.sh".text =
|
||||||
"export ZED_WINDOW_DECORATIONS=server";
|
"export ZED_WINDOW_DECORATIONS=server";
|
||||||
|
"dolphinrc".source =
|
||||||
|
mkOutOfStoreSymlink "${home-manager-repo}/dotfiles/dolphinrc";
|
||||||
|
"konsolerc".source =
|
||||||
|
mkOutOfStoreSymlink "${home-manager-repo}/dotfiles/konsolerc";
|
||||||
"onedrive/config".text = ''
|
"onedrive/config".text = ''
|
||||||
force_session_upload = "true"
|
force_session_upload = "true"
|
||||||
delay_inotify_processing = "true"
|
delay_inotify_processing = "true"
|
||||||
'';
|
'';
|
||||||
|
"yakuakerc".source =
|
||||||
|
mkOutOfStoreSymlink "${home-manager-repo}/dotfiles/yakuakerc";
|
||||||
};
|
};
|
||||||
dataFile = {
|
dataFile = {
|
||||||
|
"konsole/My Default.profile".source =
|
||||||
|
mkOutOfStoreSymlink "${home-manager-repo}/dotfiles/MyDefault.profile";
|
||||||
"kio/servicemenus/kate.desktop".source = ./../dotfiles/kate.desktop;
|
"kio/servicemenus/kate.desktop".source = ./../dotfiles/kate.desktop;
|
||||||
"kio/servicemenus/vlc.desktop".source = ./../dotfiles/vlc.desktop;
|
"kio/servicemenus/vlc.desktop".source = ./../dotfiles/vlc.desktop;
|
||||||
"kio/servicemenus/word-to-pdf.desktop".source =
|
"kio/servicemenus/word-to-pdf.desktop".source =
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
{ ... }: {
|
|
||||||
home = {
|
|
||||||
username = "millironx";
|
|
||||||
homeDirectory = "/home/millironx";
|
|
||||||
};
|
|
||||||
programs = { };
|
|
||||||
services = { };
|
|
||||||
}
|
|
||||||
|
|
@ -14,23 +14,6 @@
|
||||||
services = {
|
services = {
|
||||||
gpg-agent = { sshKeys = [ "F72C07DBA3DC0903C3ABB55E8B460803FEC22640" ]; };
|
gpg-agent = { sshKeys = [ "F72C07DBA3DC0903C3ABB55E8B460803FEC22640" ]; };
|
||||||
};
|
};
|
||||||
virtualisation.quadlet = {
|
|
||||||
containers = {
|
|
||||||
anythingllm = {
|
|
||||||
autoStart = true;
|
|
||||||
containerConfig = {
|
|
||||||
image = "docker.io/mintplexlabs/anythingllm:latest";
|
|
||||||
addHosts = [ "ollama.millironx.local:host-gateway" ];
|
|
||||||
publishPorts = [ "3001:3001" ];
|
|
||||||
volumes =
|
|
||||||
[ "${config.xdg.dataHome}/anythingllm:/app/server/storage:Z" ];
|
|
||||||
environments = { STORAGE_DIR = "/app/server/storage"; };
|
|
||||||
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
autoUpdate.enable = true;
|
|
||||||
};
|
|
||||||
xdg = {
|
xdg = {
|
||||||
configFile = {
|
configFile = {
|
||||||
"nextflow.config".text = ''
|
"nextflow.config".text = ''
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,20 @@ ungrouped:
|
||||||
hosts:
|
hosts:
|
||||||
localhost:
|
localhost:
|
||||||
ansible_connection: local
|
ansible_connection: local
|
||||||
|
harmony:
|
||||||
|
ansible_connection: local
|
||||||
odyssey:
|
odyssey:
|
||||||
ansible_connection: local
|
ansible_connection: local
|
||||||
|
|
||||||
|
asahi:
|
||||||
|
hosts:
|
||||||
|
harmony:
|
||||||
|
|
||||||
amd64:
|
amd64:
|
||||||
hosts:
|
hosts:
|
||||||
odyssey:
|
odyssey:
|
||||||
|
|
||||||
fedora:
|
fedora:
|
||||||
hosts:
|
hosts:
|
||||||
|
harmony:
|
||||||
odyssey:
|
odyssey:
|
||||||
|
|
|
||||||
|
|
@ -1,167 +0,0 @@
|
||||||
# Warning to my future self: This module was "vibe coded" by Claude Sonnet 4.5.
|
|
||||||
# I originally had a hand-written module in here that did the secrets
|
|
||||||
# translation as the root user. I knew that I would want to support multiple
|
|
||||||
# secrets files and multiple users, and thought I should be able to create an
|
|
||||||
# arbitrary number of them, similar to how you can have an arbitrary number
|
|
||||||
# of `programs.firefox.profiles`. Unfortunately, even after looking at lots of
|
|
||||||
# example modules, I could not figure out the syntax (Nix has a serious lack
|
|
||||||
# of minimum working examples), so I broke down and asked Claude to rewrite it
|
|
||||||
# for me. Based on everything that I read, this seems to be exactly what I asked
|
|
||||||
# for.
|
|
||||||
#
|
|
||||||
# Here is the prompt I used to get here:
|
|
||||||
# [@Per service isolation on NixOS with Traefik](zed:///agent/thread/94cb8a22-ff0c-4772-a1a1-018b0107f334?name=Per+service+isolation+on+NixOS+with+Traefik)
|
|
||||||
#
|
|
||||||
# [@podman-secrets.nix](file:///home/millironx/.config/home-manager/modules/podman-secrets.nix)
|
|
||||||
#
|
|
||||||
# I originally wrote this module assuming that I would use Podman as root for
|
|
||||||
# all containers. I would like to fix the module to have as many secrets files
|
|
||||||
# processed as needed with services setup for each secret that is run as the
|
|
||||||
# appropriate user. Ideally, the syntax for working with secrets to be
|
|
||||||
# translated would be
|
|
||||||
#
|
|
||||||
# ```nix
|
|
||||||
# { config, ... }: {
|
|
||||||
# age.secrets = {
|
|
||||||
# "caddy.toml" = {
|
|
||||||
# file = ./../secrets/caddy.toml.age;
|
|
||||||
# owner = "caddy";
|
|
||||||
# group = "caddy";
|
|
||||||
# };
|
|
||||||
#
|
|
||||||
# "authentik.toml" = {
|
|
||||||
# file = ./../secrets/authentik.toml.age;
|
|
||||||
# owner = "authentik";
|
|
||||||
# group = "authentik";
|
|
||||||
# };
|
|
||||||
#
|
|
||||||
# "freshrss.toml" = {
|
|
||||||
# file = ./../secrets/freshrss.toml.age;
|
|
||||||
# owner = "freshrss";
|
|
||||||
# group = "freshrss";
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
#
|
|
||||||
# millironx.podman-secrets = with config; {
|
|
||||||
# caddy = {
|
|
||||||
# user = "caddy";
|
|
||||||
# secrets-files = [
|
|
||||||
# ./../not-really-secret.toml
|
|
||||||
# age.secrets."caddy.toml".path
|
|
||||||
# ];
|
|
||||||
# };
|
|
||||||
# authentik = {
|
|
||||||
# user = "authentik";
|
|
||||||
# secrets-files = [
|
|
||||||
# age.secrets."authentik.toml".path
|
|
||||||
# ];
|
|
||||||
# };
|
|
||||||
# freshrss = {
|
|
||||||
# user = "freshrss";
|
|
||||||
# secrets-files = [
|
|
||||||
# age.secrets."freshrss.toml".path
|
|
||||||
# ];
|
|
||||||
# };
|
|
||||||
# };
|
|
||||||
# }
|
|
||||||
# ```
|
|
||||||
#
|
|
||||||
# Can you help me rewrite the module to accomplish this?
|
|
||||||
#
|
|
||||||
{ config, lib, pkgs, ... }:
|
|
||||||
with lib;
|
|
||||||
let
|
|
||||||
cfg = config.millironx.podman-secrets;
|
|
||||||
|
|
||||||
secret-translator = pkgs.writeScriptBin "secret-translator"
|
|
||||||
(builtins.readFile ./../bin/secret-translator.jl);
|
|
||||||
|
|
||||||
# Submodule type for each service's secrets configuration
|
|
||||||
serviceSecretsType = types.submodule ({ config, name, ... }: {
|
|
||||||
options = {
|
|
||||||
user = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = "User account to run the secrets translation service as";
|
|
||||||
example = "caddy";
|
|
||||||
};
|
|
||||||
|
|
||||||
secrets-files = mkOption {
|
|
||||||
type = types.listOf (types.either types.path types.string);
|
|
||||||
description =
|
|
||||||
"List of TOML files containing secrets to translate to Podman secrets";
|
|
||||||
example = literalExpression ''
|
|
||||||
[
|
|
||||||
"/run/agenix/caddy.toml"
|
|
||||||
./../not-really-secret.toml
|
|
||||||
]
|
|
||||||
'';
|
|
||||||
default = [ ];
|
|
||||||
};
|
|
||||||
|
|
||||||
ref = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description =
|
|
||||||
"Reference to the systemd service name for declaring dependencies";
|
|
||||||
readOnly = true;
|
|
||||||
default = "podman-secrets-${name}.service";
|
|
||||||
example = "podman-secrets-caddy.service";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
# Generate a systemd user service for each configured service
|
|
||||||
mkSecretsService = name: serviceCfg:
|
|
||||||
nameValuePair "podman-secrets-${name}" {
|
|
||||||
description = "Podman secrets converter service for ${name}";
|
|
||||||
wantedBy = [ "default.target" ];
|
|
||||||
|
|
||||||
unitConfig.ConditionUser = "${serviceCfg.user}";
|
|
||||||
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
ProtectProc = "invisible";
|
|
||||||
ExecStart = "${secret-translator}/bin/secret-translator ${
|
|
||||||
lib.concatStringsSep " " serviceCfg.secrets-files
|
|
||||||
}";
|
|
||||||
Environment = "PATH=/run/wrappers/bin:${
|
|
||||||
lib.makeBinPath (with pkgs; [ shadow podman julia-lts-bin ])
|
|
||||||
}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Filter out services with no secrets-files
|
|
||||||
enabledServices =
|
|
||||||
lib.filterAttrs (name: serviceCfg: serviceCfg.secrets-files != [ ]) cfg;
|
|
||||||
|
|
||||||
in {
|
|
||||||
options.millironx.podman-secrets = mkOption {
|
|
||||||
type = types.attrsOf serviceSecretsType;
|
|
||||||
description = ''
|
|
||||||
Per-service Podman secrets configuration.
|
|
||||||
Each attribute creates a separate systemd user service that translates TOML secrets
|
|
||||||
files into Podman secrets.
|
|
||||||
'';
|
|
||||||
example = literalExpression ''
|
|
||||||
{
|
|
||||||
caddy = {
|
|
||||||
user = "caddy";
|
|
||||||
secrets-files = [
|
|
||||||
./../not-really-secret.toml
|
|
||||||
config.age.secrets."caddy.toml".path
|
|
||||||
];
|
|
||||||
};
|
|
||||||
authentik = {
|
|
||||||
user = "authentik";
|
|
||||||
secrets-files = [
|
|
||||||
config.age.secrets."authentik.toml".path
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
default = { };
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf (enabledServices != { }) {
|
|
||||||
systemd.user.services = lib.mapAttrs' mkSecretsService enabledServices;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
with pkgs; {
|
|
||||||
ark = callPackage ./ark.nix { };
|
{
|
||||||
jlfmt = callPackage ./jlfmt.nix { };
|
ark = pkgs.callPackage ./ark.nix { };
|
||||||
runic = callPackage ./runic.nix { };
|
sc4pac = pkgs.callPackage ./sc4pac.nix { };
|
||||||
sc4pac = callPackage ./sc4pac.nix { };
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
{ pkgs, ... }:
|
|
||||||
with pkgs;
|
|
||||||
let
|
|
||||||
juliaWithPkgs = julia-bin.withPackages.override { setDefaultDepot = false; }
|
|
||||||
[ "JuliaFormatter" ];
|
|
||||||
depotWithPkgs = runCommand "getDepot" { } ''
|
|
||||||
${juliaWithPkgs}/bin/julia -e 'println(first(DEPOT_PATH))' | tee $out
|
|
||||||
'';
|
|
||||||
in writeShellScriptBin "jlfmt" ''
|
|
||||||
export JULIA_DEPOT_PATH=$(< ${depotWithPkgs})
|
|
||||||
exec ${juliaWithPkgs}/bin/julia --startup-file=no -e 'using JuliaFormatter; print(format_text(String(read(stdin))));' -- "$@"
|
|
||||||
''
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
{ pkgs, ... }:
|
|
||||||
with pkgs;
|
|
||||||
let
|
|
||||||
juliaWithRunic =
|
|
||||||
julia-bin.withPackages.override { setDefaultDepot = false; } [ "Runic" ];
|
|
||||||
depotWithRunic = runCommand "getRunicDepot" { } ''
|
|
||||||
${juliaWithRunic}/bin/julia -e 'println(first(DEPOT_PATH))' | tee $out
|
|
||||||
'';
|
|
||||||
in writeShellScriptBin "runic" ''
|
|
||||||
export JULIA_DEPOT_PATH=$(< ${depotWithRunic})
|
|
||||||
exec ${juliaWithRunic}/bin/julia --startup-file=no -e 'using Runic; exit(Runic.main(ARGS))' -- "$@"
|
|
||||||
''
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
mode: "755"
|
mode: "755"
|
||||||
- name: Create Firefox DNS policy
|
- name: Create Firefox DNS policy
|
||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
src: "policies.json"
|
src: "{{ playbook_dir }}/../templates/policies.json"
|
||||||
dest: /etc/firefox/policies/policies.json
|
dest: /etc/firefox/policies/policies.json
|
||||||
mode: "644"
|
mode: "644"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,7 @@
|
||||||
register: home_manager_exists
|
register: home_manager_exists
|
||||||
- name: Init home-manager
|
- name: Init home-manager
|
||||||
ansible.builtin.shell: |
|
ansible.builtin.shell: |
|
||||||
/nix/var/nix/profiles/default/bin/nix run home-manager -- switch \
|
/nix/var/nix/profiles/default/bin/nix run home-manager -- switch --flake git+https://code.millironx.com/millironx/nix-dotfiles#{{ ansible_user_id }}@{{ ansible_hostname }}
|
||||||
--flake git+https://code.millironx.com/millironx/nix-dotfiles#{{ ansible_user_id }}@{{ ansible_hostname }}
|
|
||||||
when: not home_manager_exists.stat.exists
|
when: not home_manager_exists.stat.exists
|
||||||
register: home_manager_init
|
register: home_manager_init
|
||||||
changed_when: home_manager_init.rc == 0
|
changed_when: home_manager_init.rc == 0
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,78 @@
|
||||||
---
|
---
|
||||||
- name: Configure dnf packages
|
# These are repos and packages that are useless or unavailable on Asahi Linux,
|
||||||
|
# or have completely separate install procedures.
|
||||||
|
- name: Configure amd64-specific dnf packages
|
||||||
|
hosts: amd64
|
||||||
|
become: true
|
||||||
|
tasks:
|
||||||
|
- name: Install x86-specific dnf packages
|
||||||
|
ansible.builtin.dnf:
|
||||||
|
name:
|
||||||
|
- libdvdcss
|
||||||
|
- mkvtoolnix
|
||||||
|
- mpv
|
||||||
|
- protontricks
|
||||||
|
- x264
|
||||||
|
- x264-libs
|
||||||
|
state: present
|
||||||
|
- name: Install VeraCrypt
|
||||||
|
ansible.builtin.dnf:
|
||||||
|
name: https://launchpad.net/veracrypt/trunk/1.26.20/+download/veracrypt-1.26.20-Fedora-40-x86_64.rpm
|
||||||
|
state: present
|
||||||
|
disable_gpg_check: true
|
||||||
|
|
||||||
|
- name: Configure amd64-specific Flatpaks
|
||||||
|
hosts: amd64
|
||||||
|
become: false
|
||||||
|
tasks:
|
||||||
|
- name: Install x86-specific Flatpaks
|
||||||
|
community.general.flatpak:
|
||||||
|
name:
|
||||||
|
- com.bitwarden.desktop
|
||||||
|
- com.slack.Slack
|
||||||
|
- dev.deedles.Trayscale
|
||||||
|
- org.signal.Signal
|
||||||
|
state: latest
|
||||||
|
method: user
|
||||||
|
remote: flathub
|
||||||
|
|
||||||
|
- name: Configure Asahi Linux-specific dnf packages
|
||||||
|
hosts: asahi
|
||||||
|
become: true
|
||||||
|
tasks:
|
||||||
|
- name: Install aarch64-specific dnf packages
|
||||||
|
ansible.builtin.dnf:
|
||||||
|
name:
|
||||||
|
- veracrypt
|
||||||
|
|
||||||
|
- name: Configure common (all arch) dnf packages
|
||||||
hosts: fedora
|
hosts: fedora
|
||||||
become: true
|
become: true
|
||||||
tasks:
|
tasks:
|
||||||
- name: Install dnf packages
|
- name: Install common (all arch) dnf packages
|
||||||
ansible.builtin.dnf:
|
ansible.builtin.dnf:
|
||||||
name:
|
name:
|
||||||
- chromium
|
- chromium
|
||||||
|
- firefoxpwa
|
||||||
- fontconfig-devel
|
- fontconfig-devel
|
||||||
- freetype-devel
|
- freetype-devel
|
||||||
- fribidi-devel
|
- fribidi-devel
|
||||||
|
- ghostty
|
||||||
- inkscape
|
- inkscape
|
||||||
- jq
|
- jq
|
||||||
- kate
|
- kate
|
||||||
- kdenlive
|
- kdenlive
|
||||||
- kdiff3
|
- kdiff3
|
||||||
- krita
|
- krita
|
||||||
- libdvdcss
|
|
||||||
- libjpeg-devel
|
- libjpeg-devel
|
||||||
- libpng-devel
|
- libpng-devel
|
||||||
- libtiff-devel
|
- libtiff-devel
|
||||||
- libwebp-devel
|
- libwebp-devel
|
||||||
- mkvtoolnix
|
- musescore
|
||||||
- mpv
|
|
||||||
- nextcloud-client
|
- nextcloud-client
|
||||||
- nextcloud-client-dolphin
|
- nextcloud-client-dolphin
|
||||||
- obs-studio
|
- obs-studio
|
||||||
- onedrive
|
- onedrive
|
||||||
- protontricks
|
|
||||||
- qownnotes
|
- qownnotes
|
||||||
- qt
|
- qt
|
||||||
- rssguard
|
- rssguard
|
||||||
|
|
@ -37,8 +82,6 @@
|
||||||
- thunderbird
|
- thunderbird
|
||||||
- vlc
|
- vlc
|
||||||
- vorta
|
- vorta
|
||||||
- x264
|
|
||||||
- x264-libs
|
|
||||||
- yakuake
|
- yakuake
|
||||||
- zed
|
- zed
|
||||||
- zsh
|
- zsh
|
||||||
|
|
@ -49,11 +92,6 @@
|
||||||
name: https://downloads.sourceforge.net/project/mscorefonts2/rpms/msttcore-fonts-installer-2.6-1.noarch.rpm
|
name: https://downloads.sourceforge.net/project/mscorefonts2/rpms/msttcore-fonts-installer-2.6-1.noarch.rpm
|
||||||
state: present
|
state: present
|
||||||
disable_gpg_check: true
|
disable_gpg_check: true
|
||||||
- name: Install VeraCrypt
|
|
||||||
ansible.builtin.dnf:
|
|
||||||
name: https://launchpad.net/veracrypt/trunk/1.26.20/+download/veracrypt-1.26.20-Fedora-40-x86_64.rpm
|
|
||||||
state: present
|
|
||||||
disable_gpg_check: true
|
|
||||||
- name: Install rig (R installation manager)
|
- name: Install rig (R installation manager)
|
||||||
ansible.builtin.dnf:
|
ansible.builtin.dnf:
|
||||||
name: https://github.com/r-lib/rig/releases/download/latest/r-rig-latest-1.{{ ansible_architecture }}.rpm
|
name: https://github.com/r-lib/rig/releases/download/latest/r-rig-latest-1.{{ ansible_architecture }}.rpm
|
||||||
|
|
@ -71,23 +109,21 @@
|
||||||
name: "*"
|
name: "*"
|
||||||
state: latest # noqa: package-latest
|
state: latest # noqa: package-latest
|
||||||
|
|
||||||
- name: Configure Flatpaks
|
- name: Configure common (all arch) Flatpaks
|
||||||
hosts: fedora
|
hosts: fedora
|
||||||
become: false
|
become: false
|
||||||
tasks:
|
tasks:
|
||||||
- name: Install Flatpaks
|
- name: Install common (all arch) Flatpaks
|
||||||
community.general.flatpak:
|
community.general.flatpak:
|
||||||
name:
|
name:
|
||||||
- com.bitwarden.desktop
|
|
||||||
- com.github.tchx84.Flatseal
|
- com.github.tchx84.Flatseal
|
||||||
- com.logseq.Logseq
|
- com.logseq.Logseq
|
||||||
- com.slack.Slack
|
- io.freetubeapp.FreeTube
|
||||||
- dev.deedles.Trayscale
|
|
||||||
- io.github.alainm23.planify
|
- io.github.alainm23.planify
|
||||||
- io.github.dweymouth.supersonic
|
- io.github.dweymouth.supersonic
|
||||||
- io.openrct2.OpenRCT2
|
- io.openrct2.OpenRCT2
|
||||||
- org.signal.Signal
|
|
||||||
- org.zulip.Zulip
|
- org.zulip.Zulip
|
||||||
|
- net.ankiweb.Anki
|
||||||
state: latest
|
state: latest
|
||||||
method: user
|
method: user
|
||||||
remote: flathub
|
remote: flathub
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
- name: Configure dnf package repositories
|
- name: Configure amd64-specific package repositories
|
||||||
hosts: fedora
|
hosts: amd64
|
||||||
become: true
|
become: true
|
||||||
tasks:
|
tasks:
|
||||||
- name: Install RPM Fusion free repository
|
- name: Install RPM Fusion free repository
|
||||||
|
|
@ -20,6 +20,31 @@
|
||||||
- name: Install Zotero COPR repository
|
- name: Install Zotero COPR repository
|
||||||
community.general.copr:
|
community.general.copr:
|
||||||
name: "mozes/zotero7"
|
name: "mozes/zotero7"
|
||||||
|
|
||||||
|
# Asahi Linux comes with its own strange version of RPMFusion installed, so
|
||||||
|
# RPMFusion is installed only on amd64 systems. In addition, VeraCrypt and
|
||||||
|
# Zotero *are* available via COPR, but from different repos than their amd64
|
||||||
|
# counterparts.
|
||||||
|
# Also, Asahi has its own version string, so we have to manually specify the
|
||||||
|
# chroot for COPR repos added via Ansible. This is handled automatically when
|
||||||
|
# using `dnf copr enable ...`, but not via Ansible.
|
||||||
|
- name: Configure Asahi Linux-specific package repositories
|
||||||
|
hosts: asahi
|
||||||
|
become: true
|
||||||
|
tasks:
|
||||||
|
- name: Install Zotero COPR repository
|
||||||
|
community.general.copr:
|
||||||
|
name: "isaksamsten/Zotero"
|
||||||
|
chroot: "fedora-{{ ansible_distribution_major_version }}-aarch64"
|
||||||
|
- name: Install VeraCrypt COPR repository
|
||||||
|
community.general.copr:
|
||||||
|
name: "architektapx/veracrypt"
|
||||||
|
chroot: "fedora-{{ ansible_distribution_major_version }}-aarch64"
|
||||||
|
|
||||||
|
- name: Configure common (all arch) package repositories
|
||||||
|
hosts: fedora
|
||||||
|
become: true
|
||||||
|
tasks:
|
||||||
- name: Install Tailscale repo
|
- name: Install Tailscale repo
|
||||||
ansible.builtin.yum_repository:
|
ansible.builtin.yum_repository:
|
||||||
name: tailscale-stable
|
name: tailscale-stable
|
||||||
|
|
@ -28,6 +53,14 @@
|
||||||
enabled: true
|
enabled: true
|
||||||
gpgcheck: true
|
gpgcheck: true
|
||||||
gpgkey: https://pkgs.tailscale.com/stable/fedora/repo.gpg
|
gpgkey: https://pkgs.tailscale.com/stable/fedora/repo.gpg
|
||||||
|
- name: Install FirefoxPWA repository
|
||||||
|
ansible.builtin.yum_repository:
|
||||||
|
name: firefoxpwa
|
||||||
|
description: FirefoxPWA repository
|
||||||
|
baseurl: https://packagecloud.io/filips/FirefoxPWA/fedora/$releasever/$basearch
|
||||||
|
gpgcheck: true
|
||||||
|
gpgkey: https://packagecloud.io/filips/FirefoxPWA/gpgkey
|
||||||
|
enabled: true
|
||||||
# Note that I still have to specify the chroot for COPR repos b/c of Asahi
|
# Note that I still have to specify the chroot for COPR repos b/c of Asahi
|
||||||
- name: Install RStudio copr repository
|
- name: Install RStudio copr repository
|
||||||
community.general.copr:
|
community.general.copr:
|
||||||
|
|
@ -77,7 +110,7 @@
|
||||||
register: terra_priority
|
register: terra_priority
|
||||||
changed_when: terra_priority.rc != 0
|
changed_when: terra_priority.rc != 0
|
||||||
|
|
||||||
- name: Configure Flatpack remotes
|
- name: Configure Flathub remote
|
||||||
hosts: fedora
|
hosts: fedora
|
||||||
become: false
|
become: false
|
||||||
tasks:
|
tasks:
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{ ... }: {
|
{ ... }: {
|
||||||
defaults."AltTab" = {
|
defaults."AltTab" = {
|
||||||
appearanceStyle = 0;
|
appearanceStyle = 0;
|
||||||
nextWindowGesture = 3;
|
nextWindowGesture = 1;
|
||||||
screenRecordingPermissionSkipped = true;
|
screenRecordingPermissionSkipped = true;
|
||||||
showFullscreenWindows = 0;
|
showFullscreenWindows = 0;
|
||||||
showHiddenWindows = 1;
|
showHiddenWindows = 1;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
{ pkgs, firefox-addons, buildFirefoxXpiAddon, lib, ... }: {
|
{ firefox-addons, buildFirefoxXpiAddon, lib, ... }: {
|
||||||
programs.firefox = {
|
programs.firefox = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package =
|
package =
|
||||||
|
|
@ -31,52 +31,49 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
containersForce = true;
|
containersForce = true;
|
||||||
extensions.packages = with firefox-addons;
|
extensions.packages = with firefox-addons; [
|
||||||
[
|
bitwarden
|
||||||
bitwarden
|
multi-account-containers
|
||||||
darkreader
|
floccus
|
||||||
dearrow
|
libredirect
|
||||||
enhancer-for-youtube
|
old-reddit-redirect
|
||||||
multi-account-containers
|
plasma-integration
|
||||||
old-reddit-redirect
|
pwas-for-firefox
|
||||||
sponsorblock
|
ublock-origin
|
||||||
ublock-origin
|
user-agent-string-switcher
|
||||||
user-agent-string-switcher
|
web-archives
|
||||||
zotero-connector
|
zotero-connector
|
||||||
(buildFirefoxXpiAddon rec {
|
(buildFirefoxXpiAddon rec {
|
||||||
pname = "always_in_container";
|
pname = "always_in_container";
|
||||||
version = "1.0.7";
|
version = "1.0.7";
|
||||||
addonId = "{a1e9543e-5f73-4763-b376-04e53fd12cbd}";
|
addonId = "{a1e9543e-5f73-4763-b376-04e53fd12cbd}";
|
||||||
url =
|
url =
|
||||||
"https://addons.mozilla.org/firefox/downloads/file/4032840/${pname}-${version}.xpi";
|
"https://addons.mozilla.org/firefox/downloads/file/4032840/${pname}-${version}.xpi";
|
||||||
sha256 = "sha256-bLxjL2P6Sd06q98MSHYRTNigtcjGwn/C2r4ANWCqKrw=";
|
sha256 = "sha256-bLxjL2P6Sd06q98MSHYRTNigtcjGwn/C2r4ANWCqKrw=";
|
||||||
meta = with lib; {
|
meta = with lib; {
|
||||||
homepage = "https://github.com/tiansh/always-in-container";
|
homepage = "https://github.com/tiansh/always-in-container";
|
||||||
description =
|
description =
|
||||||
"Chose a container every time you try to open a page out of a container";
|
"Chose a container every time you try to open a page out of a container";
|
||||||
license = licenses.mpl20;
|
license = licenses.mpl20;
|
||||||
platforms = platforms.all;
|
platforms = platforms.all;
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
(buildFirefoxXpiAddon rec {
|
(buildFirefoxXpiAddon rec {
|
||||||
pname = "open_with";
|
pname = "open_with";
|
||||||
version = "7.2.6";
|
version = "7.2.6";
|
||||||
addonId = "openwith@darktrojan.net";
|
addonId = "openwith@darktrojan.net";
|
||||||
url =
|
url =
|
||||||
"https://addons.mozilla.org/firefox/downloads/file/3831723/${pname}-${version}.xpi";
|
"https://addons.mozilla.org/firefox/downloads/file/3831723/${pname}-${version}.xpi";
|
||||||
sha256 = "sha256-f9eGhLxg4UyVn4o5e4DRkraLWzj11SGto/GOwsJa9kg=";
|
sha256 = "sha256-f9eGhLxg4UyVn4o5e4DRkraLWzj11SGto/GOwsJa9kg=";
|
||||||
meta = with lib; {
|
meta = with lib; {
|
||||||
homepage = "https://darktrojan.github.io/openwith/";
|
homepage = "https://darktrojan.github.io/openwith/";
|
||||||
description =
|
description =
|
||||||
"Quickly test out your web pages in Chrome, Edge, Safari, or Opera. Open With opens the current page in your other browsers with just two clicks.";
|
"Quickly test out your web pages in Chrome, Edge, Safari, or Opera. Open With opens the current page in your other browsers with just two clicks.";
|
||||||
license = licenses.mpl20;
|
license = licenses.mpl20;
|
||||||
platforms = platforms.all;
|
platforms = platforms.all;
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
] ++ (if pkgs.stdenv.hostPlatform.isDarwin then
|
];
|
||||||
[ ]
|
|
||||||
else
|
|
||||||
[ plasma-integration ]);
|
|
||||||
search = {
|
search = {
|
||||||
default = "Kagi";
|
default = "Kagi";
|
||||||
privateDefault = "Milliron X Search";
|
privateDefault = "Milliron X Search";
|
||||||
|
|
@ -180,50 +177,11 @@
|
||||||
# - Google Scholar
|
# - Google Scholar
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
settings = let
|
settings = {
|
||||||
isUuid = str:
|
|
||||||
(builtins.match
|
|
||||||
"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
|
|
||||||
str) != null;
|
|
||||||
prefix = addon: if isUuid addon then "_" else "";
|
|
||||||
button = addon:
|
|
||||||
"${prefix addon}${addon}${prefix addon}-browser-action";
|
|
||||||
always-in-container = "a1e9543e-5f73-4763-b376-04e53fd12cbd";
|
|
||||||
bitwarden = "446900e4-71c2-419f-a6a7-df9c091e268b";
|
|
||||||
dark-reader = "addon_darkreader_org";
|
|
||||||
dearrow = "dearrow_ajay_app";
|
|
||||||
enhancer-for-youtube =
|
|
||||||
"enhancerforyoutube_maximerf_addons_mozilla_org";
|
|
||||||
old-reddit-redirect = "9063c2e9-e07c-4c2c-9646-cfe7ca8d0498";
|
|
||||||
open-with = "openwith_darktrojan_net";
|
|
||||||
plasma = "plasma-browser-integration";
|
|
||||||
sponsorblock = "sponsorblocker_ajay_app";
|
|
||||||
ublock-origin = "ublock0_raymondhill_net";
|
|
||||||
user-agent-switcher = "a6c4a591-f1b2-4f03-b3ff-767e5bedf4e7";
|
|
||||||
zotero = "zotero_chnm_gmu_edu";
|
|
||||||
containers = "_testpilot-containers";
|
|
||||||
in {
|
|
||||||
"app.normandy.first_run" = false;
|
"app.normandy.first_run" = false;
|
||||||
"app.shield.optoutstudies.enabled" = false;
|
"app.shield.optoutstudies.enabled" = false;
|
||||||
"browser.ai.control.default" = "blocked";
|
|
||||||
"browser.ai.control.linkPreviewKeyPoints" = "blocked";
|
|
||||||
"browser.ai.control.pdfjsAltText" = "blocked";
|
|
||||||
"browser.ai.control.sidebarChatbot" = "blocked";
|
|
||||||
"browser.ai.control.smartTabGroups" = "blocked";
|
|
||||||
"browser.ai.control.translations" = "blocked";
|
|
||||||
"browser.contentblocking.category" = "strict";
|
"browser.contentblocking.category" = "strict";
|
||||||
"browser.formfill.enable" = false;
|
"browser.formfill.enable" = false;
|
||||||
"browser.ml.chat.enabled" = false;
|
|
||||||
"browser.ml.chat.menu" = false;
|
|
||||||
"browser.ml.chat.page" = false;
|
|
||||||
"browser.ml.chat.page.footerBadge" = false;
|
|
||||||
"browser.ml.chat.page.menuBadge" = false;
|
|
||||||
"browser.ml.chat.shortcuts" = false;
|
|
||||||
"browser.ml.chat.sidebar" = false;
|
|
||||||
"browser.ml.enable" = false;
|
|
||||||
"browser.ml.linkPreview.enabled" = false;
|
|
||||||
"browser.ml.pageAssist.enabled" = false;
|
|
||||||
"browser.ml.smartAssist.enabled" = false;
|
|
||||||
"browser.newtabpage.activity-stream.asrouter.userprefs.cfr.addons" =
|
"browser.newtabpage.activity-stream.asrouter.userprefs.cfr.addons" =
|
||||||
false;
|
false;
|
||||||
"browser.newtabpage.activity-stream.asrouter.userprefs.cfr.features" =
|
"browser.newtabpage.activity-stream.asrouter.userprefs.cfr.features" =
|
||||||
|
|
@ -274,46 +232,26 @@
|
||||||
baseDomain = "ksu.one45.com";
|
baseDomain = "ksu.one45.com";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
"browser.search.visualSearch.featureGate" = false;
|
|
||||||
"browser.shopping.experience2023.active" = false;
|
"browser.shopping.experience2023.active" = false;
|
||||||
"browser.startup.homepage_override.mstone" = "ignore";
|
"browser.startup.homepage_override.mstone" = "ignore";
|
||||||
"browser.tabs.closeWindowWithLastTab" = false;
|
"browser.tabs.closeWindowWithLastTab" = false;
|
||||||
"browser.tabs.groups.smart.enabled" = false;
|
|
||||||
"browser.tabs.groups.smart.userEnabled" = false;
|
|
||||||
"browser.tabs.inTitlebar" = 0;
|
"browser.tabs.inTitlebar" = 0;
|
||||||
"browser.theme.content-theme" = 0;
|
"browser.theme.content-theme" = 0;
|
||||||
"browser.theme.toolbar-theme" = 0;
|
"browser.theme.toolbar-theme" = 0;
|
||||||
"browser.toolbars.bookmarks.visibility" = "never";
|
"browser.toolbars.bookmarks.visibility" = "never";
|
||||||
"browser.uiCustomization.navBarWhenVerticalTabs" = [
|
|
||||||
"sidebar-button"
|
|
||||||
"back-button"
|
|
||||||
"forward-button"
|
|
||||||
"customizableui-special-spring1"
|
|
||||||
"vertical-spacer"
|
|
||||||
"urlbar-container"
|
|
||||||
"stop-reload-button"
|
|
||||||
"customizableui-special-spring2"
|
|
||||||
"downloads-button"
|
|
||||||
(button bitwarden)
|
|
||||||
(button ublock-origin)
|
|
||||||
"unified-extensions-button"
|
|
||||||
(button containers)
|
|
||||||
];
|
|
||||||
"browser.uiCustomization.state" = {
|
"browser.uiCustomization.state" = {
|
||||||
placements = {
|
placements = {
|
||||||
unified-extensions-area = map button [
|
"widget-overflow-fixed-list" = [ ];
|
||||||
dark-reader
|
"unified-extensions-area" = [
|
||||||
open-with
|
"floccus_handmadeideas_org-browser-action"
|
||||||
zotero
|
"7esoorv3_alefvanoon_anonaddy_me-browser-action"
|
||||||
user-agent-switcher
|
"plasma-browser-integration_kde_org-browser-action"
|
||||||
enhancer-for-youtube
|
"firefoxpwa_filips_si-browser-action"
|
||||||
sponsorblock
|
"_d07ccf11-c0cd-4938-a265-2a4d6ad01189_-browser-action" # Web Archives
|
||||||
dearrow
|
"openwith_darktrojan_net-browser-action"
|
||||||
always-in-container
|
"zotero_chnm_gmu_edu-browser-action"
|
||||||
old-reddit-redirect
|
|
||||||
plasma
|
|
||||||
];
|
];
|
||||||
nav-bar = [
|
"nav-bar" = [
|
||||||
"back-button"
|
"back-button"
|
||||||
"forward-button"
|
"forward-button"
|
||||||
"customizableui-special-spring1"
|
"customizableui-special-spring1"
|
||||||
|
|
@ -322,62 +260,53 @@
|
||||||
"stop-reload-button"
|
"stop-reload-button"
|
||||||
"customizableui-special-spring2"
|
"customizableui-special-spring2"
|
||||||
"downloads-button"
|
"downloads-button"
|
||||||
(button bitwarden)
|
"_446900e4-71c2-419f-a6a7-df9c091e268b_-browser-action" # Bitwarden
|
||||||
(button ublock-origin)
|
"ublock0_raymondhill_net-browser-action"
|
||||||
"unified-extensions-button"
|
"unified-extensions-button"
|
||||||
(button containers)
|
"_testpilot-containers-browser-action"
|
||||||
];
|
];
|
||||||
vertical-tabs = [ "tabbrowser-tabs" ];
|
"TabsToolbar" = [
|
||||||
PersonalToolbar = [ "import-button" "personal-bookmarks" ];
|
"firefox-view-button"
|
||||||
TabsToolbar = [ ];
|
"tabbrowser-tabs"
|
||||||
widget-overflow-fixed-list = [ ];
|
"new-tab-button"
|
||||||
|
"alltabs-button"
|
||||||
|
];
|
||||||
|
"vertical-tabs" = [ ];
|
||||||
|
"PersonalToolbar" = [ "import-button" "personal-bookmarks" ];
|
||||||
};
|
};
|
||||||
seen =
|
seen = [
|
||||||
[ "save-to-pocket-button" "developer-button" "screenshot-button" ]
|
"save-to-pocket-button"
|
||||||
++ (map button [
|
"developer-button"
|
||||||
always-in-container
|
"_446900e4-71c2-419f-a6a7-df9c091e268b_-browser-action"
|
||||||
bitwarden
|
"_testpilot-containers-browser-action"
|
||||||
dark-reader
|
"floccus_handmadeideas_org-browser-action"
|
||||||
dearrow
|
"7esoorv3_alefvanoon_anonaddy_me-browser-action"
|
||||||
enhancer-for-youtube
|
"plasma-browser-integration_kde_org-browser-action"
|
||||||
old-reddit-redirect
|
"firefoxpwa_filips_si-browser-action"
|
||||||
open-with
|
"ublock0_raymondhill_net-browser-action"
|
||||||
plasma
|
"_d07ccf11-c0cd-4938-a265-2a4d6ad01189_-browser-action"
|
||||||
sponsorblock
|
"zotero_chnm_gmu_edu-browser-action"
|
||||||
ublock-origin
|
"openwith_darktrojan_net-browser-action"
|
||||||
user-agent-switcher
|
];
|
||||||
zotero
|
|
||||||
containers
|
|
||||||
]);
|
|
||||||
dirtyAreaCache = [
|
dirtyAreaCache = [
|
||||||
"nav-bar"
|
"nav-bar"
|
||||||
"vertical-tabs"
|
"vertical-tabs"
|
||||||
"PersonalToolbar"
|
"PersonalToolbar"
|
||||||
"unified-extensions-area"
|
"unified-extensions-area"
|
||||||
"TabsToolbar"
|
|
||||||
];
|
];
|
||||||
currentVersion = 23;
|
currentVersion = 21;
|
||||||
newElementCount = 0;
|
newElementCount = 3;
|
||||||
};
|
};
|
||||||
"browser.uitour.enabled" = false;
|
"browser.urlbar.suggest.showSearchSuggestionsFirst" = false;
|
||||||
"browser.urlbar.quicksuggest.mlEnabled" = false;
|
|
||||||
"browser.urlbar.suggest.quicksuggest.nonsponsored" = false;
|
"browser.urlbar.suggest.quicksuggest.nonsponsored" = false;
|
||||||
"browser.urlbar.suggest.quicksuggest.sponsored" = false;
|
"browser.urlbar.suggest.quicksuggest.sponsored" = false;
|
||||||
"browser.urlbar.suggest.quicksuggest.trending" = false;
|
"browser.urlbar.suggest.quicksuggest.trending" = false;
|
||||||
"browser.urlbar.suggest.showSearchSuggestionsFirst" = false;
|
|
||||||
"browser.warnOnQuitShortcut" = false;
|
"browser.warnOnQuitShortcut" = false;
|
||||||
"datareporting.healthreport.uploadEnabled" = false;
|
"datareporting.healthreport.uploadEnabled" = false;
|
||||||
"datareporting.usage.uploadEnabled" = false;
|
"datareporting.usage.uploadEnabled" = false;
|
||||||
"extensions.autoDisableScopes" = 0;
|
|
||||||
"extensions.formautofill.addresses.enabled" = false;
|
"extensions.formautofill.addresses.enabled" = false;
|
||||||
"extensions.formautofill.creditCards.enabled" = false;
|
"extensions.formautofill.creditCards.enabled" = false;
|
||||||
"extensions.ml.enabled" = false;
|
"extensions.autoDisableScopes" = 0;
|
||||||
"extensions.update.autoUpdateDefault" = false;
|
|
||||||
"extensions.update.enabled" = false;
|
|
||||||
"pdfjs.enableAltText" = false;
|
|
||||||
"pdfjs.enableAltTextModelDownload" = false;
|
|
||||||
"pdfjs.enableGuessAltText" = false;
|
|
||||||
"places.semanticHistory.featureGate" = false;
|
|
||||||
"privacy.bounceTrackingProtection.mode" = 1;
|
"privacy.bounceTrackingProtection.mode" = 1;
|
||||||
"privacy.clearOnShutdown_v2.browsingHistoryAndDownloads" = false;
|
"privacy.clearOnShutdown_v2.browsingHistoryAndDownloads" = false;
|
||||||
"privacy.clearOnShutdown_v2.cache" = true;
|
"privacy.clearOnShutdown_v2.cache" = true;
|
||||||
|
|
@ -391,14 +320,6 @@
|
||||||
"privacy.trackingprotection.emailtracking.enabled" = true;
|
"privacy.trackingprotection.emailtracking.enabled" = true;
|
||||||
"privacy.trackingprotection.enabled" = true;
|
"privacy.trackingprotection.enabled" = true;
|
||||||
"privacy.trackingprotection.socialtracking.enabled" = true;
|
"privacy.trackingprotection.socialtracking.enabled" = true;
|
||||||
"sidebar.installed.extensions" = "{${bitwarden}}";
|
|
||||||
"sidebar.main.tools" = "syncedtabs,history,{${bitwarden}},bookmarks";
|
|
||||||
"sidebar.new-sidebar.has-used" = true;
|
|
||||||
"sidebar.revamp" = true;
|
|
||||||
"sidebar.verticalTabs" = true;
|
|
||||||
"sidebar.verticalTabs.dragToPinPromo.dismissed" = true;
|
|
||||||
"sidebar.visibility" = "expand-on-hover";
|
|
||||||
"signon.rememberSignons" = false;
|
|
||||||
"widget.use-xdg-desktop-portal.file-picker" = 1;
|
"widget.use-xdg-desktop-portal.file-picker" = 1;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
19
programs/ghostty.nix
Normal file
19
programs/ghostty.nix
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
{ pkgs, ... }: {
|
||||||
|
programs.ghostty =
|
||||||
|
let modifierKey = if pkgs.stdenv.isDarwin then "cmd" else "ctrl";
|
||||||
|
in {
|
||||||
|
enable = true;
|
||||||
|
package = null;
|
||||||
|
enableBashIntegration = true;
|
||||||
|
enableZshIntegration = true;
|
||||||
|
settings = {
|
||||||
|
quick-terminal-position = "top";
|
||||||
|
quick-terminal-screen = "main";
|
||||||
|
quick-terminal-autohide = true;
|
||||||
|
quick-terminal-size = "50%,50%";
|
||||||
|
keybind = "global:${modifierKey}+backquote=toggle_quick_terminal";
|
||||||
|
macos-hidden = "always";
|
||||||
|
linux-cgroup = "always";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -1,16 +1,10 @@
|
||||||
{ ... }: {
|
{ ... }: {
|
||||||
programs.git = {
|
programs.git = {
|
||||||
enable = true;
|
enable = true;
|
||||||
settings = {
|
userName = "Thomas A. Christensen II";
|
||||||
user = {
|
userEmail = "25492070+MillironX@users.noreply.github.com";
|
||||||
name = "Thomas A. Christensen II";
|
extraConfig = {
|
||||||
email = "25492070+MillironX@users.noreply.github.com";
|
core = { editor = "nvim"; };
|
||||||
};
|
|
||||||
core = {
|
|
||||||
editor = "nvim";
|
|
||||||
# git push/pull via ssh over ipv6 is slow, so force ipv4 instead
|
|
||||||
sshCommand = "ssh -4";
|
|
||||||
};
|
|
||||||
credential = { helper = "store"; };
|
credential = { helper = "store"; };
|
||||||
color = { ui = "auto"; };
|
color = { ui = "auto"; };
|
||||||
init = { defaultBranch = "master"; };
|
init = { defaultBranch = "master"; };
|
||||||
|
|
@ -46,11 +40,6 @@
|
||||||
};
|
};
|
||||||
merge = { conflictstyle = "zdiff3"; };
|
merge = { conflictstyle = "zdiff3"; };
|
||||||
pull = { rebase = true; };
|
pull = { rebase = true; };
|
||||||
"url \"ssh://git@github.com/\"".insteadOf = "https://github.com/";
|
|
||||||
"url \"ssh://git@gitlab.com/\"".insteadOf = "https://gitlab.com/";
|
|
||||||
"url \"ssh://git@codeberg.com/\"".insteadOf = "https://codeberg.com/";
|
|
||||||
"url \"ssh://git@code.millironx.com/\"".insteadOf =
|
|
||||||
"https://code.millironx.com/";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
{ ... }: {
|
|
||||||
programs.konsole = {
|
|
||||||
enable = true;
|
|
||||||
defaultProfile = "millironx";
|
|
||||||
profiles.millironx = {
|
|
||||||
colorScheme = "Breeze";
|
|
||||||
font = {
|
|
||||||
name = "MesloLGS NF";
|
|
||||||
size = 10;
|
|
||||||
};
|
|
||||||
extraConfig = {
|
|
||||||
"Cursor Options".CursorShape = 1;
|
|
||||||
General.RemoteTabTitleFormat = "[SSH] %H";
|
|
||||||
"Interaction Options" = {
|
|
||||||
CopyTextAsHTML = false;
|
|
||||||
MouseWheelZoomEnabled = false;
|
|
||||||
UnderlineFilesEnabled = true;
|
|
||||||
};
|
|
||||||
"Terminal Features".BlinkingCursorEnabled = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,178 +1,7 @@
|
||||||
{ config, ... }: {
|
{ config, ... }: {
|
||||||
|
|
||||||
imports = [ ./konsole.nix ./yakuake.nix ];
|
|
||||||
|
|
||||||
programs.plasma = {
|
programs.plasma = {
|
||||||
enable = true;
|
enable = true;
|
||||||
overrideConfig = true;
|
|
||||||
shortcuts = { yakuake.toggle-window-state = "Ctrl+`"; };
|
|
||||||
configFile = {
|
|
||||||
dolphinrc = {
|
|
||||||
DetailsMode.PreviewSize = 16;
|
|
||||||
General = {
|
|
||||||
BrowseThroughArchives = true;
|
|
||||||
EditableUrl = true;
|
|
||||||
GlobalViewProps = false;
|
|
||||||
ShowFullPath = true;
|
|
||||||
ShowStatusBar = "FullWidth";
|
|
||||||
ShowZoomSlider = true;
|
|
||||||
ViewMode = 1;
|
|
||||||
};
|
|
||||||
"KFileDialog Settings" = {
|
|
||||||
"Places Icons Auto-resize" = false;
|
|
||||||
"Places Icons Static Size" = 22;
|
|
||||||
};
|
|
||||||
PreviewSettings.Plugins =
|
|
||||||
"audiothumbnail,avif,blenderthumbnail,comicbookthumbnail,cursorthumbnail,djvuthumbnail,ebookthumbnail,exrthumbnail,directorythumbnail,fontthumbnail,imagethumbnail,jpegthumbnail,jxl,kraorathumbnail,windowsexethumbnail,windowsimagethumbnail,mobithumbnail,opendocumentthumbnail,gsthumbnail,rawthumbnail,svgthumbnail,gdk-pixbuf-thumbnailer,ffmpegthumbs,gsf-office";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
input.mice = [{
|
|
||||||
enable = true;
|
|
||||||
name = "Logitech M705";
|
|
||||||
vendorId = "046d";
|
|
||||||
productId = "406d";
|
|
||||||
naturalScroll = true;
|
|
||||||
}];
|
|
||||||
kwin = {
|
|
||||||
cornerBarrier = false;
|
|
||||||
titlebarButtons = {
|
|
||||||
left = [ "close" "minimize" "maximize" ];
|
|
||||||
right = [ "help" ];
|
|
||||||
};
|
|
||||||
virtualDesktops = {
|
|
||||||
number = 2;
|
|
||||||
rows = 1;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
panels = [
|
|
||||||
### Screen 0 panels ###
|
|
||||||
##### Top: Fedora menu | App switcher | Menu bar | CPU monitor | Memory monitor | Network monitor | System tray | clock #####
|
|
||||||
{
|
|
||||||
location = "top";
|
|
||||||
floating = true;
|
|
||||||
height = 27;
|
|
||||||
lengthMode = "fill";
|
|
||||||
opacity = "adaptive";
|
|
||||||
hiding = "normalpanel";
|
|
||||||
screen = 0;
|
|
||||||
widgets = [
|
|
||||||
{ kickoff = { icon = "fedora-logo-icon"; }; }
|
|
||||||
"org.kde.plasma.marginsseparator"
|
|
||||||
"org.kde.plasma.windowlist"
|
|
||||||
"org.kde.plasma.appmenu"
|
|
||||||
"org.kde.plasma.panelspacer"
|
|
||||||
{
|
|
||||||
name = "org.kde.plasma.systemmonitor.cpu";
|
|
||||||
config = {
|
|
||||||
Appearance.chartFace = "org.kde.ksysguard.barchart";
|
|
||||||
Sensors.highPrioritySensorIds = "[${
|
|
||||||
builtins.concatStringsSep "," (builtins.genList
|
|
||||||
(i: ''"cpu/cpu${builtins.toString i}/usage"'') 32)
|
|
||||||
}]";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "org.kde.plasma.systemmonitor.memory";
|
|
||||||
config.Appearance.chartFace = "org.kde.ksysguard.horizontalbars";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "org.kde.plasma.systemmonitor.net";
|
|
||||||
config = {
|
|
||||||
Appearance.chartFace = "org.kde.ksysguard.horizontalbars";
|
|
||||||
Sensors.highPrioritySensorIds =
|
|
||||||
''[ "network/all/download","network/all/upload" ]'';
|
|
||||||
# These are the values needed to make the network indicator
|
|
||||||
# actually useful, but it appears that plasma-manager doesn't
|
|
||||||
# support nesting this deep yet. Disable for now.
|
|
||||||
# "org.kde.ksysguard.horizontalbars".General = {
|
|
||||||
# rangeAuto = false;
|
|
||||||
# rangeFromMultiplier = 1048576;
|
|
||||||
# rangeFromUnit = 202;
|
|
||||||
# rangeToMultiplier = 1048576;
|
|
||||||
# rangeToUnit = 202;
|
|
||||||
# };
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{ systemTray = { }; }
|
|
||||||
{ digitalClock = { }; }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
##### Bottom: Virtual desktop pager | Full-name taskbar w/ pins | Downloads folder | Trash folder
|
|
||||||
{
|
|
||||||
location = "bottom";
|
|
||||||
floating = true;
|
|
||||||
height = 44;
|
|
||||||
lengthMode = "fill";
|
|
||||||
opacity = "adaptive";
|
|
||||||
hiding = "normalpanel";
|
|
||||||
screen = 0;
|
|
||||||
widgets = [
|
|
||||||
"org.kde.plasma.pager"
|
|
||||||
{
|
|
||||||
iconTasks = {
|
|
||||||
iconsOnly = false;
|
|
||||||
behavior.showTasks.onlyInCurrentScreen = true;
|
|
||||||
launchers = [
|
|
||||||
"applications:systemsettings.desktop"
|
|
||||||
"applications:org.kde.discover.desktop"
|
|
||||||
"preferred://filemanager"
|
|
||||||
"preferred://browser"
|
|
||||||
"applications:net.thunderbird.Thunderbird.desktop"
|
|
||||||
"applications:io.github.alainm23.planify.desktop"
|
|
||||||
"applications:dev.zed.Zed.desktop"
|
|
||||||
"applications:com.logseq.Logseq.desktop"
|
|
||||||
"applications:net.lutris.Lutris.desktop"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
"org.kde.plasma.panelspacer"
|
|
||||||
"org.kde.plasma.marginsseparator"
|
|
||||||
{
|
|
||||||
name = "org.kde.plasma.folder";
|
|
||||||
config = {
|
|
||||||
General.url = "file://${config.home.homeDirectory}/Downloads";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
"org.kde.plasma.trash"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
### Screen 1 panels ###
|
|
||||||
##### Top: App switcher | Menu bar #####
|
|
||||||
{
|
|
||||||
location = "top";
|
|
||||||
floating = true;
|
|
||||||
height = 27;
|
|
||||||
lengthMode = "fill";
|
|
||||||
opacity = "adaptive";
|
|
||||||
hiding = "normalpanel";
|
|
||||||
screen = 1;
|
|
||||||
widgets = [ "org.kde.plasma.windowlist" "org.kde.plasma.appmenu" ];
|
|
||||||
}
|
|
||||||
##### Bottom: Virtual desktop pager | Full-name taskbar w/o pins #####
|
|
||||||
{
|
|
||||||
location = "bottom";
|
|
||||||
floating = true;
|
|
||||||
height = 44;
|
|
||||||
lengthMode = "fill";
|
|
||||||
opacity = "adaptive";
|
|
||||||
hiding = "normalpanel";
|
|
||||||
screen = 1;
|
|
||||||
widgets = [
|
|
||||||
"org.kde.plasma.pager"
|
|
||||||
{
|
|
||||||
iconTasks = {
|
|
||||||
iconsOnly = false;
|
|
||||||
behavior.showTasks.onlyInCurrentScreen = true;
|
|
||||||
launchers = [ ];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
powerdevil.AC.autoSuspend.action = "nothing";
|
|
||||||
workspace = {
|
workspace = {
|
||||||
lookAndFeel = "org.kde.breezedark.desktop";
|
|
||||||
wallpaperFillMode = "preserveAspectCrop";
|
wallpaperFillMode = "preserveAspectCrop";
|
||||||
wallpaperSlideShow = {
|
wallpaperSlideShow = {
|
||||||
interval = 86400;
|
interval = 86400;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
let
|
let
|
||||||
conda_init = shell: ''
|
conda_init = shell: ''
|
||||||
eval "$(${pkgs.mamba-cpp}/bin/mamba shell hook --shell ${shell})"
|
eval "$(${pkgs.micromamba}/bin/micromamba shell hook --shell ${shell})"
|
||||||
|
|
||||||
'';
|
'';
|
||||||
nd_bash_function = ''
|
nd_bash_function = ''
|
||||||
|
|
@ -10,53 +10,11 @@ let
|
||||||
}
|
}
|
||||||
|
|
||||||
'';
|
'';
|
||||||
sourceCodeDirectory =
|
|
||||||
if pkgs.stdenv.hostPlatform.isDarwin then "~/Developer" else "~/src";
|
|
||||||
clone_bash_function = ''
|
|
||||||
unalias gc
|
|
||||||
function gc() {
|
|
||||||
REPO_ID="$(echo "''${1}" | \
|
|
||||||
awk '{
|
|
||||||
sub(/^git@/, "");
|
|
||||||
sub(/^https:\/\//, "");
|
|
||||||
sub (/:/, "/");
|
|
||||||
sub(/\.git$/, "");
|
|
||||||
print
|
|
||||||
}')"
|
|
||||||
git clone "https://''${REPO_ID}.git" ${sourceCodeDirectory}/''${REPO_ID}
|
|
||||||
cd ${sourceCodeDirectory}/''${REPO_ID}
|
|
||||||
}
|
|
||||||
|
|
||||||
'';
|
|
||||||
repo_init_function = ''
|
|
||||||
function rinit() {
|
|
||||||
REPO_ID="$(echo "''${1}" | \
|
|
||||||
awk '{
|
|
||||||
sub(/^git@/, "");
|
|
||||||
sub(/^https:\/\//, "");
|
|
||||||
sub (/:/, "/");
|
|
||||||
sub(/\.git$/, "");
|
|
||||||
print
|
|
||||||
}')"
|
|
||||||
|
|
||||||
mkdir -p ${sourceCodeDirectory}/''${REPO_ID}
|
|
||||||
cd ${sourceCodeDirectory}/''${REPO_ID}
|
|
||||||
|
|
||||||
git init
|
|
||||||
|
|
||||||
git remote add origin git@''${REPO_ID/\//:}.git
|
|
||||||
}
|
|
||||||
|
|
||||||
'';
|
|
||||||
|
|
||||||
shell_functions = shell:
|
|
||||||
(conda_init shell) + nd_bash_function + clone_bash_function
|
|
||||||
+ repo_init_function;
|
|
||||||
in {
|
in {
|
||||||
programs = {
|
programs = {
|
||||||
bash = {
|
bash = {
|
||||||
enable = true;
|
enable = true;
|
||||||
initExtra = shell_functions "bash" + ''
|
initExtra = conda_init "bash" + nd_bash_function + ''
|
||||||
export PS1="[\[\e[32m\]\u\[\e[m\]@\[\e[33m\]\h\[\e[m\] \[\e[34m\]\W\[\e[m\]] \\$ "
|
export PS1="[\[\e[32m\]\u\[\e[m\]@\[\e[33m\]\h\[\e[m\] \[\e[34m\]\W\[\e[m\]] \\$ "
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
@ -79,7 +37,7 @@ in {
|
||||||
"zsh-users/zsh-completions"
|
"zsh-users/zsh-completions"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
initContent = shell_functions "zsh";
|
initContent = conda_init "zsh" + nd_bash_function;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
{ pkgs, lib, config, hostname, ... }:
|
|
||||||
let
|
|
||||||
sshIdPath = host: "~/.ssh/id_ed25519__${host}";
|
|
||||||
tailnetConfig = host: { identityFile = sshIdPath host; };
|
|
||||||
gitConfig = host: tailnetConfig host // { user = "git"; };
|
|
||||||
tailnetHosts = [ "anderson" "mcentire" "bosephus" ];
|
|
||||||
gitHosts = [ "github.com" "gitlab.com" "codeberg.org" "code.millironx.com" ];
|
|
||||||
tailnetMatchBlocks =
|
|
||||||
lib.genAttrs (lib.lists.remove hostname tailnetHosts) tailnetConfig;
|
|
||||||
gitMatchBlocks = lib.genAttrs gitHosts gitConfig // {
|
|
||||||
"code.millironx.com" = (gitConfig "code.millironx.com") // {
|
|
||||||
proxyCommand = "ssh anderson -W localhost:2222";
|
|
||||||
hostname = "code.millironx.com";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
in {
|
|
||||||
programs.ssh = {
|
|
||||||
enable = true;
|
|
||||||
enableDefaultConfig = false;
|
|
||||||
matchBlocks = {
|
|
||||||
"*" = { identitiesOnly = true; };
|
|
||||||
"aahz" = {
|
|
||||||
hostname = "nistac-108-37.dhcp.ksu.edu";
|
|
||||||
user = "tchristensen";
|
|
||||||
identityFile = sshIdPath "aahz";
|
|
||||||
};
|
|
||||||
"skeeve" = {
|
|
||||||
hostname = "129.130.108.157";
|
|
||||||
user = "tchristensen";
|
|
||||||
identityFile = sshIdPath "skeeve";
|
|
||||||
};
|
|
||||||
"ceres" = {
|
|
||||||
hostname = "ceres.scinet.usda.gov";
|
|
||||||
user = "thomas.christensen";
|
|
||||||
identitiesOnly = false;
|
|
||||||
serverAliveInterval = 20;
|
|
||||||
serverAliveCountMax = 30;
|
|
||||||
extraOptions = { TCPKeepAlive = "yes"; };
|
|
||||||
};
|
|
||||||
"atlas" = {
|
|
||||||
hostname = "Atlas-login-1.hpc.msstate.edu";
|
|
||||||
user = "thomas.christensen";
|
|
||||||
identitiesOnly = false;
|
|
||||||
serverAliveInterval = 20;
|
|
||||||
serverAliveCountMax = 30;
|
|
||||||
extraOptions = { TCPKeepAlive = "yes"; };
|
|
||||||
};
|
|
||||||
"atlas-dtn" = {
|
|
||||||
hostname = "Atlas-dtn.hpc.msstate.edu";
|
|
||||||
user = "thomas.christensen";
|
|
||||||
identitiesOnly = false;
|
|
||||||
};
|
|
||||||
"code.millironx.com" = {
|
|
||||||
proxyCommand = "ssh anderson -W localhost:2222";
|
|
||||||
};
|
|
||||||
} // tailnetMatchBlocks // gitMatchBlocks;
|
|
||||||
};
|
|
||||||
|
|
||||||
home.packages = let
|
|
||||||
# Answer no to overwrite questions
|
|
||||||
keygen = host: ''
|
|
||||||
yes "n" | \
|
|
||||||
ssh-keygen \
|
|
||||||
-t ed25519 \
|
|
||||||
-f ~/.ssh/id_ed25519__${host} \
|
|
||||||
-C "millironx@${hostname}" \
|
|
||||||
-N ""
|
|
||||||
'';
|
|
||||||
in [
|
|
||||||
(pkgs.writeShellScriptBin "ssh-bootstrap-keys"
|
|
||||||
(builtins.concatStringsSep "\n" (map keygen (tailnetHosts ++ gitHosts))))
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@ -25,10 +25,6 @@
|
||||||
bundleIdentifier = "org.mozilla.thunderbird";
|
bundleIdentifier = "org.mozilla.thunderbird";
|
||||||
action = "launchOrActivateApp";
|
action = "launchOrActivateApp";
|
||||||
}
|
}
|
||||||
{
|
|
||||||
bundleIdentifier = "com.microsoft.Outlook";
|
|
||||||
action = "launchOrActivateApp";
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
bundleIdentifier = "dev.zed.Zed";
|
bundleIdentifier = "dev.zed.Zed";
|
||||||
action = "launchOrActivateApp";
|
action = "launchOrActivateApp";
|
||||||
|
|
@ -38,13 +34,11 @@
|
||||||
action = "launchOrActivateApp";
|
action = "launchOrActivateApp";
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
# Instinct dashboard
|
|
||||||
bundleIdentifier =
|
bundleIdentifier =
|
||||||
"com.apple.Safari.WebApp.2F51A6D0-087A-438F-92D3-A73FE09CB4CC";
|
"com.apple.Safari.WebApp.2F51A6D0-087A-438F-92D3-A73FE09CB4CC";
|
||||||
action = "launchOrActivateApp";
|
action = "launchOrActivateApp";
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
# Carestream
|
|
||||||
bundleIdentifier =
|
bundleIdentifier =
|
||||||
"com.apple.Safari.WebApp.5EC6478E-03A6-4147-8A4D-6EF3DE3F06D3";
|
"com.apple.Safari.WebApp.5EC6478E-03A6-4147-8A4D-6EF3DE3F06D3";
|
||||||
action = "launchOrActivateApp";
|
action = "launchOrActivateApp";
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
{ pkgs, ... }: {
|
|
||||||
programs.tmux = {
|
|
||||||
enable = true;
|
|
||||||
terminal = "tmux-256color";
|
|
||||||
plugins = with pkgs.tmuxPlugins; [ tmux-powerline ];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
# Note: this file uses the lower-level `programs.plasma.configFile` syntax
|
|
||||||
# since plasma-manager does not yet support a high-level module for Yakuake
|
|
||||||
{ ... }: {
|
|
||||||
programs.plasma.configFile.yakuakerc = {
|
|
||||||
"Desktop Entry".DefaultProfile = "millironx.profile";
|
|
||||||
Shortcuts = {
|
|
||||||
next-session = "Shift+Right; Ctrl+Shift+Tab";
|
|
||||||
previous-terminal = "none";
|
|
||||||
};
|
|
||||||
Window = {
|
|
||||||
DynamicTabTitles = true;
|
|
||||||
Height = 60;
|
|
||||||
Screen = 1;
|
|
||||||
ShowSystrayIcon = false;
|
|
||||||
Width = 60;
|
|
||||||
};
|
|
||||||
Dialogs.FirstRun = false;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
{ pkgs, hostname, ... }: {
|
{ ... }: {
|
||||||
programs.zed-editor = {
|
programs.zed-editor = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = null;
|
|
||||||
extensions = [
|
extensions = [
|
||||||
"basher"
|
"basher"
|
||||||
"clean-vscode-icons"
|
"clean-vscode-icons"
|
||||||
"caddyfile"
|
|
||||||
"clojure"
|
"clojure"
|
||||||
"dockerfile"
|
"dockerfile"
|
||||||
"earthfile"
|
"earthfile"
|
||||||
|
|
@ -25,74 +23,42 @@
|
||||||
use_modifier_to_send = true;
|
use_modifier_to_send = true;
|
||||||
default_model = {
|
default_model = {
|
||||||
provider = "zed.dev";
|
provider = "zed.dev";
|
||||||
model = "claude-sonnet-4-5";
|
model = "claude-3-7-sonnet";
|
||||||
};
|
};
|
||||||
default_profile = "minimal";
|
default_profile = "minimal";
|
||||||
};
|
};
|
||||||
buffer_font_family = "FiraCode Nerd Font";
|
buffer_font_family = "FiraCode Nerd Font";
|
||||||
buffer_font_size = 11;
|
buffer_font_size = 11;
|
||||||
features = { edit_prediction_provider = "zed"; };
|
features = { edit_prediction_provider = "zed"; };
|
||||||
git_hosting_providers = [
|
|
||||||
{
|
|
||||||
provider = "forgejo";
|
|
||||||
base_url = "https://code.millironx.com";
|
|
||||||
name = "Milliron X Code";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
provider = "forgejo";
|
|
||||||
base_url = "https://codeberg.org";
|
|
||||||
name = "Codeberg";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
languages = {
|
languages = {
|
||||||
Caddyfile = {
|
Julia = {
|
||||||
tab_size = 2;
|
formatter = {
|
||||||
formatter.external = {
|
external = {
|
||||||
command = "${pkgs.caddy}/bin/caddy";
|
command = "julia";
|
||||||
arguments = [ "fmt" "-c" "-" ];
|
arguments = [
|
||||||
|
"--project=@JuliaFormatter"
|
||||||
|
"--startup-file=no"
|
||||||
|
"-e"
|
||||||
|
"using JuliaFormatter; print(format_text(String(read(stdin))));"
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
Julia = { formatter = { external = { command = "jlfmt"; }; }; };
|
|
||||||
LaTeX = {
|
LaTeX = {
|
||||||
formatter = {
|
formatter = {
|
||||||
external = {
|
external = {
|
||||||
command = let
|
command = "tex-fmt";
|
||||||
latexindent = (pkgs.texlive.combine {
|
arguments = [ "--stdin" ];
|
||||||
inherit (pkgs.texlive) scheme-minimal latexindent;
|
|
||||||
});
|
|
||||||
in "${latexindent}/bin/latexindent";
|
|
||||||
arguments = [ "-m" "-tt" "-l" "-" ];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
Nix = {
|
|
||||||
formatter.external.command = "${pkgs.nixfmt-classic}/bin/nixfmt";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
lsp = {
|
lsp = {
|
||||||
nil = { settings.nix.flake.autoArchive = true; };
|
nil = {
|
||||||
nixd = {
|
initialization_options.formatting.command = [ "nixfmt" ];
|
||||||
settings.options.home-manager.expr = ''
|
settings.nix.flake.autoArchive = true;
|
||||||
(builtins.getFlake (builtins.toString ~/.config/home-manager)).homeConfigurations."millironx@${hostname}".options'';
|
|
||||||
};
|
|
||||||
texlab = {
|
|
||||||
settings.texlab = {
|
|
||||||
build = {
|
|
||||||
onSave = true;
|
|
||||||
forwardSearchAfter = true;
|
|
||||||
};
|
|
||||||
forwardSearch = if pkgs.stdenv.hostPlatform.isDarwin then {
|
|
||||||
executable =
|
|
||||||
"/Applications/Skim.app/Contents/SharedSupport/displayline";
|
|
||||||
args = [ "-r" "-g" "%l" "%p" "%f" ];
|
|
||||||
} else {
|
|
||||||
executable = "/usr/bin/okular";
|
|
||||||
args = [ "--unique" "file:%p#src:%l%f" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
tinymist = {
|
tinymist = {
|
||||||
initialization_options = { preview.background.enabled = true; };
|
|
||||||
settings = {
|
settings = {
|
||||||
exportPdf = "onSave";
|
exportPdf = "onSave";
|
||||||
outputPath = "$root/$name";
|
outputPath = "$root/$name";
|
||||||
|
|
@ -115,28 +81,5 @@
|
||||||
ui_font_size = 16;
|
ui_font_size = 16;
|
||||||
wrap_guides = [ 80 92 120 ];
|
wrap_guides = [ 80 92 120 ];
|
||||||
};
|
};
|
||||||
userTasks = [
|
|
||||||
{
|
|
||||||
label = "latexmk (project)";
|
|
||||||
command = "latexmk";
|
|
||||||
args = [ "-synctex=1" "-pdf" "-recorder" ];
|
|
||||||
cwd = "$ZED_DIRNAME";
|
|
||||||
tags = [ "latex-build" ];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
label = "Open Typst preview";
|
|
||||||
command = "${
|
|
||||||
if pkgs.stdenv.hostPlatform.isDarwin then "open" else "xdg-open"
|
|
||||||
} http://127.0.0.1:23635/";
|
|
||||||
use_new_terminal = true;
|
|
||||||
allow_concurrent_runs = false;
|
|
||||||
reveal = "never";
|
|
||||||
reveal_target = "dock";
|
|
||||||
hide = "always";
|
|
||||||
shell = "system";
|
|
||||||
show_summary = true;
|
|
||||||
show_command = true;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
57
secrets.nix
57
secrets.nix
|
|
@ -3,61 +3,28 @@ let
|
||||||
anderson-millironx =
|
anderson-millironx =
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM8G6okW/vpl3DTBwL64aPb+oxJsr2Wl6KzHYsLPecBc millironx@millironx.com";
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM8G6okW/vpl3DTBwL64aPb+oxJsr2Wl6KzHYsLPecBc millironx@millironx.com";
|
||||||
bosephus-host =
|
bosephus-host =
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFurtduZAml+4c1lw8JUDZqEgV09O1DGiDDZvbGIIxPh root@nixos";
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIxTfeg+GZsfmG8TuEV1xW1gXknAIKzZ3UjZ3guRY+EW root@nixos";
|
||||||
bosephus-millironx =
|
bosephus-millironx =
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILrunjDq+pAuxHEdfA8BUbBClZmj3F/5HHNpUh97hFoG millironx@bosephus";
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKaDPqRJHoqgY2pseh/mnhjaGWXprHk2s5I52LhHpHcF millironx@bosephus";
|
||||||
corianne-host =
|
odyssey-millironx =
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHKKkucebeb1GcerOZAAs5GQsgTS8kXw5W41b9Fy9+hp root@corianne.local";
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN9Aj7BtQp1Roa0tgopDrUo7g2am5WJ43lO1d1fDUz45 millironx@odyssey";
|
||||||
corianne-millironx =
|
corianne-millironx =
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOgL2lO9RJBdQYANoxGyWXcNKi5/NZkRHHo/rNqaYMc/ millironx@corianne";
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOgL2lO9RJBdQYANoxGyWXcNKi5/NZkRHHo/rNqaYMc/ millironx@corianne";
|
||||||
mcentire-host =
|
harmony-millironx =
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINT51tQgsKzTIQc9WSQj01h/gPRvAD3k9jRhXppY7xmd root@nixos";
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFBYxsCkw+ObDzIvU8z/rSlYcQx0JIt1bCVxKcDxeNNZ millironx@harmony";
|
||||||
mcentire-millironx =
|
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOdC6eNx2nBi3PWK/n4GJMbVf+NlQJv13aUqxse/h1kL millironx@mcentire";
|
|
||||||
odyssey-millironx =
|
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKM5Q2zl3b91j+foqcVeQT+wb5DFEp+MbgotTTaKqZZi millironx@odyssey";
|
|
||||||
system-administrators = [
|
system-administrators = [
|
||||||
anderson-millironx
|
anderson-millironx
|
||||||
bosephus-millironx
|
bosephus-millironx
|
||||||
corianne-millironx
|
|
||||||
mcentire-millironx
|
|
||||||
odyssey-millironx
|
odyssey-millironx
|
||||||
|
corianne-millironx
|
||||||
|
harmony-millironx
|
||||||
];
|
];
|
||||||
|
|
||||||
in {
|
in {
|
||||||
"secrets/ansible-vault-password.age".publicKeys = system-administrators;
|
|
||||||
"secrets/authentik.toml.age".publicKeys = system-administrators
|
|
||||||
++ [ mcentire-host ];
|
|
||||||
"secrets/borgmatic-passphrase.age".publicKeys = system-administrators
|
|
||||||
++ [ mcentire-host ];
|
|
||||||
"secrets/borgmatic-ssh-config.age".publicKeys = system-administrators
|
|
||||||
++ [ mcentire-host ];
|
|
||||||
"secrets/darwin-policies-json.age".publicKeys = system-administrators
|
|
||||||
++ [ corianne-host ];
|
|
||||||
"secrets/fireflyiii.toml.age".publicKeys = system-administrators
|
|
||||||
++ [ mcentire-host ];
|
|
||||||
"secrets/freshrss.toml.age".publicKeys = system-administrators
|
|
||||||
++ [ mcentire-host ];
|
|
||||||
"secrets/immich.toml.age".publicKeys = system-administrators
|
|
||||||
++ [ mcentire-host ];
|
|
||||||
"secrets/millironx-books-s3.age".publicKeys = system-administrators
|
|
||||||
++ [ mcentire-host ];
|
|
||||||
"secrets/millironx-music-s3.age".publicKeys = system-administrators
|
|
||||||
++ [ mcentire-host ];
|
|
||||||
"secrets/millironx-photos-s3.age".publicKeys = system-administrators
|
|
||||||
++ [ mcentire-host ];
|
|
||||||
"secrets/navidrome.toml.age".publicKeys = system-administrators
|
|
||||||
++ [ mcentire-host ];
|
|
||||||
"secrets/network-information.age".publicKeys = system-administrators
|
"secrets/network-information.age".publicKeys = system-administrators
|
||||||
++ [ bosephus-host ];
|
++ [ bosephus-host ];
|
||||||
"secrets/peertube.toml.age".publicKeys = system-administrators
|
"secrets/pihole.age".publicKeys = system-administrators ++ [ bosephus-host ];
|
||||||
++ [ mcentire-host ];
|
"secrets/ansible-vault-password.age".publicKeys = system-administrators;
|
||||||
"secrets/redis-immich-password.age".publicKeys = system-administrators
|
"secrets/darwin-policies-json.age".publicKeys = system-administrators;
|
||||||
++ [ mcentire-host ];
|
|
||||||
"secrets/redis-password.age".publicKeys = system-administrators
|
|
||||||
++ [ mcentire-host ];
|
|
||||||
"secrets/redis-peertube-password.age".publicKeys = system-administrators
|
|
||||||
++ [ mcentire-host ];
|
|
||||||
"secrets/vaultwarden.toml.age".publicKeys = system-administrators
|
|
||||||
++ [ mcentire-host ];
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,13 @@
|
||||||
age-encryption.org/v1
|
age-encryption.org/v1
|
||||||
-> ssh-ed25519 il3lzQ gG2K4w+Ncxzlo7I016D66Qli9ZXO0tJZx24bd8W3i3c
|
-> ssh-ed25519 il3lzQ Ni2CHjeijXHfF62cUqVTm8MAOn6rRg8UrhqN6xvdkyk
|
||||||
Uh25eTs8tCylMWLS5y/6+nGDJi5w0hMX42Vv9EkPOLQ
|
DsT0Ysx88FlCLeRzoOGctX7KqatX9/UCr5WdtdLJAf4
|
||||||
-> ssh-ed25519 Qoav5g qpN7AW+7un/T5Kaowj9wynv6mvGjPxZ6OSyE1Df530s
|
-> ssh-ed25519 1g/xww jRn91F29sISMyi41anAlzVCzt1t1DnUqxtryqkTQPlM
|
||||||
aZl3Reu0I0OTWD7UdJkX980CYU7+CvztM/Y6VhkwsHg
|
cysgZLQR0YhiJYXBl59DjKbm+N8FnjA46wkQtnAzBFA
|
||||||
-> ssh-ed25519 dbKeHw NeLt5KtTWCCyXWo7juyTvUbBPOP2str0cUGVrekTa3g
|
-> ssh-ed25519 +kBihw t6wlSnDKGgSzGhNJnryXVbDR40DATaV3fHovtI/u7zo
|
||||||
05KPe9UCyftByc2yPXWaR6nunFOHJs7TDXhp95MAWKU
|
zOyCZtzfLKeer9K6SMpfTxn6El4HB7gQFQqLOxIYB5U
|
||||||
-> ssh-ed25519 3qPtug YgmmVbVRXtm8v0PMGEcJNe6JxyaGGzAYg8UAFXJbG1M
|
-> ssh-ed25519 dbKeHw cn+8WTwis58bYm2pfEra6LeLvzEZ8GhZrOEeN+kkhCM
|
||||||
j0VTO1sov6ehwHCJm7VvcJw6tPmO5BltYF52QN0L7Ds
|
fnlUAj8JtG8+r7Cj8xYUgF+JM6Pwqawn4sGI1LOeN78
|
||||||
-> ssh-ed25519 FRQvIA e7h4+bKea5jnQsd2FWRhqBcXFxRkQ7PIlst2AISU0Ts
|
-> ssh-ed25519 Svnssw zmDBR8TdRZ9NzNhwPYRN6c8naTxAkULyUZpKgk7Gshk
|
||||||
p23BmQBf4IFvRWIFbH+pv343QWiFjALRzXbtsMX4KAc
|
0XCwpegEIlGXhnzLLUtmciKQiYiZRgnSOSvCcYeXXk8
|
||||||
--- 0gDFsGuZmMXbL1I80gHVtNnosSUqMEiE+xWvy5t3x3I
|
--- D/lZ36n5sVste2NWfdOx8/klPh0CTmMjVQN74KIqDRY
|
||||||
î.uÙæ0DT>áâÝ™<C39D>KйþEË0*
ðjÊ 3
|
]%得ヌC}<7D>弡鶲ネモ"vホネ#<23>アェ釋「tュ、ワ_Q;^*!サ+<+ア瑁詞ネdBラ/Kメ<4B>ノ`
|
||||||
™Œ)ë]DÜÙêy»ýi”’wYyš}
|
|
||||||
.øßóé{
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
age-encryption.org/v1
|
|
||||||
-> ssh-ed25519 il3lzQ chVwBwTYt6dAYZPFZUNNsF1NW0VkycNPHZ8RPLCnyEY
|
|
||||||
aMt9rOJuwYdb8XccnIrJ/yZYDxIQFDOZ3zOFweSoo2s
|
|
||||||
-> ssh-ed25519 Qoav5g OHv7JuUA3awyCAlDvh8iA1kYKJxVzM8ykpB69/e5Bg8
|
|
||||||
rdJ/PvI7cdDwU4mNTeugiX7zVJ6ng8nGaTQ4UrLUF5E
|
|
||||||
-> ssh-ed25519 dbKeHw pnUZoFIEoElzAnpmNtUIWSzEtwZHmnFoCjDog7MCMXM
|
|
||||||
wKwrG3DTQcPJ644mbIpwAP1ey3UDO3SKDdGOb1N72Gc
|
|
||||||
-> ssh-ed25519 3qPtug z0c+ulm6T5aahAYiQ83JPrn80wr9ebP25XosPFBChDo
|
|
||||||
+MieUtLK9FFov7S1zfqXxGfA6qm7maGa45EvzKWbv9c
|
|
||||||
-> ssh-ed25519 FRQvIA HutWJKyryB3rCrQsgklhGhXV1V51N11bYR3uxCQnkWg
|
|
||||||
4Ewdwph4wGh3PHqnGT4l+0mrih7A/8hSlJei5ZD+sl0
|
|
||||||
-> ssh-ed25519 +C0WRg b3OoHH4x6EXT6+tydgLqQDCIMqF0LQnUoiz6SRB6wnY
|
|
||||||
mbSaxs5mEuLDoJ3hMiFSYW6PNZCj8vjgDd+gPz+XQ08
|
|
||||||
--- QLgvimOYpWhRRslEIFutWtrzu1+0eMK4vOiTWa1HsoQ
|
|
||||||
d¤Ÿ¿[RA”;½0T›æ½VˆqX$Ù^L g!-øé+–‡óÉ<C3B3>;9Êpå¿á‰Mè Ú`þõúÒ‚ Óñ,¨½[S° ÛZÚ€Ž_VYŸQ)G#¸ƒ´Á$hoÙRXºè5F¾æúŒê
½!p¾ý*ÈÇ^ÔŽe&<£:-uÇr¡aþëqQÞ焞çk\o?tLèù\¼ŸhÙ;µŠ[ËPƒcg‰`GC†NE+&˜Çè¡S0žÊÍ݃
|
|
||||||
\ÅŠ`ÐT¼ÌT9cŽxs¥ƒ4:7aàCtZV¦’Cò÷¾®ð`bz<>¶ŽÄcU7žŽçqŒáL<C3A1>…ƒ^@?‰úk~ª84Ø)çÜ›è$¾€¯FÅRÜüúnci’’^‡¯zÐʸTçjª ó»Ôå£õi"½ï<eàž£–¢Š;‘ÉI‹©å¸èàñks}s´DÜ—5î
|
|
||||||
ü¿»‡Qš·vå’©»X]HàÛD\+fYë^çQ–+ŒüŒ
|
|
||||||
àcÈ„„J[¥ãôw Zïæõžæ±HD¬¯Ó™úÝͨ§%Væò?ÛÛ;çÞÓ)éÍ€ðÆdÖg“+á¹
žêê’½<15>¯IsØS…¸£ç•Îd|¶
|
|
||||||
¥6£×Ô>Åï<͈¦ã¶ûó¬µ!Pàâ4<>!<21>ûñÄ}“ÅwÈ]‡DÛiñœ÷ØŠxÝMÑúÆ÷–¶ÐoÈ÷®Whÿºb‹Ÿ¡½;.–~ë<>2eICZÎâ-þ$¨ýÚb$jUE
|
|
||||||
gÌþ½BSYkÚÛE÷7“Ž*ßJãÉU[ËUÕq¤ÔkÒ¼Íal¤–pC ·ì4»u¬˜!è¥oìiÅÓ¾p‚Ÿnc_tÒ¿£¥ýÿ?öig¶Ù‘Ρܗ&øïÕ¢-Á¤-Ûm<>DLOíúMâ^ 7*%»«
|
|
||||||
\eQ^–ç*.<v
~ñ¢ç1y8oÁy`Z<04>%+=fSÄf| Ç›(üá¹ÆH)€q˜°]·8¬+éÿÈP±QÔ>’Ì •7_ºàY½N¡ZqìœN£'PQM_Ȫáu£ôåí$¾Šrª¢öÞÑôz›¸<E280BA>‹
Û.;à<
|
|
||||||
Û›c jÁÏ*40§ÉàmÖÜZ|/*T/:´¼
|
|
||||||
ò<EFBFBD>‡•3±m¸ÈEv“œ<E2809C>0†¡96ßeŠ(K}ÝZgUÕð°%•tÄ<74>’}»/t!O<>e%KîË¡M–®Ô-¬îËa¡üÛÆyµ¦<C2B5>Ž·3¼_D‡¹°.P’>'†¯;H!V<16>Š“]Á)(lysÛáÕÖ
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,16 +0,0 @@
|
||||||
age-encryption.org/v1
|
|
||||||
-> ssh-ed25519 il3lzQ J2O5tm8FwykSVE5NsBDfhSbvlbQjX0WMLoEXQzWaEjI
|
|
||||||
rd0Qv9FPN1/1Dg0XYPIzJ9cmCpBZFj8YYqwobS2d9sM
|
|
||||||
-> ssh-ed25519 Qoav5g kOvIfzk09psmJxzNXWuDQgt4nqnv1DFftE9rs+xIY0g
|
|
||||||
E+kJGvsh+pFPg0Cudjil4NYwIuGmwQeC+N7W/3X9/Ag
|
|
||||||
-> ssh-ed25519 dbKeHw VzzlW2SaVbBZy6LvstgroCIvVcfnAYUvnL833z75QD4
|
|
||||||
DBd2k5lclWgWq3K3FBeteGEdlHRE/+yYSeF+WR0gklM
|
|
||||||
-> ssh-ed25519 3qPtug EZ8q2muIjjYdBOlfQlP1qvCdIyDPMJK0t9KdIIZimA8
|
|
||||||
xchzaGEMgLtOmLhjTRtmHw07FVS26bMIXMDgGLJnvMo
|
|
||||||
-> ssh-ed25519 FRQvIA GIa9h2oEvu1VFy6lHCCNV+PZTODxw/vIIHDol+xgIn0
|
|
||||||
hOnFLpHtQ/ateSPFf9n+pUSmdSaJL0twRnSaGI0Cftw
|
|
||||||
-> ssh-ed25519 +C0WRg HX7YNeBy28lOjvJF1xSVfALm0w/ypLdHiarsxbm5Zjg
|
|
||||||
dvknR/6Ma4Iuv+TUlIUMbtFnUuNIHvMa2zTuJaCFT1w
|
|
||||||
--- Bx0Pk6zkC4t+N99Z8OZujsrp52e/o8rzkfbeIAuTdT8
|
|
||||||
mÌ-¹™Ÿª—X$ùßüuTJ³’Â$}ɽ‹‘=<3D>–ªmå
éÍ|TÇÍpˆ2€õº«ß©2b}JüØ‘{¾á”ôÛV3¯
ȯVXmõÓ¤Iÿ,¢².Ÿew©oaÛtŠ7Ñå†7õ‰}ÑR¥Ç2aìOòFŠbæ<62>.M'IZPº¢OBzÙÇþ2˜Á[‰âÖnÛ¹wåm™tãçÜCÈ?Ñ}6mo;™dÃë¢i`5‰êD]2ª•OÔòóuÉ.
VKh
|
|
||||||
<EFBFBD>Ô>éÙäù8ªàù÷ù<>ÿЗ=<3D>¹¿ëöLch×ï@¡Ší”“åkjù`Jn»Ç7õ<37>iãN§HAP@
t
|
|
||||||
Binary file not shown.
|
|
@ -1,15 +0,0 @@
|
||||||
age-encryption.org/v1
|
|
||||||
-> ssh-ed25519 il3lzQ n1OQY7WHrgjVLbLJe3NrPgeoBOwrNNN015pEwIJBVAc
|
|
||||||
TfWN0cBYodnwT86gaaHRkJTfpCMWyh55T5ArzFxy8uU
|
|
||||||
-> ssh-ed25519 Qoav5g E6ZGpt5/waFDyXLLyV+Q4Zd8OeUiisJISShimFQVbAg
|
|
||||||
uzISpPwDXu6jMc+D+joIK3cJzaGix6RSrDQ2nkqcGCU
|
|
||||||
-> ssh-ed25519 dbKeHw fy7YQS6dYHaOia3/ABMpF0EjvLAkKcjWigoYRioG/1c
|
|
||||||
DBDD++PiU/epgY/JUXfhy3kt46JXTs2D+5ijxVNONuA
|
|
||||||
-> ssh-ed25519 3qPtug iBhCONkntdU977HrT4rFTHgNqO2Im3FwzxmqOwZ9hx8
|
|
||||||
hZgpXL7j06vk3kKLIVXwGbh4E+tPgrpTm0gHTfZwxcE
|
|
||||||
-> ssh-ed25519 FRQvIA YI1txEuUyOU4MtzUcWYc9+fJ1FrNOmLlkkZo9X5MVU4
|
|
||||||
b9f/AuFwecwFOo9prS1GxLQQ/3caWk/2mLGeZQJE63k
|
|
||||||
-> ssh-ed25519 +C0WRg PkkasYZwbyN0HQWEcklpFpvpmvf4/zaHFHRU6l/T6kY
|
|
||||||
aQwpKj7cBNaS1ecHWv7RsNgw7flQYSm4OCSocLdBBzo
|
|
||||||
--- J4+qUzSBeBIpp/gDp8GX7/feuO2lCeft+7SZjfV7YS0
|
|
||||||
ô`<60>ÁT·k2Ô6BInïªÒ›f„¨×Z›ç킼k…Ú‘Ì#š£6 7ME?Œ¶òF~!aØn a~FL£íÄý¡·…èTŒ:G¢táË—>²À'O©
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
age-encryption.org/v1
|
|
||||||
-> ssh-ed25519 il3lzQ L3OLJwCbSgLewelx2MYb4yDl4hkpNE/j+LmVIdIp3CU
|
|
||||||
v6heZ3+NL0VkwuK15F3xmv22rljX066MJB03VLt3LyU
|
|
||||||
-> ssh-ed25519 Qoav5g Cvyx2Ut6a/KZtvUAu961Auqsd+92jE1pGbDvbJ8ou0w
|
|
||||||
kwodVfF7EPze0mQvYrMNAg8YGzy3alWyMi8PTvUOyPc
|
|
||||||
-> ssh-ed25519 dbKeHw fjkqFnMw5NVz2oTBp2WlR/YCcIjidcBA2NNZCbrksgo
|
|
||||||
7Zsk2sSi1mAUdItJNtHeGach9lxwYBR5geq9PXPz1/U
|
|
||||||
-> ssh-ed25519 3qPtug 8GF1sCHAugn/6VH3hrRQgnzz4tu9+Luj+wp0B/2fQz0
|
|
||||||
EHP5gICmuE2Yai2wJvwI7KYUcAHQWgf1P+P+xq23e3Q
|
|
||||||
-> ssh-ed25519 FRQvIA 0QmMjoGHL6EUw5W1tZktQczseLlE40mLaEwADNPM3jQ
|
|
||||||
S+75VFsmpr4ooZRaOToGdxg+WSa70zPUE9SXQxrzUjE
|
|
||||||
-> ssh-ed25519 +C0WRg ePl8ulb0e3sasvqjxUW7CfiRFSfVTHcje2bcHFTk30w
|
|
||||||
O0hFVifiygtXh7xgPhMRb3OkMoHupy9GQ3kSkalhFrU
|
|
||||||
--- h/+rwjqsgJcN1Tr4ZbmpQahNXO9mtzLfdOu8WCb/0JM
|
|
||||||
hC§¡`Õ5»Lk¨%iZì4/ĺ¹[<5B>1j"Åæ49ÍŒÂ' ú¹Á …^›ä¹á·b;º Ÿ¤…zi%ôvº ÜÌÙPîÙn+¿»;¤"[mÔÓ‘7‹¸<E280B9>—
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
age-encryption.org/v1
|
|
||||||
-> ssh-ed25519 il3lzQ IIIDzyMnmDnefMaLuNLE6N8nhocZcJqpfmUPvDBzrGY
|
|
||||||
A4Yjwnl8xf+7aqP6D+XJYCUlef5oBF7Dexg4PbI9GS8
|
|
||||||
-> ssh-ed25519 Qoav5g /liTL1E+0ifHMo37z938l3jtGbHNoTYrOZ3W7N5XUCE
|
|
||||||
AyOM2lzlIi+w+SRcnC8yWeDTjbRROnw0Dchl1smR3P8
|
|
||||||
-> ssh-ed25519 dbKeHw iyGKNA8zFVpY1Na51pWX5CuNU/Ba+5032dQywcOuIkY
|
|
||||||
RQ0MWsPUFCtaB+xDPEYbIntaRzd88rAkv8vUWg1NniY
|
|
||||||
-> ssh-ed25519 3qPtug EvdfmB3UcxrJ+nhD3HRp6AmHayt1t77Td3y62doScjY
|
|
||||||
RAq8xqAlcOvYVF1bY76fnyUksRmfZ5fH3otBwfE7abg
|
|
||||||
-> ssh-ed25519 FRQvIA glZbqImvS+WldS975VBRAusuDsARgVIPbh7CyHnZvlo
|
|
||||||
SSwkaxzbUlm/nyycLeKCJwoUjDFlD1/jOANHLy6RkiI
|
|
||||||
-> ssh-ed25519 +C0WRg Hk89txDODsNY0R/4KuHvr77XRuuoeR+xlwgspjuw8h0
|
|
||||||
uizmodROqR+kkZGHbiLJLswg3OhP2afpvRoKsmpYjJk
|
|
||||||
--- zdE6Xh7aGHLa5L8OmSVLwP/LuJFNBRT/wUVlfVTGMY4
|
|
||||||
;<3B>”ŸFŽ9es3õr<C3B5>÷Ç]`6|ÁÎúâkVí…›ë;QëÄÊ€qÆ<71>±Ì!†;,ø½º'3ð¸µY[Û«ñ<C2AB>A@4‚ÊhþPH|¾wYWc¨W»ƒ™™œ½ÇTú±'ôym÷`ß¼l+ŒÝ-0L£.Ê~Þ¼,WJ‰~n€6<E282AC>›»d—z:•÷nª½1E
|
|
||||||
Binary file not shown.
|
|
@ -1,19 +0,0 @@
|
||||||
age-encryption.org/v1
|
|
||||||
-> ssh-ed25519 il3lzQ X4wTfjY1YkaFhWu9qKFz0YOcj/AmTbi52J2bs12HvxA
|
|
||||||
3Czx+WG8aBzgtECaRN8+Vi6RaegAFvB35S24UV8aZN8
|
|
||||||
-> ssh-ed25519 Qoav5g 4lgXMVjj//dhHJq1cBq1NPi/wtlbBV0LtnGjOaGOfWs
|
|
||||||
5WxCQoigFychLgojxa8LFF+QF9Rl4zvgd71JMs6wLdM
|
|
||||||
-> ssh-ed25519 dbKeHw asKjMxRTTxV9vgj2nPDHg71ZFhjZosubJ3TIBWbZr28
|
|
||||||
IGAYJ4bXk2krbibf4ulGcRs8gAflLpvFpNw04rvpL2U
|
|
||||||
-> ssh-ed25519 3qPtug CClSIx04Ec/nDUB0pJ3FinZG4ENvEheUb3kl4pE3e0s
|
|
||||||
ozFOacyF8nJ0UQNhM9xY2cHDZ4y5B2DSMDqOMnNQceE
|
|
||||||
-> ssh-ed25519 FRQvIA Va4MJBepZrozHgx2pvD3swSF/vo66bPvR6jdnXDu4RE
|
|
||||||
bD8vxvx6Dda0Cfcl1VeogN70vsJcrTg9/oHr9RjECkE
|
|
||||||
-> ssh-ed25519 +C0WRg 6BxuX4cBo2d4ImIg9rWH4Q2qkYojROeOur9zdFk+r14
|
|
||||||
JeFOuop6XU2WQM+eVyuNPMMKnVbhWU4/SVZVKlGGgHo
|
|
||||||
--- quo/T1+XbfB0mlyUOFZaPBywX0ZYo9p+VeATWe+9ufE
|
|
||||||
aµ¯²²®
|
|
||||||
CY™›w”¼ƒrŸ9“²Oªí<C2AA>UÞ<55>ìô‚öõJ°¥è²ä1¯E“5ù沇4«ò›FC¡<43>³aj
y),%›X(¼Å8e*™ªÙp+§?ÃL( -ψ/H¦|CìÅõ`’üÏ›šf¤¢}ž9pÕùï¸u'<27>æOèPÀo…ÌîÑ3à·B^fúµxÁ¡<C381>Ûó¾^C£§û´ÉÐ!– ¤i‚kr>Ž»+gi>!åbíb¡Ž;J驃£÷ˆÊúçÕU׋€î,<2C>ü7/ÂàÔÆ¿0H¦¨FÅô
|
|
||||||
×7
`<60>9MÔ AkÍrZ°^;‹'Úâ‚·²#T±àΚínŠª>~“íºáø²³lY«n<C2AB>+òÊ+š$ê]Ô©½bų?»š²¨w#˜×FTÉjF´‡¬´Gã÷¢¡!áf}<1C>éüý|"<22>s##Šo›ÛÑ.ï°*<2A>•!^N‘xæ¦c^ˆ—yô“Náz <09>©ÚøSqÌš¿ñ5ß=%}kIèdO¡´h¨9KÈÐF†gÈvY²‚ÈiŠ›º>Zu
|
|
||||||
m)bY9Õ)½WKÇ“&“³7)¸ÔX0±qnA
=Àa…¦ðµø?#muÒ÷SPòʰ¥4jdñÛ\RŸ„'ð›"td/ÁBÝ<42>Vä<>&ŠÏPé_
ùS&^RÉÅ)Hgç¶ŽZg<5A>"
|
|
||||||
·§,ËE'éQý¡ÇôQ,sJ.E>c+r
Nè\Ú›²ß”<C39F>—"ÙŠ¯Í6yæàz@X]¥fÛ¬ÒÔê}…g¯™!Å)ÊXà-ñ1’æq<C3A6>¾œ7ç#,øO‰T·»Ä ™€¹Úƒ<²±*báà§qÆ_„$‡Ú‰Ÿ¢|“Ô¢2[cJ};¸Î¼î
»ÍмÂcîÎ ÂÌÙøOAÐs:]dª2ØNQ5öÙXį09`5H¼Ù¦zŽ„¢ƒ™q<E284A2>ЫŽN嬖*öÛÀßÄìLÐl™Y°ÊïžËíàA¬zò/+¦m8}±*„eaù¼
îlÈÝ7EÎÛ6ÏQ[²¨#òrÞ[s溽z{²t—É$©‡~<7E>yê'ÆJwÂ_íäÒL”ÒçÕ¨ßräÆS(0s?ØÁ,‰ìtqÐâ/mïT¶RP6øTl$[¤
|
|
||||||
15
secrets/pihole.age
Normal file
15
secrets/pihole.age
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> ssh-ed25519 il3lzQ Q+/uqZhUWs5pb5T1ocD+/qTSo4DJbd/W1exruQ34zAE
|
||||||
|
8HFRvEblGVrkoVaqAl/Af6wrDn6A+3unZIMBipEkwgA
|
||||||
|
-> ssh-ed25519 1g/xww PqXxTvLaF6ZlcVov81VrVH130jFh2iGmHPRtBYV4ME4
|
||||||
|
1VBknQzaNZyoz2wvgKX+IZGaOEnJ1xGvxPYxq10ar/U
|
||||||
|
-> ssh-ed25519 +kBihw QXNxY9OQeIM98OqmHoa/S2kMZqSX+ndgxGyCJpHJ+gg
|
||||||
|
b3DmfUswyPQ09sp57v3QMNEF/Ka3w9Qj2s1kGUSinmQ
|
||||||
|
-> ssh-ed25519 dbKeHw 5GzjKgjUX5e6Net7voWBykC17zRcdSFDFbDsSwp5FAU
|
||||||
|
GwTEg3YR9HdcQHPg+XjP2Lg1BpcWA4VunbZSBdxVaYU
|
||||||
|
-> ssh-ed25519 Svnssw imRjD5CJu/jOac3t/APHbYBnsyJVQdebR6K52A6GdwM
|
||||||
|
n+Q9kEEkYRBuEzWlSwbjJNsjF8uKloeUEWYxHa29B4U
|
||||||
|
-> ssh-ed25519 jb0ALQ 4qbGIofHcyhJVfL24peGqqzg0tFdxbWBHJFenwehIAI
|
||||||
|
Ta3ye4quyHvvE+2CGZwYvQMwWfdrLIdqADLvJYhllPY
|
||||||
|
--- 3hbht7PYqFafVmcQWQwv3q2gUXM8HXajtmAaMnrh59s
|
||||||
|
+óX9ð¾84R2ƒª,òôˆ±¨(#42ì#*, bùôŒç¦½Hã_z…œ…¨Í
}ß… ®ë›xñ‚7Aœ!<21>)ê)vʞ¨¨•W-÷¿eX-G‡<´¸@~â¢èEÜk¬?kG‘lQK¬4c&*JöÂå9V_Ä0ÕöµzÓ+ɰ¯CÞ
ÑžÀQ°ò«ÃGô§XÁ˜k¡g*£æð
-Àjƒö¼‚l½ú3¿‰1ÏJš´üM·OE†[=S
|
||||||
Binary file not shown.
|
|
@ -1,15 +0,0 @@
|
||||||
age-encryption.org/v1
|
|
||||||
-> ssh-ed25519 il3lzQ +3QKyGwA3YIugwmg9HB0V/t7cBVbAFjOlry6ZfvQbHc
|
|
||||||
WxWlzQCFZ3ZjMLOBNTvFnuTMF0OoBXkY6zn6I58uelE
|
|
||||||
-> ssh-ed25519 Qoav5g O7hK+ULznjDTYX0ey1cvHvbNETb9rNBl+3O17O8TAGU
|
|
||||||
d/d5s8wo//ILRoRIE899Ss3omRUa5NQ/nxRGNePnklc
|
|
||||||
-> ssh-ed25519 dbKeHw R5/LQXhrcQQgW/6zSCsAaCF/NIb+ZdO97477oqn0124
|
|
||||||
Q9XSQf6rPLHqQ8x00xWo7tq4yV3aQBj6XOBQacbSaF4
|
|
||||||
-> ssh-ed25519 3qPtug S5h30YhRhTe3zfqsEfKY9Tal4BRg9UcE5upgS6HTB0A
|
|
||||||
Zyr6C3FW4B0GCPfptO81qkG2F/BjhoV7amDDK2tjCnU
|
|
||||||
-> ssh-ed25519 FRQvIA 3G8iuKib32TZRCpQcveIcq9FW31XVjPAXDoK4VJkMgo
|
|
||||||
11UATLiVrvRLufKnaBv7/9Gacv4OWLFFUy+wn+qAntc
|
|
||||||
-> ssh-ed25519 +C0WRg +bh2U+siwCJ80GWYA6WPM2X9X/o/yNG1P2AhdVyGi2E
|
|
||||||
wgaRcvwl9Reo3KlpuYHmSnnQx0b+PvwpC8+zy0qCADE
|
|
||||||
--- rA+vwNaBF/mZmpoBH2Uh1+FnxhAUA1+kj3ei6am4Db0
|
|
||||||
w;wïkóf<C3B3>F½(z<>‹Ÿ¿U<C2BF>ü“ ¡Åå7‘¶v™·©Â{9 R:ºÁì–¦ÿiNIìut ±RÑŒL<.öŠ55|h:x> ŒîrW
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
age-encryption.org/v1
|
|
||||||
-> ssh-ed25519 il3lzQ uuX+vjN9kMAHh9hGjeCPqzIP93EFCBpk4RVQG6PewFE
|
|
||||||
glWR1c0s0pxqvNvEzZ82WL7S+TUA55if/FIOwiMVykY
|
|
||||||
-> ssh-ed25519 Qoav5g 6t8bcEOsz8tWsrKELmiZGj10asMvBWuFBoWV4f4cCi4
|
|
||||||
CoiDzRmN4JGYTqQoTTixEY1v6oNaZjCW8rzDvcrA+iM
|
|
||||||
-> ssh-ed25519 dbKeHw xV1Ls2Iga9Y1ZZ24utEHsM6gk8vPpaQ1sZiC+r6zMRA
|
|
||||||
DsETbzvC8swXS3ArF1ERsMk2ZhBGfOM202UnDW+RlTc
|
|
||||||
-> ssh-ed25519 3qPtug 9bs1ASzCep+cDIR2zzxiTVkCvcUrNwG+Qp4nlIr5fGg
|
|
||||||
CWzvA96wRmmGdg5jMak74G904H2vFcNEBOVFeGDIphU
|
|
||||||
-> ssh-ed25519 FRQvIA 7VR57CAWggNyvEc0AGdq9341z9tnM/pAGyESVrfSjnE
|
|
||||||
EqAv4Kv3INFjD2EQBjnxMCgGjcrrKJtU8n44t/WlqhM
|
|
||||||
-> ssh-ed25519 +C0WRg jNWg3MW5MLOCAUOavNmkanJJlpIRT9ohJzu039l0EkQ
|
|
||||||
xVkCVWf2nGYDV3nXeRytcLHMgKW6u7N35GxyOskfy+Y
|
|
||||||
--- wwMsEtkO7yFwiOxBR7rRFLROZMeamS25hkqTgGW8TJk
|
|
||||||
¨Cìl*¸÷ÉÌ<€!'±Ø0Ü—gA%V¾qMEªkgªÁ¹ £ñþ…ÑÐ~ó!Ùß8Ljþ¥há2…:l/æÙ*
|
|
||||||
Binary file not shown.
|
|
@ -1,8 +1,10 @@
|
||||||
$ANSIBLE_VAULT;1.1;AES256
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
33613635643765623937663135313833396162343134383466343966333964386364356134663264
|
65366137313461383534313965646333656565353061336361363661613033393264353661346337
|
||||||
3137633339396462633431316634623834646437646162360a626564313831373761636161656232
|
3838653162383134393463323631613439373663396363380a633339396236363962313333343465
|
||||||
35316566336232666336646231356665366633303530623961666465366163306166623336656364
|
31623961393532666136616438633734366261353866383264323730383432326635626637343739
|
||||||
3835353035333031620a633332376237336530343134623832363534383761616564616138363766
|
3235313062623637380a386235316437396534353261383832643165316565386263396664363962
|
||||||
30306361383462353361636161636335313461313835663362393839623735313738316465656537
|
62393364333335373631356161373263313930343565626433383539373030363662353630633933
|
||||||
66396635323432376530346532353238346139376261366237343763373535623364633731323830
|
63336333613965653635313637336437653139616564313861336332323739653865383531356233
|
||||||
333730373965613131336166626230333263
|
31373530343766343131346663656566363038643230343462336332323135323337353539303763
|
||||||
|
33366638393064323431323636346161343936643062323861313766613264336465326132333631
|
||||||
|
33306666383561653965303539313366653030663330393363363565333439383133
|
||||||
|
|
|
||||||
6
secrets_harmony.enc
Normal file
6
secrets_harmony.enc
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
|
38383539613238613864336630316433666436623334313334393762396536663530336264306661
|
||||||
|
3338616565316138616666343862366638643134343931320a633366363539326461346636373738
|
||||||
|
66393138653463663536313065623332383166386332303564323939336630333163623637386434
|
||||||
|
6538393966633731660a616437356233643234363562366433663437383439326161353330356331
|
||||||
|
63346432663036353332303266343361346266396437396131376531303265356233
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
$ANSIBLE_VAULT;1.1;AES256
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
61363033383536303833366237323662663236313163663033306138383162383062643830616466
|
30343638643335363463653231623566623961613534323261393639623865633964653634333562
|
||||||
6531636430613462646161343939343363663533373737340a613433363666353432383463356439
|
3838613035393661656362383736313561366466396439390a383162366362643364636335613664
|
||||||
33656266633131336565613433653062656563656637656464346232656238646339303961373265
|
39646137666437353762363764373562393736626530333336626261366232383063633732623238
|
||||||
6639643637303433380a393163366331373964353261383662656664643031626432366231346332
|
6531633638366335640a363461383535646663316533386137323966326237373836363561323462
|
||||||
34303964346137616233343930333331306363326332383465653163386539306430303965316437
|
66646635383137333834363165666365366235333734646364616637383363666239
|
||||||
30343333373565623431653436653832356366343937653136346535316166383262623730343831
|
|
||||||
62376532346237323465653261316339353034323633623632313630666531373839633665333637
|
|
||||||
34356162356565396564
|
|
||||||
|
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
||||||
{ config, pkgs, home-manager-quadlet-nix, ... }:
|
|
||||||
let
|
|
||||||
user = "audiobookshelf";
|
|
||||||
port = "28346";
|
|
||||||
stateDirectory = "/var/lib/${user}";
|
|
||||||
in {
|
|
||||||
age.secrets = {
|
|
||||||
millironx-books-s3-token.file = ./../secrets/millironx-books-s3.age;
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.systemPackages = [ pkgs.s3fs ];
|
|
||||||
|
|
||||||
fileSystems."millironx-books" = {
|
|
||||||
device = "millironx-books";
|
|
||||||
mountPoint = "/mount/s3/millironx-books";
|
|
||||||
fsType = "fuse./run/current-system/sw/bin/s3fs";
|
|
||||||
noCheck = true;
|
|
||||||
options = [
|
|
||||||
"_netdev"
|
|
||||||
"allow_other"
|
|
||||||
"use_path_request_style"
|
|
||||||
"url=https://us-east-1.linodeobjects.com/"
|
|
||||||
"passwd_file=${config.age.secrets.millironx-books-s3-token.path}"
|
|
||||||
"uid=${user}"
|
|
||||||
"gid=${user}"
|
|
||||||
"umask=0022"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.tmpfiles.rules =
|
|
||||||
map (d: "d ${stateDirectory}/${d} 1775 ${user} ${user} -") [
|
|
||||||
""
|
|
||||||
"config"
|
|
||||||
"metadata"
|
|
||||||
];
|
|
||||||
|
|
||||||
services.borgmatic.configurations."${config.networking.hostName}" = {
|
|
||||||
source_directories =
|
|
||||||
map (d: "${stateDirectory}/${d}") [ "config" "metadata" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.caddy.virtualHosts."books.millironx.com".extraConfig = ''
|
|
||||||
reverse_proxy http://127.0.0.1:${port}
|
|
||||||
'';
|
|
||||||
|
|
||||||
users.users."${user}" = {
|
|
||||||
group = "${user}";
|
|
||||||
isNormalUser = true;
|
|
||||||
home = stateDirectory;
|
|
||||||
createHome = true;
|
|
||||||
linger = true;
|
|
||||||
autoSubUidGidRange = true;
|
|
||||||
};
|
|
||||||
users.groups."${user}" = { };
|
|
||||||
|
|
||||||
home-manager.users."${user}" = { config, osConfig, ... }: {
|
|
||||||
imports = [ home-manager-quadlet-nix ];
|
|
||||||
|
|
||||||
home.stateVersion = "25.05";
|
|
||||||
|
|
||||||
virtualisation.quadlet = {
|
|
||||||
autoUpdate.enable = true;
|
|
||||||
containers.audiobookshelf = {
|
|
||||||
autoStart = true;
|
|
||||||
containerConfig = {
|
|
||||||
image = "ghcr.io/advplyr/audiobookshelf:latest";
|
|
||||||
environments = { TZ = "America/New_York"; };
|
|
||||||
volumes = [
|
|
||||||
"/mount/s3/millironx-books/audiobooks:/audiobooks:U"
|
|
||||||
"/mount/s3/millironx-books/podcasts:/podcasts:U"
|
|
||||||
"${stateDirectory}/config:/config:U"
|
|
||||||
"${stateDirectory}/metadata:/metadata:U"
|
|
||||||
];
|
|
||||||
publishPorts = [ "127.0.0.1:${port}:80" ];
|
|
||||||
addHosts = [ "auth.millironx.com:host-gateway" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,227 +0,0 @@
|
||||||
{ config, pkgs, home-manager-quadlet-nix, ... }:
|
|
||||||
let
|
|
||||||
user = "authentik";
|
|
||||||
state-directory = "/var/lib/authentik";
|
|
||||||
port = "9000";
|
|
||||||
|
|
||||||
in {
|
|
||||||
# Secrets are translated in the system NixOS scope, but performed by the user,
|
|
||||||
# via a user systemd unit, so are available in the user's Podman secrets
|
|
||||||
age.secrets = {
|
|
||||||
"authentik.toml" = {
|
|
||||||
file = ./../secrets/authentik.toml.age;
|
|
||||||
owner = "${user}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
millironx.podman-secrets.authentik = {
|
|
||||||
user = "${user}";
|
|
||||||
secrets-files = [ config.age.secrets."authentik.toml".path ];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Podman, unlike Docker apparently, does not automatically create mount points
|
|
||||||
# within folders, so every mounted folder needs to be specified here.
|
|
||||||
systemd.tmpfiles.rules = [
|
|
||||||
"d ${state-directory} 1775 ${user} ${user} -"
|
|
||||||
"d ${state-directory}/database 1775 ${user} ${user} -"
|
|
||||||
"d ${state-directory}/data 1775 ${user} ${user} -"
|
|
||||||
"d ${state-directory}/media 1775 ${user} ${user} -"
|
|
||||||
"d ${state-directory}/certs 1775 ${user} ${user} -"
|
|
||||||
"d ${state-directory}/custom-templates 1775 ${user} ${user} -"
|
|
||||||
];
|
|
||||||
|
|
||||||
services.caddy.virtualHosts."auth.millironx.com".extraConfig = ''
|
|
||||||
reverse_proxy http://127.0.0.1:${port}
|
|
||||||
'';
|
|
||||||
|
|
||||||
services.borgmatic.configurations."${config.networking.hostName}" = {
|
|
||||||
source_directories = [
|
|
||||||
"${state-directory}/data"
|
|
||||||
"${state-directory}/media"
|
|
||||||
"${state-directory}/certs"
|
|
||||||
"${state-directory}/custom-templates"
|
|
||||||
];
|
|
||||||
|
|
||||||
postgresql_databases = [{
|
|
||||||
name = "authentik";
|
|
||||||
psql_command =
|
|
||||||
"/run/wrappers/bin/sudo -iu ${user} ${pkgs.podman}/bin/podman exec authentik-db psql --username=${user}";
|
|
||||||
pg_dump_command =
|
|
||||||
"/run/wrappers/bin/sudo -iu ${user} ${pkgs.podman}/bin/podman exec authentik-db pg_dump --username=${user}";
|
|
||||||
pg_restore_command =
|
|
||||||
"/run/wrappers/bin/sudo -iu ${user} ${pkgs.podman}/bin/podman exec authentik-db pg_restore --username=${user}";
|
|
||||||
}];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Create a dedicated user for this service
|
|
||||||
users.users."${user}" = {
|
|
||||||
# Group is technically not mandatory, but NixOS complains that an unset
|
|
||||||
# group is "unsafe." The group has to be declared below
|
|
||||||
group = "${user}";
|
|
||||||
|
|
||||||
# System users don't have a shell. For security purposes, that *would* be
|
|
||||||
# superior, but that means that, e.g. borgmatic can't `sudo` into the
|
|
||||||
# account to access Podman commands
|
|
||||||
isNormalUser = true;
|
|
||||||
|
|
||||||
# A home directory is mandatory in order to allow systemd user units to be
|
|
||||||
# created and run
|
|
||||||
home = "${state-directory}";
|
|
||||||
createHome = true;
|
|
||||||
|
|
||||||
# Settings for running containers while a login shell is not active
|
|
||||||
linger = true;
|
|
||||||
autoSubUidGidRange = true;
|
|
||||||
};
|
|
||||||
users.groups."${user}" = { };
|
|
||||||
|
|
||||||
services.crowdsec = {
|
|
||||||
localConfig.acquisitions = [{
|
|
||||||
source = "journalctl";
|
|
||||||
journalctl_filter = [ "_SYSTEMD_USER_UNIT=${user}.service" ];
|
|
||||||
labels.type = "authentik";
|
|
||||||
}];
|
|
||||||
hub.collections = [ "firix/authentik" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
home-manager.users."${user}" = { config, osConfig, ... }: {
|
|
||||||
imports = [ home-manager-quadlet-nix ];
|
|
||||||
|
|
||||||
home.stateVersion = "25.05";
|
|
||||||
|
|
||||||
virtualisation.quadlet = {
|
|
||||||
containers = let
|
|
||||||
secrets = map (s: "${s},type=env") [
|
|
||||||
"AUTHENTIK_POSTGRESQL__PASSWORD"
|
|
||||||
"AUTHENTIK_SECRET_KEY"
|
|
||||||
"AUTHENTIK_EMAIL__HOST"
|
|
||||||
"AUTHENTIK_EMAIL__PORT"
|
|
||||||
"AUTHENTIK_EMAIL__USERNAME"
|
|
||||||
"AUTHENTIK_EMAIL__PASSWORD"
|
|
||||||
"AUTHENTIK_EMAIL__USE_SSL"
|
|
||||||
"AUTHENTIK_EMAIL__USE_TLS"
|
|
||||||
"AUTHENTIK_EMAIL__FROM"
|
|
||||||
"AUTHENTIK_STORAGE__S3__ACCESS_KEY"
|
|
||||||
"AUTHENTIK_STORAGE__S3__SECRET_KEY"
|
|
||||||
"AUTHENTIK_STORAGE__S3__BUCKET_NAME"
|
|
||||||
"AUTHENTIK_STORAGE__S3__REGION"
|
|
||||||
"AUTHENTIK_STORAGE__S3__ENDPOINT"
|
|
||||||
"AUTHENTIK_STORAGE__S3__CUSTOM_DOMAIN"
|
|
||||||
];
|
|
||||||
in {
|
|
||||||
authentik-db = {
|
|
||||||
autoStart = true;
|
|
||||||
containerConfig = {
|
|
||||||
image = "docker.io/library/postgres:16";
|
|
||||||
environments = {
|
|
||||||
POSTGRES_DB = "${user}";
|
|
||||||
POSTGRES_USER = "${user}";
|
|
||||||
};
|
|
||||||
secrets = [
|
|
||||||
# POSTGRES_PASSWORD is used by the container to setup the
|
|
||||||
# database, PGPASSWORD is used by pg_dump to authenticate for
|
|
||||||
# backup purposes
|
|
||||||
"AUTHENTIK_POSTGRESQL__PASSWORD,type=env,target=POSTGRES_PASSWORD"
|
|
||||||
"AUTHENTIK_POSTGRESQL__PASSWORD,type=env,target=PGPASSWORD"
|
|
||||||
];
|
|
||||||
|
|
||||||
# Double dollarsigns are required for use of *container* environment
|
|
||||||
# variables, Nix escaping creates the weird $\${} syntax
|
|
||||||
healthCmd = "pg_isready -d $\${POSTGRES_DB} -U $\${POSTGRES_USER}";
|
|
||||||
healthInterval = "30s";
|
|
||||||
healthRetries = 5;
|
|
||||||
healthStartPeriod = "20s";
|
|
||||||
|
|
||||||
# Volumes have to be bound with the :U label to allow for username
|
|
||||||
# remapping in rootless containers. :Z/:z is not needed b/c NixOS
|
|
||||||
# does not support SELinux
|
|
||||||
volumes =
|
|
||||||
[ "${state-directory}/database:/var/lib/postgresql/data:U" ];
|
|
||||||
|
|
||||||
# A network is actually required for these containers to talk to one
|
|
||||||
# another. I suppose the more idiomatic way would be for these
|
|
||||||
# related containers to be in a "pod," but I'm still struggling
|
|
||||||
# learning the idiosyncrasies of quadlet/rootless/podman, so we'll
|
|
||||||
# stick with this for now
|
|
||||||
networks =
|
|
||||||
[ config.virtualisation.quadlet.networks.authentik-net.ref ];
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
# Allowing this container to start before the secrets are translated
|
|
||||||
# will lead to errors. Use osConfig b/c secrets are declared in the
|
|
||||||
# system NixOS scope, even though it is a user process.
|
|
||||||
unitConfig.Requires =
|
|
||||||
[ osConfig.millironx.podman-secrets.authentik.ref ];
|
|
||||||
unitConfig.After =
|
|
||||||
[ osConfig.millironx.podman-secrets.authentik.ref ];
|
|
||||||
};
|
|
||||||
|
|
||||||
authentik-worker = {
|
|
||||||
autoStart = true;
|
|
||||||
containerConfig = {
|
|
||||||
image = "ghcr.io/goauthentik/server:2026.2";
|
|
||||||
environments = {
|
|
||||||
AUTHENTIK_POSTGRESQL__HOST = "authentik-db";
|
|
||||||
AUTHENTIK_POSTGRESQL__NAME = "${user}";
|
|
||||||
AUTHENTIK_POSTGRESQL__USER = "${user}";
|
|
||||||
AUTHENTIK_STORAGE__BACKEND = "s3";
|
|
||||||
};
|
|
||||||
exec = "worker";
|
|
||||||
inherit secrets;
|
|
||||||
volumes = [
|
|
||||||
# Remount media folder into new location based on
|
|
||||||
# <https://docs.goauthentik.io/releases/2025.12/#storage-improvements>
|
|
||||||
"${state-directory}/data:/data:U"
|
|
||||||
"${state-directory}/media:/data/media:U"
|
|
||||||
"${state-directory}/custom-templates:/templates:U"
|
|
||||||
"${state-directory}/certs:/certs:U"
|
|
||||||
];
|
|
||||||
networks =
|
|
||||||
[ config.virtualisation.quadlet.networks.authentik-net.ref ];
|
|
||||||
};
|
|
||||||
unitConfig.Requires =
|
|
||||||
[ config.virtualisation.quadlet.containers.authentik-db.ref ];
|
|
||||||
unitConfig.After =
|
|
||||||
[ config.virtualisation.quadlet.containers.authentik-db.ref ];
|
|
||||||
};
|
|
||||||
|
|
||||||
authentik = {
|
|
||||||
autoStart = true;
|
|
||||||
containerConfig = {
|
|
||||||
image = "ghcr.io/goauthentik/server:2026.2";
|
|
||||||
environments = {
|
|
||||||
AUTHENTIK_POSTGRESQL__HOST = "authentik-db";
|
|
||||||
AUTHENTIK_POSTGRESQL__NAME = "${user}";
|
|
||||||
AUTHENTIK_POSTGRESQL__USER = "${user}";
|
|
||||||
AUTHENTIK_STORAGE__BACKEND = "s3";
|
|
||||||
};
|
|
||||||
exec = "server";
|
|
||||||
inherit secrets;
|
|
||||||
|
|
||||||
# Change from Traefik: publish ports to localhost only via 127.0.0.1
|
|
||||||
# and then reverse proxy to that port. Authentik does not appear to
|
|
||||||
# have a way to configure the port, so we will use the default of
|
|
||||||
# 9000 for non-secured traffic.
|
|
||||||
publishPorts = [ "127.0.0.1:${port}:${port}" ];
|
|
||||||
volumes = [
|
|
||||||
"${state-directory}/media:/media:U"
|
|
||||||
"${state-directory}/custom-templates:/templates:U"
|
|
||||||
];
|
|
||||||
networks =
|
|
||||||
[ config.virtualisation.quadlet.networks.authentik-net.ref ];
|
|
||||||
};
|
|
||||||
unitConfig.Requires =
|
|
||||||
[ config.virtualisation.quadlet.containers.authentik-db.ref ];
|
|
||||||
unitConfig.After =
|
|
||||||
[ config.virtualisation.quadlet.containers.authentik-db.ref ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
networks.authentik-net = { };
|
|
||||||
|
|
||||||
# One of the main advantages of using Quadlet
|
|
||||||
autoUpdate.enable = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
{ pkgs, config, ... }: {
|
|
||||||
|
|
||||||
# We don't want to expose the location where borg backups are going, so we
|
|
||||||
# will setup an encrypted ssh config that references the host/username
|
|
||||||
# combo as simply 'borgserver'
|
|
||||||
age.secrets = {
|
|
||||||
borgmatic-ssh-config = { file = ./../secrets/borgmatic-ssh-config.age; };
|
|
||||||
borgmatic-passphrase = { file = ./../secrets/borgmatic-passphrase.age; };
|
|
||||||
};
|
|
||||||
|
|
||||||
services.borgmatic = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
# This is the bare-bones way to get Borgmatic up and running. Other services
|
|
||||||
# are expected to declare their stateful directories by adding to
|
|
||||||
# `services.borgmatic.configurations."${config.networking.hostName}".source_directories`
|
|
||||||
# and to add their databases to
|
|
||||||
# `services.borgmatic.configurations."${config.networking.hostName}".[mariadb|postgresql|etc]_databases`
|
|
||||||
|
|
||||||
configurations."${config.networking.hostName}" = {
|
|
||||||
source_directories = [ "/home" "/root" ];
|
|
||||||
repositories = [{
|
|
||||||
label = "${config.networking.hostName}-default";
|
|
||||||
path = "ssh://borgserver/./repo";
|
|
||||||
}];
|
|
||||||
ssh_command =
|
|
||||||
"${pkgs.openssh}/bin/ssh -F ${config.age.secrets.borgmatic-ssh-config.path}";
|
|
||||||
encryption_passcommand =
|
|
||||||
"${pkgs.coreutils}/bin/cat ${config.age.secrets.borgmatic-passphrase.path}";
|
|
||||||
keep_daily = 7;
|
|
||||||
keep_weekly = 4;
|
|
||||||
keep_monthly = 6;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
{ config, ... }: {
|
|
||||||
services.caddy = {
|
|
||||||
enable = true;
|
|
||||||
logFormat = "level INFO";
|
|
||||||
};
|
|
||||||
|
|
||||||
services.crowdsec = {
|
|
||||||
localConfig.acquisitions = [{
|
|
||||||
filenames = [ "${config.services.caddy.logDir}/*.log" ];
|
|
||||||
labels.type = "caddy";
|
|
||||||
}];
|
|
||||||
|
|
||||||
hub.parsers = [ "crowdsecurity/caddy-logs" ];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,51 +1,90 @@
|
||||||
{ pkgs, config, ... }: {
|
{ pkgs, config, ... }:
|
||||||
|
let
|
||||||
|
crowdsec-url = "127.0.0.1:2763";
|
||||||
|
firewall-bouncer-name = "fw-bouncer";
|
||||||
|
# Although this key can be reproduced by anyone who actually cares to, the
|
||||||
|
# Crowdsec API will not be exposed to the outside world, so keeping this key
|
||||||
|
# super secret really isn't that important to me. Still make it look random
|
||||||
|
# so that hungry botnets can't just slurp up the password in plaintext.
|
||||||
|
firewall-bouncer-key = builtins.hashString "sha256"
|
||||||
|
"${config.networking.hostName}-crowdsec-bouncer-salt";
|
||||||
|
toMultiYAML = items:
|
||||||
|
pkgs.lib.concatMapStrings (item:
|
||||||
|
''
|
||||||
|
|
||||||
|
---
|
||||||
|
'' + (pkgs.lib.generators.toYAML { } item) + "\n") items;
|
||||||
|
in {
|
||||||
services = {
|
services = {
|
||||||
crowdsec = {
|
crowdsec = {
|
||||||
enable = true;
|
enable = true;
|
||||||
localConfig = {
|
|
||||||
acquisitions = [
|
|
||||||
{
|
|
||||||
source = "journalctl";
|
|
||||||
journalctl_filter = [ "_SYSTEMD_UNIT=sshd.service" ];
|
|
||||||
labels.type = "syslog";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
filenames = [ "/var/log/auth.log" ];
|
|
||||||
labels.type = "syslog";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
filenames = [ "/var/log/syslog" "/var/log/kern.log" ];
|
|
||||||
labels.type = "syslog";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
hub = {
|
|
||||||
collections = [
|
|
||||||
"crowdsecurity/base-http-scenarios"
|
|
||||||
"crowdsecurity/http-cve"
|
|
||||||
"crowdsecurity/http-dos"
|
|
||||||
"crowdsecurity/iptables"
|
|
||||||
"crowdsecurity/linux"
|
|
||||||
"crowdsecurity/sshd"
|
|
||||||
"crowdsecurity/whitelist-good-actors"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
settings = {
|
settings = {
|
||||||
general = { api.server.enable = true; };
|
api.server = { listen_uri = crowdsec-url; };
|
||||||
# See https://github.com/NixOS/nixpkgs/issues/445342
|
allowLocalJournalAccess = true;
|
||||||
lapi.credentialsFile = "/var/lib/crowdsec/lapi-credentials.yaml";
|
crowdsec_service.acquisition_path = pkgs.writeText "acquisitions.yaml"
|
||||||
|
(toMultiYAML [
|
||||||
|
{
|
||||||
|
source = "journalctl";
|
||||||
|
journalctl_filter = [ "_SYSTEMD_UNIT=sshd.service" ];
|
||||||
|
labels.type = "syslog";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
filenames = [ "/var/log/auth.log" ];
|
||||||
|
labels.type = "syslog";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
filenames = [ "/var/log/syslog" "/var/log/kern.log" ];
|
||||||
|
labels.type = "syslog";
|
||||||
|
}
|
||||||
|
]);
|
||||||
};
|
};
|
||||||
autoUpdateService = true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
crowdsec-firewall-bouncer = {
|
crowdsec-firewall-bouncer = {
|
||||||
enable = true;
|
enable = true;
|
||||||
registerBouncer.enable = true;
|
settings = {
|
||||||
|
api_url = firewall-bouncer-name;
|
||||||
|
api_key = firewall-bouncer-key;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
users.users."${config.services.crowdsec.user}".extraGroups = [ "adm" ];
|
systemd.services.crowdsec.serviceConfig = {
|
||||||
|
ExecStartPre = let
|
||||||
|
bouncer-script = pkgs.writeScriptBin "register-bouncer" ''
|
||||||
|
#!${pkgs.runtimeShell}
|
||||||
|
set -eu
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
systemd.tmpfiles.rules = let cfg = config.services.crowdsec;
|
if ! cscli bouncers list | grep -q "${firewall-bouncer-name}"; then
|
||||||
in [ "d /var/lib/crowdsec 0755 ${cfg.user} ${cfg.group}" ];
|
cscli bouncers add "${firewall-bouncer-name}" --key "${firewall-bouncer-key}"
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
collection-check = collection: ''
|
||||||
|
|
||||||
|
if ! cscli collections list | grep -q "${collection}"; then
|
||||||
|
cscli collections install "${collection}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
'';
|
||||||
|
collections = [
|
||||||
|
"crowdsecurity/base-http-scenarios"
|
||||||
|
"crowdsecurity/http-cve"
|
||||||
|
"crowdsecurity/http-dos"
|
||||||
|
"crowdsecurity/iptables"
|
||||||
|
"crowdsecurity/linux"
|
||||||
|
"crowdsecurity/sshd"
|
||||||
|
"crowdsecurity/whitelist-good-actors"
|
||||||
|
];
|
||||||
|
collection-script = pkgs.writeScriptBin "install-collections" ''
|
||||||
|
#!${pkgs.runtimeShell}
|
||||||
|
set -eu
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
${pkgs.lib.concatMapStrings collection-check collections}
|
||||||
|
'';
|
||||||
|
in [
|
||||||
|
"${bouncer-script}/bin/register-bouncer"
|
||||||
|
"${collection-script}/bin/install-collections"
|
||||||
|
];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,164 +0,0 @@
|
||||||
{ config, pkgs, home-manager-quadlet-nix, ... }:
|
|
||||||
let
|
|
||||||
user = "fireflyiii";
|
|
||||||
port = "34733";
|
|
||||||
containerPort = "8080";
|
|
||||||
authentikPort = "9000";
|
|
||||||
stateDirectory = "/var/lib/${user}";
|
|
||||||
servicePaths = [ "upload" ];
|
|
||||||
databasePaths = [ "database" ];
|
|
||||||
in {
|
|
||||||
age.secrets."fireflyiii.toml" = {
|
|
||||||
file = ./../secrets/fireflyiii.toml.age;
|
|
||||||
owner = user;
|
|
||||||
};
|
|
||||||
|
|
||||||
millironx.podman-secrets.fireflyiii = {
|
|
||||||
inherit user;
|
|
||||||
secrets-files = [ config.age.secrets."fireflyiii.toml".path ];
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.tmpfiles.rules =
|
|
||||||
map (d: "d ${stateDirectory}/${d} 1775 ${user} ${user} -")
|
|
||||||
([ "" ] ++ servicePaths ++ databasePaths);
|
|
||||||
|
|
||||||
services.borgmatic.configurations."${config.networking.hostName}" = {
|
|
||||||
source_directories = map (d: "${stateDirectory}/${d}") servicePaths;
|
|
||||||
postgresql_databases = [{
|
|
||||||
name = user;
|
|
||||||
psql_command =
|
|
||||||
"/run/wrappers/bin/sudo -iu ${user} ${pkgs.podman}/bin/podman exec ${user}-db psql --username=${user}";
|
|
||||||
pg_dump_command =
|
|
||||||
"/run/wrappers/bin/sudo -iu ${user} ${pkgs.podman}/bin/podman exec ${user}-db pg_dump --username=${user}";
|
|
||||||
pg_restore_command =
|
|
||||||
"/run/wrappers/bin/sudo -iu ${user} ${pkgs.podman}/bin/podman exec ${user}-db pg_restore --username=${user}";
|
|
||||||
}];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.caddy.virtualHosts."money.millironx.com".extraConfig = ''
|
|
||||||
reverse_proxy /outpost.goauthentik.io/* http://127.0.0.1:${authentikPort}
|
|
||||||
@protected not path /oauth/* /api/*
|
|
||||||
forward_auth @protected http://127.0.0.1:${authentikPort} {
|
|
||||||
uri /outpost.goauthentik.io/auth/caddy
|
|
||||||
copy_headers X-Authentik-Username X-Authentik-Groups X-Authentik-Entitlements X-Authentik-Email X-Authentik-Name X-Authentik-Uid X-Authentik-Jwt X-Authentik-Meta-Jwks X-Authentik-Meta-Outpost X-Authentik-Meta-Provider X-Authentik-Meta-App X-Authentik-Meta-Version
|
|
||||||
}
|
|
||||||
reverse_proxy http://127.0.0.1:${port}
|
|
||||||
'';
|
|
||||||
|
|
||||||
users.users."${user}" = {
|
|
||||||
group = user;
|
|
||||||
isNormalUser = true;
|
|
||||||
home = stateDirectory;
|
|
||||||
createHome = true;
|
|
||||||
linger = true;
|
|
||||||
autoSubUidGidRange = true;
|
|
||||||
};
|
|
||||||
users.groups."${user}" = { };
|
|
||||||
|
|
||||||
home-manager.users."${user}" = { config, osConfig, ... }: {
|
|
||||||
imports = [ home-manager-quadlet-nix ];
|
|
||||||
|
|
||||||
home.stateVersion = "25.05";
|
|
||||||
|
|
||||||
systemd.user = let inherit (config.virtualisation.quadlet) containers;
|
|
||||||
in {
|
|
||||||
services."${user}-cron" = {
|
|
||||||
Unit = {
|
|
||||||
Description = "Firefly III cron";
|
|
||||||
Requires = [ containers."${user}".ref ];
|
|
||||||
After = [ containers."${user}".ref ];
|
|
||||||
};
|
|
||||||
Service.ExecStart =
|
|
||||||
"${pkgs.podman}/bin/podman exec ${user} /usr/local/bin/php /var/www/html/artisan firefly-iii:cron";
|
|
||||||
};
|
|
||||||
timers."${user}-cron" = {
|
|
||||||
Unit.Description = "Firefly III cron";
|
|
||||||
Timer.OnCalendar = "daily";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
virtualisation.quadlet = let
|
|
||||||
inherit (config.virtualisation.quadlet) containers;
|
|
||||||
inherit (config.virtualisation.quadlet) networks;
|
|
||||||
secrets = osConfig.millironx.podman-secrets.fireflyiii;
|
|
||||||
in {
|
|
||||||
autoUpdate.enable = true;
|
|
||||||
autoEscape = true;
|
|
||||||
|
|
||||||
networks."${user}" = { };
|
|
||||||
|
|
||||||
containers = {
|
|
||||||
"${user}-db" = {
|
|
||||||
autoStart = true;
|
|
||||||
containerConfig = {
|
|
||||||
image = "docker.io/library/postgres:16";
|
|
||||||
environments = {
|
|
||||||
POSTGRES_DB = user;
|
|
||||||
POSTGRES_USER = user;
|
|
||||||
};
|
|
||||||
secrets = [
|
|
||||||
"POSTGRES_PASSWORD,type=env"
|
|
||||||
"POSTGRES_PASSWORD,type=env,target=PGPASSWORD"
|
|
||||||
];
|
|
||||||
healthCmd = "pg_isready -d $\${POSTGRES_DB} -U $\${POSTGRES_USER}";
|
|
||||||
healthInterval = "30s";
|
|
||||||
healthRetries = 5;
|
|
||||||
healthStartPeriod = "20s";
|
|
||||||
volumes =
|
|
||||||
[ "${stateDirectory}/database:/var/lib/postgresql/data:U" ];
|
|
||||||
networks = [ networks."${user}".ref ];
|
|
||||||
};
|
|
||||||
unitConfig.Requires = [ secrets.ref ];
|
|
||||||
unitConfig.After = [ secrets.ref ];
|
|
||||||
};
|
|
||||||
|
|
||||||
"${user}" = {
|
|
||||||
autoStart = true;
|
|
||||||
containerConfig = {
|
|
||||||
image = "docker.io/fireflyiii/core:version-6";
|
|
||||||
environments = {
|
|
||||||
APP_ENV = "local";
|
|
||||||
DEFAULT_LANGUAGE = "en_US";
|
|
||||||
TZ = "America/New_York";
|
|
||||||
TRUSTED_PROXIES = "*";
|
|
||||||
DB_CONNECTION = "pgsql";
|
|
||||||
DB_HOST = "${user}-db";
|
|
||||||
DB_PORT = "5432";
|
|
||||||
DB_DATABASE = user;
|
|
||||||
DB_USERNAME = user;
|
|
||||||
CACHE_DRIVER = "redis";
|
|
||||||
SESSION_DRIVER = "redis";
|
|
||||||
REDIS_SCHEME = "tcp";
|
|
||||||
REDIS_HOST = "host.docker.internal";
|
|
||||||
REDIS_PORT = "6379";
|
|
||||||
REDIS_DB = "0";
|
|
||||||
REDIS_CACHE_DB = "1";
|
|
||||||
MAIL_MAILER = "smtp";
|
|
||||||
APP_URL = "https://money.millironx.com";
|
|
||||||
AUTHENTICATION_GUARD = "remote_user_guard";
|
|
||||||
AUTHENTICATION_GUARD_HEADER = "HTTP_X_AUTHENTIK_USERNAME";
|
|
||||||
AUTHENTICATION_GUARD_EMAIL = "HTTP_X_AUTHENTIK_EMAIL";
|
|
||||||
};
|
|
||||||
secrets = map (s: "${s},type=env") [
|
|
||||||
"SITE_OWNER"
|
|
||||||
"APP_KEY"
|
|
||||||
"DB_PASSWORD"
|
|
||||||
"MAIL_HOST"
|
|
||||||
"MAIL_PORT"
|
|
||||||
"MAIL_FROM"
|
|
||||||
"MAIL_USERNAME"
|
|
||||||
"MAIL_PASSWORD"
|
|
||||||
"MAIL_ENCRYPTION"
|
|
||||||
"REDIS_PASSWORD"
|
|
||||||
];
|
|
||||||
volumes = [ "${stateDirectory}/upload:/var/html/storage/upload:U" ];
|
|
||||||
networks = [ networks."${user}".ref ];
|
|
||||||
publishPorts = [ "127.0.0.1:${port}:${containerPort}" ];
|
|
||||||
};
|
|
||||||
unitConfig.Requires = [ secrets.ref containers."${user}-db".ref ];
|
|
||||||
unitConfig.After = [ secrets.ref containers."${user}-db".ref ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,146 +0,0 @@
|
||||||
{ config, pkgs, home-manager-quadlet-nix, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
user = "freshrss";
|
|
||||||
port = "37374";
|
|
||||||
stateDirectory = "/var/lib/freshrss";
|
|
||||||
serviceContainer = "freshrss";
|
|
||||||
stateSubDir = subDir: "${stateDirectory}/${subDir}";
|
|
||||||
createTmpfilesRule = subDir: "d ${stateSubDir subDir} 1755 ${user} ${user}";
|
|
||||||
|
|
||||||
dbDirectories = [ "database" ];
|
|
||||||
serviceDirectories = [ "data" "extensions" ];
|
|
||||||
in {
|
|
||||||
age.secrets = {
|
|
||||||
"freshrss.toml" = {
|
|
||||||
file = ./../secrets/freshrss.toml.age;
|
|
||||||
owner = "${user}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
millironx.podman-secrets.freshrss = {
|
|
||||||
user = "${user}";
|
|
||||||
secrets-files = [ config.age.secrets."freshrss.toml".path ];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.caddy.virtualHosts."feeds.millironx.com".extraConfig = ''
|
|
||||||
reverse_proxy http://127.0.0.1:${port} {
|
|
||||||
header_up X-Forwarded-Port 443
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
|
|
||||||
systemd.tmpfiles.rules = builtins.map createTmpfilesRule
|
|
||||||
([ stateDirectory ] ++ dbDirectories ++ serviceDirectories);
|
|
||||||
|
|
||||||
services.borgmatic.configurations."${config.networking.hostName}" = {
|
|
||||||
source_directories = builtins.map stateSubDir dbDirectories;
|
|
||||||
|
|
||||||
postgresql_databases = [{
|
|
||||||
name = serviceContainer;
|
|
||||||
psql_command =
|
|
||||||
"/run/wrappers/bin/sudo -iu ${user} ${pkgs.podman}/bin/podman exec ${serviceContainer}-db psql --username=${user}";
|
|
||||||
pg_dump_command =
|
|
||||||
"/run/wrappers/bin/sudo -iu ${user} ${pkgs.podman}/bin/podman exec ${serviceContainer}-db pg_dump --username=${user}";
|
|
||||||
pg_restore_command =
|
|
||||||
"/run/wrappers/bin/sudo -iu ${user} ${pkgs.podman}/bin/podman exec ${serviceContainer}-db pg_restore --username=${user}";
|
|
||||||
}];
|
|
||||||
};
|
|
||||||
|
|
||||||
users.users."${user}" = {
|
|
||||||
group = "${user}";
|
|
||||||
isNormalUser = true;
|
|
||||||
home = "${stateDirectory}";
|
|
||||||
createHome = true;
|
|
||||||
linger = true;
|
|
||||||
autoSubUidGidRange = true;
|
|
||||||
};
|
|
||||||
users.groups."${user}" = { };
|
|
||||||
|
|
||||||
home-manager.users."${user}" = { config, osConfig, ... }: {
|
|
||||||
imports = [ home-manager-quadlet-nix ];
|
|
||||||
|
|
||||||
home.stateVersion = "25.05";
|
|
||||||
|
|
||||||
virtualisation.quadlet = let
|
|
||||||
inherit (config.virtualisation.quadlet) containers;
|
|
||||||
inherit (config.virtualisation.quadlet) networks;
|
|
||||||
secrets = osConfig.millironx.podman-secrets.freshrss;
|
|
||||||
|
|
||||||
in {
|
|
||||||
containers = {
|
|
||||||
"${serviceContainer}-db" = {
|
|
||||||
autoStart = true;
|
|
||||||
containerConfig = {
|
|
||||||
image = "docker.io/library/postgres:16";
|
|
||||||
environments = {
|
|
||||||
POSTGRES_DB = "${user}";
|
|
||||||
POSTGRES_USER = "${user}";
|
|
||||||
};
|
|
||||||
secrets = [
|
|
||||||
"POSTGRES_PASSWORD,type=env"
|
|
||||||
"POSTGRES_PASSWORD,type=env,target=PGPASSWORD"
|
|
||||||
];
|
|
||||||
healthCmd = "pg_isready -d $\${POSTGRES_DB} -U $\${POSTGRES_USER}";
|
|
||||||
healthInterval = "30s";
|
|
||||||
healthRetries = 5;
|
|
||||||
healthStartPeriod = "20s";
|
|
||||||
volumes =
|
|
||||||
[ "${stateDirectory}/database:/var/lib/postgresql/data:U" ];
|
|
||||||
networks = [ networks."${serviceContainer}".ref ];
|
|
||||||
};
|
|
||||||
unitConfig.Requires = [ secrets.ref ];
|
|
||||||
unitConfig.After = [ secrets.ref ];
|
|
||||||
};
|
|
||||||
|
|
||||||
"${serviceContainer}" = {
|
|
||||||
autoStart = true;
|
|
||||||
containerConfig = {
|
|
||||||
image = "docker.io/freshrss/freshrss:1";
|
|
||||||
# Required to allow the container to talk to the host ports, in
|
|
||||||
# other words, to resolve Authentik correctly
|
|
||||||
addHosts = [ "auth.millironx.com:host-gateway" ];
|
|
||||||
environments = {
|
|
||||||
TZ = osConfig.time.timeZone;
|
|
||||||
CRON_MIN = "2,32";
|
|
||||||
LISTEN = "0.0.0.0:${port}";
|
|
||||||
TRUSTED_PROXY = "172.16.0.1/12 192.168.0.1/16";
|
|
||||||
OIDC_ENABLED = "1";
|
|
||||||
OIDC_PROVIDER_METADATA_URL =
|
|
||||||
"https://auth.millironx.com/application/o/freshrss/.well-known/openid-configuration";
|
|
||||||
OIDC_REMOTE_USER_CLAIM = "preferred_username";
|
|
||||||
OIDC_SCOPES = "openid email profile";
|
|
||||||
OIDC_X_FORWARDED_HEADERS =
|
|
||||||
"X-Forwarded-Host X-Forwarded-Port X-Forwarded-Proto";
|
|
||||||
};
|
|
||||||
secrets = [
|
|
||||||
"OIDC_CLIENT_ID,type=env"
|
|
||||||
"OIDC_CLIENT_SECRET,type=env"
|
|
||||||
"OIDC_CLIENT_CRYPTO_KEY,type=env"
|
|
||||||
];
|
|
||||||
healthCmd = "cli/health.php";
|
|
||||||
healthTimeout = "10s";
|
|
||||||
healthStartPeriod = "60s";
|
|
||||||
healthStartupInterval = "11s";
|
|
||||||
healthInterval = "75s";
|
|
||||||
healthRetries = 3;
|
|
||||||
networks = [ networks."${serviceContainer}".ref ];
|
|
||||||
publishPorts = [ "127.0.0.1:${port}:${port}" ];
|
|
||||||
volumes = [
|
|
||||||
"${stateDirectory}/data:/var/www/FreshRSS/data:U"
|
|
||||||
"${stateDirectory}/extensions:/var/www/FreshRSS/extensions:U"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
unitConfig.Requires =
|
|
||||||
[ secrets.ref containers."${serviceContainer}-db".ref ];
|
|
||||||
unitConfig.After =
|
|
||||||
[ secrets.ref containers."${serviceContainer}-db".ref ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
networks."${serviceContainer}" = { };
|
|
||||||
|
|
||||||
autoUpdate.enable = true;
|
|
||||||
autoEscape = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
services.gpg-agent = {
|
services.gpg-agent = {
|
||||||
enable = true;
|
enable = true;
|
||||||
enableBashIntegration = true;
|
enableBashIntegration = true;
|
||||||
enableSshSupport = false;
|
enableSshSupport = true;
|
||||||
enableZshIntegration = true;
|
enableZshIntegration = true;
|
||||||
defaultCacheTtl = 604800;
|
defaultCacheTtl = 604800;
|
||||||
maxCacheTtl = 604800;
|
maxCacheTtl = 604800;
|
||||||
|
|
|
||||||
|
|
@ -1,182 +0,0 @@
|
||||||
{ config, pkgs, home-manager-quadlet-nix, ... }:
|
|
||||||
let
|
|
||||||
user = "immich";
|
|
||||||
port = "46642";
|
|
||||||
containerPort = "2283";
|
|
||||||
redisPort = 64664;
|
|
||||||
stateDirectory = "/var/lib/${user}";
|
|
||||||
servicePaths = [ ];
|
|
||||||
databasePaths = [ "database" ];
|
|
||||||
s3BucketName = "millironx-photos";
|
|
||||||
s3MountDirectory = "/mount/s3/${s3BucketName}";
|
|
||||||
immich-version = "v2";
|
|
||||||
in {
|
|
||||||
age.secrets = {
|
|
||||||
millironx-photos-s3-token.file = ./../secrets/millironx-photos-s3.age;
|
|
||||||
redis-immich-password.file = ./../secrets/redis-immich-password.age;
|
|
||||||
"immich.toml" = {
|
|
||||||
file = ./../secrets/immich.toml.age;
|
|
||||||
owner = user;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
millironx.podman-secrets.immich = {
|
|
||||||
inherit user;
|
|
||||||
secrets-files = [ config.age.secrets."immich.toml".path ];
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.tmpfiles.rules =
|
|
||||||
map (d: "d ${stateDirectory}/${d} 1775 ${user} ${user} -")
|
|
||||||
([ "" ] ++ servicePaths ++ databasePaths);
|
|
||||||
|
|
||||||
environment.systemPackages = [ pkgs.s3fs ];
|
|
||||||
|
|
||||||
fileSystems."${s3BucketName}" = {
|
|
||||||
device = s3BucketName;
|
|
||||||
mountPoint = s3MountDirectory;
|
|
||||||
fsType = "fuse./run/current-system/sw/bin/s3fs";
|
|
||||||
noCheck = true;
|
|
||||||
options = [
|
|
||||||
"_netdev"
|
|
||||||
"allow_other"
|
|
||||||
"use_path_request_style"
|
|
||||||
"url=https://us-east-1.linodeobjects.com/"
|
|
||||||
"passwd_file=${config.age.secrets.millironx-photos-s3-token.path}"
|
|
||||||
"uid=${user}"
|
|
||||||
"gid=${user}"
|
|
||||||
"umask=0022"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
services = {
|
|
||||||
borgmatic.configurations."${config.networking.hostName}" = {
|
|
||||||
source_directories = map (d: "${stateDirectory}/${d}") servicePaths;
|
|
||||||
postgresql_databases = [{
|
|
||||||
name = user;
|
|
||||||
psql_command =
|
|
||||||
"/run/wrappers/bin/sudo -iu ${user} ${pkgs.podman}/bin/podman exec ${user}-db psql --username=${user}";
|
|
||||||
pg_dump_command =
|
|
||||||
"/run/wrappers/bin/sudo -iu ${user} ${pkgs.podman}/bin/podman exec ${user}-db pg_dump --username=${user}";
|
|
||||||
pg_restore_command =
|
|
||||||
"/run/wrappers/bin/sudo -iu ${user} ${pkgs.podman}/bin/podman exec ${user}-db pg_restore --username=${user}";
|
|
||||||
}];
|
|
||||||
};
|
|
||||||
|
|
||||||
caddy.virtualHosts."photos.millironx.com".extraConfig = ''
|
|
||||||
reverse_proxy http://127.0.0.1:${port}
|
|
||||||
'';
|
|
||||||
|
|
||||||
redis.servers."${user}" = {
|
|
||||||
enable = true;
|
|
||||||
port = redisPort;
|
|
||||||
bind = "0.0.0.0";
|
|
||||||
requirePassFile = config.age.secrets.redis-immich-password.path;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
users.users."${user}" = {
|
|
||||||
group = user;
|
|
||||||
isNormalUser = true;
|
|
||||||
home = stateDirectory;
|
|
||||||
createHome = true;
|
|
||||||
linger = true;
|
|
||||||
autoSubUidGidRange = true;
|
|
||||||
};
|
|
||||||
users.groups."${user}" = { };
|
|
||||||
|
|
||||||
home-manager.users."${user}" = { config, osConfig, ... }: {
|
|
||||||
imports = [ home-manager-quadlet-nix ];
|
|
||||||
|
|
||||||
home.stateVersion = "25.05";
|
|
||||||
|
|
||||||
virtualisation.quadlet = let
|
|
||||||
inherit (config.virtualisation.quadlet) containers;
|
|
||||||
inherit (config.virtualisation.quadlet) networks;
|
|
||||||
inherit (config.virtualisation.quadlet) volumes;
|
|
||||||
secrets = osConfig.millironx.podman-secrets.immich;
|
|
||||||
db-user = "postgres";
|
|
||||||
in {
|
|
||||||
autoUpdate.enable = true;
|
|
||||||
autoEscape = true;
|
|
||||||
|
|
||||||
networks."${user}" = { };
|
|
||||||
|
|
||||||
volumes.model-cache.volumeConfig = { };
|
|
||||||
|
|
||||||
containers = {
|
|
||||||
"${user}-db" = {
|
|
||||||
autoStart = true;
|
|
||||||
containerConfig = {
|
|
||||||
# For some reason, the -rootless variant seems to hang, so go with
|
|
||||||
# the rootful one (even though this user has no root access)
|
|
||||||
image = "docker.io/tensorchord/pgvecto-rs:pg16-v0.3.0";
|
|
||||||
environments = {
|
|
||||||
POSTGRES_DB = user;
|
|
||||||
POSTGRES_USER = db-user;
|
|
||||||
POSTGRES_INITDB_ARGS = "--data-checksums";
|
|
||||||
};
|
|
||||||
secrets = [
|
|
||||||
"POSTGRES_PASSWORD,type=env"
|
|
||||||
"POSTGRES_PASSWORD,type=env,target=PGPASSWORD"
|
|
||||||
];
|
|
||||||
healthCmd = "pg_isready -d $\${POSTGRES_DB} -U $\${POSTGRES_USER}";
|
|
||||||
healthInterval = "30s";
|
|
||||||
healthRetries = 5;
|
|
||||||
healthStartPeriod = "20s";
|
|
||||||
volumes =
|
|
||||||
[ "${stateDirectory}/database:/var/lib/postgresql/data:U" ];
|
|
||||||
networks = [ networks."${user}".ref ];
|
|
||||||
};
|
|
||||||
unitConfig.Requires = [ secrets.ref ];
|
|
||||||
unitConfig.After = [ secrets.ref ];
|
|
||||||
};
|
|
||||||
|
|
||||||
"${user}-ml" = {
|
|
||||||
autoStart = true;
|
|
||||||
containerConfig = {
|
|
||||||
image =
|
|
||||||
"ghcr.io/immich-app/immich-machine-learning:${immich-version}";
|
|
||||||
networks = [ networks."${user}".ref ];
|
|
||||||
volumes = [ "${volumes.model-cache.ref}:/cache" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
"${user}" = {
|
|
||||||
autoStart = true;
|
|
||||||
containerConfig = {
|
|
||||||
image = "ghcr.io/immich-app/immich-server:${immich-version}";
|
|
||||||
environments = {
|
|
||||||
DB_HOSTNAME = "${user}-db";
|
|
||||||
DB_USERNAME = db-user;
|
|
||||||
DB_DATABASE_NAME = user;
|
|
||||||
REDIS_HOSTNAME = "host.docker.internal";
|
|
||||||
REDIS_PORT = builtins.toString redisPort;
|
|
||||||
};
|
|
||||||
secrets =
|
|
||||||
map (s: "${s},type=env") [ "DB_PASSWORD" "REDIS_PASSWORD" ];
|
|
||||||
volumes = [
|
|
||||||
# Generally, mounts need the :U directive, but in the case of
|
|
||||||
# mounting the root of a bucket, that hangs. Uploads are verified
|
|
||||||
# to work without that, so everything should be fine
|
|
||||||
"${s3MountDirectory}:/usr/src/app/upload"
|
|
||||||
"/etc/localtime:/etc/localtime:ro"
|
|
||||||
];
|
|
||||||
networks = [ networks."${user}".ref ];
|
|
||||||
publishPorts = [ "127.0.0.1:${port}:${containerPort}" ];
|
|
||||||
addHosts = [ "auth.millironx.com:host-gateway" ];
|
|
||||||
};
|
|
||||||
unitConfig.Requires = [
|
|
||||||
secrets.ref
|
|
||||||
containers."${user}-db".ref
|
|
||||||
containers."${user}-ml".ref
|
|
||||||
];
|
|
||||||
unitConfig.After = [
|
|
||||||
secrets.ref
|
|
||||||
containers."${user}-db".ref
|
|
||||||
containers."${user}-ml".ref
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
{ pkgs, lib, config, ... }: let
|
|
||||||
driver-name = "iHD"; in
|
|
||||||
{
|
|
||||||
environment = {
|
|
||||||
sessionVariables.LIBVA_DRIVER_NAME = driver-name;
|
|
||||||
systemPackages = with pkgs; [
|
|
||||||
jellyfin
|
|
||||||
jellyfin-web
|
|
||||||
jellyfin-ffmpeg
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
hardware.graphics = {
|
|
||||||
enable = true;
|
|
||||||
extraPackages = with pkgs; [
|
|
||||||
intel-ocl
|
|
||||||
intel-media-driver
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Allow the unfree drivers
|
|
||||||
nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [
|
|
||||||
"intel-ocl"
|
|
||||||
];
|
|
||||||
|
|
||||||
services.jellyfin = {
|
|
||||||
enable = true;
|
|
||||||
openFirewall = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.jellyfin.environment.LIBVA_DRIVER_NAME = driver-name;
|
|
||||||
|
|
||||||
users.users.${config.services.jellyfin.user}.extraGroups = [ "mixstudios" "render" ];
|
|
||||||
}
|
|
||||||
|
|
@ -1,132 +0,0 @@
|
||||||
{ config, pkgs, home-manager-quadlet-nix, ... }:
|
|
||||||
let
|
|
||||||
user = "navidrome";
|
|
||||||
port = "4533";
|
|
||||||
authentikPort = "9000";
|
|
||||||
stateDirectory = "/var/lib/${user}";
|
|
||||||
s3BucketName = "millironx-music";
|
|
||||||
s3MountDirectory = "/mount/s3/${s3BucketName}";
|
|
||||||
in {
|
|
||||||
age.secrets = {
|
|
||||||
millironx-music-s3-token.file = ./../secrets/millironx-music-s3.age;
|
|
||||||
"navidrome.toml" = {
|
|
||||||
file = ./../secrets/navidrome.toml.age;
|
|
||||||
owner = user;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
millironx.podman-secrets.navidrome = {
|
|
||||||
inherit user;
|
|
||||||
secrets-files = [ config.age.secrets."navidrome.toml".path ];
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.systemPackages = [ pkgs.s3fs ];
|
|
||||||
|
|
||||||
fileSystems."${s3BucketName}" = {
|
|
||||||
device = s3BucketName;
|
|
||||||
mountPoint = s3MountDirectory;
|
|
||||||
fsType = "fuse./run/current-system/sw/bin/s3fs";
|
|
||||||
noCheck = true;
|
|
||||||
options = [
|
|
||||||
"_netdev"
|
|
||||||
"allow_other"
|
|
||||||
"use_path_request_style"
|
|
||||||
"url=https://us-east-1.linodeobjects.com/"
|
|
||||||
"passwd_file=${config.age.secrets.millironx-music-s3-token.path}"
|
|
||||||
"uid=${user}"
|
|
||||||
"gid=${user}"
|
|
||||||
"umask=0022"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.tmpfiles.rules =
|
|
||||||
map (d: "d ${stateDirectory}/${d} 1775 ${user} ${user} -") [ "" "data" ];
|
|
||||||
|
|
||||||
services.borgmatic.configurations."${config.networking.hostName}" = {
|
|
||||||
source_directories = map (d: "${stateDirectory}/${d}") [ "data" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Modified from
|
|
||||||
# - <https://www.navidrome.org/docs/getting-started/extauth-quickstart/#example-caddy-with-authentik>
|
|
||||||
# - <https://www.navidrome.org/docs/usage/integration/authentication/#caddy-with-forward_auth>
|
|
||||||
# Modifications are exclusively changes from Docker hostnames to 127.0.0.1 and
|
|
||||||
# port numbers
|
|
||||||
services.caddy.virtualHosts."music.millironx.com".extraConfig = ''
|
|
||||||
# Authentik output endpoint
|
|
||||||
reverse_proxy /outpost.goauthentik.io/* http://127.0.0.1:${authentikPort}
|
|
||||||
|
|
||||||
# Protect everything except share and subsonic endpoints
|
|
||||||
@protected not path /share/* /rest/*
|
|
||||||
forward_auth @protected http://127.0.0.1:${authentikPort} {
|
|
||||||
uri /outpost.goauthentik.io/auth/caddy
|
|
||||||
copy_headers X-Authentik-Username>Remote-User
|
|
||||||
}
|
|
||||||
|
|
||||||
# Authentik uses the Authorization header if present, so should be able to
|
|
||||||
# authenticate subsonic clients that support BasicAuth. Requests from the
|
|
||||||
# Navidrome Web App will be authenticated via the existing session cookie.
|
|
||||||
# If you want to have Navidrome authenticate subsonic requests, remove this
|
|
||||||
# forward_auth block.
|
|
||||||
@subsonic path /rest/*
|
|
||||||
forward_auth @subsonic http://127.0.0.1:${authentikPort} {
|
|
||||||
uri /outpost.goauthentik.io/auth/caddy
|
|
||||||
copy_headers X-Authentik-Username>Remote-User
|
|
||||||
|
|
||||||
# Some clients that claim to support basicauth still expect a subsonic
|
|
||||||
# response in case of authentication failure instead of a proper basicauth
|
|
||||||
# response.
|
|
||||||
@error status 1xx 3xx 4xx 5xx
|
|
||||||
handle_response @error {
|
|
||||||
respond <<SUBSONICERR
|
|
||||||
<subsonic-response xmlns="http://subsonic.org/restapi" status="failed" version="1.16.1" type="proxy-auth" serverVersion="n/a" openSubsonic="true">
|
|
||||||
<error code="40" message="Invalid credentials or unsupported client"></error>
|
|
||||||
</subsonic-response>
|
|
||||||
SUBSONICERR 200
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Forward everything to Navidrome
|
|
||||||
reverse_proxy http://127.0.0.1:${port}
|
|
||||||
'';
|
|
||||||
|
|
||||||
users.users."${user}" = {
|
|
||||||
group = "${user}";
|
|
||||||
isNormalUser = true;
|
|
||||||
home = stateDirectory;
|
|
||||||
createHome = true;
|
|
||||||
linger = true;
|
|
||||||
autoSubUidGidRange = true;
|
|
||||||
};
|
|
||||||
users.groups."${user}" = { };
|
|
||||||
|
|
||||||
home-manager.users."${user}" = { config, osConfig, ... }: {
|
|
||||||
imports = [ home-manager-quadlet-nix ];
|
|
||||||
|
|
||||||
home.stateVersion = "25.05";
|
|
||||||
|
|
||||||
virtualisation.quadlet = {
|
|
||||||
autoUpdate.enable = true;
|
|
||||||
containers.navidrome = {
|
|
||||||
autoStart = true;
|
|
||||||
containerConfig = {
|
|
||||||
image = "docker.io/deluan/navidrome:latest";
|
|
||||||
environments = {
|
|
||||||
ND_BASEURL = "https://music.millironx.com";
|
|
||||||
# pasta appears to use the static host IP so trust that
|
|
||||||
ND_EXTAUTH_TRUSTEDSOURCES = "23.239.13.247/24";
|
|
||||||
};
|
|
||||||
secrets =
|
|
||||||
map (s: "${s},type=env") [ "ND_LASTFM_APIKEY" "ND_LASTFM_SECRET" ];
|
|
||||||
volumes = [
|
|
||||||
"${s3MountDirectory}:/music:ro"
|
|
||||||
"${stateDirectory}/data:/data:U"
|
|
||||||
];
|
|
||||||
publishPorts = [ "127.0.0.1:${port}:${port}" ];
|
|
||||||
};
|
|
||||||
unitConfig.Requires =
|
|
||||||
[ osConfig.millironx.podman-secrets.navidrome.ref ];
|
|
||||||
unitConfig.After = [ osConfig.millironx.podman-secrets.navidrome.ref ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
50
services/nixos-update.nix
Normal file
50
services/nixos-update.nix
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
# This file is designed to be used in the imports
|
||||||
|
{ pkgs, config, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
environment.systemPackages = [
|
||||||
|
(pkgs.writeScriptBin "update-nixos" ''
|
||||||
|
#!${pkgs.bash}/bin/bash
|
||||||
|
echo "Requesting system update..."
|
||||||
|
${pkgs.systemd}/bin/systemctl start nixos-update.service
|
||||||
|
'')
|
||||||
|
];
|
||||||
|
|
||||||
|
# Service to update NixOS configuration from git repo
|
||||||
|
systemd.services."nixos-update" = {
|
||||||
|
description = "Update NixOS configuration from git repository";
|
||||||
|
path = with pkgs; [ coreutils ];
|
||||||
|
script = ''
|
||||||
|
# Rebuild the system directly from the remote flake
|
||||||
|
${pkgs.nixos-rebuild}/bin/nixos-rebuild switch --flake git+https://code.millironx.com/millironx/nix-dotfiles.git#${config.networking.hostName}
|
||||||
|
'';
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
User = "root";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Timer to run the update service daily at 3am
|
||||||
|
systemd.timers."nixos-update" = {
|
||||||
|
wantedBy = [ "timers.target" ];
|
||||||
|
description = "Run NixOS update daily at 3am";
|
||||||
|
timerConfig = {
|
||||||
|
OnCalendar = "3:00";
|
||||||
|
Persistent = true;
|
||||||
|
Unit = "nixos-update.service";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Polkit rule to allow non-root users to trigger the update
|
||||||
|
security.polkit.extraConfig = ''
|
||||||
|
polkit.addRule(function(action, subject) {
|
||||||
|
if (action.id == "org.freedesktop.systemd1.manage-units" &&
|
||||||
|
action.lookup("unit") == "nixos-update.service" &&
|
||||||
|
action.lookup("verb") == "start" &&
|
||||||
|
subject.isInGroup("wheel")) {
|
||||||
|
return polkit.Result.YES;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
'';
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
{ ... }: {
|
|
||||||
services.openssh = {
|
|
||||||
enable = true;
|
|
||||||
settings = {
|
|
||||||
PermitRootLogin = "no";
|
|
||||||
PasswordAuthentication = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,221 +0,0 @@
|
||||||
{ config, pkgs, home-manager-quadlet-nix, ... }:
|
|
||||||
let
|
|
||||||
domain = "video.millironx.com";
|
|
||||||
user = "peertube";
|
|
||||||
port = "33788";
|
|
||||||
containerPort = "9000";
|
|
||||||
rtmpHostPort = "41936";
|
|
||||||
rtmpContainerPort = "1935";
|
|
||||||
redisPort = 63378;
|
|
||||||
stateDirectory = "/var/lib/${user}";
|
|
||||||
servicePaths = [ "data" "config" "assets" ];
|
|
||||||
databasePaths = [ "database" ];
|
|
||||||
peertubeVersion = "v8.1.4";
|
|
||||||
peertubeAssetsDir = "${pkgs.peertube}/client/dist";
|
|
||||||
in {
|
|
||||||
age.secrets = {
|
|
||||||
"redis-${user}-password".file = ./../secrets/redis-${user}-password.age;
|
|
||||||
"${user}.toml" = {
|
|
||||||
file = ./../secrets/${user}.toml.age;
|
|
||||||
owner = user;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
millironx.podman-secrets.${user} = {
|
|
||||||
inherit user;
|
|
||||||
secrets-files = [ config.age.secrets."${user}.toml".path ];
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.tmpfiles.rules =
|
|
||||||
map (d: "d ${stateDirectory}/${d} 1775 ${user} ${user} -")
|
|
||||||
([ "" ] ++ servicePaths ++ databasePaths);
|
|
||||||
|
|
||||||
services = {
|
|
||||||
borgmatic.configurations."${config.networking.hostName}" = {
|
|
||||||
source_directories = map (d: "${stateDirectory}/${d}") servicePaths;
|
|
||||||
postgresql_databases = [{
|
|
||||||
name = user;
|
|
||||||
psql_command =
|
|
||||||
"/run/wrappers/bin/sudo -iu ${user} ${pkgs.podman}/bin/podman exec ${user}-db psql --username=${user}";
|
|
||||||
pg_dump_command =
|
|
||||||
"/run/wrappers/bin/sudo -iu ${user} ${pkgs.podman}/bin/podman exec ${user}-db pg_dump --username=${user}";
|
|
||||||
pg_restore_command =
|
|
||||||
"/run/wrappers/bin/sudo -iu ${user} ${pkgs.podman}/bin/podman exec ${user}-db pg_restore --username=${user}";
|
|
||||||
}];
|
|
||||||
};
|
|
||||||
|
|
||||||
caddy.virtualHosts.${domain}.extraConfig =
|
|
||||||
builtins.readFile ./../conf/peertube.caddyfile;
|
|
||||||
|
|
||||||
redis.servers.${user} = {
|
|
||||||
enable = true;
|
|
||||||
port = redisPort;
|
|
||||||
bind = "0.0.0.0";
|
|
||||||
requirePassFile = config.age.secrets."redis-${user}-password".path;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Forward RTMP (privileged) port to container-accessible (non-privileged) port
|
|
||||||
systemd = {
|
|
||||||
sockets."peertube-rtmp" = {
|
|
||||||
description = "PeerTube RTMP Socket";
|
|
||||||
wantedBy = [ "sockets.target" ];
|
|
||||||
socketConfig = {
|
|
||||||
ListenStream = "0.0.0.0:${rtmpContainerPort}";
|
|
||||||
Accept = false;
|
|
||||||
Service = "peertube-rtmp-forward.service";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services = {
|
|
||||||
"peertube-rtmp-forward" = {
|
|
||||||
description = "PeerTube RTMP Port Forwarder";
|
|
||||||
requires = [ "peertube-rtmp.socket" ];
|
|
||||||
after = [ "network.target" ];
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "notify";
|
|
||||||
ExecStart =
|
|
||||||
"${pkgs.systemd}/lib/systemd/systemd-socket-proxyd 127.0.0.1:${rtmpHostPort}";
|
|
||||||
PrivateTmp = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# This is a hack - I'm deliberately hijacking the systemd service that is
|
|
||||||
# set up by `services.caddy` in order to sync the `let` variables with the
|
|
||||||
# external Caddyfile via environment variables
|
|
||||||
# This is safe for NixOS 25.11 - see
|
|
||||||
# <https://github.com/NixOS/nixpkgs/blob/nixos-25.11/nixos/modules/services/web-servers/caddy/default.nix#L412>
|
|
||||||
caddy.environment = {
|
|
||||||
MILLIRONX_PEERTUBE_PORT = port;
|
|
||||||
MILLIRONX_PEERTUBE_ASSETS_DIR = peertubeAssetsDir;
|
|
||||||
MILLIRONX_PEERTUBE_DATA_DIR = "${stateDirectory}/data";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
networking.firewall.allowedTCPPorts = [ 1935 ];
|
|
||||||
|
|
||||||
users.users.${user} = {
|
|
||||||
group = user;
|
|
||||||
isNormalUser = true;
|
|
||||||
home = stateDirectory;
|
|
||||||
createHome = true;
|
|
||||||
linger = true;
|
|
||||||
autoSubUidGidRange = true;
|
|
||||||
};
|
|
||||||
users.groups.${user} = { };
|
|
||||||
# Another hack - allows the Caddy user to be able to read files that
|
|
||||||
# PeerTube writes into its dist/ folders
|
|
||||||
users.users.${config.services.caddy.user}.extraGroups = [ user ];
|
|
||||||
|
|
||||||
home-manager.users.${user} = { config, osConfig, ... }: {
|
|
||||||
imports = [ home-manager-quadlet-nix ];
|
|
||||||
|
|
||||||
home.stateVersion = "25.05";
|
|
||||||
|
|
||||||
virtualisation.quadlet = let
|
|
||||||
inherit (config.virtualisation.quadlet) containers;
|
|
||||||
inherit (config.virtualisation.quadlet) networks;
|
|
||||||
secrets = osConfig.millironx.podman-secrets.${user};
|
|
||||||
in {
|
|
||||||
autoUpdate.enable = true;
|
|
||||||
autoEscape = true;
|
|
||||||
|
|
||||||
networks.${user} = { };
|
|
||||||
|
|
||||||
containers = {
|
|
||||||
"${user}-db" = {
|
|
||||||
autoStart = true;
|
|
||||||
containerConfig = {
|
|
||||||
image = "docker.io/library/postgres:16";
|
|
||||||
environments = {
|
|
||||||
POSTGRES_DB = user;
|
|
||||||
POSTGRES_USER = user;
|
|
||||||
};
|
|
||||||
secrets = [
|
|
||||||
"POSTGRES_PASSWORD,type=env"
|
|
||||||
"POSTGRES_PASSWORD,type=env,target=PGPASSWORD"
|
|
||||||
];
|
|
||||||
healthCmd = "pg_isready -d $\${POSTGRES_DB} -U $\${POSTGRES_USER}";
|
|
||||||
healthInterval = "30s";
|
|
||||||
healthRetries = 5;
|
|
||||||
healthStartPeriod = "20s";
|
|
||||||
volumes =
|
|
||||||
[ "${stateDirectory}/database:/var/lib/postgresql/data:U" ];
|
|
||||||
networks = [ networks."${user}".ref ];
|
|
||||||
};
|
|
||||||
unitConfig.Requires = [ secrets.ref ];
|
|
||||||
unitConfig.After = [ secrets.ref ];
|
|
||||||
};
|
|
||||||
|
|
||||||
"${user}" = {
|
|
||||||
autoStart = true;
|
|
||||||
containerConfig = {
|
|
||||||
image = "docker.io/chocobozzz/peertube:${peertubeVersion}";
|
|
||||||
environments = let bucket = "millironx-publicfiles";
|
|
||||||
in {
|
|
||||||
PEERTUBE_CONTACT_FORM_ENABLED = "false";
|
|
||||||
PEERTUBE_DB_HOSTNAME = "${user}-db";
|
|
||||||
PEERTUBE_DB_SSL = "false";
|
|
||||||
PEERTUBE_DB_USERNAME = user;
|
|
||||||
PEERTUBE_OBJECT_STORAGE_CAPTIONS_BUCKET_NAME = bucket;
|
|
||||||
PEERTUBE_OBJECT_STORAGE_CAPTIONS_PREFIX = "captions";
|
|
||||||
PEERTUBE_OBJECT_STORAGE_ENABLED = "true";
|
|
||||||
PEERTUBE_OBJECT_STORAGE_ORIGINAL_VIDEO_FILES_BUCKET_NAME = bucket;
|
|
||||||
PEERTUBE_OBJECT_STORAGE_ORIGINAL_VIDEO_FILES_PREFIX = "original";
|
|
||||||
PEERTUBE_OBJECT_STORAGE_STREAMING_PLAYLISTS_BUCKET_NAME = bucket;
|
|
||||||
PEERTUBE_OBJECT_STORAGE_STREAMING_PLAYLISTS_PREFIX = "playlists";
|
|
||||||
PEERTUBE_OBJECT_STORAGE_UPLOAD_ACL_PUBLIC = "public-read";
|
|
||||||
PEERTUBE_OBJECT_STORAGE_USER_EXPORTS_BUCKET_NAME = bucket;
|
|
||||||
PEERTUBE_OBJECT_STORAGE_USER_EXPORTS_PREFIX = "user-export";
|
|
||||||
PEERTUBE_OBJECT_STORAGE_WEB_VIDEOS_BUCKET_NAME = bucket;
|
|
||||||
PEERTUBE_OBJECT_STORAGE_WEB_VIDEOS_PREFIX = "videos";
|
|
||||||
PEERTUBE_REDIS_HOSTNAME = "host.docker.internal";
|
|
||||||
PEERTUBE_REDIS_PORT = builtins.toString redisPort;
|
|
||||||
PEERTUBE_SIGNUP_ENABLED = "false";
|
|
||||||
PEERTUBE_TRANSCODING_1080P = "true";
|
|
||||||
PEERTUBE_TRANSCODING_144P = "true";
|
|
||||||
PEERTUBE_TRANSCODING_360P = "true";
|
|
||||||
PEERTUBE_TRANSCODING_480P = "true";
|
|
||||||
PEERTUBE_TRANSCODING_720P = "true";
|
|
||||||
PEERTUBE_TRANSCODING_ENABLED = "true";
|
|
||||||
PEERTUBE_TRANSCODING_HLS_ENABLED = "true";
|
|
||||||
PEERTUBE_TRANSCODING_THREADS = "2";
|
|
||||||
PEERTUBE_TRUST_PROXY = ''["127.0.0.1","loopback"]'';
|
|
||||||
PEERTUBE_USER_VIDEO_QUOTA = "0";
|
|
||||||
PEERTUBE_WEBSERVER_HOSTNAME = domain;
|
|
||||||
};
|
|
||||||
secrets = map (s: "${s},type=env") [
|
|
||||||
"PEERTUBE_ADMIN_EMAIL"
|
|
||||||
"PEERTUBE_DB_PASSWORD"
|
|
||||||
"PEERTUBE_OBJECT_STORAGE_CREDENTIALS_ACCESS_KEY_ID"
|
|
||||||
"PEERTUBE_OBJECT_STORAGE_CREDENTIALS_SECRET_ACCESS_KEY"
|
|
||||||
"PEERTUBE_OBJECT_STORAGE_ENDPOINT"
|
|
||||||
"PEERTUBE_OBJECT_STORAGE_REGION"
|
|
||||||
"PEERTUBE_REDIS_AUTH"
|
|
||||||
"PEERTUBE_SECRET"
|
|
||||||
"PEERTUBE_SMTP_FROM"
|
|
||||||
"PEERTUBE_SMTP_HOSTNAME"
|
|
||||||
"PEERTUBE_SMTP_PASSWORD"
|
|
||||||
"PEERTUBE_SMTP_PORT"
|
|
||||||
"PEERTUBE_SMTP_USERNAME"
|
|
||||||
];
|
|
||||||
networks = [ networks."${user}".ref ];
|
|
||||||
publishPorts = [
|
|
||||||
"127.0.0.1:${port}:${containerPort}"
|
|
||||||
"127.0.0.1:${rtmpHostPort}:${rtmpContainerPort}"
|
|
||||||
];
|
|
||||||
addHosts = [ "auth.millironx.com:host-gateway" ];
|
|
||||||
volumes = [
|
|
||||||
"${stateDirectory}/data:/data"
|
|
||||||
"${stateDirectory}/config:/config"
|
|
||||||
"${peertubeAssetsDir}:/app/client/dist:ro"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
unitConfig.Requires = [ secrets.ref containers."${user}-db".ref ];
|
|
||||||
unitConfig.After = [ secrets.ref containers."${user}-db".ref ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
27
services/pihole.nix
Normal file
27
services/pihole.nix
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
{ config, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
age.secrets = {
|
||||||
|
pihole-credentials = {
|
||||||
|
file = ./../secrets/pihole.age;
|
||||||
|
owner = "root";
|
||||||
|
group = "root";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
virtualisation = {
|
||||||
|
quadlet = {
|
||||||
|
containers = {
|
||||||
|
pihole = {
|
||||||
|
containerConfig = {
|
||||||
|
image = "docker.io/pihole/pihole:2025.06.2";
|
||||||
|
publishPorts =
|
||||||
|
[ "53:53/tcp" "53:53/udp" "80:80/tcp" "443:443/tcp" ];
|
||||||
|
environmentFiles = [ config.age.secrets.pihole-credentials.path ];
|
||||||
|
networks = [ "bridge" ];
|
||||||
|
dns = [ "127.0.0.1" "194.242.2.9" "9.9.9.9" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
services.samba = {
|
services.samba = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = pkgs.sambaFull;
|
package = pkgs.sambaFull;
|
||||||
|
securityType = "user";
|
||||||
openFirewall = true;
|
openFirewall = true;
|
||||||
settings = {
|
settings = {
|
||||||
global = {
|
global = {
|
||||||
|
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
let port = "7327";
|
|
||||||
in {
|
|
||||||
services.searx = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
configureUwsgi = true;
|
|
||||||
uwsgiConfig = {
|
|
||||||
disable-logging = true;
|
|
||||||
http = ":${port}";
|
|
||||||
};
|
|
||||||
|
|
||||||
redisCreateLocally = true;
|
|
||||||
|
|
||||||
settings = {
|
|
||||||
general = {
|
|
||||||
instance_name = "Milliron X Search";
|
|
||||||
enable_metrics = false;
|
|
||||||
};
|
|
||||||
search = { autocomplete = "duckduckgo"; };
|
|
||||||
server = {
|
|
||||||
base_url = "https://search.millironx.com/";
|
|
||||||
limiter = true;
|
|
||||||
public_instance = true;
|
|
||||||
image_proxy = true;
|
|
||||||
method = "GET";
|
|
||||||
secret_key = "rC35eF8DRpJDqa";
|
|
||||||
};
|
|
||||||
ui = { query_in_title = false; };
|
|
||||||
hostnames = {
|
|
||||||
replace = { "(www.)?reddit.com$" = "old.reddit.com"; };
|
|
||||||
low_priority = [
|
|
||||||
"(.*.)?facebooks.com$"
|
|
||||||
"(.*.)?youtube.com$"
|
|
||||||
"(.*.)?youtu.be$"
|
|
||||||
"(.*.)?reddit.com$"
|
|
||||||
"(.*.)?redd.it$"
|
|
||||||
"(www.)?twitter.com$"
|
|
||||||
"(www.)?x.com$"
|
|
||||||
];
|
|
||||||
high_priority = [ "(.*.)?wikipedia.org$" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.caddy.virtualHosts."search.millironx.com".extraConfig = ''
|
|
||||||
reverse_proxy http://127.0.0.1:${port}
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
{ hostname, ... }: {
|
|
||||||
services.syncthing = let
|
|
||||||
devices = {
|
|
||||||
bracket.id =
|
|
||||||
"6I5AHYC-IWSO3SZ-TZY4SSR-Z7MGB2V-QMCMJXE-QW5JBQV-DBDU5YV-4LRLKQW";
|
|
||||||
boozer.id =
|
|
||||||
"JKLIUHR-SBAVQCX-43ETUQR-M4ZZA75-JXK7EOF-F5RJBG7-PT363R6-MJ6WLQ4";
|
|
||||||
} // (if hostname != "odyssey" then {
|
|
||||||
odyssey.id =
|
|
||||||
"YC6NDSU-2JRS4MY-BSM4B5V-FWPXKSJ-S573II2-HDOSWSN-DVIDORQ-UUHTKQB";
|
|
||||||
} else
|
|
||||||
{ }) // (if hostname != "corianne" then {
|
|
||||||
corianne.id =
|
|
||||||
"EN5KDDZ-F6DYDSR-KK35M2M-BVGBU4W-MVC4ENT-5EPWA6M-BBJPIBU-EQTPRQX";
|
|
||||||
} else
|
|
||||||
{ });
|
|
||||||
in {
|
|
||||||
enable = true;
|
|
||||||
settings = {
|
|
||||||
inherit devices;
|
|
||||||
folders = let deviceNames = builtins.attrNames devices;
|
|
||||||
in {
|
|
||||||
Logseq = {
|
|
||||||
label = "Logseq";
|
|
||||||
id = "kkqs5-4upcf";
|
|
||||||
path = "~/Logseq";
|
|
||||||
type = "sendreceive";
|
|
||||||
versioning = {
|
|
||||||
type = "trashcan";
|
|
||||||
params.cleanoutDays = 14;
|
|
||||||
};
|
|
||||||
devices = deviceNames;
|
|
||||||
};
|
|
||||||
SyncBucket = {
|
|
||||||
label = "SyncBucket";
|
|
||||||
id = "9l6gb-rkyou";
|
|
||||||
path = "~/SyncBucket";
|
|
||||||
type = "sendreceive";
|
|
||||||
versioning = {
|
|
||||||
type = "trashcan";
|
|
||||||
params.cleanoutDays = 14;
|
|
||||||
};
|
|
||||||
devices = deviceNames;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
options = { urAccepted = -1; };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
{ ... }: {
|
|
||||||
services.tailscale = {
|
|
||||||
enable = true;
|
|
||||||
useRoutingFeatures = "server";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,170 +0,0 @@
|
||||||
{ config, pkgs, home-manager-quadlet-nix, ... }:
|
|
||||||
let
|
|
||||||
user = "vaultwarden";
|
|
||||||
port = "9285";
|
|
||||||
containerPort = port;
|
|
||||||
authentikPort = "9000";
|
|
||||||
stateDirectory = "/var/lib/${user}";
|
|
||||||
servicePaths = [ "data" ];
|
|
||||||
databasePaths = [ "database" ];
|
|
||||||
in {
|
|
||||||
age.secrets."vaultwarden.toml" = {
|
|
||||||
file = ./../secrets/vaultwarden.toml.age;
|
|
||||||
owner = user;
|
|
||||||
};
|
|
||||||
|
|
||||||
millironx.podman-secrets.vaultwarden = {
|
|
||||||
inherit user;
|
|
||||||
secrets-files = [ config.age.secrets."vaultwarden.toml".path ];
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.tmpfiles.rules =
|
|
||||||
map (d: "d ${stateDirectory}/${d} 1775 ${user} ${user} -")
|
|
||||||
([ "" ] ++ servicePaths ++ databasePaths);
|
|
||||||
|
|
||||||
services.borgmatic.configurations."${config.networking.hostName}" = {
|
|
||||||
source_directories = map (d: "${stateDirectory}/${d}") servicePaths;
|
|
||||||
postgresql_databases = [{
|
|
||||||
name = user;
|
|
||||||
psql_command =
|
|
||||||
"/run/wrappers/bin/sudo -iu ${user} ${pkgs.podman}/bin/podman exec ${user}-db psql --username=${user}";
|
|
||||||
pg_dump_command =
|
|
||||||
"/run/wrappers/bin/sudo -iu ${user} ${pkgs.podman}/bin/podman exec ${user}-db pg_dump --username=${user}";
|
|
||||||
pg_restore_command =
|
|
||||||
"/run/wrappers/bin/sudo -iu ${user} ${pkgs.podman}/bin/podman exec ${user}-db pg_restore --username=${user}";
|
|
||||||
}];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.caddy.virtualHosts."vault.millironx.com".extraConfig = ''
|
|
||||||
# See <https://github.com/dani-garcia/vaultwarden/wiki/Proxy-examples>
|
|
||||||
encode zstd gzip
|
|
||||||
header / {
|
|
||||||
Strict-Transport-Security "max-age=31536000;"
|
|
||||||
X-XSS-Protection "0"
|
|
||||||
X-Frame-Options "DENY"
|
|
||||||
X-Robots-Tag "noindex, nofollow"
|
|
||||||
X-Content-Type-Options "nosniff"
|
|
||||||
-Server
|
|
||||||
-X-Powered-By
|
|
||||||
-Last-Modified
|
|
||||||
}
|
|
||||||
|
|
||||||
@admin {
|
|
||||||
path /admin*
|
|
||||||
not remote_ip private_ranges 100.64.0.0/10
|
|
||||||
}
|
|
||||||
respond @admin "Access denied to remote clients. Use localhost or VPN." 403
|
|
||||||
|
|
||||||
reverse_proxy http://127.0.0.1:${port} {
|
|
||||||
header_up X-Real-IP {remote_host}
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
|
|
||||||
services.crowdsec = {
|
|
||||||
localConfig.acquisitions = [{
|
|
||||||
source = "journalctl";
|
|
||||||
journalctl_filter = [ "_SYSTEMD_USER_UNIT=${user}.service" ];
|
|
||||||
labels.type = "bitwarden";
|
|
||||||
}];
|
|
||||||
hub.collections = [ "MariuszKociubinski/bitwarden" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
users.users."${user}" = {
|
|
||||||
group = user;
|
|
||||||
isNormalUser = true;
|
|
||||||
home = stateDirectory;
|
|
||||||
createHome = true;
|
|
||||||
linger = true;
|
|
||||||
autoSubUidGidRange = true;
|
|
||||||
};
|
|
||||||
users.groups."${user}" = { };
|
|
||||||
|
|
||||||
home-manager.users."${user}" = { config, osConfig, ... }: {
|
|
||||||
imports = [ home-manager-quadlet-nix ];
|
|
||||||
|
|
||||||
home.stateVersion = "25.05";
|
|
||||||
|
|
||||||
virtualisation.quadlet = let
|
|
||||||
inherit (config.virtualisation.quadlet) containers;
|
|
||||||
inherit (config.virtualisation.quadlet) networks;
|
|
||||||
secrets = osConfig.millironx.podman-secrets.vaultwarden;
|
|
||||||
in {
|
|
||||||
autoUpdate.enable = true;
|
|
||||||
autoEscape = true;
|
|
||||||
|
|
||||||
networks."${user}" = { };
|
|
||||||
|
|
||||||
containers = {
|
|
||||||
"${user}-db" = {
|
|
||||||
autoStart = true;
|
|
||||||
containerConfig = {
|
|
||||||
image = "docker.io/library/postgres:16";
|
|
||||||
environments = {
|
|
||||||
POSTGRES_DB = user;
|
|
||||||
POSTGRES_USER = user;
|
|
||||||
};
|
|
||||||
secrets = [
|
|
||||||
"POSTGRES_PASSWORD,type=env"
|
|
||||||
"POSTGRES_PASSWORD,type=env,target=PGPASSWORD"
|
|
||||||
];
|
|
||||||
healthCmd = "pg_isready -d $\${POSTGRES_DB} -U $\${POSTGRES_USER}";
|
|
||||||
healthInterval = "30s";
|
|
||||||
healthRetries = 5;
|
|
||||||
healthStartPeriod = "20s";
|
|
||||||
volumes =
|
|
||||||
[ "${stateDirectory}/database:/var/lib/postgresql/data:U" ];
|
|
||||||
networks = [ networks."${user}".ref ];
|
|
||||||
};
|
|
||||||
unitConfig.Requires = [ secrets.ref ];
|
|
||||||
unitConfig.After = [ secrets.ref ];
|
|
||||||
};
|
|
||||||
|
|
||||||
"${user}" = {
|
|
||||||
autoStart = true;
|
|
||||||
containerConfig = {
|
|
||||||
image = "ghcr.io/dani-garcia/vaultwarden:latest";
|
|
||||||
addHosts = [ "auth.millironx.com:host-gateway" ];
|
|
||||||
environments = {
|
|
||||||
DOMAIN = "https://vault.millironx.com";
|
|
||||||
ROCKET_PORT = port;
|
|
||||||
PUSH_ENABLED = "true";
|
|
||||||
SIGNUPS_ALLOWED = "false";
|
|
||||||
SMTP_FROM_NAME = "Milliron X Vault";
|
|
||||||
SMTP_SECURITY = "force_tls";
|
|
||||||
SSO_ENABLED = "true";
|
|
||||||
SSO_ONLY = "true";
|
|
||||||
SSO_AUTHORITY =
|
|
||||||
"https://auth.millironx.com/application/o/vaultwarden/";
|
|
||||||
SSO_SCOPES = "openid profile email offline_access";
|
|
||||||
# Needed to keep token expiration errors from happening
|
|
||||||
# See <https://github.com/dani-garcia/vaultwarden/issues/6311#issuecomment-3929409097>
|
|
||||||
SSO_AUTH_ONLY_NOT_SESSION = "true";
|
|
||||||
};
|
|
||||||
secrets = map (s: "${s},type=env") [
|
|
||||||
"ADMIN_TOKEN"
|
|
||||||
"DATABASE_URL"
|
|
||||||
"PUSH_INSTALLATION_ID"
|
|
||||||
"PUSH_INSTALLATION_KEY"
|
|
||||||
"SMTP_FROM"
|
|
||||||
"SMTP_HOST"
|
|
||||||
"SMTP_PORT"
|
|
||||||
"SMTP_PASSWORD"
|
|
||||||
"SMTP_USERNAME"
|
|
||||||
"SSO_CLIENT_ID"
|
|
||||||
"SSO_CLIENT_SECRET"
|
|
||||||
"YUBICO_CLIENT_ID"
|
|
||||||
"YUBICO_SECRET_KEY"
|
|
||||||
];
|
|
||||||
volumes = [ "${stateDirectory}/data:/data:U" ];
|
|
||||||
networks = [ networks."${user}".ref ];
|
|
||||||
publishPorts = [ "127.0.0.1:${port}:${containerPort}" ];
|
|
||||||
};
|
|
||||||
unitConfig.Requires = [ secrets.ref containers."${user}-db".ref ];
|
|
||||||
unitConfig.After = [ secrets.ref containers."${user}-db".ref ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -15,8 +15,6 @@ in {
|
||||||
rig-install
|
rig-install
|
||||||
];
|
];
|
||||||
|
|
||||||
age.secrets.firefox-policy.file = ./../../secrets/darwin-policies-json.age;
|
|
||||||
|
|
||||||
# Use a custom configuration.nix location.
|
# Use a custom configuration.nix location.
|
||||||
# $ darwin-rebuild switch -I darwin-config=$HOME/.config/nixpkgs/darwin/configuration.nix
|
# $ darwin-rebuild switch -I darwin-config=$HOME/.config/nixpkgs/darwin/configuration.nix
|
||||||
environment.darwinConfig = "$HOME/.config/home-manager/configuration.nix";
|
environment.darwinConfig = "$HOME/.config/home-manager/configuration.nix";
|
||||||
|
|
@ -26,35 +24,9 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
# Auto upgrade nix package and the daemon service.
|
# Auto upgrade nix package and the daemon service.
|
||||||
nix = {
|
nix.enable = true;
|
||||||
enable = true;
|
#services.nix-daemon.tempDir = "/nix/tmp";
|
||||||
gc = {
|
nix.package = pkgs.nix;
|
||||||
automatic = true;
|
|
||||||
interval = { Weekday = 1; };
|
|
||||||
options = ''
|
|
||||||
--delete-older-than 90d
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
settings = {
|
|
||||||
substituters =
|
|
||||||
[ "https://nix-community.cachix.org" "https://cache.nixos.org/" ];
|
|
||||||
trusted-public-keys = [
|
|
||||||
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Needed for rosetta-builder, see
|
|
||||||
# <https://github.com/cpick/nix-rosetta-builder/issues/40#issuecomment-3368602687>
|
|
||||||
# <https://github.com/cpick/nix-rosetta-builder/issues/37>
|
|
||||||
linux-builder = {
|
|
||||||
enable = true;
|
|
||||||
ephemeral = true;
|
|
||||||
};
|
|
||||||
extraOptions = ''
|
|
||||||
extra-platforms = x86_64-darwin
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
nix-rosetta-builder.onDemand = true;
|
|
||||||
|
|
||||||
# Create /etc/zshrc that loads the nix-darwin environment.
|
# Create /etc/zshrc that loads the nix-darwin environment.
|
||||||
programs.zsh.enable = true; # default shell on catalina
|
programs.zsh.enable = true; # default shell on catalina
|
||||||
|
|
@ -99,12 +71,11 @@ in {
|
||||||
in [
|
in [
|
||||||
(sysApp "Firefox")
|
(sysApp "Firefox")
|
||||||
(sysApp "Thunderbird")
|
(sysApp "Thunderbird")
|
||||||
(sysApp "Microsoft Outlook")
|
|
||||||
(sysApp "Zed")
|
|
||||||
(sysApp "Logseq")
|
(sysApp "Logseq")
|
||||||
|
(sysApp "Zed")
|
||||||
(sysApp "Steam")
|
(sysApp "Steam")
|
||||||
(localApp "Instinct Dashboard")
|
(chromeApp "Instinct Dashboard")
|
||||||
(localApp "Carestream")
|
(chromeApp "Carestream")
|
||||||
];
|
];
|
||||||
show-process-indicators = true;
|
show-process-indicators = true;
|
||||||
show-recents = false;
|
show-recents = false;
|
||||||
|
|
@ -159,11 +130,6 @@ in {
|
||||||
--user=${config.system.primaryUser} \
|
--user=${config.system.primaryUser} \
|
||||||
--set-home \
|
--set-home \
|
||||||
_rig-install ${r-version}
|
_rig-install ${r-version}
|
||||||
|
|
||||||
echo "Applying custom defaults..."
|
|
||||||
/usr/bin/defaults import \
|
|
||||||
/Library/Preferences/org.mozilla.firefox \
|
|
||||||
${config.age.secrets.firefox-policy.path}
|
|
||||||
'';
|
'';
|
||||||
|
|
||||||
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
||||||
|
|
@ -192,7 +158,15 @@ in {
|
||||||
no_quarantine = true;
|
no_quarantine = true;
|
||||||
|
|
||||||
};
|
};
|
||||||
taps = [ "r-lib/rig" ];
|
taps = [
|
||||||
|
"homebrew/services"
|
||||||
|
{
|
||||||
|
name = "millironx/millironx";
|
||||||
|
clone_target =
|
||||||
|
"https://code.millironx.com/millironx/homebrew-millironx.git";
|
||||||
|
}
|
||||||
|
"r-lib/rig"
|
||||||
|
];
|
||||||
brews = [
|
brews = [
|
||||||
"borgbackup/tap/borgbackup-fuse"
|
"borgbackup/tap/borgbackup-fuse"
|
||||||
"buildkit"
|
"buildkit"
|
||||||
|
|
@ -203,17 +177,23 @@ in {
|
||||||
"docker"
|
"docker"
|
||||||
"docker-buildx"
|
"docker-buildx"
|
||||||
"docker-credential-helper"
|
"docker-credential-helper"
|
||||||
|
"firefoxpwa"
|
||||||
"mpv"
|
"mpv"
|
||||||
];
|
];
|
||||||
casks = [
|
casks = [
|
||||||
"alt-tab"
|
"alt-tab"
|
||||||
"dash"
|
"anki"
|
||||||
"db-browser-for-sqlite"
|
"db-browser-for-sqlite"
|
||||||
|
"dolphin"
|
||||||
"firefox"
|
"firefox"
|
||||||
|
"freetube"
|
||||||
|
"ghostty"
|
||||||
"inkscape"
|
"inkscape"
|
||||||
"iterm2"
|
"iterm2"
|
||||||
|
"logi-options+"
|
||||||
"logseq"
|
"logseq"
|
||||||
"macfuse"
|
"macfuse"
|
||||||
|
"musescore"
|
||||||
"nextcloud"
|
"nextcloud"
|
||||||
"openrct2"
|
"openrct2"
|
||||||
"qownnotes"
|
"qownnotes"
|
||||||
|
|
@ -221,7 +201,6 @@ in {
|
||||||
"rig"
|
"rig"
|
||||||
"rstudio"
|
"rstudio"
|
||||||
"signal"
|
"signal"
|
||||||
"skim"
|
|
||||||
"slack"
|
"slack"
|
||||||
"stats"
|
"stats"
|
||||||
"steam"
|
"steam"
|
||||||
|
|
@ -231,7 +210,6 @@ in {
|
||||||
"ungoogled-chromium"
|
"ungoogled-chromium"
|
||||||
"veracrypt"
|
"veracrypt"
|
||||||
"vlc"
|
"vlc"
|
||||||
"vienna"
|
|
||||||
"vorta"
|
"vorta"
|
||||||
"zed"
|
"zed"
|
||||||
"zotero"
|
"zotero"
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,9 @@
|
||||||
imports = [
|
imports = [
|
||||||
./hardware-configuration/bosephus.nix
|
./hardware-configuration/bosephus.nix
|
||||||
./hardware-configuration/bosephus-external-drives.nix
|
./hardware-configuration/bosephus-external-drives.nix
|
||||||
./../../services/jellyfin.nix
|
./../../services/nixos-update.nix
|
||||||
./../../services/samba.nix
|
./../../services/samba.nix
|
||||||
|
./../../services/pihole.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
# Bootloader.
|
# Bootloader.
|
||||||
|
|
@ -17,8 +18,8 @@
|
||||||
boot.loader.efi.canTouchEfiVariables = true;
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
# Ignore lid - so I can close without having the system go into sleep mode
|
# Ignore lid - so I can close without having the system go into sleep mode
|
||||||
services.logind.settings.Login.HandleLidSwitch = "ignore";
|
services.logind.lidSwitch = "ignore";
|
||||||
services.logind.settings.Login.HandleLidSwitchDocked = "ignore";
|
services.logind.lidSwitchDocked = "ignore";
|
||||||
|
|
||||||
# Secrets
|
# Secrets
|
||||||
age.secrets = {
|
age.secrets = {
|
||||||
|
|
|
||||||
|
|
@ -4,32 +4,36 @@
|
||||||
{ config, lib, pkgs, modulesPath, ... }:
|
{ config, lib, pkgs, modulesPath, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
imports =
|
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
|
||||||
[ (modulesPath + "/installer/scan/not-detected.nix")
|
|
||||||
];
|
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" "sr_mod" ];
|
boot.initrd.availableKernelModules =
|
||||||
|
[ "xhci_pci" "ahci" "ehci_pci" "usb_storage" "sd_mod" "sdhci_pci" ];
|
||||||
boot.initrd.kernelModules = [ ];
|
boot.initrd.kernelModules = [ ];
|
||||||
boot.kernelModules = [ "kvm-intel" ];
|
boot.kernelModules = [ "kvm-amd" ];
|
||||||
boot.extraModulePackages = [ ];
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
fileSystems."/" =
|
fileSystems."/" = {
|
||||||
{ device = "/dev/disk/by-uuid/9abca97b-c2d6-47e7-ac44-acc1d6171d44";
|
device = "/dev/disk/by-uuid/db76854b-5b08-40a6-8ba9-a160690d3f7c";
|
||||||
fsType = "ext4";
|
fsType = "ext4";
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/boot" =
|
fileSystems."/boot" = {
|
||||||
{ device = "/dev/disk/by-uuid/EA34-1939";
|
device = "/dev/disk/by-uuid/5D5B-B53A";
|
||||||
fsType = "vfat";
|
fsType = "vfat";
|
||||||
options = [ "fmask=0077" "dmask=0077" ];
|
options = [ "fmask=0077" "dmask=0077" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
swapDevices =
|
swapDevices =
|
||||||
[ { device = "/dev/disk/by-uuid/230c09c1-0bd2-4961-85cf-8aa58fe15bd9"; }
|
[{ device = "/dev/disk/by-uuid/f912c60e-710f-4ea7-b2da-df25e7a44ced"; }];
|
||||||
];
|
|
||||||
|
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||||
|
# (the default) this is the recommended approach. When using systemd-networkd it's
|
||||||
|
# still possible to use this option, but it's recommended to use it in conjunction
|
||||||
|
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
|
||||||
|
networking.useDHCP = lib.mkDefault true;
|
||||||
|
# networking.interfaces.wlp1s0.useDHCP = lib.mkDefault true;
|
||||||
|
|
||||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
hardware.cpu.amd.updateMicrocode =
|
||||||
|
lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,21 +3,8 @@
|
||||||
{
|
{
|
||||||
imports = [ # Include the results of the hardware scan.
|
imports = [ # Include the results of the hardware scan.
|
||||||
./hardware-configuration/mcentire.nix
|
./hardware-configuration/mcentire.nix
|
||||||
./../../modules/podman-secrets.nix
|
./../../services/nixos-update.nix
|
||||||
./../../services/borgmatic.nix
|
|
||||||
./../../services/caddy.nix
|
|
||||||
./../../services/crowdsec.nix
|
./../../services/crowdsec.nix
|
||||||
./../../services/authentik.nix
|
|
||||||
./../../services/audiobookshelf.nix
|
|
||||||
./../../services/fireflyiii.nix
|
|
||||||
./../../services/freshrss.nix
|
|
||||||
./../../services/immich.nix
|
|
||||||
./../../services/navidrome.nix
|
|
||||||
./../../services/openssh.nix
|
|
||||||
./../../services/peertube.nix
|
|
||||||
./../../services/searxng.nix
|
|
||||||
./../../services/tailscale.nix
|
|
||||||
./../../services/vaultwarden.nix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
# Use the GRUB 2 boot loader.
|
# Use the GRUB 2 boot loader.
|
||||||
|
|
@ -28,7 +15,6 @@
|
||||||
useDHCP = false;
|
useDHCP = false;
|
||||||
interfaces.eth0.useDHCP = true;
|
interfaces.eth0.useDHCP = true;
|
||||||
hostName = "mcentire"; # Define your hostname.
|
hostName = "mcentire"; # Define your hostname.
|
||||||
firewall.allowedTCPPorts = [ 80 443 ];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Set your time zone.
|
# Set your time zone.
|
||||||
|
|
@ -54,7 +40,7 @@
|
||||||
millironx = {
|
millironx = {
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
description = "Thomas A. Christensen II";
|
description = "Thomas A. Christensen II";
|
||||||
extraGroups = [ "adm" "wheel" ];
|
extraGroups = [ "wheel" ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -65,30 +51,11 @@
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [ neovim inetutils mtr sysstat git ];
|
environment.systemPackages = with pkgs; [ neovim inetutils mtr sysstat git ];
|
||||||
|
|
||||||
age.secrets.redis-password = {
|
|
||||||
file = ./../../secrets/redis-password.age;
|
|
||||||
owner = config.services.redis.servers.redis.user;
|
|
||||||
};
|
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
# Do not "enable" database services, but include the package configuration
|
openssh.enable = true;
|
||||||
# so that borgmatic does not freak out about unset variables
|
tailscale.enable = true;
|
||||||
postgresql.package = pkgs.postgresql_17;
|
|
||||||
|
|
||||||
redis.servers.redis = {
|
|
||||||
enable = true;
|
|
||||||
# Apparently, a port is actually required, see
|
|
||||||
# <https://discourse.nixos.org/t/how-to-setup-redis-server-configuration-nix/21878/7>
|
|
||||||
# Evaluating this in the Nix repl confirms that the port is set
|
|
||||||
# incorrectly in the final config when left out
|
|
||||||
port = 6379;
|
|
||||||
bind = "0.0.0.0";
|
|
||||||
requirePassFile = config.age.secrets.redis-password.path;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
virtualisation.quadlet.enable = true;
|
|
||||||
|
|
||||||
system.stateVersion = "25.05"; # Did you read the comment?
|
system.stateVersion = "25.05"; # Did you read the comment?
|
||||||
nix = { extraOptions = "experimental-features = nix-command flakes"; };
|
nix = { extraOptions = "experimental-features = nix-command flakes"; };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue