Harden server and add Nix-native CI + self-hosted Gitea Actions
- caddy: security headers (X-Content-Type-Options/X-XSS-Protection/ X-Frame-Options) on all vhosts + baseline CSP; strip SnappyMail upstream copies via header_down on mail.severijnse.eu - tlsa-updater: compute TLSA 3 1 1 from cert SPKI (SHA-256), sync _25/_465/_993, fail-safe placeholders; coredns zone updated - pre-commit: wire cachix/git-hooks.nix (alejandra, statix, actionlint, deadnix); CI pre-commit job over x86_64 + aarch64 matrix - gitea: enable Gitea Actions + self-hosted runner (native:host, aarch64 via binfmt); add .gitea/workflows/ci.yml and local hook - fix statix warnings (merge repeated systemd/database/configFile keys) + disable empty_pattern via statix.toml (nixpkgs standard) - Clean up unused lambda patterns across 38 .nix files via deadnix - Format whole repo with alejandra (27 files) - Remove .github/workflows/ci.yml (Gitea shadows .github; runner labels differ) - Fix CI nix-not-found: export /run/current-system/sw/bin in PATH - Trim aarch64 from pre-commit matrix (no QEMU binfmt deployed yet)
This commit is contained in:
@@ -0,0 +1,84 @@
|
|||||||
|
# Source: adapted from the official cachix/install-nix-action "Flakes CI workflow" example
|
||||||
|
# https://github.com/cachix/install-nix-action
|
||||||
|
# (README: "Flakes CI workflow with nix build and flake check")
|
||||||
|
# Every action used here (actions/checkout) is from an official GitHub repo.
|
||||||
|
#
|
||||||
|
# Adaptations for Gitea Actions:
|
||||||
|
# * runs-on: native - Gitea's self-hosted native runner. cachix/install-nix-action
|
||||||
|
# explicitly supports self-hosted runners, and this runner's host already provides
|
||||||
|
# Nix (Lix), so the installer step is omitted and flakes are enabled via NIX_CONFIG
|
||||||
|
# (identical to the action's `extra_nix_config: experimental-features = nix-command flakes`).
|
||||||
|
# * The native runner only puts its `hostPackages` on PATH, which does NOT include Nix.
|
||||||
|
# Each job therefore exports the host's system Nix (/run/current-system/sw/bin) onto
|
||||||
|
# PATH before invoking `nix`. This uses the host's actual Lix rather than installing a
|
||||||
|
# second Nix client that would mismatch the running Lix daemon.
|
||||||
|
# * Gitea context vars (gitea.workflow / gitea.head_ref / gitea.sha) for concurrency.
|
||||||
|
# * matrix over x86_64-linux + aarch64-linux for flake-check (--no-build, eval-only).
|
||||||
|
# Pre-commit checks run on x86_64-linux only: building aarch64 derivations needs
|
||||||
|
# QEMU binfmt (registered via boot.binfmt.emulatedSystems) + nix extra-platforms,
|
||||||
|
# which require a nixos-rebuild switch that hasn't been applied yet.
|
||||||
|
|
||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
# Least-privilege by default; jobs opt into what they need.
|
||||||
|
permissions: {}
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ gitea.workflow }}-${{ gitea.head_ref || gitea.sha }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
env:
|
||||||
|
NIX_CONFIG: |
|
||||||
|
experimental-features = nix-command flakes
|
||||||
|
extra-platforms = aarch64-linux
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
flake-check:
|
||||||
|
name: Flake check (${{ matrix.system }})
|
||||||
|
runs-on: native
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
system:
|
||||||
|
- x86_64-linux
|
||||||
|
- aarch64-linux
|
||||||
|
timeout-minutes: 30
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
|
- name: Flake check (${{ matrix.system }})
|
||||||
|
run: |
|
||||||
|
export PATH=/run/current-system/sw/bin:$PATH
|
||||||
|
nix flake check --no-build --system ${{ matrix.system }}
|
||||||
|
|
||||||
|
pre-commit:
|
||||||
|
name: Pre-commit checks (${{ matrix.system }})
|
||||||
|
runs-on: native
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
# aarch64-linux omitted: building aarch64 derivations needs QEMU binfmt +
|
||||||
|
# extra-platforms; system hasn't been rebuilt to apply them yet.
|
||||||
|
system:
|
||||||
|
- x86_64-linux
|
||||||
|
timeout-minutes: 20
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
|
- name: Pre-commit checks (${{ matrix.system }})
|
||||||
|
run: |
|
||||||
|
export PATH=/run/current-system/sw/bin:$PATH
|
||||||
|
nix build .#checks.${{ matrix.system }}.pre-commit
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
name: CI
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [main]
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
# Least-privilege by default; jobs opt into what they need.
|
|
||||||
permissions: {}
|
|
||||||
|
|
||||||
# Cancel superseded runs on the same ref.
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.head_ref || github.sha }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
check:
|
|
||||||
name: Flake check (${{ matrix.system }})
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
system:
|
|
||||||
- x86_64-linux
|
|
||||||
- aarch64-linux
|
|
||||||
# Match the architecture to a native runner, exactly like nixpkgs
|
|
||||||
# (its treefmt/parse/owners jobs run on ubuntu-24.04-arm).
|
|
||||||
runs-on: ${{ matrix.system == 'aarch64-linux' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }}
|
|
||||||
timeout-minutes: 30
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
||||||
with:
|
|
||||||
persist-credentials: false
|
|
||||||
|
|
||||||
- uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7
|
|
||||||
with:
|
|
||||||
extra_nix_config: |
|
|
||||||
experimental-features = nix-command flakes
|
|
||||||
|
|
||||||
# Evaluate the flake for this system (incl. nixosConfigurations) without
|
|
||||||
# building. Catches the class of break we hit with the duplicate module block.
|
|
||||||
- name: Flake check (${{ matrix.system }})
|
|
||||||
run: nix flake check --no-build --system ${{ matrix.system }}
|
|
||||||
|
|
||||||
format:
|
|
||||||
name: Formatting check (${{ matrix.system }})
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
system:
|
|
||||||
- x86_64-linux
|
|
||||||
- aarch64-linux
|
|
||||||
runs-on: ${{ matrix.system == 'aarch64-linux' && 'ubuntu-24.04-arm' || 'ubuntu-latest' }}
|
|
||||||
timeout-minutes: 10
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
||||||
with:
|
|
||||||
persist-credentials: false
|
|
||||||
|
|
||||||
- uses: cachix/install-nix-action@a49548c11d9846ad46ecc0115273879b045f001c # v31.10.7
|
|
||||||
with:
|
|
||||||
extra_nix_config: |
|
|
||||||
experimental-features = nix-command flakes
|
|
||||||
|
|
||||||
# alejandra is the configured formatter (flake.nix perSystem.formatter).
|
|
||||||
# Checked per-system so both architectures stay formatted.
|
|
||||||
- name: Formatting check (${{ matrix.system }})
|
|
||||||
run: nix run .#formatter.${{ matrix.system }} -- --check .
|
|
||||||
@@ -19,7 +19,10 @@
|
|||||||
|
|
||||||
### ⚠ <sup><sub><samp>PLEASE RESPECT THE CREDITS IF YOU USE SOMETHING FROM MY DESKTOP/SETUP.</samp></sub></sup>
|
### ⚠ <sup><sub><samp>PLEASE RESPECT THE CREDITS IF YOU USE SOMETHING FROM MY DESKTOP/SETUP.</samp></sub></sup>
|
||||||
|
|
||||||
> **Note:** This configuration has been refactored to remove Home Manager to reduce evaluation overhead. While projects like `hjem` and `hjem-rum` were considered, a pure NixOS approach was chosen for simplicity and performance.
|
> **Note:** Built with [flake-parts](https://flake.parts/). The client
|
||||||
|
> configurations (`desktop`, `laptop`, `tty`) use Home Manager, while the
|
||||||
|
> Hetzner server is isolated on `nixos-24.05`. The flake builds for both
|
||||||
|
> **x86_64-linux** and **aarch64-linux**.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -48,12 +51,17 @@
|
|||||||
## 🌼 <samp>INSTALLATION (NixOS)</samp>
|
## 🌼 <samp>INSTALLATION (NixOS)</samp>
|
||||||
|
|
||||||
> Request:
|
> Request:
|
||||||
> [NixOs](https://channels.nixos.org/nixos-25.05/latest-nixos-minimal-x86_64-linux.iso)
|
> [NixOS](https://channels.nixos.org/nixos-24.05/latest-nixos-minimal-x86_64-linux.iso)
|
||||||
|
|
||||||
- Download ISO.
|
This flake targets **both** `x86_64-linux` and `aarch64-linux`, so grab the
|
||||||
|
minimal ISO for your architecture:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
wget -O https://channels.nixos.org/nixos-24.05/latest-nixos-minimal-x86_64-linux.iso
|
# x86_64
|
||||||
|
wget -O nixos-minimal.iso https://channels.nixos.org/nixos-24.05/latest-nixos-minimal-x86_64-linux.iso
|
||||||
|
|
||||||
|
# aarch64 (e.g. Raspberry Pi / ARM boxes)
|
||||||
|
wget -O nixos-minimal-aarch64.iso https://channels.nixos.org/nixos-24.05/latest-nixos-minimal-aarch64-linux.iso
|
||||||
```
|
```
|
||||||
|
|
||||||
- Boot Into the Installer.
|
- Boot Into the Installer.
|
||||||
@@ -118,10 +126,10 @@ rm -rf /mnt/etc/nixos/hosts/aesthetic/configuration.nix
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Move to folder
|
# Move to folder
|
||||||
cd mnt/etc/nixos
|
cd /mnt/etc/nixos
|
||||||
|
|
||||||
# Install
|
# Install (desktop for a graphical machine, or #laptop)
|
||||||
nixos-install --flake .#aesthetic
|
nixos-install --flake .#desktop
|
||||||
```
|
```
|
||||||
|
|
||||||
- Reboot
|
- Reboot
|
||||||
@@ -143,7 +151,7 @@ If you're using this NixOS configuration flake locally, you can simplify the pro
|
|||||||
To switch your system configuration with `nh`, use:
|
To switch your system configuration with `nh`, use:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
NH_FLAKE=/home/someone/Dev/kaku/ nh os switch
|
NH_FLAKE=/etc/nixos nh os switch
|
||||||
```
|
```
|
||||||
|
|
||||||
This avoids needing to type out the full `nixos-rebuild` command manually and provides a cleaner workflow when iterating on your setup.
|
This avoids needing to type out the full `nixos-rebuild` command manually and provides a cleaner workflow when iterating on your setup.
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.5 MiB |
Generated
+38
@@ -82,6 +82,22 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"flake-compat_2": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1767039857,
|
||||||
|
"narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "flake-compat",
|
||||||
|
"rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "flake-compat",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"flake-parts": {
|
"flake-parts": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs-lib": [
|
"nixpkgs-lib": [
|
||||||
@@ -122,6 +138,27 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"git-hooks-nix": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-compat": "flake-compat_2",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1783008725,
|
||||||
|
"narHash": "sha256-jGiy6+sxjNWXSjp25uoJuNfyH9zBK1PEDY0lVoL4ibQ=",
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "git-hooks.nix",
|
||||||
|
"rev": "bca82caa46d5ec0f5d422c61fb1e30bc51313cbe",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "cachix",
|
||||||
|
"repo": "git-hooks.nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"helium": {
|
"helium": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
@@ -254,6 +291,7 @@
|
|||||||
"flake-compat": "flake-compat",
|
"flake-compat": "flake-compat",
|
||||||
"flake-parts": "flake-parts",
|
"flake-parts": "flake-parts",
|
||||||
"flake-utils": "flake-utils",
|
"flake-utils": "flake-utils",
|
||||||
|
"git-hooks-nix": "git-hooks-nix",
|
||||||
"helium": "helium",
|
"helium": "helium",
|
||||||
"import-tree": "import-tree",
|
"import-tree": "import-tree",
|
||||||
"nix-index-db": "nix-index-db",
|
"nix-index-db": "nix-index-db",
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
inputs.flake-parts.lib.mkFlake {inherit inputs;} {
|
inputs.flake-parts.lib.mkFlake {inherit inputs;} {
|
||||||
systems = ["x86_64-linux" "aarch64-linux"];
|
systems = ["x86_64-linux" "aarch64-linux"];
|
||||||
|
|
||||||
imports = [./hosts ./pkgs];
|
imports = [./hosts ./pkgs inputs.git-hooks-nix.flakeModule];
|
||||||
|
|
||||||
perSystem = {
|
perSystem = {
|
||||||
config,
|
config,
|
||||||
@@ -21,6 +21,37 @@
|
|||||||
};
|
};
|
||||||
# Nix Formatter
|
# Nix Formatter
|
||||||
formatter = pkgs.alejandra;
|
formatter = pkgs.alejandra;
|
||||||
|
|
||||||
|
# Pre-commit hooks (flake-parts module from cachix/git-hooks.nix).
|
||||||
|
# `nix build .#checks.<system>.pre-commit` runs these in CI; the same
|
||||||
|
# set is installed in `nix develop` for local use.
|
||||||
|
# alejandra.settings.check = true => verify-only (no in-place writes),
|
||||||
|
# which is what we want in the read-only CI sandbox.
|
||||||
|
pre-commit.settings.hooks = {
|
||||||
|
alejandra = {
|
||||||
|
enable = true;
|
||||||
|
settings.check = true;
|
||||||
|
};
|
||||||
|
statix = {
|
||||||
|
enable = true;
|
||||||
|
# hardware-configuration.nix is auto-generated by NixOS; it legitimately
|
||||||
|
# repeats `boot` keys, which statix would otherwise flag. Exclude it here.
|
||||||
|
settings.ignore = ["hardware-configuration.nix"];
|
||||||
|
# Lint config (statix.toml at repo root). Disables `empty_pattern`, which
|
||||||
|
# flags the standard NixOS `{ ... }:` module pattern that nixpkgs likewise
|
||||||
|
# permits.
|
||||||
|
settings.config = "./statix.toml";
|
||||||
|
};
|
||||||
|
deadnix.enable = true;
|
||||||
|
actionlint.enable = true;
|
||||||
|
trim-trailing-whitespace.enable = true;
|
||||||
|
end-of-file-fixer.enable = true;
|
||||||
|
check-yaml.enable = true;
|
||||||
|
check-toml.enable = true;
|
||||||
|
check-added-large-files.enable = true;
|
||||||
|
check-merge-conflicts.enable = true;
|
||||||
|
detect-private-keys.enable = true;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -40,6 +71,14 @@
|
|||||||
inputs.nixpkgs-lib.follows = "nixpkgs";
|
inputs.nixpkgs-lib.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Nix-native pre-commit framework (maintained successor to
|
||||||
|
# pre-commit-hooks.nix). Follows our nixpkgs to avoid version skew
|
||||||
|
# with the rest of the flake.
|
||||||
|
git-hooks-nix = {
|
||||||
|
url = "github:cachix/git-hooks.nix";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
|
|
||||||
# rest of inputs, alphabetical order
|
# rest of inputs, alphabetical order
|
||||||
|
|||||||
@@ -7,4 +7,4 @@
|
|||||||
"NEWS.md": "11866"
|
"NEWS.md": "11866"
|
||||||
},
|
},
|
||||||
"version": 8
|
"version": 8
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
indent_type = "Spaces"
|
indent_type = "Spaces"
|
||||||
indent_width = 2
|
indent_width = 2
|
||||||
column_width = 120
|
column_width = 120
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
{
|
{
|
||||||
config,
|
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
{
|
{
|
||||||
config,
|
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
{
|
{pkgs, ...}: let
|
||||||
inputs,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
kotlin-lsp = pkgs.runCommand "kotlin-lsp" {} ''
|
kotlin-lsp = pkgs.runCommand "kotlin-lsp" {} ''
|
||||||
mkdir -p $out/bin
|
mkdir -p $out/bin
|
||||||
ln -s ${pkgs.kotlin-language-server}/bin/kotlin-language-server $out/bin/kotlin-lsp
|
ln -s ${pkgs.kotlin-language-server}/bin/kotlin-language-server $out/bin/kotlin-lsp
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
{
|
{pkgs, ...}: {
|
||||||
inputs,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
users.users.someone.packages = with pkgs; [
|
users.users.someone.packages = with pkgs; [
|
||||||
# screenshot
|
# screenshot
|
||||||
grim
|
grim
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{pkgs}: {
|
{}: {
|
||||||
"XF86AudioPlay" = {
|
"XF86AudioPlay" = {
|
||||||
_props.allow-when-locked = true;
|
_props.allow-when-locked = true;
|
||||||
spawn._args = ["playerctl" "play-pause"];
|
spawn._args = ["playerctl" "play-pause"];
|
||||||
|
|||||||
@@ -36,10 +36,11 @@
|
|||||||
(
|
(
|
||||||
if typeOf element == "null"
|
if typeOf element == "null"
|
||||||
then "null"
|
then "null"
|
||||||
else if element == false
|
else if typeOf element == "bool"
|
||||||
then "false"
|
then
|
||||||
else if element == true
|
if element
|
||||||
then "true"
|
then "true"
|
||||||
|
else "false"
|
||||||
else if typeOf element == "string"
|
else if typeOf element == "string"
|
||||||
then ''"${sanitizeString element}"''
|
then ''"${sanitizeString element}"''
|
||||||
else toString element
|
else toString element
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
binds = import ./_binds.nix {inherit pkgs;};
|
binds = import ./_binds.nix {inherit pkgs;};
|
||||||
rules = import ./_rules.nix;
|
rules = import ./_rules.nix;
|
||||||
|
|
||||||
finalConfig = toKDL.generate "niri-config.kdl" (settings // {binds = binds;} // rules);
|
finalConfig = toKDL.generate "niri-config.kdl" (settings // {inherit binds;} // rules);
|
||||||
in {
|
in {
|
||||||
environment.sessionVariables = {
|
environment.sessionVariables = {
|
||||||
NIRI_CONFIG = "$HOME/.config/niri/config.kdl";
|
NIRI_CONFIG = "$HOME/.config/niri/config.kdl";
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
{
|
{pkgs, ...}: {
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
users.users.someone.packages = [pkgs.ashell];
|
users.users.someone.packages = [pkgs.ashell];
|
||||||
|
|
||||||
xdg.configFile."ashell/config.toml".text = ''
|
xdg.configFile."ashell/config.toml".text = ''
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
{
|
{pkgs, ...}: {
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
users.users.someone.packages = [pkgs.mako];
|
users.users.someone.packages = [pkgs.mako];
|
||||||
|
|
||||||
xdg.configFile."mako/config".text = ''
|
xdg.configFile."mako/config".text = ''
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
{
|
{pkgs, ...}: {
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
users.users.someone.packages = [pkgs.walker pkgs.elephant];
|
users.users.someone.packages = [pkgs.walker pkgs.elephant];
|
||||||
|
|
||||||
xdg.configFile."walker/config.toml".text = ''
|
xdg.configFile."walker/config.toml".text = ''
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
{
|
{pkgs, ...}: let
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
alacritty-wrapped = pkgs.writeShellScriptBin "alacritty-wayland" ''
|
alacritty-wrapped = pkgs.writeShellScriptBin "alacritty-wayland" ''
|
||||||
export WAYLAND_DISPLAY="wayland-1"
|
export WAYLAND_DISPLAY="wayland-1"
|
||||||
export XDG_CURRENT_DESKTOP="Niri"
|
export XDG_CURRENT_DESKTOP="Niri"
|
||||||
|
|||||||
@@ -2,9 +2,7 @@
|
|||||||
config,
|
config,
|
||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
}: let
|
}: {
|
||||||
sshConfigFile = "ssh/config";
|
|
||||||
in {
|
|
||||||
users.users.someone.packages = with pkgs; [
|
users.users.someone.packages = with pkgs; [
|
||||||
openssh
|
openssh
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
{
|
{pkgs, ...}: {
|
||||||
inputs,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
users.users.someone.packages = with pkgs; [
|
users.users.someone.packages = with pkgs; [
|
||||||
# archives
|
# archives
|
||||||
zip
|
zip
|
||||||
|
|||||||
@@ -80,19 +80,21 @@ in {
|
|||||||
enable = true;
|
enable = true;
|
||||||
defaultApplications = associations;
|
defaultApplications = associations;
|
||||||
};
|
};
|
||||||
configFile."xdg-desktop-portal-termfilechooser/config".text = ''
|
configFile = {
|
||||||
[filechooser]
|
"xdg-desktop-portal-termfilechooser/config".text = ''
|
||||||
cmd=${yaziWrapper}/bin/yazi-wrapper
|
[filechooser]
|
||||||
default_dir=$HOME
|
cmd=${yaziWrapper}/bin/yazi-wrapper
|
||||||
open_mode=suggested
|
default_dir=$HOME
|
||||||
save_mode=suggested
|
open_mode=suggested
|
||||||
'';
|
save_mode=suggested
|
||||||
configFile."user-dirs.dirs".source = userDirsConfig;
|
'';
|
||||||
configFile."mimeapps.list".text = ''
|
"user-dirs.dirs".source = userDirsConfig;
|
||||||
[Default Applications]
|
"mimeapps.list".text = ''
|
||||||
${lib.concatStringsSep "\n" (lib.mapAttrsToList (k: v: "${k}=${lib.concatStringsSep ";" v}") associations)}
|
[Default Applications]
|
||||||
[Added Associations]
|
${lib.concatStringsSep "\n" (lib.mapAttrsToList (k: v: "${k}=${lib.concatStringsSep ";" v}") associations)}
|
||||||
${lib.concatStringsSep "\n" (lib.mapAttrsToList (k: v: "${k}=${lib.concatStringsSep ";" v}") associations)}
|
[Added Associations]
|
||||||
'';
|
${lib.concatStringsSep "\n" (lib.mapAttrsToList (k: v: "${k}=${lib.concatStringsSep ";" v}") associations)}
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -159,7 +159,7 @@ in {
|
|||||||
${lib.concatStringsSep "\n" (
|
${lib.concatStringsSep "\n" (
|
||||||
lib.flatten (
|
lib.flatten (
|
||||||
lib.mapAttrsToList (
|
lib.mapAttrsToList (
|
||||||
user: userCfg:
|
_user: userCfg:
|
||||||
(lib.mapAttrsToList (mkLinkScript cfg.configHome) userCfg.configFiles)
|
(lib.mapAttrsToList (mkLinkScript cfg.configHome) userCfg.configFiles)
|
||||||
++ (lib.mapAttrsToList (mkLinkScript cfg.cacheHome) userCfg.cacheFiles)
|
++ (lib.mapAttrsToList (mkLinkScript cfg.cacheHome) userCfg.cacheFiles)
|
||||||
++ (lib.mapAttrsToList (mkLinkScript cfg.dataHome) userCfg.dataFiles)
|
++ (lib.mapAttrsToList (mkLinkScript cfg.dataHome) userCfg.dataFiles)
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
inputs,
|
inputs,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
self,
|
|
||||||
...
|
...
|
||||||
}: {
|
}: {
|
||||||
imports = [
|
imports = [
|
||||||
|
|||||||
+1
-2
@@ -55,8 +55,7 @@ in {
|
|||||||
hetzner = nixosSystem24 {
|
hetzner = nixosSystem24 {
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit inputs self;
|
inherit inputs self unstablePkgs;
|
||||||
unstablePkgs = unstablePkgs;
|
|
||||||
};
|
};
|
||||||
modules = [
|
modules = [
|
||||||
inputs.disko.nixosModules.disko
|
inputs.disko.nixosModules.disko
|
||||||
|
|||||||
+1
-1
@@ -3487,4 +3487,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -3,4 +3,4 @@ age-encryption.org/v1
|
|||||||
K8kjoDS2ODYJdNZCUmhTfQOWFHEFCkb90d9K5fEnxYo
|
K8kjoDS2ODYJdNZCUmhTfQOWFHEFCkb90d9K5fEnxYo
|
||||||
--- j1a/Uo7QXWC0dnbSGKaRj/T9GkChC7BQf6kYC0HN8f4
|
--- j1a/Uo7QXWC0dnbSGKaRj/T9GkChC7BQf6kYC0HN8f4
|
||||||
êßçé}N
|
êßçé}N
|
||||||
,âôxoT#c„d¸b,¥Á›�o¶wšah@Z˜&àWU]S6T �þôá”ó¾þº)Yõg
|
,âôxoT#c„d¸b,¥Á›�o¶wšah@Z˜&àWU]S6T �þôá”ó¾þº)Yõg
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -1,9 +1,4 @@
|
|||||||
{
|
{...}: {
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
imports = [
|
imports = [
|
||||||
./networking.nix
|
./networking.nix
|
||||||
./users.nix
|
./users.nix
|
||||||
|
|||||||
@@ -2,9 +2,7 @@
|
|||||||
# 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,
|
lib,
|
||||||
pkgs,
|
|
||||||
modulesPath,
|
modulesPath,
|
||||||
...
|
...
|
||||||
}: {
|
}: {
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
{
|
{...}: {
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
boot = {
|
boot = {
|
||||||
loader = {
|
loader = {
|
||||||
grub = {
|
grub = {
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
{
|
{...}: {
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
networking = {
|
networking = {
|
||||||
hostName = "debian-4gb-fsn1-1";
|
hostName = "debian-4gb-fsn1-1";
|
||||||
domain = "severijnse.eu";
|
domain = "severijnse.eu";
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
{
|
{pkgs, ...}: {
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
users.users = {
|
users.users = {
|
||||||
root = {
|
root = {
|
||||||
openssh.authorizedKeys.keys = [
|
openssh.authorizedKeys.keys = [
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
{
|
{...}: {
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
# NOTE: Caddy handles all TLS natively via its ACME integration.
|
# NOTE: Caddy handles all TLS natively via its ACME integration.
|
||||||
# This module is kept as a fallback for non-Caddy services.
|
# This module is kept as a fallback for non-Caddy services.
|
||||||
# Currently NOT imported in default.nix — uncomment there to activate.
|
# Currently NOT imported in default.nix — uncomment there to activate.
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
{
|
{pkgs, ...}: let
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
backupScript = pkgs.writeShellScript "weekly-backup" ''
|
backupScript = pkgs.writeShellScript "weekly-backup" ''
|
||||||
BACKUP_DIR="/home/admin/backups"
|
BACKUP_DIR="/home/admin/backups"
|
||||||
SRC="/home/admin"
|
SRC="/home/admin"
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
{
|
{...}: let
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
domain = "severijnse.eu";
|
|
||||||
antiScrape = ''
|
antiScrape = ''
|
||||||
@bad_bot {
|
@bad_bot {
|
||||||
header_regexp User-Agent "(?i)(scrapy|cpython-requests|python-requests|curl|wget|go-http-client|ltx71|petalbot|bytespider|dotbot|ahrefsbot|semrushbot|mj12bot|dataforseo|facebookexternalhit|claudebot|anthropic-ai|perplexity|gptbot|chatgpt-user|omnisci|imgproxy|ccbot|exabot|360spider|baiduspider|sogou|duckduckgo|amazonbot|cohere-ai|diffbot|imagesiftbot).*"
|
header_regexp User-Agent "(?i)(scrapy|cpython-requests|python-requests|curl|wget|go-http-client|ltx71|petalbot|bytespider|dotbot|ahrefsbot|semrushbot|mj12bot|dataforseo|facebookexternalhit|claudebot|anthropic-ai|perplexity|gptbot|chatgpt-user|omnisci|imgproxy|ccbot|exabot|360spider|baiduspider|sogou|duckduckgo|amazonbot|cohere-ai|diffbot|imagesiftbot).*"
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
{
|
{pkgs, ...}: let
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
zoneFile = pkgs.writeText "severijnse.eu.db" ''
|
zoneFile = pkgs.writeText "severijnse.eu.db" ''
|
||||||
$ORIGIN severijnse.eu.
|
$ORIGIN severijnse.eu.
|
||||||
$TTL 3600
|
$TTL 3600
|
||||||
@@ -71,37 +66,48 @@
|
|||||||
severijnse.eu IN SSHFP 4 2 c02f4b13aef78579f3466851fcc741c0169eaa63237463ceacc9bb72a2be0519
|
severijnse.eu IN SSHFP 4 2 c02f4b13aef78579f3466851fcc741c0169eaa63237463ceacc9bb72a2be0519
|
||||||
'';
|
'';
|
||||||
in {
|
in {
|
||||||
# Decrypt DNSSEC keys from sops-encrypted file using the age key at /etc/age/keys.txt
|
systemd = {
|
||||||
# Uses sops CLI directly instead of sops-nix's sops-install-secrets (avoids Go 1.25 build dep)
|
services = {
|
||||||
systemd.services.decrypt-coredns-keys = {
|
decrypt-coredns-keys = {
|
||||||
description = "Decrypt CoreDNS DNSSEC signing keys";
|
description = "Decrypt CoreDNS DNSSEC signing keys";
|
||||||
before = ["coredns.service"];
|
before = ["coredns.service"];
|
||||||
wantedBy = ["coredns.service"];
|
wantedBy = ["coredns.service"];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
RemainAfterExit = true;
|
RemainAfterExit = true;
|
||||||
Environment = "SOPS_AGE_KEY_FILE=/etc/age/keys.txt";
|
Environment = "SOPS_AGE_KEY_FILE=/etc/age/keys.txt";
|
||||||
|
};
|
||||||
|
script = ''
|
||||||
|
SOPS_FILE=${../../secrets/coredns-keys.yaml}
|
||||||
|
KEYS_DIR=/var/lib/coredns/keys
|
||||||
|
mkdir -p "$KEYS_DIR"
|
||||||
|
|
||||||
|
${pkgs.sops}/bin/sops --decrypt --extract '["coredns_ksk_key"]' "$SOPS_FILE" > "$KEYS_DIR/Kseverijnse.eu.+013+20930.key"
|
||||||
|
${pkgs.sops}/bin/sops --decrypt --extract '["coredns_ksk_private"]' "$SOPS_FILE" > "$KEYS_DIR/Kseverijnse.eu.+013+20930.private"
|
||||||
|
${pkgs.sops}/bin/sops --decrypt --extract '["coredns_zsk_key"]' "$SOPS_FILE" > "$KEYS_DIR/Kseverijnse.eu.+013+38678.key"
|
||||||
|
${pkgs.sops}/bin/sops --decrypt --extract '["coredns_zsk_private"]' "$SOPS_FILE" > "$KEYS_DIR/Kseverijnse.eu.+013+38678.private"
|
||||||
|
|
||||||
|
chmod 644 "$KEYS_DIR/"*
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
coredns = {
|
||||||
|
after = ["decrypt-coredns-keys.service"];
|
||||||
|
requires = ["decrypt-coredns-keys.service"];
|
||||||
|
|
||||||
|
# Copy zone file from Nix store to writable location on service start
|
||||||
|
# TLSA updater will modify the writable copy at runtime
|
||||||
|
preStart = ''
|
||||||
|
cp -f ${zoneFile} /var/lib/coredns/zones/severijnse.eu.db
|
||||||
|
chown coredns:coredns /var/lib/coredns/zones/severijnse.eu.db
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
script = ''
|
tmpfiles.rules = [
|
||||||
SOPS_FILE=${../../secrets/coredns-keys.yaml}
|
"d /var/lib/coredns 0750 coredns coredns -"
|
||||||
KEYS_DIR=/var/lib/coredns/keys
|
"d /var/lib/coredns/zones 0750 coredns coredns -"
|
||||||
mkdir -p "$KEYS_DIR"
|
"d /var/lib/coredns/keys 0750 coredns coredns -"
|
||||||
|
];
|
||||||
${pkgs.sops}/bin/sops --decrypt --extract '["coredns_ksk_key"]' "$SOPS_FILE" > "$KEYS_DIR/Kseverijnse.eu.+013+20930.key"
|
|
||||||
${pkgs.sops}/bin/sops --decrypt --extract '["coredns_ksk_private"]' "$SOPS_FILE" > "$KEYS_DIR/Kseverijnse.eu.+013+20930.private"
|
|
||||||
${pkgs.sops}/bin/sops --decrypt --extract '["coredns_zsk_key"]' "$SOPS_FILE" > "$KEYS_DIR/Kseverijnse.eu.+013+38678.key"
|
|
||||||
${pkgs.sops}/bin/sops --decrypt --extract '["coredns_zsk_private"]' "$SOPS_FILE" > "$KEYS_DIR/Kseverijnse.eu.+013+38678.private"
|
|
||||||
|
|
||||||
chmod 644 "$KEYS_DIR/"*
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Ensure coredns waits for key decryption
|
|
||||||
systemd.services.coredns = {
|
|
||||||
after = ["decrypt-coredns-keys.service"];
|
|
||||||
requires = ["decrypt-coredns-keys.service"];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.coredns = {
|
services.coredns = {
|
||||||
enable = true;
|
enable = true;
|
||||||
config = ''
|
config = ''
|
||||||
@@ -126,19 +132,4 @@ in {
|
|||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
# Copy zone file from Nix store to writable location on service start
|
|
||||||
# TLSA updater will modify the writable copy at runtime
|
|
||||||
systemd.services.coredns = {
|
|
||||||
preStart = ''
|
|
||||||
cp -f ${zoneFile} /var/lib/coredns/zones/severijnse.eu.db
|
|
||||||
chown coredns:coredns /var/lib/coredns/zones/severijnse.eu.db
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.tmpfiles.rules = [
|
|
||||||
"d /var/lib/coredns 0750 coredns coredns -"
|
|
||||||
"d /var/lib/coredns/zones 0750 coredns coredns -"
|
|
||||||
"d /var/lib/coredns/keys 0750 coredns coredns -"
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
{
|
{...}: {
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
# Keep fail2ban as OCI container to preserve the web UI
|
# Keep fail2ban as OCI container to preserve the web UI
|
||||||
virtualisation.oci-containers.containers.fail2ban = {
|
virtualisation.oci-containers.containers.fail2ban = {
|
||||||
image = "crazymax/fail2ban:latest";
|
image = "crazymax/fail2ban:latest";
|
||||||
|
|||||||
@@ -1,54 +1,87 @@
|
|||||||
{
|
{
|
||||||
config,
|
|
||||||
pkgs,
|
pkgs,
|
||||||
lib,
|
|
||||||
unstablePkgs,
|
unstablePkgs,
|
||||||
...
|
...
|
||||||
}: {
|
}: {
|
||||||
services.postgresql = {
|
services = {
|
||||||
enable = true;
|
postgresql = {
|
||||||
package = pkgs.postgresql_14;
|
enable = true;
|
||||||
ensureDatabases = ["gitea"];
|
package = pkgs.postgresql_14;
|
||||||
ensureUsers = [
|
ensureDatabases = ["gitea"];
|
||||||
{
|
ensureUsers = [
|
||||||
|
{
|
||||||
|
name = "gitea";
|
||||||
|
ensureDBOwnership = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
gitea = {
|
||||||
|
enable = true;
|
||||||
|
package = unstablePkgs.gitea;
|
||||||
|
database = {
|
||||||
|
type = "postgres";
|
||||||
name = "gitea";
|
name = "gitea";
|
||||||
ensureDBOwnership = true;
|
user = "gitea";
|
||||||
}
|
};
|
||||||
];
|
appName = "Jory's Git";
|
||||||
|
lfs.enable = true;
|
||||||
|
settings = {
|
||||||
|
server = {
|
||||||
|
DOMAIN = "git.severijnse.eu";
|
||||||
|
ROOT_URL = "https://git.severijnse.eu/";
|
||||||
|
HTTP_PORT = 3000;
|
||||||
|
SSH_PORT = 222;
|
||||||
|
SSH_LISTEN_PORT = 2222;
|
||||||
|
START_SSH_SERVER = true;
|
||||||
|
SSH_USER = "git";
|
||||||
|
BUILTIN_SSH_SERVER_USER = "git";
|
||||||
|
LANDING_PAGE = "explore";
|
||||||
|
};
|
||||||
|
service = {
|
||||||
|
DISABLE_REGISTRATION = true;
|
||||||
|
REQUIRE_SIGNIN_VIEW = false;
|
||||||
|
};
|
||||||
|
repository = {
|
||||||
|
DEFAULT_BRANCH = "main";
|
||||||
|
};
|
||||||
|
actions = {
|
||||||
|
ENABLED = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
gitea-actions-runner = {
|
||||||
|
# nixos-24-05's gitea-actions-runner module hardcodes bin/act_runner,
|
||||||
|
# but the current upstream package (1.0.3, matching gitea 1.26) ships
|
||||||
|
# bin/gitea-runner. Wrap it so both names resolve.
|
||||||
|
package = pkgs.runCommand "gitea-actions-runner-wrapped" {} ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
ln -s ${unstablePkgs.gitea-actions-runner}/bin/gitea-runner $out/bin/act_runner
|
||||||
|
'';
|
||||||
|
instances.default = {
|
||||||
|
enable = true;
|
||||||
|
name = "hetzner";
|
||||||
|
url = "https://git.severijnse.eu";
|
||||||
|
tokenFile = "/var/lib/secrets/gitea-runner-token";
|
||||||
|
labels = ["native:host"];
|
||||||
|
hostPackages = with pkgs; [
|
||||||
|
bash
|
||||||
|
coreutils
|
||||||
|
curl
|
||||||
|
gawk
|
||||||
|
gitMinimal
|
||||||
|
gnused
|
||||||
|
nodejs
|
||||||
|
wget
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# Gitea connects to local Postgres via Unix socket (peer auth).
|
# Gitea connects to local Postgres via Unix socket (peer auth).
|
||||||
# No password needed — the socket is at /run/postgresql by default.
|
# No password needed — the socket is at /run/postgresql by default.
|
||||||
# createDatabase = true ensures the DB + user are set up automatically.
|
# createDatabase = true ensures the DB + user are set up automatically.
|
||||||
services.gitea = {
|
|
||||||
enable = true;
|
|
||||||
package = unstablePkgs.gitea;
|
|
||||||
database.type = "postgres";
|
|
||||||
database.name = "gitea";
|
|
||||||
database.user = "gitea";
|
|
||||||
appName = "Jory's Git";
|
|
||||||
lfs.enable = true;
|
|
||||||
settings = {
|
|
||||||
server = {
|
|
||||||
DOMAIN = "git.severijnse.eu";
|
|
||||||
ROOT_URL = "https://git.severijnse.eu/";
|
|
||||||
HTTP_PORT = 3000;
|
|
||||||
SSH_PORT = 222;
|
|
||||||
SSH_LISTEN_PORT = 2222;
|
|
||||||
START_SSH_SERVER = true;
|
|
||||||
SSH_USER = "git";
|
|
||||||
BUILTIN_SSH_SERVER_USER = "git";
|
|
||||||
LANDING_PAGE = "explore";
|
|
||||||
};
|
|
||||||
service = {
|
|
||||||
DISABLE_REGISTRATION = true;
|
|
||||||
REQUIRE_SIGNIN_VIEW = false;
|
|
||||||
};
|
|
||||||
repository = {
|
|
||||||
DEFAULT_BRANCH = "main";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Gitea built-in SSH server: listens on high port 2222 (no privileged-cap needed),
|
# Gitea built-in SSH server: listens on high port 2222 (no privileged-cap needed),
|
||||||
# while clone URLs advertise port 222. Firewall redirects 222 -> 2222.
|
# while clone URLs advertise port 222. Firewall redirects 222 -> 2222.
|
||||||
@@ -61,4 +94,12 @@
|
|||||||
${pkgs.nftables}/bin/nft add chain inet gitea-redirect prerouting '{ type nat hook prerouting priority dstnat; }' 2>/dev/null || true
|
${pkgs.nftables}/bin/nft add chain inet gitea-redirect prerouting '{ type nat hook prerouting priority dstnat; }' 2>/dev/null || true
|
||||||
${pkgs.nftables}/bin/nft add rule inet gitea-redirect prerouting tcp dport 222 redirect to :2222 2>/dev/null || true
|
${pkgs.nftables}/bin/nft add rule inet gitea-redirect prerouting tcp dport 222 redirect to :2222 2>/dev/null || true
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
# --- Gitea Actions self-hosted CI runner ---
|
||||||
|
# The native runner only exposes `hostPackages` on PATH (see the list above),
|
||||||
|
# which intentionally omits Nix. CI steps export the host's system Nix
|
||||||
|
# (/run/current-system/sw/bin, i.e. Lix) onto PATH rather than installing a
|
||||||
|
# second Nix client, so the running Lix daemon is used directly.
|
||||||
|
# aarch64 builds run under QEMU user-emulation via boot.binfmt below.
|
||||||
|
boot.binfmt.emulatedSystems = ["aarch64-linux"];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
{
|
{...}: {
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
virtualisation.oci-containers.containers.mailserver = {
|
virtualisation.oci-containers.containers.mailserver = {
|
||||||
image = "ghcr.io/docker-mailserver/docker-mailserver:latest";
|
image = "ghcr.io/docker-mailserver/docker-mailserver:latest";
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
{
|
{...}: {
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
virtualisation.oci-containers.containers = {
|
virtualisation.oci-containers.containers = {
|
||||||
hbbr = {
|
hbbr = {
|
||||||
image = "rustdesk/rustdesk-server:latest";
|
image = "rustdesk/rustdesk-server:latest";
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
{
|
{...}: {
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
virtualisation.oci-containers.containers.shkeeper = {
|
virtualisation.oci-containers.containers.shkeeper = {
|
||||||
image = "vsyshost/shkeeper:2.5.29";
|
image = "vsyshost/shkeeper:2.5.29";
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
{
|
{...}: {
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
virtualisation.oci-containers.containers.snappymail = {
|
virtualisation.oci-containers.containers.snappymail = {
|
||||||
image = "djmaze/snappymail:latest";
|
image = "djmaze/snappymail:latest";
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
{
|
{pkgs, ...}: let
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
# Caddy's canonical certificate storage (XDG data dir). Renewals land here,
|
# Caddy's canonical certificate storage (XDG data dir). Renewals land here,
|
||||||
# owned caddy:caddy 0600 — the mail server's non-root Postfix/Dovecot cannot
|
# owned caddy:caddy 0600 — the mail server's non-root Postfix/Dovecot cannot
|
||||||
# read it directly, so we copy it into a world-readable distribution dir.
|
# read it directly, so we copy it into a world-readable distribution dir.
|
||||||
@@ -58,42 +53,44 @@
|
|||||||
echo "tlsa-update: TLSA set to $HEX"
|
echo "tlsa-update: TLSA set to $HEX"
|
||||||
'';
|
'';
|
||||||
in {
|
in {
|
||||||
# Ensure the distribution dir exists (Caddy does not write here).
|
systemd = {
|
||||||
systemd.tmpfiles.rules = [
|
# Ensure the distribution dir exists (Caddy does not write here).
|
||||||
"d ${distCertDir} 0755 root root - -"
|
tmpfiles.rules = [
|
||||||
];
|
"d ${distCertDir} 0755 root root - -"
|
||||||
|
];
|
||||||
|
|
||||||
systemd.services.tlsa-update = {
|
services.tlsa-update = {
|
||||||
description = "Sync Caddy TLS certificate to mail server and update DANE/TLSA records";
|
description = "Sync Caddy TLS certificate to mail server and update DANE/TLSA records";
|
||||||
after = ["caddy.service" "coredns.service"];
|
after = ["caddy.service" "coredns.service"];
|
||||||
partOf = ["coredns.service"];
|
partOf = ["coredns.service"];
|
||||||
wantedBy = ["multi-user.target"];
|
wantedBy = ["multi-user.target"];
|
||||||
path = with pkgs; [openssl coreutils gnused podman systemd];
|
path = with pkgs; [openssl coreutils gnused podman systemd];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
ExecStart = "${syncScript}";
|
ExecStart = "${syncScript}";
|
||||||
User = "root";
|
User = "root";
|
||||||
Group = "root";
|
Group = "root";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
# Fire as soon as Caddy rewrites the certificate on renewal (the atomic rewrite
|
# Fire as soon as Caddy rewrites the certificate on renewal (the atomic rewrite
|
||||||
# changes the directory mtime), eliminating the up-to-24h DANE drift window.
|
# changes the directory mtime), eliminating the up-to-24h DANE drift window.
|
||||||
systemd.paths.tlsa-update = {
|
paths.tlsa-update = {
|
||||||
description = "Watch Caddy certificate directory for renewal";
|
description = "Watch Caddy certificate directory for renewal";
|
||||||
wantedBy = ["paths.target"];
|
wantedBy = ["paths.target"];
|
||||||
pathConfig = {
|
pathConfig = {
|
||||||
PathModified = [caddyCertDir];
|
PathModified = [caddyCertDir];
|
||||||
Unit = "tlsa-update.service";
|
Unit = "tlsa-update.service";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
# Fallback in case a renewal event is missed (e.g. inotify overflow).
|
# Fallback in case a renewal event is missed (e.g. inotify overflow).
|
||||||
systemd.timers.tlsa-update = {
|
timers.tlsa-update = {
|
||||||
wantedBy = ["timers.target"];
|
wantedBy = ["timers.target"];
|
||||||
timerConfig = {
|
timerConfig = {
|
||||||
OnCalendar = "daily";
|
OnCalendar = "daily";
|
||||||
Persistent = true;
|
Persistent = true;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
{
|
{...}: {
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
virtualisation.oci-containers.containers.vaultwarden = {
|
virtualisation.oci-containers.containers.vaultwarden = {
|
||||||
image = "vaultwarden/server:latest";
|
image = "vaultwarden/server:latest";
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
{
|
{...}: {
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
virtualisation.oci-containers.containers.watchtower = {
|
virtualisation.oci-containers.containers.watchtower = {
|
||||||
image = "ghcr.io/nicholas-fedor/watchtower:latest";
|
image = "ghcr.io/nicholas-fedor/watchtower:latest";
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
{
|
{...}: {
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
virtualisation.oci-containers.containers.wg-easy = {
|
virtualisation.oci-containers.containers.wg-easy = {
|
||||||
image = "ghcr.io/wg-easy/wg-easy:latest";
|
image = "ghcr.io/wg-easy/wg-easy:latest";
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
{
|
{...}: {
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
virtualisation.oci-containers.containers.wrxproxy = {
|
virtualisation.oci-containers.containers.wrxproxy = {
|
||||||
image = "localhost/wrxproxy:latest";
|
image = "localhost/wrxproxy:latest";
|
||||||
autoStart = false;
|
autoStart = false;
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
{
|
{pkgs, ...}: {
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
time.timeZone = "Europe/Amsterdam";
|
time.timeZone = "Europe/Amsterdam";
|
||||||
|
|
||||||
i18n.defaultLocale = "en_US.UTF-8";
|
i18n.defaultLocale = "en_US.UTF-8";
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
disabled = ["empty_pattern"]
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
pkgs,
|
pkgs,
|
||||||
lib,
|
|
||||||
...
|
...
|
||||||
}: {
|
}: {
|
||||||
boot = {
|
boot = {
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
{
|
{pkgs, ...}: {
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
services = {
|
services = {
|
||||||
printing = {
|
printing = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{...}: {
|
_: {
|
||||||
systemd.user.services.xdg-desktop-portal = {
|
systemd.user.services.xdg-desktop-portal = {
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
UnsetEnvironment = "NIX_XDG_DESKTOP_PORTAL_DIR";
|
UnsetEnvironment = "NIX_XDG_DESKTOP_PORTAL_DIR";
|
||||||
|
|||||||
Reference in New Issue
Block a user