Compare commits
4 Commits
master
...
1360209574
| Author | SHA1 | Date | |
|---|---|---|---|
|
1360209574
|
|||
|
5d7b6e7d62
|
|||
|
2c59f6b7c2
|
|||
|
4e8a67a391
|
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
secrets
|
||||||
|
Timeline.org
|
||||||
7
Makefile
7
Makefile
@@ -1,7 +0,0 @@
|
|||||||
DIR=$(HOME)/Projects/zion
|
|
||||||
|
|
||||||
switch:
|
|
||||||
nixos-rebuild switch --no-reexec --target-host root@zion \
|
|
||||||
--build-host root@zion --flake path://$(DIR)#zion
|
|
||||||
|
|
||||||
.DEFAULT_GOAL := switch
|
|
||||||
45
README.org
45
README.org
@@ -8,46 +8,9 @@
|
|||||||
|
|
||||||
- ZFS pool configuration: hardware-configuration.nix
|
- ZFS pool configuration: hardware-configuration.nix
|
||||||
- Network configuration: networking.nix
|
- Network configuration: networking.nix
|
||||||
- Synchronization and backup services: datasync.nix
|
- Printing and scanner server: printing.nix
|
||||||
- Web services and reverse proxy: webstack.nix
|
- Nginx and PostgreSQL: webstack.nix
|
||||||
- Development tools: devops.nix
|
- Radicale and Syncthing: datasync.nix
|
||||||
- Smartd: monitoring.nix
|
- Gitea: devops.nix
|
||||||
- Systemd services and timers: periodic.nix
|
|
||||||
- Curated articles: information.nix
|
|
||||||
|
|
||||||
All the modules are imported in *configuration.nix*
|
All the modules are imported in *configuration.nix*
|
||||||
|
|
||||||
** Installation
|
|
||||||
|
|
||||||
1. Download the sdcard image
|
|
||||||
2. Use initial config file
|
|
||||||
|
|
||||||
#+begin_src shell
|
|
||||||
cp install.nix configuration.nix
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
3. Move the repo to the server and the agenix key
|
|
||||||
|
|
||||||
#+begin_src shell
|
|
||||||
scp -r Projects/zion zion:/home/nixos/system
|
|
||||||
scp .ssh/zion root@zion:/etc/ssh/id_ed25519
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
4. Mount the firmware partition
|
|
||||||
|
|
||||||
#+begin_src shell
|
|
||||||
mount /dev/mmcblk1p1 /boot
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
5. Rebuild the system using Flakes
|
|
||||||
|
|
||||||
#+begin_src shell
|
|
||||||
nix-shell -p git
|
|
||||||
sudo nixos-rebuild switch --flake /home/nixos/system#zion
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
6. Restore the SQL databases
|
|
||||||
|
|
||||||
#+begin_src shell
|
|
||||||
gunzip -c /vault/backups/zion/databases/all.sql.gz | psql -U postgres
|
|
||||||
#+end_src
|
|
||||||
|
|||||||
@@ -1,283 +1,108 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
{
|
{
|
||||||
config,
|
# NixOS wants to enable GRUB by default
|
||||||
inputs,
|
boot.loader.grub.enable = false;
|
||||||
pkgs,
|
# Enables the generation of /boot/extlinux/extlinux.conf
|
||||||
lib,
|
boot.loader.generic-extlinux-compatible.enable = true;
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with pkgs;
|
# A bunch of boot parameters needed for optimal runtime on RPi 3B
|
||||||
|
boot.kernelParams = ["cma=32M"];
|
||||||
{
|
boot.loader.raspberryPi = {
|
||||||
# Kernel configuration
|
|
||||||
boot = {
|
|
||||||
blacklistedKernelModules = [
|
|
||||||
"btusb"
|
|
||||||
"bluetooth"
|
|
||||||
];
|
|
||||||
kernelParams = [
|
|
||||||
"zfs.zfs_arc_max=8589934592"
|
|
||||||
"zfs.zfs_arc_min=1073741824"
|
|
||||||
];
|
|
||||||
supportedFilesystems = [ "zfs" ];
|
|
||||||
zfs = {
|
|
||||||
requestEncryptionCredentials = false;
|
|
||||||
extraPools = [ "vault" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Secure boot using lanzaboote
|
|
||||||
boot.loader = {
|
|
||||||
efi.canTouchEfiVariables = true;
|
|
||||||
systemd-boot = {
|
|
||||||
enable = true;
|
enable = true;
|
||||||
configurationLimit = 50;
|
version = 3;
|
||||||
editor = false;
|
uboot.enable = true;
|
||||||
};
|
firmwareConfig = ''
|
||||||
timeout = 3;
|
hdmi_force_hotplug=1
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
# Declare system packages
|
environment.systemPackages = with pkgs; [
|
||||||
environment.systemPackages = [
|
raspberrypi-tools
|
||||||
libraspberrypi
|
|
||||||
htop
|
|
||||||
neovim
|
|
||||||
git
|
git
|
||||||
inputs.agenix.packages.${config.nixpkgs.localSystem.system}.default
|
tmux
|
||||||
|
htop
|
||||||
|
vim
|
||||||
];
|
];
|
||||||
|
|
||||||
|
# !!! Adding a swap file is optional, but strongly recommended!
|
||||||
|
swapDevices = [ { device = "/swapfile"; size = 1024; } ];
|
||||||
|
|
||||||
# Configure basic SSH access
|
# Configure basic SSH access
|
||||||
services.openssh = {
|
services.openssh = {
|
||||||
enable = true;
|
enable = true;
|
||||||
settings = {
|
permitRootLogin = "yes";
|
||||||
PermitRootLogin = "yes";
|
|
||||||
PasswordAuthentication = false;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Cleanup tmp on startup
|
# Cleanup tmp on startup
|
||||||
boot.tmp.cleanOnBoot = true;
|
boot.cleanTmpDir = true;
|
||||||
|
|
||||||
|
# Set hostname
|
||||||
|
networking.hostName = "zion";
|
||||||
|
|
||||||
# Create coolneng user
|
# Create coolneng user
|
||||||
users.users.coolneng = {
|
users.users.coolneng = {
|
||||||
isNormalUser = true;
|
isNormalUser = true;
|
||||||
home = "/home/coolneng";
|
home = "/home/coolneng";
|
||||||
extraGroups = [
|
extraGroups = [ "wheel" "lp" "scanner" ];
|
||||||
"wheel"
|
openssh.authorizedKeys.keys = [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDG7JtfAqcbZV28wkNTfSWSqTOo5buH+dyT0w6SlTqq+KFh5DxREB0yGuM1UfjLpyLQ0XI7UbhCwNG28Li4yv/hwPGq63TF1kl+w4sjQKFn4bOUv1NvsfSN3oTamjfYoVsrapCiXqOvZkzEKMF47MSwOfPkqZ6ihU5V3INA0IZbl1Ri+r9MsIzvY76ZHBiF6rVqQJjdXVDbcLMViOrM56FpyK+ICo+uTkErsEbYFwevVTv9memOh778RRPesBobpZjggWOI4HXXxqk35myInYjHve9K4ox6YZMjwnwnEftONr2HyoBBcBNT+wWd1jtYxCoCWQ3vVkn4LGBDOQ3+HKb4rT3JxI66VfFyQWGJPdgJL5/ZNRlBqA7CpAtE7JaR6l7d3mCCoGW2B0atWiEXecwb8dz4CzzYm1r9Wz27L74OtPzUqcV7mQjCVDcnRsY/MtfhzyWzhB3tujVqnRtF3VrFSrm0YXS1ZWG4dltX1cfgud8s8XwwBKcFw5NdCrVxq3nRMNlGcSqbXC+RnrkK/i6ciAriZdXgFrmnBl+6qEmqIO15u2IPvDhnQs18DzRkHnPQegphhHhHix5aaqNbLfSRZNCTQaqE774X+0kuU/RWylI4muIyf4k9x+et4txeU2OC6l0W0LMpbsELzXIRr/ZBFrGHbE7/KLi8HNiAJ0KmAQ== coolneng@monolith" ];
|
||||||
"docker"
|
shell = "/run/current-system/sw/bin/fish";
|
||||||
];
|
|
||||||
openssh.authorizedKeys.keys = [
|
|
||||||
# panacea
|
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFRqINHR7/zc+c3/PuR+NeSsBHXXzBiEtFWSK6QaxQTW coolneng@panacea"
|
|
||||||
# caravanserai
|
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIX0poiPhFLFh88fhpLFX7n1oCevVRyTxe9ZvGmjPq8n zion"
|
|
||||||
];
|
|
||||||
shell = "${fish}/bin/fish";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Set neovim as default editor
|
# Set vim as default editor
|
||||||
programs.neovim = {
|
programs.vim.defaultEditor = true;
|
||||||
enable = true;
|
|
||||||
defaultEditor = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Set timezone and synchronize NTP
|
# Set timezone and synchronize NTP
|
||||||
time.timeZone = "Europe/Brussels";
|
time.timeZone = "Europe/Brussels";
|
||||||
services.timesyncd.enable = true;
|
services.timesyncd.enable = true;
|
||||||
|
|
||||||
|
# Enable zfs support
|
||||||
|
networking.hostId = "bb26c304";
|
||||||
|
boot.supportedFilesystems = [ "zfs" ];
|
||||||
|
boot.zfs.extraPools = [ "vault" ];
|
||||||
|
|
||||||
# Scrub zpool monthly
|
# Scrub zpool monthly
|
||||||
services.zfs.autoScrub = {
|
services.zfs.autoScrub = {
|
||||||
enable = true;
|
enable = true;
|
||||||
interval = "monthly";
|
interval = "monthly";
|
||||||
};
|
};
|
||||||
|
|
||||||
# Run Nix garbage collector, while avoiding recompilation and enable flakes
|
# Auto-upgrade the system and reboot if needed
|
||||||
nix = {
|
|
||||||
settings = {
|
|
||||||
auto-optimise-store = true;
|
|
||||||
trusted-users = [
|
|
||||||
"root"
|
|
||||||
"coolneng"
|
|
||||||
];
|
|
||||||
lazy-trees = true;
|
|
||||||
eval-cores = 2;
|
|
||||||
};
|
|
||||||
gc = {
|
|
||||||
automatic = true;
|
|
||||||
options = "--delete-older-than 14d";
|
|
||||||
dates = "Mon 03:00";
|
|
||||||
};
|
|
||||||
extraOptions = ''
|
|
||||||
keep-outputs = true
|
|
||||||
keep-derivations = true
|
|
||||||
gc-keep-outputs = true
|
|
||||||
experimental-features = nix-command flakes
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
# Use same version of nixpkgs for nix-shell
|
|
||||||
nix.nixPath =
|
|
||||||
let
|
|
||||||
path = toString ./.;
|
|
||||||
in
|
|
||||||
[
|
|
||||||
"nixpkgs=${inputs.nixpkgs}"
|
|
||||||
"nixos-config=${path}/configuration.nix"
|
|
||||||
];
|
|
||||||
|
|
||||||
# Configure fish shell
|
|
||||||
programs.fish.enable = true;
|
|
||||||
users.users.root = {
|
|
||||||
shell = "${fish}/bin/fish";
|
|
||||||
openssh.authorizedKeys.keys = config.users.users.coolneng.openssh.authorizedKeys.keys;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Keep logs for a month
|
|
||||||
services.journald.extraConfig = "MaxRetentionSec=4week";
|
|
||||||
|
|
||||||
# Increase inotify limits and maximum buffer size
|
|
||||||
boot.kernel.sysctl = {
|
|
||||||
"fs.inotify.max_user_watches" = 204800;
|
|
||||||
"net.core.rmem_max" = 2500000;
|
|
||||||
"net.core.wmem_max" = 2500000;
|
|
||||||
};
|
|
||||||
|
|
||||||
# MOTD message
|
|
||||||
programs.fish.interactiveShellInit = "${./scripts/motd.sh}";
|
|
||||||
|
|
||||||
# NixOS version
|
|
||||||
system.stateVersion = "24.11";
|
|
||||||
|
|
||||||
# Specify secrets
|
|
||||||
age = {
|
|
||||||
secrets.wireguard = {
|
|
||||||
file = secrets/wireguard.age;
|
|
||||||
owner = "systemd-network";
|
|
||||||
group = "systemd-network";
|
|
||||||
};
|
|
||||||
secrets.syncthing.file = secrets/syncthing.age;
|
|
||||||
secrets.msmtp.file = secrets/msmtp.age;
|
|
||||||
secrets.gitea = {
|
|
||||||
file = secrets/gitea.age;
|
|
||||||
owner = "gitea";
|
|
||||||
group = "gitea";
|
|
||||||
};
|
|
||||||
secrets.miniflux = {
|
|
||||||
file = secrets/miniflux.age;
|
|
||||||
owner = "miniflux";
|
|
||||||
group = "miniflux";
|
|
||||||
};
|
|
||||||
secrets.git = {
|
|
||||||
file = secrets/git.age;
|
|
||||||
owner = "coolneng";
|
|
||||||
group = "users";
|
|
||||||
};
|
|
||||||
# HACK The owner and group is set by systemd due to the use of DynamicUser
|
|
||||||
secrets.dendrite = {
|
|
||||||
file = secrets/dendrite.age;
|
|
||||||
owner = "63026";
|
|
||||||
group = "63026";
|
|
||||||
};
|
|
||||||
secrets.dendrite-postgres = {
|
|
||||||
file = secrets/dendrite-postgres.age;
|
|
||||||
owner = "63026";
|
|
||||||
group = "63026";
|
|
||||||
};
|
|
||||||
secrets.telegram = {
|
|
||||||
file = secrets/telegram.age;
|
|
||||||
};
|
|
||||||
secrets.mqtt-sender = {
|
|
||||||
file = secrets/mqtt-sender.age;
|
|
||||||
owner = "mosquitto";
|
|
||||||
group = "mosquitto";
|
|
||||||
};
|
|
||||||
secrets.mqtt-receiver = {
|
|
||||||
file = secrets/mqtt-receiver.age;
|
|
||||||
owner = "mosquitto";
|
|
||||||
group = "mosquitto";
|
|
||||||
};
|
|
||||||
secrets.facebook = {
|
|
||||||
file = secrets/facebook.age;
|
|
||||||
};
|
|
||||||
secrets.signal = {
|
|
||||||
file = secrets/signal.age;
|
|
||||||
};
|
|
||||||
secrets.inadyn-duckdns = {
|
|
||||||
file = secrets/inadyn-duckdns.age;
|
|
||||||
owner = "inadyn";
|
|
||||||
group = "inadyn";
|
|
||||||
};
|
|
||||||
secrets.inadyn-porkbun = {
|
|
||||||
file = secrets/inadyn-porkbun.age;
|
|
||||||
owner = "inadyn";
|
|
||||||
group = "inadyn";
|
|
||||||
};
|
|
||||||
secrets.inadyn-porkbun-secret = {
|
|
||||||
file = secrets/inadyn-porkbun-secret.age;
|
|
||||||
owner = "inadyn";
|
|
||||||
group = "inadyn";
|
|
||||||
};
|
|
||||||
secrets.acme-duckdns = {
|
|
||||||
file = secrets/acme-duckdns.age;
|
|
||||||
owner = "acme";
|
|
||||||
group = "nginx";
|
|
||||||
};
|
|
||||||
secrets.acme-porkbun = {
|
|
||||||
file = secrets/acme-porkbun.age;
|
|
||||||
owner = "acme";
|
|
||||||
group = "nginx";
|
|
||||||
};
|
|
||||||
secrets.microbin = {
|
|
||||||
file = secrets/microbin.age;
|
|
||||||
owner = "63026";
|
|
||||||
group = "63026";
|
|
||||||
};
|
|
||||||
secrets.readeck = {
|
|
||||||
file = secrets/readeck.age;
|
|
||||||
owner = "63026";
|
|
||||||
group = "63026";
|
|
||||||
};
|
|
||||||
identityPaths = [ "/etc/ssh/id_ed25519" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Auto-upgrade the system
|
|
||||||
system.autoUpgrade = {
|
system.autoUpgrade = {
|
||||||
enable = true;
|
enable = true;
|
||||||
allowReboot = true;
|
allowReboot = true;
|
||||||
flake = "/home/coolneng/system";
|
|
||||||
flags = [
|
|
||||||
"--update-input"
|
|
||||||
"nixpkgs"
|
|
||||||
"--commit-lock-file"
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Configure git for auto-upgrade
|
# Enable zeroconf
|
||||||
programs.git = {
|
services.avahi = {
|
||||||
enable = true;
|
enable = true;
|
||||||
config = {
|
nssmdns = true;
|
||||||
user.name = "coolneng";
|
publish = {
|
||||||
user.email = "akasroua@gmail.com";
|
enable = true;
|
||||||
safe.directory = "/home/coolneng/system";
|
userServices = true;
|
||||||
credential.helper = "store --file ${config.age.secrets.git.path}";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# Disable man pages
|
# Run Nix garbage collector daily
|
||||||
documentation.man.enable = false;
|
nix.gc = {
|
||||||
|
automatic = true;
|
||||||
|
dates = "03:15";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Configure fish shell
|
||||||
|
programs.fish.enable = true;
|
||||||
|
users.users.root.shell = "/run/current-system/sw/bin/fish";
|
||||||
|
|
||||||
|
# Start a tmux session
|
||||||
|
#programs.tmux.enable = true;
|
||||||
|
|
||||||
# Import other configuration modules
|
# Import other configuration modules
|
||||||
imports = [
|
imports = [
|
||||||
./modules/hardware-configuration.nix
|
./modules/printing.nix
|
||||||
./modules/networking.nix
|
./modules/networking.nix
|
||||||
./modules/datasync.nix
|
./modules/datasync.nix
|
||||||
|
./modules/hardware-configuration.nix
|
||||||
./modules/webstack.nix
|
./modules/webstack.nix
|
||||||
./modules/devops.nix
|
./modules/devops.nix
|
||||||
./modules/monitoring.nix
|
|
||||||
./modules/periodic.nix
|
|
||||||
./modules/communication.nix
|
|
||||||
./modules/information.nix
|
|
||||||
./modules/containers.nix
|
|
||||||
];
|
];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
398
flake.lock
generated
398
flake.lock
generated
@@ -1,398 +0,0 @@
|
|||||||
{
|
|
||||||
"nodes": {
|
|
||||||
"agenix": {
|
|
||||||
"inputs": {
|
|
||||||
"darwin": "darwin",
|
|
||||||
"home-manager": "home-manager",
|
|
||||||
"nixpkgs": [
|
|
||||||
"nixpkgs"
|
|
||||||
],
|
|
||||||
"systems": "systems"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1762618334,
|
|
||||||
"narHash": "sha256-wyT7Pl6tMFbFrs8Lk/TlEs81N6L+VSybPfiIgzU8lbQ=",
|
|
||||||
"owner": "ryantm",
|
|
||||||
"repo": "agenix",
|
|
||||||
"rev": "fcdea223397448d35d9b31f798479227e80183f6",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "ryantm",
|
|
||||||
"repo": "agenix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"darwin": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"agenix",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1744478979,
|
|
||||||
"narHash": "sha256-dyN+teG9G82G+m+PX/aSAagkC+vUv0SgUw3XkPhQodQ=",
|
|
||||||
"owner": "lnl7",
|
|
||||||
"repo": "nix-darwin",
|
|
||||||
"rev": "43975d782b418ebf4969e9ccba82466728c2851b",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "lnl7",
|
|
||||||
"ref": "master",
|
|
||||||
"repo": "nix-darwin",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"determinate": {
|
|
||||||
"inputs": {
|
|
||||||
"determinate-nixd-aarch64-darwin": "determinate-nixd-aarch64-darwin",
|
|
||||||
"determinate-nixd-aarch64-linux": "determinate-nixd-aarch64-linux",
|
|
||||||
"determinate-nixd-x86_64-linux": "determinate-nixd-x86_64-linux",
|
|
||||||
"nix": "nix",
|
|
||||||
"nixpkgs": "nixpkgs_2"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1766177528,
|
|
||||||
"narHash": "sha256-Bl+p766mM7qNCZtMqmTz13RuUbOMKsFa+/vnGYoxgPk=",
|
|
||||||
"rev": "b159c082f0f9bdefa6c386189a13c5fa0734d8d8",
|
|
||||||
"revCount": 317,
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://api.flakehub.com/f/pinned/DeterminateSystems/determinate/3.15.0/019b3865-57a1-7d80-98c5-962fac29c404/source.tar.gz"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://flakehub.com/f/DeterminateSystems/determinate/%2A"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"determinate-nixd-aarch64-darwin": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"narHash": "sha256-vDaEQ5T4eA7kEPREmm68IVWGR6zT0aDL5slZxA6dkSc=",
|
|
||||||
"type": "file",
|
|
||||||
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.15.0/macOS"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"type": "file",
|
|
||||||
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.15.0/macOS"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"determinate-nixd-aarch64-linux": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"narHash": "sha256-Hf4JsIv5G3IR0Q0RHGLSNdmDzFv97sVQQKwzY6A0vV4=",
|
|
||||||
"type": "file",
|
|
||||||
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.15.0/aarch64-linux"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"type": "file",
|
|
||||||
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.15.0/aarch64-linux"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"determinate-nixd-x86_64-linux": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"narHash": "sha256-J+J4E02XpEl0ZkpzMbUmGCf6S4yk0gYCYmiGzZ058ik=",
|
|
||||||
"type": "file",
|
|
||||||
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.15.0/x86_64-linux"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"type": "file",
|
|
||||||
"url": "https://install.determinate.systems/determinate-nixd/tag/v3.15.0/x86_64-linux"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"devshell": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1642188268,
|
|
||||||
"narHash": "sha256-DNz4xScpXIn7rSDohdayBpPR9H9OWCMDOgTYegX081k=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "devshell",
|
|
||||||
"rev": "696acc29668b644df1740b69e1601119bf6da83b",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "devshell",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-compat": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1696426674,
|
|
||||||
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
|
||||||
"owner": "edolstra",
|
|
||||||
"repo": "flake-compat",
|
|
||||||
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "edolstra",
|
|
||||||
"repo": "flake-compat",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-compat_2": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1641205782,
|
|
||||||
"narHash": "sha256-4jY7RCWUoZ9cKD8co0/4tFARpWB+57+r1bLLvXNJliY=",
|
|
||||||
"owner": "edolstra",
|
|
||||||
"repo": "flake-compat",
|
|
||||||
"rev": "b7547d3eed6f32d06102ead8991ec52ab0a4f1a7",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "edolstra",
|
|
||||||
"repo": "flake-compat",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-parts": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs-lib": [
|
|
||||||
"determinate",
|
|
||||||
"nix",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1748821116,
|
|
||||||
"narHash": "sha256-F82+gS044J1APL0n4hH50GYdPRv/5JWm34oCJYmVKdE=",
|
|
||||||
"rev": "49f0870db23e8c1ca0b5259734a02cd9e1e371a1",
|
|
||||||
"revCount": 377,
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://api.flakehub.com/f/pinned/hercules-ci/flake-parts/0.1.377%2Brev-49f0870db23e8c1ca0b5259734a02cd9e1e371a1/01972f28-554a-73f8-91f4-d488cc502f08/source.tar.gz"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://flakehub.com/f/hercules-ci/flake-parts/0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"git-hooks-nix": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-compat": "flake-compat",
|
|
||||||
"gitignore": [
|
|
||||||
"determinate",
|
|
||||||
"nix"
|
|
||||||
],
|
|
||||||
"nixpkgs": [
|
|
||||||
"determinate",
|
|
||||||
"nix",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1747372754,
|
|
||||||
"narHash": "sha256-2Y53NGIX2vxfie1rOW0Qb86vjRZ7ngizoo+bnXU9D9k=",
|
|
||||||
"rev": "80479b6ec16fefd9c1db3ea13aeb038c60530f46",
|
|
||||||
"revCount": 1026,
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://api.flakehub.com/f/pinned/cachix/git-hooks.nix/0.1.1026%2Brev-80479b6ec16fefd9c1db3ea13aeb038c60530f46/0196d79a-1b35-7b8e-a021-c894fb62163d/source.tar.gz"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://flakehub.com/f/cachix/git-hooks.nix/0.1.941"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"home-manager": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"agenix",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1745494811,
|
|
||||||
"narHash": "sha256-YZCh2o9Ua1n9uCvrvi5pRxtuVNml8X2a03qIFfRKpFs=",
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "home-manager",
|
|
||||||
"rev": "abfad3d2958c9e6300a883bd443512c55dfeb1be",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "home-manager",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nix": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-parts": "flake-parts",
|
|
||||||
"git-hooks-nix": "git-hooks-nix",
|
|
||||||
"nixpkgs": "nixpkgs",
|
|
||||||
"nixpkgs-23-11": "nixpkgs-23-11",
|
|
||||||
"nixpkgs-regression": "nixpkgs-regression"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1766174426,
|
|
||||||
"narHash": "sha256-0ZofAQZNgg5nfIKsVb7g4It6ufmIyLtfFRPOf+6WRkk=",
|
|
||||||
"rev": "15d6091194b5b90d292e8d6283db77f09c303b1e",
|
|
||||||
"revCount": 24285,
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://api.flakehub.com/f/pinned/DeterminateSystems/nix-src/3.15.0/019b3854-cca6-7298-a91c-0fd8551a7270/source.tar.gz"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://flakehub.com/f/DeterminateSystems/nix-src/%2A"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nix-matrix-appservices": {
|
|
||||||
"inputs": {
|
|
||||||
"devshell": "devshell",
|
|
||||||
"flake-compat": "flake-compat_2",
|
|
||||||
"nixlib": "nixlib",
|
|
||||||
"nixpkgs": [
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1683490239,
|
|
||||||
"narHash": "sha256-QKzpvl2XrqbobWq/I/smDa9hEniwctjJybXPVILHP0w=",
|
|
||||||
"owner": "coffeetables",
|
|
||||||
"repo": "nix-matrix-appservices",
|
|
||||||
"rev": "e795d2fbc61da45d49802bb3e8f8d0c70ddc1e68",
|
|
||||||
"type": "gitlab"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "coffeetables",
|
|
||||||
"repo": "nix-matrix-appservices",
|
|
||||||
"type": "gitlab"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixlib": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1643502816,
|
|
||||||
"narHash": "sha256-Wrbt6Gs+hjXD3HUICPBJHKnHEUqiyx8rzHCgvqC1Bok=",
|
|
||||||
"owner": "divnix",
|
|
||||||
"repo": "nixpkgs.lib",
|
|
||||||
"rev": "ebed7ec5bcb5d01e298535989c6c321df18b631a",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "divnix",
|
|
||||||
"repo": "nixpkgs.lib",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixos-hardware": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1764440730,
|
|
||||||
"narHash": "sha256-ZlJTNLUKQRANlLDomuRWLBCH5792x+6XUJ4YdFRjtO4=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixos-hardware",
|
|
||||||
"rev": "9154f4569b6cdfd3c595851a6ba51bfaa472d9f3",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "NixOS",
|
|
||||||
"ref": "master",
|
|
||||||
"repo": "nixos-hardware",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1761597516,
|
|
||||||
"narHash": "sha256-wxX7u6D2rpkJLWkZ2E932SIvDJW8+ON/0Yy8+a5vsDU=",
|
|
||||||
"rev": "daf6dc47aa4b44791372d6139ab7b25269184d55",
|
|
||||||
"revCount": 811874,
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.2505.811874%2Brev-daf6dc47aa4b44791372d6139ab7b25269184d55/019a3494-3498-707e-9086-1fb81badc7fe/source.tar.gz"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://flakehub.com/f/NixOS/nixpkgs/0.2505"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs-23-11": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1717159533,
|
|
||||||
"narHash": "sha256-oamiKNfr2MS6yH64rUn99mIZjc45nGJlj9eGth/3Xuw=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "a62e6edd6d5e1fa0329b8653c801147986f8d446",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "a62e6edd6d5e1fa0329b8653c801147986f8d446",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs-regression": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1643052045,
|
|
||||||
"narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs_2": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1765772535,
|
|
||||||
"narHash": "sha256-aq+dQoaPONOSjtFIBnAXseDm9TUhIbe215TPmkfMYww=",
|
|
||||||
"rev": "09b8fda8959d761445f12b55f380d90375a1d6bb",
|
|
||||||
"revCount": 911985,
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://api.flakehub.com/f/pinned/DeterminateSystems/nixpkgs-weekly/0.1.911985%2Brev-09b8fda8959d761445f12b55f380d90375a1d6bb/019b25ab-7c11-79e0-a0b0-c94d455b7190/source.tar.gz"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"type": "tarball",
|
|
||||||
"url": "https://flakehub.com/f/DeterminateSystems/nixpkgs-weekly/0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs_3": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1766201043,
|
|
||||||
"narHash": "sha256-eplAP+rorKKd0gNjV3rA6+0WMzb1X1i16F5m5pASnjA=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "b3aad468604d3e488d627c0b43984eb60e75e782",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "NixOS",
|
|
||||||
"ref": "nixos-25.11",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": {
|
|
||||||
"inputs": {
|
|
||||||
"agenix": "agenix",
|
|
||||||
"determinate": "determinate",
|
|
||||||
"nix-matrix-appservices": "nix-matrix-appservices",
|
|
||||||
"nixos-hardware": "nixos-hardware",
|
|
||||||
"nixpkgs": "nixpkgs_3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"systems": {
|
|
||||||
"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",
|
|
||||||
"version": 7
|
|
||||||
}
|
|
||||||
50
flake.nix
50
flake.nix
@@ -1,50 +0,0 @@
|
|||||||
{
|
|
||||||
description = "System configuration for zion";
|
|
||||||
|
|
||||||
nixConfig = {
|
|
||||||
extra-substituters = "https://install.determinate.systems";
|
|
||||||
extra-trusted-public-keys = ''
|
|
||||||
cache.flakehub.com-3:hJuILl5sVK4iKm86JzgdXW12Y2Hwd5G07qKtHTOcDCM=
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
inputs = {
|
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
|
|
||||||
determinate.url = "https://flakehub.com/f/DeterminateSystems/determinate/*";
|
|
||||||
agenix = {
|
|
||||||
url = "github:ryantm/agenix";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
|
||||||
nixos-hardware.url = "github:NixOS/nixos-hardware/master";
|
|
||||||
nix-matrix-appservices = {
|
|
||||||
url = "gitlab:coffeetables/nix-matrix-appservices";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
outputs =
|
|
||||||
{ self, nixpkgs, ... }@inputs:
|
|
||||||
let
|
|
||||||
system = "x86_64-linux";
|
|
||||||
|
|
||||||
pkgs = import pkgs { inherit system; };
|
|
||||||
|
|
||||||
lib = nixpkgs.lib;
|
|
||||||
|
|
||||||
in
|
|
||||||
{
|
|
||||||
nixosConfigurations.zion = lib.nixosSystem {
|
|
||||||
inherit system;
|
|
||||||
modules = [
|
|
||||||
(import ./configuration.nix)
|
|
||||||
inputs.agenix.nixosModules.age
|
|
||||||
inputs.nixos-hardware.nixosModules.aoostar-r1-n100
|
|
||||||
inputs.determinate.nixosModules.default
|
|
||||||
];
|
|
||||||
specialArgs = {
|
|
||||||
inherit inputs;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with pkgs;
|
|
||||||
|
|
||||||
# NOTE Reference the environment variable set in the corresponding agenix secret
|
|
||||||
let
|
|
||||||
database = {
|
|
||||||
connection_string = "$DB_STRING";
|
|
||||||
max_open_conns = 100;
|
|
||||||
max_idle_conns = 5;
|
|
||||||
conn_max_lifetime = -1;
|
|
||||||
};
|
|
||||||
|
|
||||||
in
|
|
||||||
{
|
|
||||||
# Matrix server configuration
|
|
||||||
services.dendrite = {
|
|
||||||
enable = true;
|
|
||||||
httpPort = 8008;
|
|
||||||
environmentFile = config.age.secrets.dendrite-postgres.path;
|
|
||||||
loadCredential = [ "private_key:${config.age.secrets.dendrite.path}" ];
|
|
||||||
settings = {
|
|
||||||
global = {
|
|
||||||
server_name = "coolneng.duckdns.org";
|
|
||||||
private_key = config.age.secrets.dendrite.path;
|
|
||||||
inherit database;
|
|
||||||
dns_cache.enabled = true;
|
|
||||||
};
|
|
||||||
# HACK Inherit postgres connection string for the rest of the DBs
|
|
||||||
app_service_api = {
|
|
||||||
inherit database;
|
|
||||||
};
|
|
||||||
media_api = {
|
|
||||||
inherit database;
|
|
||||||
};
|
|
||||||
room_server = {
|
|
||||||
inherit database;
|
|
||||||
};
|
|
||||||
push_server = {
|
|
||||||
inherit database;
|
|
||||||
};
|
|
||||||
mscs = {
|
|
||||||
inherit database;
|
|
||||||
mscs = [
|
|
||||||
"msc2836"
|
|
||||||
"msc2946"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
sync_api = {
|
|
||||||
inherit database;
|
|
||||||
};
|
|
||||||
key_server = {
|
|
||||||
inherit database;
|
|
||||||
};
|
|
||||||
federation_api = {
|
|
||||||
inherit database;
|
|
||||||
};
|
|
||||||
user_api = {
|
|
||||||
account_database = database;
|
|
||||||
device_database = database;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Start dendrite after config files are mounted
|
|
||||||
systemd.services.dendrite.unitConfig.RequiresMountsFor = [
|
|
||||||
/var/lib/matrix-as-facebook
|
|
||||||
/var/lib/matrix-as-signal
|
|
||||||
/var/lib/matrix-as-telegram
|
|
||||||
];
|
|
||||||
|
|
||||||
# MQTT configuration
|
|
||||||
services.mosquitto = {
|
|
||||||
enable = true;
|
|
||||||
dataDir = "/vault/mosquitto";
|
|
||||||
logType = [
|
|
||||||
"websockets"
|
|
||||||
"error"
|
|
||||||
"warning"
|
|
||||||
"notice"
|
|
||||||
"information"
|
|
||||||
];
|
|
||||||
logDest = [ "syslog" ];
|
|
||||||
listeners = [
|
|
||||||
{
|
|
||||||
users.homeostasis = {
|
|
||||||
acl = [ "write #" ];
|
|
||||||
hashedPasswordFile = config.age.secrets.mqtt-sender.path;
|
|
||||||
};
|
|
||||||
users.prometheus = {
|
|
||||||
acl = [ "read #" ];
|
|
||||||
hashedPasswordFile = config.age.secrets.mqtt-receiver.path;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
{
|
|
||||||
# Podman setup
|
|
||||||
virtualisation = {
|
|
||||||
containers.enable = true;
|
|
||||||
podman = {
|
|
||||||
enable = true;
|
|
||||||
dockerCompat = true;
|
|
||||||
extraPackages = with pkgs; [ zfs ];
|
|
||||||
};
|
|
||||||
|
|
||||||
oci-containers = {
|
|
||||||
backend = "podman";
|
|
||||||
containers = {
|
|
||||||
# Openbooks configuration
|
|
||||||
openbooks = {
|
|
||||||
image = "evanbuss/openbooks@sha256:4fa9188885368c2303b7dc527d48b3159aaa7022010e29b3ed96842018793590";
|
|
||||||
ports = [ "127.0.0.1:9000:80" ];
|
|
||||||
cmd = [
|
|
||||||
"--name"
|
|
||||||
"bradar"
|
|
||||||
"--searchbot"
|
|
||||||
"searchook"
|
|
||||||
"--persist"
|
|
||||||
"--tls"
|
|
||||||
"false"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
# Prometheus MQTT integration
|
|
||||||
mqtt2prometheus = {
|
|
||||||
image = "hikhvar/mqtt2prometheus@sha256:8e166d36feaa5ddcad703eef3a2c5167a154d6eef306a40fe6509861580c0714";
|
|
||||||
ports = [ "127.0.0.1:9641:9641" ];
|
|
||||||
volumes = [ "/vault/mqtt2prometheus/config.yaml:/config.yaml" ];
|
|
||||||
};
|
|
||||||
# Podcast synchronization
|
|
||||||
opodsync = {
|
|
||||||
image = "ganeshlab/opodsync@sha256:32626b732fe38687a5dfd703d515136e413c4b16f286b38656718ad03f0d94c1";
|
|
||||||
ports = [ "127.0.0.1:9090:8080" ];
|
|
||||||
volumes = [ "/vault/opodsync:/var/www/server/data" ];
|
|
||||||
};
|
|
||||||
# Photo gallery
|
|
||||||
pigallery2 = {
|
|
||||||
image = "bpatrik/pigallery2@sha256:c936e4504cfe7158198542a8db794b24afb0301155d89e911f13bd04e0b406c2";
|
|
||||||
ports = [ "127.0.0.1:9191:80" ];
|
|
||||||
volumes = [
|
|
||||||
"/vault/pigallery2/config:/app/data/config"
|
|
||||||
"/vault/pigallery2/db:/app/data/db"
|
|
||||||
"/vault/pigallery2/tmp:/app/data/tmp"
|
|
||||||
"/vault/syncthing/Photos:/app/data/images"
|
|
||||||
];
|
|
||||||
cmd = [
|
|
||||||
"-e"
|
|
||||||
"NODE_ENV=production"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Start services after ZFS mount
|
|
||||||
systemd.services.podman-mqtt2prometheus.unitConfig.RequiresMountsFor = [ /vault/mqtt2prometheus ];
|
|
||||||
}
|
|
||||||
@@ -1,114 +1,44 @@
|
|||||||
{
|
# Syncthing and Radicale configuration
|
||||||
config,
|
{ config, pkgs, lib, ... }:
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
{
|
||||||
|
|
||||||
# Syncthing configuration
|
environment.systemPackages = with pkgs; [
|
||||||
|
syncthing
|
||||||
|
radicale
|
||||||
|
];
|
||||||
|
|
||||||
|
# Enable syncthingthing
|
||||||
services.syncthing = {
|
services.syncthing = {
|
||||||
enable = true;
|
enable = true;
|
||||||
openDefaultPorts = true;
|
openDefaultPorts = true;
|
||||||
guiAddress = "0.0.0.0:8384";
|
guiAddress = "0.0.0.0:8384";
|
||||||
dataDir = "/vault/syncthing";
|
dataDir = "/vault/syncthing";
|
||||||
key = config.age.secrets.syncthing.path;
|
declarative = {
|
||||||
settings = {
|
|
||||||
extraOptions.options = {
|
|
||||||
maxFolderConcurrency = 4;
|
|
||||||
progressUpdateIntervalS = -1;
|
|
||||||
};
|
|
||||||
devices = {
|
devices = {
|
||||||
panacea.id = "VEGVHKF-P4FT3BD-4T3ML7J-65URQOU-3XKNMI5-6LGWSCI-BIQZOUE-RKQ6PQX";
|
monolith = { id = "QGDGEZQ-INE7XDY-DNX2QI4-QI7ANQJ-57REEO2-FUMH545-FZS5RYU-ULF7HA2"; };
|
||||||
caravanserai.id = "XQAXYEU-FWLAFZM-GTZYDGH-AIRBEXI-4CZD365-JUBTHDA-GOXXOYV-E5LEYQE";
|
roamer = { id = "DS3PJH3-J6SNMHM-XUJTDLO-DHGJL5U-J3RUMAG-4OSJWIK-VSJSDVJ-PIHZ2QP"; };
|
||||||
};
|
};
|
||||||
folders = {
|
folders = {
|
||||||
Documents = {
|
"Documents" = { devices = [ "monolith" "roamer" ]; id = "wusdj-bfjkr"; };
|
||||||
id = "wusdj-bfjkr";
|
"Notes" = { devices = [ "monolith" "roamer" ]; id = "2aqt7-vpprc"; };
|
||||||
type = "receiveonly";
|
"Music" = { devices = [ "monolith" "roamer" ]; id = "kafhz-bfmzm"; };
|
||||||
path = "/vault/syncthing/Documents";
|
"Photos" = { devices = [ "monolith" "roamer" ]; id = "mjibc-ustcg"; };
|
||||||
devices = [
|
"Security" = { devices = [ "monolith" "roamer" ]; id = "z4lpn-pmm3v"; };
|
||||||
"panacea"
|
"Projects" = { devices = [ "monolith" ]; id = "cjhmu-avy9v"; };
|
||||||
"caravanserai"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
Notes = {
|
Documents.type = "receiveonly";
|
||||||
id = "kafhz-bfmzm";
|
Notes.type = "receiveonly";
|
||||||
type = "receiveonly";
|
Music.type = "receiveonly";
|
||||||
path = "/vault/syncthing/Notes";
|
Photos.type = "receiveonly";
|
||||||
devices = [
|
Security.type = "receiveonly";
|
||||||
"panacea"
|
Projects.type = "receiveonly";
|
||||||
"caravanserai"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
Music = {
|
Documents.path = "/vault/syncthing/Documents";
|
||||||
id = "2aqt7-vpprc";
|
Notes.path = "/vault/syncthing/Notes";
|
||||||
type = "receiveonly";
|
Music.path = "/vault/syncthing/Music";
|
||||||
path = "/vault/syncthing/Music";
|
Photos.path = "/vault/syncthing/Photos";
|
||||||
devices = [
|
Security.path = "/vault/syncthing/Security";
|
||||||
"panacea"
|
Projects.path = "/vault/syncthing/Projects";
|
||||||
"caravanserai"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
Photos = {
|
|
||||||
id = "mjibc-ustcg";
|
|
||||||
type = "receiveonly";
|
|
||||||
path = "/vault/syncthing/Photos";
|
|
||||||
devices = [
|
|
||||||
"panacea"
|
|
||||||
"caravanserai"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
Projects = {
|
|
||||||
id = "cjhmu-avy9v";
|
|
||||||
type = "receiveonly";
|
|
||||||
path = "/vault/syncthing/Projects";
|
|
||||||
devices = [ "panacea" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
Phone = {
|
|
||||||
id = "m2007j20cg_vc7r-photos";
|
|
||||||
type = "receiveonly";
|
|
||||||
path = "/vault/syncthing/Photos/Phone";
|
|
||||||
devices = [
|
|
||||||
"panacea"
|
|
||||||
"caravanserai"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
Files = {
|
|
||||||
id = "tsk52-u6rbk";
|
|
||||||
type = "receiveonly";
|
|
||||||
path = "/vault/syncthing/Files";
|
|
||||||
devices = [
|
|
||||||
"panacea"
|
|
||||||
"caravanserai"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
Phone-screenshots = {
|
|
||||||
id = "pp70r-pbr70";
|
|
||||||
type = "receiveonly";
|
|
||||||
path = "/vault/syncthing/Photos/Phone-screenshots";
|
|
||||||
devices = [
|
|
||||||
"panacea"
|
|
||||||
"caravanserai"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
Audio = {
|
|
||||||
id = "tarrs-5mxck";
|
|
||||||
type = "receiveonly";
|
|
||||||
path = "/vault/syncthing/Audio";
|
|
||||||
devices = [
|
|
||||||
"panacea"
|
|
||||||
"caravanserai"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -116,30 +46,19 @@
|
|||||||
# Enable Radicale
|
# Enable Radicale
|
||||||
services.radicale = {
|
services.radicale = {
|
||||||
enable = true;
|
enable = true;
|
||||||
settings = {
|
config = ''
|
||||||
server.hosts = [ "127.0.0.1:5232" ];
|
[server]
|
||||||
auth = {
|
hosts = 127.0.0.1:5232
|
||||||
type = "htpasswd";
|
max_connections = 20
|
||||||
htpasswd_filename = "/vault/radicale/users";
|
max_content_length = 100000000
|
||||||
htpasswd_encryption = "md5";
|
timeout = 30
|
||||||
delay = 1;
|
|
||||||
};
|
|
||||||
storage.filesystem_folder = "/vault/radicale/collections";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# ZFS automatic snapshots
|
[auth]
|
||||||
services.zfs.autoSnapshot = {
|
type = htpasswd
|
||||||
enable = true;
|
htpasswd_filename = /var/lib/radicale/users
|
||||||
frequent = 4;
|
htpasswd_encryption = plain
|
||||||
hourly = 24;
|
delay = 1
|
||||||
daily = 7;
|
'';
|
||||||
weekly = 4;
|
|
||||||
monthly = 12;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Start services after ZFS mount
|
|
||||||
systemd.services.syncthing.unitConfig.RequiresMountsFor = [ /vault/syncthing ];
|
|
||||||
systemd.services.radicale.unitConfig.RequiresMountsFor = [ /vault/radicale ];
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,35 +1,24 @@
|
|||||||
|
# Software development configuration
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
{
|
{
|
||||||
config,
|
environment.systemPackages = with pkgs; [
|
||||||
pkgs,
|
gitea
|
||||||
lib,
|
];
|
||||||
...
|
|
||||||
}:
|
# Gitea setup with daily backup
|
||||||
{
|
|
||||||
# Set up Gitea with LFS support
|
|
||||||
services.gitea = {
|
services.gitea = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
domain = "coolneng.duckdns.org";
|
||||||
|
rootUrl = "https://coolneng.duckdns.org/gitea";
|
||||||
database = {
|
database = {
|
||||||
type = "postgres";
|
type = "postgres";
|
||||||
passwordFile = config.age.secrets.gitea.path;
|
passwordFile = "/var/keys/gitea/db";
|
||||||
};
|
};
|
||||||
|
cookieSecure = true;
|
||||||
|
disableRegistration = true;
|
||||||
repositoryRoot = "/vault/git";
|
repositoryRoot = "/vault/git";
|
||||||
|
dump.enable = true;
|
||||||
appName = "Gitea";
|
appName = "Gitea";
|
||||||
lfs = {
|
|
||||||
enable = true;
|
|
||||||
contentDir = "${config.services.gitea.repositoryRoot}/data/lfs";
|
|
||||||
};
|
|
||||||
settings = {
|
|
||||||
server = {
|
|
||||||
DISABLE_SSH = true;
|
|
||||||
DOMAIN = "git.psydnd.org";
|
|
||||||
ROOT_URL = "https://git.psydnd.org";
|
|
||||||
};
|
|
||||||
service.DISABLE_REGISTRATION = true;
|
|
||||||
session.COOKIE_SECURE = true;
|
|
||||||
actions.ENABLED = true;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Start services after ZFS mount
|
|
||||||
systemd.services.gitea.unitConfig.RequiresMountsFor = [ /vault/git ];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,58 +1,64 @@
|
|||||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||||
# and may be overwritten by future invocations. Please make changes
|
# and may be overwritten by future invocations. Please make changes
|
||||||
# to /etc/nixos/configuration.nix instead.
|
# to /etc/nixos/configuration.nix instead.
|
||||||
{ config, lib, pkgs, modulesPath, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
imports =
|
imports =
|
||||||
[ (modulesPath + "/installer/scan/not-detected.nix")
|
[ <nixpkgs/nixos/modules/installer/scan/not-detected.nix>
|
||||||
];
|
];
|
||||||
|
|
||||||
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usbhid" "sd_mod" ];
|
boot.initrd.availableKernelModules = [ "usb_storage" ];
|
||||||
boot.initrd.kernelModules = [ ];
|
boot.initrd.kernelModules = [ ];
|
||||||
boot.kernelModules = [ "kvm-intel" ];
|
boot.kernelModules = [ ];
|
||||||
boot.extraModulePackages = [ ];
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
fileSystems."/" =
|
fileSystems."/" =
|
||||||
{ device = "sysion/stateful/root";
|
{ device = "/dev/disk/by-uuid/44444444-4444-4444-8888-888888888888";
|
||||||
|
fsType = "ext4";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/vault" =
|
||||||
|
{ device = "vault";
|
||||||
fsType = "zfs";
|
fsType = "zfs";
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/nix" =
|
fileSystems."/vault/git" =
|
||||||
{ device = "sysion/ephemeral/nix";
|
{ device = "vault/git";
|
||||||
fsType = "zfs";
|
fsType = "zfs";
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/tmp" =
|
fileSystems."/vault/syncthing" =
|
||||||
{ device = "sysion/ephemeral/tmp";
|
{ device = "vault/syncthing";
|
||||||
fsType = "zfs";
|
fsType = "zfs";
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/home/coolneng" =
|
fileSystems."/vault/backups" =
|
||||||
{ device = "sysion/stateful/home";
|
{ device = "vault/backups";
|
||||||
fsType = "zfs";
|
fsType = "zfs";
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems."/boot" =
|
fileSystems."/vault/nextcloud" =
|
||||||
{ device = "/dev/disk/by-uuid/C332-4650";
|
{ device = "vault/nextcloud";
|
||||||
fsType = "vfat";
|
fsType = "zfs";
|
||||||
options = [ "fmask=0022" "dmask=0022" ];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
swapDevices =
|
fileSystems."/vault/backups/monolith" =
|
||||||
[ { device = "/dev/disk/by-uuid/d388feef-a651-4dae-8161-f666136de240"; }
|
{ device = "vault/backups/monolith";
|
||||||
];
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
|
||||||
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
fileSystems."/vault/backups/zion" =
|
||||||
# (the default) this is the recommended approach. When using systemd-networkd it's
|
{ device = "vault/backups/zion";
|
||||||
# still possible to use this option, but it's recommended to use it in conjunction
|
fsType = "zfs";
|
||||||
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
|
};
|
||||||
networking.useDHCP = lib.mkDefault true;
|
|
||||||
# networking.interfaces.enp2s0.useDHCP = lib.mkDefault true;
|
|
||||||
# networking.interfaces.enp3s0.useDHCP = lib.mkDefault true;
|
|
||||||
# networking.interfaces.wg0.useDHCP = lib.mkDefault true;
|
|
||||||
# networking.interfaces.wlp4s0.useDHCP = lib.mkDefault true;
|
|
||||||
|
|
||||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
fileSystems."/vault/backups/zion/databases" =
|
||||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
{ device = "vault/backups/zion/databases";
|
||||||
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
|
||||||
|
swapDevices = [ ];
|
||||||
|
|
||||||
|
nix.maxJobs = lib.mkDefault 4;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
{
|
|
||||||
# Miniflux configuration
|
|
||||||
services.miniflux = {
|
|
||||||
enable = true;
|
|
||||||
adminCredentialsFile = config.age.secrets.miniflux.path;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Microbin configuration
|
|
||||||
services.microbin = {
|
|
||||||
enable = true;
|
|
||||||
passwordFile = config.age.secrets.microbin.path;
|
|
||||||
settings = {
|
|
||||||
MICROBIN_PORT = 9091;
|
|
||||||
MICROBIN_PUBLIC_PATH = "https://bin.psydnd.org";
|
|
||||||
MICROBIN_QR = true;
|
|
||||||
MICROBIN_WIDE = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Readeck configuration
|
|
||||||
services.readeck = {
|
|
||||||
enable = true;
|
|
||||||
settings = {
|
|
||||||
server = {
|
|
||||||
host = "127.0.0.1";
|
|
||||||
port = 9092;
|
|
||||||
allowed_hosts = [ "read.psydnd.org" ];
|
|
||||||
trusted_proxies = [ "127.0.0.1" ];
|
|
||||||
environmentFile = config.age.secrets.readeck.path;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# NOTE Load credentials using environment variables
|
|
||||||
systemd.services.readeck.serviceConfig.EnvironmentFile = config.age.secrets.readeck.path;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with pkgs;
|
|
||||||
|
|
||||||
{
|
|
||||||
# Notify when a disk starts going haywire
|
|
||||||
services.smartd = {
|
|
||||||
enable = true;
|
|
||||||
notifications.mail = {
|
|
||||||
enable = true;
|
|
||||||
sender = "akasroua+smartd@disroot.org";
|
|
||||||
recipient = "akasroua@disroot.org";
|
|
||||||
mailer = "${msmtp}/bin/msmtp -t --read-envelope-from";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Notify about zpool problems
|
|
||||||
services.zfs.zed = {
|
|
||||||
enableMail = false;
|
|
||||||
settings = {
|
|
||||||
ZED_EMAIL_ADDR = "akasroua+smartd@disroot.org";
|
|
||||||
ZED_EMAIL_PROG = "mail";
|
|
||||||
ZED_EMAIL_OPTS = "-s '@SUBJECT@' @ADDRESS@";
|
|
||||||
ZED_NOTIFY_VERBOSE = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Set up msmtp as notifier
|
|
||||||
programs.msmtp = {
|
|
||||||
enable = true;
|
|
||||||
defaults = {
|
|
||||||
port = 587;
|
|
||||||
tls = true;
|
|
||||||
};
|
|
||||||
accounts = {
|
|
||||||
default = {
|
|
||||||
auth = true;
|
|
||||||
host = "disroot.org";
|
|
||||||
user = "akasroua@disroot.org";
|
|
||||||
passwordeval = "${coreutils}/bin/cat ${config.age.secrets.msmtp.path}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Metrics collection
|
|
||||||
services.prometheus = {
|
|
||||||
enable = true;
|
|
||||||
port = 9001;
|
|
||||||
retentionTime = "10y";
|
|
||||||
extraFlags = [ "--web.enable-admin-api" ];
|
|
||||||
exporters = {
|
|
||||||
node = {
|
|
||||||
enable = true;
|
|
||||||
enabledCollectors = [ "systemd" ];
|
|
||||||
port = 9002;
|
|
||||||
};
|
|
||||||
postgres.enable = true;
|
|
||||||
smartctl.enable = true;
|
|
||||||
};
|
|
||||||
scrapeConfigs = [
|
|
||||||
{
|
|
||||||
job_name = "zion";
|
|
||||||
static_configs = [
|
|
||||||
{
|
|
||||||
targets = [
|
|
||||||
"localhost:${toString config.services.prometheus.exporters.node.port}"
|
|
||||||
"localhost:${toString config.services.prometheus.exporters.postgres.port}"
|
|
||||||
"localhost:${toString config.services.prometheus.exporters.smartctl.port}"
|
|
||||||
"localhost:9641" # MQTT2Prometheus
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Grafana configuration
|
|
||||||
services.grafana = {
|
|
||||||
enable = true;
|
|
||||||
settings.server = {
|
|
||||||
domain = "grafana.psydnd.org";
|
|
||||||
http_port = 9009;
|
|
||||||
http_addr = "127.0.0.1";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,189 +1,36 @@
|
|||||||
{
|
{ config, pkgs, lib, ... }:
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
let
|
let password = builtins.readFile /var/lib/ddclient/token;
|
||||||
wireguard_port = 1194;
|
|
||||||
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
# Enable systemd-networkd
|
|
||||||
networking = {
|
|
||||||
hostName = "zion";
|
|
||||||
hostId = "760bfad7";
|
|
||||||
useDHCP = false;
|
|
||||||
useNetworkd = true;
|
|
||||||
dhcpcd.enable = false;
|
|
||||||
};
|
|
||||||
systemd.network.wait-online.enable = false;
|
|
||||||
|
|
||||||
# Assign a static IP
|
environment.systemPackages = with pkgs; [
|
||||||
systemd.network.networks."24-home" = {
|
ddclient
|
||||||
name = "enp2s0";
|
|
||||||
matchConfig.Name = "enp2s0";
|
|
||||||
address = [ "192.168.128.2/23" ];
|
|
||||||
gateway = [ "192.168.128.1" ];
|
|
||||||
dns = [
|
|
||||||
"127.0.0.1"
|
|
||||||
"::1"
|
|
||||||
];
|
];
|
||||||
networkConfig.DNSSEC = "no";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Dynamic DNS configuration
|
# Dynamic DNS configuration
|
||||||
services.inadyn = {
|
services.ddclient = {
|
||||||
enable = true;
|
enable = true;
|
||||||
interval = "*:0/30";
|
quiet = true;
|
||||||
settings.provider."duckdns" = {
|
protocol = "duckdns";
|
||||||
hostname = "coolneng.duckdns.org";
|
domains = [ "coolneng.duckdns.org" ];
|
||||||
include = config.age.secrets.inadyn-duckdns.path;
|
inherit password;
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Dynamic DNS configuration for Porkbun
|
|
||||||
# NOTE Temporary workaround until Inadyn fixes the Porkbun module
|
|
||||||
services.oink = {
|
|
||||||
enable = true;
|
|
||||||
apiKeyFile = config.age.secrets.inadyn-porkbun.path;
|
|
||||||
secretApiKeyFile = config.age.secrets.inadyn-porkbun-secret.path;
|
|
||||||
settings.interval = 1800;
|
|
||||||
domains = [
|
|
||||||
{
|
|
||||||
domain = "psydnd.org";
|
|
||||||
subdomain = "";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Firewall configuration
|
# Firewall configuration
|
||||||
networking.firewall = {
|
networking.firewall = {
|
||||||
allowedTCPPorts = [
|
allowedTCPPorts = [
|
||||||
80 # HTTP
|
631 # Cups
|
||||||
443 # HTTPS
|
6566 # SANE
|
||||||
53 # DNS
|
80
|
||||||
8448 # Matrix
|
443
|
||||||
1883 # MQTT
|
|
||||||
];
|
];
|
||||||
allowedUDPPorts = [
|
autoLoadConntrackHelpers = true;
|
||||||
wireguard_port # Wireguard
|
connectionTrackingModules = [ "sane" ];
|
||||||
53 # DNS
|
|
||||||
];
|
|
||||||
extraCommands = ''
|
|
||||||
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o ${
|
|
||||||
config.systemd.network.networks."24-home".name
|
|
||||||
} -j MASQUERADE
|
|
||||||
ip6tables -t nat -A POSTROUTING -s fd00::0/128 -o ${
|
|
||||||
config.systemd.network.networks."24-home".name
|
|
||||||
} -j MASQUERADE
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Wireguard setup
|
# Disable IPv6
|
||||||
systemd.network.netdevs."wg0" = {
|
networking.enableIPv6 = false;
|
||||||
netdevConfig = {
|
|
||||||
Kind = "wireguard";
|
|
||||||
Name = "wg0";
|
|
||||||
};
|
|
||||||
wireguardConfig = {
|
|
||||||
ListenPort = wireguard_port;
|
|
||||||
PrivateKeyFile = config.age.secrets.wireguard.path;
|
|
||||||
};
|
|
||||||
wireguardPeers = [
|
|
||||||
# panacea
|
|
||||||
{
|
|
||||||
PublicKey = "XMkTztU2Y8hw6Fu/2o4Gszij+EmNacvFMXuZyHS1n38=";
|
|
||||||
AllowedIPs = [
|
|
||||||
"10.8.0.2/32"
|
|
||||||
"fd00::2/128"
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
# caravanserai
|
|
||||||
{
|
|
||||||
PublicKey = "mCsTj09H7lfDDs8vMQkJOlItHtHQ6MPUyfGO5ZjBbVs=";
|
|
||||||
AllowedIPs = [
|
|
||||||
"10.8.0.3/32"
|
|
||||||
"fd00::3/128"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
# kathreftis
|
|
||||||
{
|
|
||||||
PublicKey = "qfHtv6LSZjtxvH46d8pysr+/yPo2tV9cZumgIpxBNF4=";
|
|
||||||
AllowedIPs = [
|
|
||||||
"10.8.0.4/32"
|
|
||||||
"fd00::4/128"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.network.networks."wg0" = {
|
|
||||||
matchConfig.Name = "wg0";
|
|
||||||
networkConfig = {
|
|
||||||
Address = [
|
|
||||||
"10.8.0.1/24"
|
|
||||||
"fd00::1/128"
|
|
||||||
];
|
|
||||||
IPv4Forwarding = true;
|
|
||||||
IPv6Forwarding = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Disable systemd-resolved DNS stub
|
|
||||||
services.resolved = {
|
|
||||||
enable = true;
|
|
||||||
llmnr = "false";
|
|
||||||
extraConfig = ''
|
|
||||||
MulticastDNS=yes
|
|
||||||
DNSStubListener=no
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
# DNS server with ad-block
|
|
||||||
services.dnsmasq = {
|
|
||||||
enable = true;
|
|
||||||
settings = {
|
|
||||||
domain-needed = true;
|
|
||||||
bogus-priv = true;
|
|
||||||
no-resolv = true;
|
|
||||||
|
|
||||||
listen-address = [
|
|
||||||
"127.0.0.1"
|
|
||||||
"192.168.128.2"
|
|
||||||
"10.8.0.1"
|
|
||||||
"::1"
|
|
||||||
"fd00::1"
|
|
||||||
];
|
|
||||||
bind-interfaces = true;
|
|
||||||
server = [ "127.0.0.1#43" ];
|
|
||||||
|
|
||||||
cache-size = 10000;
|
|
||||||
local-ttl = 300;
|
|
||||||
|
|
||||||
conf-file = "${pkgs.dnsmasq}/share/dnsmasq/trust-anchors.conf";
|
|
||||||
dnssec = false;
|
|
||||||
address = "/psydnd.org/192.168.128.2";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Encrypted DNS
|
|
||||||
services.dnscrypt-proxy = {
|
|
||||||
enable = true;
|
|
||||||
upstreamDefaults = true;
|
|
||||||
settings = {
|
|
||||||
listen_addresses = [
|
|
||||||
"127.0.0.1:43"
|
|
||||||
"[::1]:43"
|
|
||||||
];
|
|
||||||
sources.public-resolvers = {
|
|
||||||
urls = [ "https://download.dnscrypt.info/resolvers-list/v3/public-resolvers.md" ];
|
|
||||||
cache_file = "/var/lib/dnscrypt-proxy2/public-resolvers.md";
|
|
||||||
minisign_key = "RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3";
|
|
||||||
};
|
|
||||||
blocked_names.blocked_names_file = "/var/lib/dnscrypt-proxy/blocklist.txt";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
|
|
||||||
let
|
|
||||||
stateDir = "/var/lib/dnscrypt-proxy";
|
|
||||||
blocklist = "${stateDir}/blocklist.txt";
|
|
||||||
|
|
||||||
in
|
|
||||||
{
|
|
||||||
# PostgreSQL daily backups
|
|
||||||
services.postgresqlBackup = {
|
|
||||||
enable = true;
|
|
||||||
backupAll = true;
|
|
||||||
location = "/vault/backups/zion/databases";
|
|
||||||
startAt = "*-*-* 05:15:00";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Fetch hosts-blocklists daily
|
|
||||||
# TODO Download the list if the file doesn't exist the first time
|
|
||||||
systemd.services.download-dns-blocklist = {
|
|
||||||
description = "Download hosts-blocklists";
|
|
||||||
wantedBy = [ "default.target" ];
|
|
||||||
path = with pkgs; [
|
|
||||||
curl
|
|
||||||
coreutils
|
|
||||||
];
|
|
||||||
script = ''
|
|
||||||
curl -L https://download.dnscrypt.info/blacklists/domains/mybase.txt -o ${blocklist}
|
|
||||||
'';
|
|
||||||
serviceConfig.Type = "oneshot";
|
|
||||||
startAt = "02:00:00";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Push zion changes to git daily
|
|
||||||
systemd.user.services.zion-push = {
|
|
||||||
description = "Push zion changes to git";
|
|
||||||
wantedBy = [ "default.target" ];
|
|
||||||
path = with pkgs; [ git ];
|
|
||||||
script = ''
|
|
||||||
${pkgs.git}/bin/git -C /home/coolneng/system pull
|
|
||||||
${pkgs.git}/bin/git -C /home/coolneng/system push
|
|
||||||
'';
|
|
||||||
serviceConfig.Type = "oneshot";
|
|
||||||
startAt = "07:00:00";
|
|
||||||
after = [ "network-online.target" ];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
36
modules/printing.nix
Normal file
36
modules/printing.nix
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# CUPS and SANE configuration
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
{
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
cups
|
||||||
|
sane-backends
|
||||||
|
];
|
||||||
|
|
||||||
|
# Enable CUPS with Zeroconf
|
||||||
|
services.printing = {
|
||||||
|
enable = true;
|
||||||
|
drivers = with pkgs; [ hplip_3_18_5 ];
|
||||||
|
browsing = true;
|
||||||
|
listenAddresses = [ "0.0.0.0:631" ];
|
||||||
|
defaultShared = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Enable SANE
|
||||||
|
hardware.sane = {
|
||||||
|
enable = true;
|
||||||
|
extraBackends = with pkgs; [ hplip_3_18_5 ];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.saned = {
|
||||||
|
enable = true;
|
||||||
|
extraConfig = ''
|
||||||
|
192.168.1.0/24
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users.scanner = {
|
||||||
|
extraGroups = [ "lp" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,17 +1,18 @@
|
|||||||
# Web services configuration
|
# LEPP stack configuration
|
||||||
{
|
{ config, pkgs, lib, ... }:
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
{
|
||||||
|
|
||||||
# Reverse proxy configuration
|
environment.systemPackages = with pkgs; [
|
||||||
|
nginx
|
||||||
|
postgresql_11
|
||||||
|
libressl
|
||||||
|
miniflux
|
||||||
|
];
|
||||||
|
|
||||||
services.nginx = {
|
services.nginx = {
|
||||||
enable = true;
|
enable = true;
|
||||||
recommendedTlsSettings = true;
|
recommendedTlsSettings = true;
|
||||||
recommendedBrotliSettings = true;
|
recommendedGzipSettings = true;
|
||||||
recommendedProxySettings = true;
|
recommendedProxySettings = true;
|
||||||
recommendedOptimisation = true;
|
recommendedOptimisation = true;
|
||||||
clientMaxBodySize = "0";
|
clientMaxBodySize = "0";
|
||||||
@@ -20,196 +21,89 @@
|
|||||||
sslDhparam = "/var/lib/dhparams/nginx.pem";
|
sslDhparam = "/var/lib/dhparams/nginx.pem";
|
||||||
commonHttpConfig = ''
|
commonHttpConfig = ''
|
||||||
# Add HSTS header with preloading to HTTPS requests.
|
# Add HSTS header with preloading to HTTPS requests.
|
||||||
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";
|
# Adding this header to HTTP requests is discouraged
|
||||||
|
map $scheme $hsts_header {
|
||||||
|
https "max-age=31536000; includeSubdomains; preload";
|
||||||
|
}
|
||||||
|
add_header Strict-Transport-Security $hsts_header;
|
||||||
|
|
||||||
|
# Enable CSP for your services.
|
||||||
|
#add_header Content-Security-Policy "script-src 'self'; object-src 'none'; base-uri 'none';" always;
|
||||||
|
|
||||||
# Minimize information leaked to other domains
|
# Minimize information leaked to other domains
|
||||||
add_header 'Referrer-Policy' 'strict-origin-when-cross-origin';
|
add_header 'Referrer-Policy' 'origin-when-cross-origin';
|
||||||
|
|
||||||
|
# Disable embedding as a frame
|
||||||
|
add_header X-Frame-Options DENY;
|
||||||
|
|
||||||
# Prevent injection of code in other mime types (XSS Attacks)
|
# Prevent injection of code in other mime types (XSS Attacks)
|
||||||
add_header X-Content-Type-Options nosniff;
|
add_header X-Content-Type-Options nosniff;
|
||||||
|
|
||||||
|
# Enable XSS protection of the browser.
|
||||||
|
# May be unnecessary when CSP is configured properly (see above)
|
||||||
add_header X-XSS-Protection "1; mode=block";
|
add_header X-XSS-Protection "1; mode=block";
|
||||||
add_header X-Frame-Options SAMEORIGIN;
|
|
||||||
|
|
||||||
# This might create errors
|
# This might create errors
|
||||||
proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
|
proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
|
||||||
'';
|
'';
|
||||||
virtualHosts = {
|
virtualHosts = {
|
||||||
# Old domain being redirected
|
|
||||||
"coolneng.duckdns.org" = {
|
"coolneng.duckdns.org" = {
|
||||||
useACMEHost = "coolneng.duckdns.org";
|
enableACME = true;
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
locations = {
|
sslCertificate = "/var/lib/acme/coolneng.duckdns.org/fullchain.pem";
|
||||||
"/".return = "301 https://psydnd.org$request_uri";
|
sslCertificateKey = "/var/lib/acme/coolneng.duckdns.org/key.pem";
|
||||||
# Delegation for Matrix
|
locations."/radicale/" = {
|
||||||
"/.well-known/" = {
|
|
||||||
alias = "${../well-known}" + "/";
|
|
||||||
extraConfig = ''
|
|
||||||
${config.services.nginx.commonHttpConfig}
|
|
||||||
default_type application/json;
|
|
||||||
add_header Access-Control-Allow-Origin * always;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
# Redirect subdomains
|
|
||||||
"~^(?<subdomain>.+)\.coolneng\.duckdns\.org$" = {
|
|
||||||
useACMEHost = "coolneng.duckdns.org";
|
|
||||||
forceSSL = true;
|
|
||||||
locations."/".return = "301 https://$subdomain.psydnd.org$request_uri";
|
|
||||||
};
|
|
||||||
# Current domain
|
|
||||||
"psydnd.org" = {
|
|
||||||
useACMEHost = "psydnd.org";
|
|
||||||
forceSSL = true;
|
|
||||||
};
|
|
||||||
"radicale.psydnd.org" = {
|
|
||||||
useACMEHost = "psydnd.org";
|
|
||||||
forceSSL = true;
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://localhost:5232/";
|
proxyPass = "http://localhost:5232/";
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
proxy_set_header X-Script-Name /;
|
proxy_set_header X-Script-Name /radicale;
|
||||||
proxy_pass_header Authorization;
|
proxy_pass_header Authorization;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
locations."/syncthing/" = {
|
||||||
|
proxyPass = "http://localhost:8384/";
|
||||||
};
|
};
|
||||||
"sync.psydnd.org" = {
|
locations."/gitea/" = {
|
||||||
useACMEHost = "psydnd.org";
|
|
||||||
forceSSL = true;
|
|
||||||
locations."/".proxyPass = "http://localhost:8384/";
|
|
||||||
};
|
|
||||||
"git.psydnd.org" = {
|
|
||||||
useACMEHost = "psydnd.org";
|
|
||||||
forceSSL = true;
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://localhost:3000/";
|
proxyPass = "http://localhost:3000/";
|
||||||
extraConfig = ''
|
|
||||||
${config.services.nginx.commonHttpConfig}
|
|
||||||
# Disable embedding as a frame, except from the same origin
|
|
||||||
add_header Content-Security-Policy "frame-src git.psydnd.org; frame-ancestors git.psydnd.org";
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
locations."/miniflux/" = {
|
||||||
|
proxyPass = "http://localhost:8080/miniflux/";
|
||||||
};
|
};
|
||||||
"rss.psydnd.org" = {
|
locations."/wallabag/" = {
|
||||||
useACMEHost = "psydnd.org";
|
proxyPass = "http://localhost:8081/";
|
||||||
forceSSL = true;
|
|
||||||
locations."/".proxyPass = "http://localhost:8080/";
|
|
||||||
};
|
};
|
||||||
"matrix.psydnd.org" = {
|
|
||||||
useACMEHost = "psydnd.org";
|
|
||||||
forceSSL = true;
|
|
||||||
listen = [
|
|
||||||
# IPv4
|
|
||||||
{
|
|
||||||
addr = "0.0.0.0";
|
|
||||||
port = 8448;
|
|
||||||
ssl = true;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
addr = "0.0.0.0";
|
|
||||||
port = 443;
|
|
||||||
ssl = true;
|
|
||||||
}
|
|
||||||
# IPv6
|
|
||||||
{
|
|
||||||
addr = "[::]";
|
|
||||||
port = 8448;
|
|
||||||
ssl = true;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
addr = "[::]";
|
|
||||||
port = 443;
|
|
||||||
ssl = true;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
locations."~ ^(/_matrix|/_synapse/client)".proxyPass = "http://localhost:8008";
|
|
||||||
};
|
|
||||||
"element.psydnd.org" = {
|
|
||||||
useACMEHost = "psydnd.org";
|
|
||||||
forceSSL = true;
|
|
||||||
locations."/".root = pkgs.element-web.override {
|
|
||||||
conf.default_server_config = {
|
|
||||||
"m.homeserver"."base_url" = "https://matrix.psydnd.org";
|
|
||||||
"m.identity_server"."base_url" = "https://vector.im";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
"books.psydnd.org" = {
|
|
||||||
useACMEHost = "psydnd.org";
|
|
||||||
forceSSL = true;
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://localhost:9000/";
|
|
||||||
proxyWebsockets = true;
|
|
||||||
extraConfig = ''
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "Upgrade";
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
"grafana.psydnd.org" = {
|
|
||||||
useACMEHost = "psydnd.org";
|
|
||||||
forceSSL = true;
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://localhost:9009/";
|
|
||||||
proxyWebsockets = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
"podcast.psydnd.org" = {
|
|
||||||
useACMEHost = "psydnd.org";
|
|
||||||
forceSSL = true;
|
|
||||||
locations."/".proxyPass = "http://localhost:9090/";
|
|
||||||
};
|
|
||||||
"bin.psydnd.org" = {
|
|
||||||
useACMEHost = "psydnd.org";
|
|
||||||
forceSSL = true;
|
|
||||||
locations."/".proxyPass = "http://localhost:9091/";
|
|
||||||
};
|
|
||||||
"read.psydnd.org" = {
|
|
||||||
useACMEHost = "psydnd.org";
|
|
||||||
forceSSL = true;
|
|
||||||
locations."/".proxyPass = "http://localhost:9092/";
|
|
||||||
};
|
|
||||||
"photos.psydnd.org" = {
|
|
||||||
useACMEHost = "psydnd.org";
|
|
||||||
forceSSL = true;
|
|
||||||
locations."/".proxyPass = "http://localhost:9191/";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# ACME certs configuration
|
# ACME certs configuration
|
||||||
security.acme = {
|
security.acme.certs = {
|
||||||
acceptTerms = true;
|
|
||||||
defaults = {
|
|
||||||
email = "akasroua@disroot.org";
|
|
||||||
group = "nginx";
|
|
||||||
};
|
|
||||||
certs = {
|
|
||||||
"coolneng.duckdns.org" = {
|
"coolneng.duckdns.org" = {
|
||||||
domain = "*.coolneng.duckdns.org";
|
email = "akasroua@gmail.com";
|
||||||
dnsProvider = "duckdns";
|
postRun = "systemctl reload nginx.service";
|
||||||
environmentFile = config.age.secrets.acme-duckdns.path;
|
|
||||||
};
|
|
||||||
"psydnd.org" = {
|
|
||||||
domain = "psydnd.org";
|
|
||||||
extraDomainNames = [ "*.psydnd.org" ];
|
|
||||||
dnsProvider = "porkbun";
|
|
||||||
environmentFile = config.age.secrets.acme-porkbun.path;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# Generate dhparams
|
# Generate dhparams
|
||||||
security.dhparams = {
|
security.dhparams = {
|
||||||
enable = true;
|
enable = true;
|
||||||
defaultBitSize = 4096;
|
params = { nginx.bits = 2048; };
|
||||||
params.nginx.bits = 4096;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# PostgreSQL databases configuration
|
# PostgreSQL databases configuration
|
||||||
services.postgresql = {
|
services.postgresql = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = pkgs.postgresql_16;
|
package = pkgs.postgresql_11;
|
||||||
|
ensureDatabases = [ "gitea" "wallabag" ];
|
||||||
|
ensureUsers = [
|
||||||
|
{
|
||||||
|
name = "gitea";
|
||||||
|
ensurePermissions = {"DATABASE gitea" = "ALL PRIVILEGES";};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "wallabag";
|
||||||
|
ensurePermissions = {"DATABASE wallabag" = "ALL PRIVILEGES";};
|
||||||
|
}
|
||||||
|
];
|
||||||
authentication = lib.mkForce ''
|
authentication = lib.mkForce ''
|
||||||
# Generated file; do not edit!
|
# Generated file; do not edit!
|
||||||
# TYPE DATABASE USER ADDRESS METHOD
|
# TYPE DATABASE USER ADDRESS METHOD
|
||||||
@@ -217,22 +111,26 @@
|
|||||||
host all all 127.0.0.1/32 trust
|
host all all 127.0.0.1/32 trust
|
||||||
host all all ::1/128 trust
|
host all all ::1/128 trust
|
||||||
'';
|
'';
|
||||||
settings = {
|
identMap = ''
|
||||||
max_connections = "300";
|
gitea-users gitea gitea
|
||||||
shared_buffers = "1024MB";
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# PostgreSQL daily backups
|
||||||
|
services.postgresqlBackup = {
|
||||||
|
enable = true;
|
||||||
|
backupAll = true;
|
||||||
|
location = "/vault/backups/zion/databases";
|
||||||
|
startAt = "*-*-* 05:15:00";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Miniflux configuration
|
||||||
|
services.miniflux = {
|
||||||
|
enable = true;
|
||||||
|
adminCredentialsFile = "/var/keys/miniflux/admin";
|
||||||
|
config = {
|
||||||
|
BASE_URL = "https://coolneng.duckdns.org/miniflux/";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# Restart reverse proxy after services startup
|
|
||||||
systemd.services.nginx.after = [
|
|
||||||
"gitea.service"
|
|
||||||
"syncthing.service"
|
|
||||||
"miniflux.service"
|
|
||||||
"radicale.service"
|
|
||||||
"dendrite.service"
|
|
||||||
"grafana.service"
|
|
||||||
"podman-openbooks.service"
|
|
||||||
"podman-mqtt2prometheus.service"
|
|
||||||
"podman-opodsync.service"
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,66 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
partition_disk() {
|
|
||||||
parted "$DISK" -- mklabel gpt
|
|
||||||
parted "$DISK" -- mkpart ESP fat32 1MiB 1025MiB
|
|
||||||
parted "$DISK" -- mkpart linux-swap 1025MiB 17409MiB
|
|
||||||
parted "$DISK" -- mkpart primary 17409MiB 100%
|
|
||||||
parted "$DISK" -- set 1 boot on
|
|
||||||
mkfs.fat -F32 -n BOOT "$DISK"p1
|
|
||||||
mkswap "$DISK"p2
|
|
||||||
swapon "$DISK"p2
|
|
||||||
}
|
|
||||||
|
|
||||||
zfs_setup() {
|
|
||||||
zpool import -f vault
|
|
||||||
zpool create -f -o ashift=12 -o autotrim=on -O acltype=posixacl -O relatime=on \
|
|
||||||
-O xattr=sa -O dnodesize=legacy -O normalization=formD -O mountpoint=none \
|
|
||||||
-O canmount=off -O devices=off -R /mnt -O compression=zstd "$POOL_NAME" "$DISK"p3
|
|
||||||
zfs create -o mountpoint=legacy -o com.sun:auto-snapshot=false "$POOL_NAME"/ephemeral
|
|
||||||
zfs create -o mountpoint=legacy -o com.sun:auto-snapshot=false "$POOL_NAME"/ephemeral/nix
|
|
||||||
zfs create -o mountpoint=legacy -o com.sun:auto-snapshot=false -o sync=disabled -o setuid=off "$POOL_NAME"/ephemeral/tmp
|
|
||||||
zfs create -o mountpoint=legacy -o com.sun:auto-snapshot=false "$POOL_NAME"/stateful
|
|
||||||
zfs create -o mountpoint=legacy -o com.sun:auto-snapshot=true "$POOL_NAME"/stateful/home
|
|
||||||
zfs create -o mountpoint=legacy -o com.sun:auto-snapshot=false "$POOL_NAME"/stateful/root
|
|
||||||
}
|
|
||||||
|
|
||||||
mount_datasets() {
|
|
||||||
mount -t zfs sysion/stateful/root /mnt
|
|
||||||
mkdir -p /mnt/boot
|
|
||||||
mount "$DISK"p1 /mnt/boot
|
|
||||||
mkdir -p /mnt/home/coolneng
|
|
||||||
mount -t zfs sysion/stateful/home /mnt/home/coolneng
|
|
||||||
mkdir -p /mnt/nix
|
|
||||||
mount -t zfs sysion/ephemeral/nix /mnt/nix
|
|
||||||
mkdir -p /mnt/tmp
|
|
||||||
mount -t zfs sysion/ephemeral/tmp /mnt/tmp
|
|
||||||
}
|
|
||||||
|
|
||||||
install_system() {
|
|
||||||
nixos-generate-config --root /mnt
|
|
||||||
mv /mnt/etc/nixos/hardware-configuration.nix modules/hardware-configuration.nix
|
|
||||||
nix-shell -p git --command "nixos-install --root /mnt --flake .#zion"
|
|
||||||
}
|
|
||||||
|
|
||||||
usage() {
|
|
||||||
echo "Usage: install.sh <disk>"
|
|
||||||
echo "disk: full path to the disk (e.g. /dev/sda)"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ $# != 1 ]; then
|
|
||||||
usage
|
|
||||||
fi
|
|
||||||
|
|
||||||
DISK="$1"
|
|
||||||
POOL_NAME="sysion"
|
|
||||||
|
|
||||||
echo "Let's start by partitioning the disk"
|
|
||||||
partition_disk
|
|
||||||
echo "Starting up the ZFS machinery"
|
|
||||||
zfs_setup
|
|
||||||
echo "Mounting the horse"
|
|
||||||
mount_datasets
|
|
||||||
echo "Lift off to the NixOS planet"
|
|
||||||
install_system
|
|
||||||
echo "All ready, time to rejoice"
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
#!/run/current-system/sw/bin/bash
|
|
||||||
# Kernel information
|
|
||||||
LINUX=$(uname -rs | cut -d " " -f2)
|
|
||||||
|
|
||||||
# System uptime
|
|
||||||
uptime=$(cut -f1 -d. </proc/uptime)
|
|
||||||
upDays=$((uptime / 60 / 60 / 24))
|
|
||||||
upHours=$((uptime / 60 / 60 % 24))
|
|
||||||
upMins=$((uptime / 60 % 60))
|
|
||||||
upSecs=$((uptime % 60))
|
|
||||||
|
|
||||||
# System load
|
|
||||||
MEMORY=$(free -m | awk 'NR==2{printf "%s/%sMB (%.2f%%)\n", $3,$2,$3*100/$2 }')
|
|
||||||
CPU_LOAD=$(uptime | cut -d: -f5)
|
|
||||||
|
|
||||||
echo "============================================================
|
|
||||||
- Kernel..............: $LINUX
|
|
||||||
- System load.........:$CPU_LOAD
|
|
||||||
- Memory used.........: $MEMORY
|
|
||||||
- System uptime.......: $upDays days $upHours hours $upMins minutes $upSecs seconds
|
|
||||||
============================================================"
|
|
||||||
services=(
|
|
||||||
"syncthing.service"
|
|
||||||
"radicale.service"
|
|
||||||
"miniflux.service"
|
|
||||||
"gitea.service"
|
|
||||||
"dendrite.service"
|
|
||||||
"nginx.service"
|
|
||||||
"dnsmasq.service"
|
|
||||||
"dnscrypt-proxy.service"
|
|
||||||
"podman-openbooks.service"
|
|
||||||
"mosquitto.service"
|
|
||||||
"podman-mqtt2prometheus.service"
|
|
||||||
"prometheus.service"
|
|
||||||
"grafana.service"
|
|
||||||
)
|
|
||||||
|
|
||||||
for var in "${services[@]}"; do
|
|
||||||
if [[ -z $var ]]; then
|
|
||||||
printf "\n"
|
|
||||||
else
|
|
||||||
if systemctl -q is-active "${var}"; then
|
|
||||||
printf "%-40s [\e[32mOK\e[39m]\n" "$var"
|
|
||||||
else
|
|
||||||
printf "%-40s [\e[31mFAIL\e[39m]\n" "$var"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "============================================================"
|
|
||||||
Binary file not shown.
@@ -1,5 +0,0 @@
|
|||||||
age-encryption.org/v1
|
|
||||||
-> ssh-ed25519 iUaRGg 7JImhL2Wo/eJEwUGP+NhEf36yq5gHO9q1GYhY2HaMAY
|
|
||||||
eAMhD0sqHQS+aayBpOsY8+081i72QAhJCFbBe0//uwU
|
|
||||||
--- 4K8cXsDuWZrmWNJ+rz166ej9o/gLFc7CfJuzAsG0BxA
|
|
||||||
|.<2E><><EFBFBD> f<><66>f<EFBFBD>=<1D>-<2D>X$P<>:
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,8 +0,0 @@
|
|||||||
age-encryption.org/v1
|
|
||||||
-> ssh-ed25519 iUaRGg MMf85MfBRho4AAWRJW6WlGxG4Drnuz9qqBlTzpOKiRc
|
|
||||||
tZSl7z0wkSO0K0mJ44q9Ix3yVCMp3LMh/jllNAOK5+E
|
|
||||||
-> n5p-grease .1Sb)yr iCEC
|
|
||||||
lXYS70Iag6qiAErdO8kSpaTqeBwXTWszUTCT1M3Uy4VxFY17
|
|
||||||
--- iWFH19Fd0y8eP9rkWjHt4xqFXqVC/S6dNEfczvRkGwY
|
|
||||||
txE <09>Rͫ$Y<><0F><><EFBFBD><EFBFBD>j`<60>n<EFBFBD><6E>j<EFBFBD><6A><EFBFBD><13><14><><EFBFBD>RI<18>P$$Ag<01>]볷<>2<EFBFBD><32>gF
|
|
||||||
t<EFBFBD>[u<06><><EFBFBD><EFBFBD>M<EFBFBD><1E>nG<6E><47><17><><07>q<07><>;xa<78>š<EFBFBD>qe
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
age-encryption.org/v1
|
|
||||||
-> ssh-ed25519 iUaRGg qr3AoWBF4bx+2bK0STPQtBRDjU6HW5SfXIIUE8GJfxE
|
|
||||||
mr9m+Le1RrMFumNjSEXpkqbqK9e6jbT4ltWvx/hRplE
|
|
||||||
-> !W;iA-grease 343tk
|
|
||||||
f2Fn5fkaYHB/X9wKx/Fa5pJN
|
|
||||||
--- RynMspwxpbATQ4tCuRoyB9d62IhnADztJu58ohN7mkw
|
|
||||||
e<EFBFBD>E<EFBFBD><EFBFBD><EFBFBD><EFBFBD>'+<2B><>(Ϙ<><0F><>.0O<EFBFBD><EFBFBD>+$%@YWw|<1A><>v2<76>Ri-<2D>ոi<D5B8><69><18>f<07><>f<1A><>i<EFBFBD><69><EFBFBD>vO<0F>܆<><DC86>w!<1F><><EFBFBD><EFBFBD><EFBFBD>Q<EFBFBD><1D>7<EFBFBD>H<EFBFBD>O<EFBFBD>i<EFBFBD><69>0d9<64>!G-<2D>CY<43>+ẖyOB<1C>?<3F><>)<29>Ю1<D0AE><31>뒚iK<><4B>z-~M<>_|#a<>Z<03>4I<><49>(<28>g<02><><EFBFBD><EFBFBD>o<EFBFBD>
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
age-encryption.org/v1
|
|
||||||
-> ssh-ed25519 iUaRGg XMrsd1RQcDq/SpFtqpB4Gj1keCvJsMB+VA58qZirYA4
|
|
||||||
tf8NQzoEYJXlKBjtX4ZplaPQv51RCW9yHulvKZB8c8g
|
|
||||||
--- 5wZntAZCQ4pGYrgDFd63w6Y+Taaatcw5z0tDSvShi30
|
|
||||||
<EFBFBD><EFBFBD>4<EFBFBD><EFBFBD><EFBFBD>Ɖq3<EFBFBD>&
|
|
||||||
><0E>4<EFBFBD><34>J<EFBFBD>?<3F><0F><>QW<51>jZ<:'<<16>x(<28>Y<16>i<EFBFBD>ZDO#<23>w<7F><77>R<EFBFBD><52><EFBFBD>O@2<>cAj (f<><66><EFBFBD><EFBFBD>M<EFBFBD><4D><EFBFBD>
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
age-encryption.org/v1
|
|
||||||
-> ssh-ed25519 iUaRGg paS5BxWWicriSLAZyCBKd2xylLAp4/LcHmogO7me8yQ
|
|
||||||
MWW/Pkvn+4G4YeYXY9ZPXC92TbcFXQMyHJ2ltFzXpZs
|
|
||||||
--- ZdFfQ7tHfEo+u/0MmigCNh6OIxkd2bimRN30rMUs1ks
|
|
||||||
<EFBFBD>9<EFBFBD>7Y<EFBFBD>$B<>sX<0E>ʽb<CABD>O'J<><4A>S'<27>5!<21><>UMʯ-v<>m<EFBFBD><6D><EFBFBD><EFBFBD><EFBFBD>8%|R,<2C>~I<><14><>G<EFBFBD><47>VQE<0E>0D<30>:Qv<<1E><>)<29><0B><>%fc<66><63>XZչ 7+yB
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,8 +0,0 @@
|
|||||||
age-encryption.org/v1
|
|
||||||
-> ssh-ed25519 iUaRGg JT+as1Cl66qOy5yY3WJNs0bh51DWaCe/+XZLR8m1L0A
|
|
||||||
/6CyRX6Ks7Wr/ySlJhdfkabcy4N5rQ0VzGtlbxL8RCs
|
|
||||||
-> L$l;-grease uU_g`a
|
|
||||||
N00Z5C8AKzdnGZuFUHqY6uZBiMryyT3IXkdNlYW2fVJLOSfkfFdXssIK9hcMObyi
|
|
||||||
sQENGphUf1Sk16Vo9p4emOL5mtzU
|
|
||||||
--- flb9q0/Q608TJ6K9fsGULVwi2Pk860Cz750d5DBSfMM
|
|
||||||
1<EFBFBD>%<25><>=<3D>Lڮ<4C><DAAE>s<EFBFBD>c/<2F>Iy<49><79>oT!<21>ڏ<EFBFBD>&X<0F><><EFBFBD>WՒZ̋<5A><CC8B><0E>8Z<38><5A><EFBFBD><EFBFBD><EFBFBD>æ<19><><EFBFBD><EFBFBD><06> <09><0B>tw<74>'<27><> i<>e<65>_<EFBFBD>}-<2D>V<EFBFBD>$<24>S<EFBFBD><53><EFBFBD><EFBFBD><EFBFBD>خA<D8AE><41><EFBFBD>h<EFBFBD><68><EFBFBD><04><>!<21><>9Z<39><5A><05><>hqіIa<49><61>,
|
|
||||||
Binary file not shown.
@@ -1,7 +0,0 @@
|
|||||||
age-encryption.org/v1
|
|
||||||
-> ssh-ed25519 iUaRGg +E0/YCwuUtJNFQHtniQyN+xU/1s0phXNMd5YYbOGGFA
|
|
||||||
Xfht0XPm+oflQLicH5MWGF2nLzu44p/DgahpZa2K70k
|
|
||||||
-> NlBVK_)-grease SRaB^ jo >B#rtU zoC-H]
|
|
||||||
lAQL9zTNvGOmJv7FhQaYKd9Ac+MdQSKAhN8hgOTzyh4
|
|
||||||
--- 0ox9Q/KOAhuHxkDHIwj6ab6rzie4T/mU9GIT8p4x+0g
|
|
||||||
<12>UC<55><43>8<EFBFBD><38>^<5E>UK<55><4B><EFBFBD>x<EFBFBD>U<EFBFBD>^<5E>=<3D>)<29>d<EFBFBD>l<><6C><EFBFBD><12><><EFBFBD><EFBFBD>Q<EFBFBD>ҫpQH<51><48><EFBFBD><EFBFBD>1<EFBFBD><31>x<EFBFBD><78>;K<>U;<3B>lb<><62>K9<4B>*`<60><>:I<>:<3A><><13><>t<EFBFBD><74>SF<53><46>f<EFBFBD>yGU
|
|
||||||
Binary file not shown.
@@ -1,25 +0,0 @@
|
|||||||
let
|
|
||||||
zion = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFRqINHR7/zc+c3/PuR+NeSsBHXXzBiEtFWSK6QaxQTW";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
"wireguard.age".publicKeys = [ zion ];
|
|
||||||
"syncthing.age".publicKeys = [ zion ];
|
|
||||||
"msmtp.age".publicKeys = [ zion ];
|
|
||||||
"gitea.age".publicKeys = [ zion ];
|
|
||||||
"miniflux.age".publicKeys = [ zion ];
|
|
||||||
"git.age".publicKeys = [ zion ];
|
|
||||||
"dendrite.age".publicKeys = [ zion ];
|
|
||||||
"dendrite-postgres.age".publicKeys = [ zion ];
|
|
||||||
"telegram.age".publicKeys = [ zion ];
|
|
||||||
"mqtt-sender.age".publicKeys = [ zion ];
|
|
||||||
"mqtt-receiver.age".publicKeys = [ zion ];
|
|
||||||
"facebook.age".publicKeys = [ zion ];
|
|
||||||
"signal.age".publicKeys = [ zion ];
|
|
||||||
"inadyn-duckdns.age".publicKeys = [ zion ];
|
|
||||||
"inadyn-porkbun.age".publicKeys = [ zion ];
|
|
||||||
"inadyn-porkbun-secret.age".publicKeys = [ zion ];
|
|
||||||
"acme-duckdns.age".publicKeys = [ zion ];
|
|
||||||
"acme-porkbun.age".publicKeys = [ zion ];
|
|
||||||
"microbin.age".publicKeys = [ zion ];
|
|
||||||
"readeck.age".publicKeys = [ zion ];
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
age-encryption.org/v1
|
|
||||||
-> ssh-ed25519 iUaRGg J/gZDBtDsIzjCzO1y2vXgxl8YuvWJgcpk+8KMOp63kg
|
|
||||||
1XF9JFAIscHWFJMTctZOxVIBYhYliUFays5gwjZt6hs
|
|
||||||
-> vM4\2y\'-grease
|
|
||||||
bj9VKIuH0l1v5X8N2v4p+u3VySDKjj3WAyVZ7f+wmy16wncrNyMtiUZ+ELBWfqXd
|
|
||||||
XOyeGZoKBHwd8lOgkZ+va0BEkBJs9piX
|
|
||||||
--- K2uN9JxuqPQpAxjQ+6dgsqhsq50nTkLsw8QGJprE5hQ
|
|
||||||
H<EFBFBD><EFBFBD><EFBFBD>S<>:<3A>eJ4}'<27><><EFBFBD>T<EFBFBD><54>˦<0B><>[<5B>'<27>M<EFBFBD><4D><EFBFBD>9<><07><>E6_<36><12><><EFBFBD><1D><><EFBFBD>_<EFBFBD><5F><EFBFBD><EFBFBD>yPM8''<27>'<15>F<><46><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Rڡ"<22>ݏ<EFBFBD>X<EFBFBD><58><EFBFBD><EFBFBD>;<3B><>4<EFBFBD>J/>k<1C>5<EFBFBD><<15><>:<3A>M<EFBFBD>lK$<24>ӟq<D39F>S<EFBFBD><53><EFBFBD><EFBFBD>#<23>Ō<04>j<EFBFBD>X)<29><>v<EFBFBD><76><EFBFBD><EFBFBD>Ou<4F><75>J<>P<EFBFBD><12><>~
|
|
||||||
Binary file not shown.
Binary file not shown.
@@ -1,5 +0,0 @@
|
|||||||
age-encryption.org/v1
|
|
||||||
-> ssh-ed25519 iUaRGg zWm4+j3/IRqd3uZqGzXVcHvs+urNrvDMOceWKbpl018
|
|
||||||
HlIKCFYt7n3iKZav5i0YiB4awRMJML0XUowX8sKKH2c
|
|
||||||
--- ysvYVxgK1OeqCk8KdNF+uWsaQ9EzVRku7nw37aUAW3A
|
|
||||||
c<EFBFBD><EFBFBD>b<EFBFBD>W|bU<62>B"<22><04>Ե<EFBFBD><D4B5><EFBFBD><EFBFBD><EFBFBD><03><>U<EFBFBD>
|
|
||||||
Binary file not shown.
Binary file not shown.
@@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"m.homeserver": {
|
|
||||||
"base_url": "https://matrix.psydnd.org"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{ "m.server": "matrix.psydnd.org:443" }
|
|
||||||
Reference in New Issue
Block a user