aboutsummaryrefslogtreecommitdiff
path: root/modules/server
diff options
context:
space:
mode:
authoraethrvmn <me@aethrvmn.gr>2025-08-31 14:21:34 +0000
committeraethrvmn <me@aethrvmn.gr>2025-08-31 14:21:34 +0000
commitbfd970a07c231b5781871c16cb4612eb4c6b8fd4 (patch)
tree50a4ac5138d1f438e4d5bad3a3dd880a0784cd3e /modules/server
parentadded flake (diff)
imported system/home-manager config
Diffstat (limited to '')
-rw-r--r--modules/server/calibre/default.nix39
-rw-r--r--modules/server/cgit/default.nix76
-rw-r--r--modules/server/cgit/static/cgit.css1346
-rwxr-xr-xmodules/server/cgit/static/favicon.pngbin0 -> 2535629 bytes
-rwxr-xr-xmodules/server/cgit/static/logo.pngbin0 -> 2535629 bytes
-rw-r--r--modules/server/default.nix53
-rw-r--r--modules/server/forgejo/default.nix42
-rw-r--r--modules/server/gemini/default.nix57
-rw-r--r--modules/server/grafana/default.nix23
-rw-r--r--modules/server/immich/default.nix28
-rw-r--r--modules/server/jellyfin/default.nix27
-rw-r--r--modules/server/ollama/default.nix69
12 files changed, 1760 insertions, 0 deletions
diff --git a/modules/server/calibre/default.nix b/modules/server/calibre/default.nix
new file mode 100644
index 0000000..d177ac1
--- /dev/null
+++ b/modules/server/calibre/default.nix
@@ -0,0 +1,39 @@
+{ config, pkgs, ... }:
+let
+ libDir = "/var/lib/calibre-web/library";
+in {
+ services = {
+ calibre-web = {
+ enable = true;
+
+ listen = {
+ ip = "127.0.0.1";
+ port = 3020;
+ };
+
+ options = {
+ calibreLibrary = libDir;
+ enableBookUploading = true;
+ };
+ };
+
+ nginx = {
+ virtualHosts."library.internal" = {
+ locations."/" = {
+ proxyPass = "http://127.0.0.1:3020";
+ proxyWebsockets = true;
+ };
+ };
+ };
+ };
+
+ systemd.services.calibre-web = {
+ preStart = ''
+ if [ ! -f "${libDir}/metadata.db" ]; then
+ mkdir -p "${libDir}"
+ ${pkgs.calibre}/bin/calibredb add --empty \
+ --with-library "${libDir}"
+ fi
+ '';
+ };
+}
diff --git a/modules/server/cgit/default.nix b/modules/server/cgit/default.nix
new file mode 100644
index 0000000..08784fe
--- /dev/null
+++ b/modules/server/cgit/default.nix
@@ -0,0 +1,76 @@
+{ config, pkgs, lib, ... }:
+let
+ cgitWithAssets = pkgs.cgit.overrideAttrs (old: {
+ pname = "cgit-with-assets";
+
+ postInstall = (old.postInstall or "") + ''
+ # overwrite the stock files that the module aliases
+ install -Dm444 ${./static/cgit.css} $out/cgit/cgit.css
+ install -Dm444 ${./static/logo.png} $out/cgit/cgit.png # keep the name!
+ install -Dm444 ${./static/favicon.png} $out/cgit/favicon.ico
+ '';
+ });
+in {
+ services = {
+ cgit."code" = {
+ enable = true;
+ scanPath = "/srv/git";
+ package = cgitWithAssets;
+
+ settings = {
+ cache-size = 0;
+ cache-scanrc-ttl = 0;
+ enable-log-filecount = 1;
+ enable-log-linecount = 1;
+ enable-git-config = 1;
+
+ localtime = 1;
+
+ noplainemail = 1;
+
+ root-title = "code.aethrvmn.gr";
+ root-desc = "αpothēke of aethrvmn";
+ clone-url = "https://code.aethrvmn.gr/$CGIT_REPO_URL";
+
+ logo-link = "https://aethrvmn.gr/";
+
+ about-filter = "${pkgs.cgit}/lib/cgit/filters/about-formatting.sh";
+ source-filter = "${pkgs.cgit}/lib/cgit/filters/syntax-highlighting.py";
+ };
+
+ nginx.virtualHost = "code.internal";
+ };
+ };
+
+ users = {
+ groups.git = { };
+
+ users = {
+ git = {
+ isSystemUser = true;
+ description = "aethrvmn";
+ group = "git";
+ home = "/srv/git";
+ homeMode = "0755";
+ createHome = true;
+ shell = "${pkgs.git}/bin/git-shell";
+
+ openssh.authorizedKeys.keys = [
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFTRmMBlTFJbOWQBLI9XS2HMdUSlsAcaQ6vWjLpfweEo aethrvmn@apotheke.earth"
+ ];
+ };
+
+ cgit = {
+ isSystemUser = true;
+ extraGroups = [ "git" ];
+ };
+ };
+ };
+
+ systemd = {
+ tmpfiles.rules = [
+ # type path mode uid gid age target
+ "L /srv/git/static - git git - /home/aethrvmn/.nix/modules/server/cgit/static"
+ ];
+ };
+}
diff --git a/modules/server/cgit/static/cgit.css b/modules/server/cgit/static/cgit.css
new file mode 100644
index 0000000..d2ee006
--- /dev/null
+++ b/modules/server/cgit/static/cgit.css
@@ -0,0 +1,1346 @@
+@import url(source-code-pro/source-code-pro.css);
+
+div#cgit {
+ padding: 0em;
+ margin: 0em;
+ font-family: sans-serif;
+ font-size: 10pt;
+ color: #333;
+ background: white;
+ padding: 4px;
+}
+
+div#cgit a {
+ color: blue;
+ text-decoration: none;
+}
+
+div#cgit a:hover {
+ text-decoration: underline;
+}
+
+div#cgit table {
+ border-collapse: collapse;
+}
+
+div#cgit table#header {
+ width: 100%;
+ margin-bottom: 1em;
+}
+
+div#cgit table#header td.logo {
+ width: 96px;
+ vertical-align: top;
+
+ img {
+ width: 96px;
+ }
+}
+
+div#cgit table#header td.main {
+ font-size: 250%;
+ padding-left: 10px;
+ white-space: nowrap;
+}
+
+div#cgit table#header td.main a {
+ color: #000;
+}
+
+div#cgit table#header td.form {
+ text-align: right;
+ vertical-align: bottom;
+ padding-right: 1em;
+ padding-bottom: 2px;
+ white-space: nowrap;
+}
+
+div#cgit table#header td.form form,
+div#cgit table#header td.form input,
+div#cgit table#header td.form select {
+ font-size: 90%;
+}
+
+div#cgit table#header td.sub {
+ color: #777;
+ border-top: solid 1px #ccc;
+ padding-left: 10px;
+}
+
+div#cgit table.tabs {
+ border-bottom: solid 3px #ccc;
+ border-collapse: collapse;
+ margin-top: 2em;
+ margin-bottom: 0px;
+ width: 100%;
+}
+
+div#cgit table.tabs td {
+ padding: 0px 1em;
+ vertical-align: bottom;
+}
+
+div#cgit table.tabs td a {
+ padding: 2px 0.75em;
+ color: #777;
+ font-size: 110%;
+}
+
+div#cgit table.tabs td a.active {
+ color: #000;
+ background-color: #ccc;
+}
+
+div#cgit table.tabs a[href^="http://"]:after, div#cgit table.tabs a[href^="https://"]:after
+{
+ content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAQAAAAnOwc2AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfgAhcJDQY+gm2TAAAAHWlUWHRDb21tZW50AAAAAABDcmVhdGVkIHdpdGggR0lNUGQuZQcAAABbSURBVAhbY2BABs4MU4CwhYHBh2Erww4wrGFQZHjI8B8IgUIscJWyDHcggltQhI4zGDCcRwhChPggHIggP1QoAVmQkSETrGoHsiAEsACtBYN0oDAMbgU6EBcAAL2eHUt4XUU4AAAAAElFTkSuQmCC);
+ opacity: 0.5;
+ margin: 0 0 0 5px;
+}
+
+div#cgit table.tabs td.form {
+ text-align: right;
+}
+
+div#cgit table.tabs td.form form {
+ padding-bottom: 2px;
+ font-size: 90%;
+ white-space: nowrap;
+}
+
+div#cgit table.tabs td.form input,
+div#cgit table.tabs td.form select {
+ font-size: 90%;
+}
+
+div#cgit div.path {
+ margin: 0px;
+ padding: 5px 2em 2px 2em;
+ color: #000;
+ background-color: #eee;
+}
+
+div#cgit div.content {
+ margin: 0px;
+ padding: 2em;
+ border-bottom: solid 3px #ccc;
+}
+
+div#cgit table.list {
+ width: 100%;
+ border: none;
+ border-collapse: collapse;
+}
+
+div#cgit table.list tr {
+ background: white;
+}
+
+div#cgit table.list tr.logheader {
+ background: #eee;
+}
+
+div#cgit table.list tr:nth-child(even) {
+ background: #f7f7f7;
+}
+
+div#cgit table.list tr:nth-child(odd) {
+ background: white;
+}
+
+div#cgit table.list tr:hover {
+ background: #eee;
+}
+
+div#cgit table.list tr.nohover {
+ background: white;
+}
+
+div#cgit table.list tr.nohover:hover {
+ background: white;
+}
+
+div#cgit table.list tr.nohover-highlight:hover:nth-child(even) {
+ background: #f7f7f7;
+}
+
+div#cgit table.list tr.nohover-highlight:hover:nth-child(odd) {
+ background: white;
+}
+
+div#cgit table.list th {
+ font-weight: bold;
+ /* color: #888;
+ border-top: dashed 1px #888;
+ border-bottom: dashed 1px #888;
+ */
+ padding: 0.1em 0.5em 0.05em 0.5em;
+ vertical-align: baseline;
+}
+
+div#cgit table.list td {
+ border: none;
+ padding: 0.1em 0.5em 0.1em 0.5em;
+}
+
+div#cgit table.list td.commitgraph {
+ font-family: "Source Code Pro", "Courier New", monospace;
+ white-space: pre;
+}
+div#cgit pre {
+ font-family: "Source Code Pro", "Courier New", monospace;
+}
+
+div#cgit table.list td.commitgraph .column1 {
+ color: #a00;
+}
+
+div#cgit table.list td.commitgraph .column2 {
+ color: #0a0;
+}
+
+div#cgit table.list td.commitgraph .column3 {
+ color: #aa0;
+}
+
+div#cgit table.list td.commitgraph .column4 {
+ color: #00a;
+}
+
+div#cgit table.list td.commitgraph .column5 {
+ color: #a0a;
+}
+
+div#cgit table.list td.commitgraph .column6 {
+ color: #0aa;
+}
+
+div#cgit table.list td.logsubject {
+ font-family: "Source Code Pro", "Courier New", monospace;
+ font-weight: bold;
+}
+
+div#cgit table.list td.logmsg {
+ font-family: "Source Code Pro", "Courier New", monospace;
+ white-space: pre;
+ padding: 0 0.5em;
+}
+
+div#cgit table.list td a {
+ color: black;
+}
+
+div#cgit table.list td a.ls-dir {
+ font-weight: bold;
+ color: #00f;
+}
+
+div#cgit table.list td a:hover {
+ color: #00f;
+}
+
+div#cgit img {
+ border: none;
+}
+
+div#cgit input#switch-btn {
+ margin: 2px 0px 0px 0px;
+}
+
+div#cgit td#sidebar input.txt {
+ width: 100%;
+ margin: 2px 0px 0px 0px;
+}
+
+div#cgit table#grid {
+ margin: 0px;
+}
+
+div#cgit td#content {
+ vertical-align: top;
+ padding: 1em 2em 1em 1em;
+ border: none;
+}
+
+div#cgit div#summary {
+ vertical-align: top;
+ margin-bottom: 1em;
+}
+
+div#cgit table#downloads {
+ float: right;
+ border-collapse: collapse;
+ border: solid 1px #777;
+ margin-left: 0.5em;
+ margin-bottom: 0.5em;
+}
+
+div#cgit table#downloads th {
+ background-color: #ccc;
+}
+
+div#cgit div#blob {
+ border: solid 1px black;
+}
+
+div#cgit div.error {
+ color: red;
+ font-weight: bold;
+ margin: 1em 2em;
+}
+
+div#cgit a.ls-blob,
+div#cgit a.ls-dir,
+div#cgit .ls-mod {
+ font-family: "Source Code Pro", "Courier New", monospace;
+}
+
+div#cgit td.ls-size {
+ text-align: right;
+ font-family: "Source Code Pro", "Courier New", monospace;
+ width: 10em;
+}
+
+div#cgit td.ls-mode {
+ font-family: "Source Code Pro", "Courier New", monospace;
+ width: 10em;
+}
+
+div#cgit table.blob {
+ margin-top: 0.5em;
+ border-top: solid 1px black;
+}
+
+div#cgit table.blob td.hashes,
+div#cgit table.blob td.lines {
+ margin: 0;
+ padding: 0 0 0 0.5em;
+ vertical-align: top;
+ color: black;
+}
+
+div#cgit table.blob td.linenumbers {
+ margin: 0;
+ padding: 0 0.5em 0 0.5em;
+ vertical-align: top;
+ text-align: right;
+ border-right: 1px solid gray;
+}
+
+div#cgit table.blob pre {
+ padding: 0;
+ margin: 0;
+}
+
+div#cgit table.blob td.linenumbers a,
+div#cgit table.ssdiff td.lineno a {
+ color: gray;
+ text-align: right;
+ text-decoration: none;
+}
+
+div#cgit table.blob td.linenumbers a:hover,
+div#cgit table.ssdiff td.lineno a:hover {
+ color: black;
+}
+
+div#cgit table.blame td.hashes,
+div#cgit table.blame td.lines,
+div#cgit table.blame td.linenumbers {
+ padding: 0;
+}
+
+div#cgit table.blame td.hashes div.alt,
+div#cgit table.blame td.lines div.alt {
+ padding: 0 0.5em 0 0.5em;
+}
+
+div#cgit table.blame td.linenumbers div.alt {
+ padding: 0 0.5em 0 0;
+}
+
+div#cgit table.blame div.alt:nth-child(even) {
+ background: #eee;
+}
+
+div#cgit table.blame div.alt:nth-child(odd) {
+ background: white;
+}
+
+div#cgit table.blame td.lines > div {
+ position: relative;
+}
+
+div#cgit table.blame td.lines > div > pre {
+ padding: 0 0 0 0.5em;
+ position: absolute;
+ top: 0;
+}
+
+div#cgit table.blame .oid {
+ font-size: 100%;
+}
+
+div#cgit table.bin-blob {
+ margin-top: 0.5em;
+ border: solid 1px black;
+}
+
+div#cgit table.bin-blob th {
+ font-family: "Source Code Pro", "Courier New", monospace;
+ white-space: pre;
+ border: solid 1px #777;
+ padding: 0.5em 1em;
+}
+
+div#cgit table.bin-blob td {
+ font-family: "Source Code Pro", "Courier New", monospace;
+ white-space: pre;
+ border-left: solid 1px #777;
+ padding: 0em 1em;
+}
+
+div#cgit table.nowrap td {
+ white-space: nowrap;
+}
+
+div#cgit table.commit-info {
+ border-collapse: collapse;
+ margin-top: 1.5em;
+}
+
+div#cgit div.cgit-panel {
+ float: right;
+ margin-top: 1.5em;
+}
+
+div#cgit div.cgit-panel table {
+ border-collapse: collapse;
+ border: solid 1px #aaa;
+ background-color: #eee;
+}
+
+div#cgit div.cgit-panel th {
+ text-align: center;
+}
+
+div#cgit div.cgit-panel td {
+ padding: 0.25em 0.5em;
+}
+
+div#cgit div.cgit-panel td.label {
+ padding-right: 0.5em;
+}
+
+div#cgit div.cgit-panel td.ctrl {
+ padding-left: 0.5em;
+}
+
+div#cgit table.commit-info th {
+ text-align: left;
+ font-weight: normal;
+ padding: 0.1em 1em 0.1em 0.1em;
+ vertical-align: top;
+}
+
+div#cgit table.commit-info td {
+ font-weight: normal;
+ padding: 0.1em 1em 0.1em 0.1em;
+}
+
+div#cgit div.commit-subject {
+ font-weight: bold;
+ font-size: 125%;
+ margin: 1.5em 0em 0.5em 0em;
+ padding: 0em;
+}
+
+div#cgit div.commit-msg {
+ white-space: pre;
+ font-family: "Source Code Pro", "Courier New", monospace;
+}
+
+div#cgit div.notes-header {
+ font-weight: bold;
+ padding-top: 1.5em;
+}
+
+div#cgit div.notes {
+ white-space: pre;
+ font-family: "Source Code Pro", "Courier New", monospace;
+ border: solid 1px #ee9;
+ background-color: #ffd;
+ padding: 0.3em 2em 0.3em 1em;
+ float: left;
+}
+
+div#cgit div.notes-footer {
+ clear: left;
+}
+
+div#cgit div.diffstat-header {
+ font-weight: bold;
+ padding-top: 1.5em;
+}
+
+div#cgit table.diffstat {
+ border-collapse: collapse;
+ border: solid 1px #aaa;
+ background-color: #eee;
+}
+
+div#cgit table.diffstat th {
+ font-weight: normal;
+ text-align: left;
+ text-decoration: underline;
+ padding: 0.1em 1em 0.1em 0.1em;
+ font-size: 100%;
+}
+
+div#cgit table.diffstat td {
+ padding: 0.2em 0.2em 0.1em 0.1em;
+ font-size: 100%;
+ border: none;
+}
+
+div#cgit table.diffstat td.mode {
+ white-space: nowrap;
+}
+
+div#cgit table.diffstat td span.modechange {
+ padding-left: 1em;
+ color: red;
+}
+
+div#cgit table.diffstat td.add a {
+ color: green;
+}
+
+div#cgit table.diffstat td.del a {
+ color: red;
+}
+
+div#cgit table.diffstat td.upd a {
+ color: blue;
+}
+
+div#cgit table.diffstat td.graph {
+ width: 500px;
+ vertical-align: middle;
+}
+
+div#cgit table.diffstat td.graph table {
+ border: none;
+}
+
+div#cgit table.diffstat td.graph td {
+ padding: 0px;
+ border: 0px;
+ height: 7pt;
+}
+
+div#cgit table.diffstat td.graph td.add {
+ background-color: #5c5;
+}
+
+div#cgit table.diffstat td.graph td.rem {
+ background-color: #c55;
+}
+
+div#cgit div.diffstat-summary {
+ color: #888;
+ padding-top: 0.5em;
+}
+
+div#cgit table.diff {
+ width: 100%;
+}
+
+div#cgit table.diff td {
+ font-family: "Source Code Pro", "Courier New", monospace;
+ white-space: pre;
+}
+
+div#cgit table.diff td div.head {
+ font-weight: bold;
+ margin-top: 1em;
+ color: black;
+}
+
+div#cgit table.diff td div.hunk {
+ color: #009;
+}
+
+div#cgit table.diff td div.add {
+ color: green;
+}
+
+div#cgit table.diff td div.del {
+ color: red;
+}
+
+div#cgit .oid {
+ font-family: "Source Code Pro", "Courier New", monospace;
+ font-size: 90%;
+}
+
+div#cgit .left {
+ text-align: left;
+}
+
+div#cgit .right {
+ text-align: right;
+}
+
+div#cgit table.list td.reposection {
+ font-style: italic;
+ color: #888;
+}
+
+div#cgit a.button {
+ font-size: 80%;
+ padding: 0em 0.5em;
+}
+
+div#cgit a.primary {
+ font-size: 100%;
+}
+
+div#cgit a.secondary {
+ font-size: 90%;
+}
+
+div#cgit td.toplevel-repo {
+}
+
+div#cgit table.list td.sublevel-repo {
+ padding-left: 1.5em;
+}
+
+div#cgit ul.pager {
+ list-style-type: none;
+ text-align: center;
+ margin: 1em 0em 0em 0em;
+ padding: 0;
+}
+
+div#cgit ul.pager li {
+ display: inline-block;
+ margin: 0.25em 0.5em;
+}
+
+div#cgit ul.pager a {
+ color: #777;
+}
+
+div#cgit ul.pager .current {
+ font-weight: bold;
+}
+
+div#cgit span.age-mins {
+ font-weight: bold;
+ color: #080;
+}
+
+div#cgit span.age-hours {
+ color: #080;
+}
+
+div#cgit span.age-days {
+ color: #040;
+}
+
+div#cgit span.age-weeks {
+ color: #444;
+}
+
+div#cgit span.age-months {
+ color: #888;
+}
+
+div#cgit span.age-years {
+ color: #bbb;
+}
+
+div#cgit span.insertions {
+ color: #080;
+}
+
+div#cgit span.deletions {
+ color: #800;
+}
+
+div#cgit div.footer {
+ margin-top: 0.5em;
+ text-align: center;
+ font-size: 80%;
+ color: #ccc;
+}
+
+div#cgit div.footer a {
+ color: #ccc;
+ text-decoration: none;
+}
+
+div#cgit div.footer a:hover {
+ text-decoration: underline;
+}
+
+div#cgit a.branch-deco {
+ color: #000;
+ margin: 0px 0.5em;
+ padding: 0px 0.25em;
+ background-color: #88ff88;
+ border: solid 1px #007700;
+}
+
+div#cgit a.tag-deco {
+ color: #000;
+ margin: 0px 0.5em;
+ padding: 0px 0.25em;
+ background-color: #ffff88;
+ border: solid 1px #777700;
+}
+
+div#cgit a.tag-annotated-deco {
+ color: #000;
+ margin: 0px 0.5em;
+ padding: 0px 0.25em;
+ background-color: #ffcc88;
+ border: solid 1px #777700;
+}
+
+div#cgit a.remote-deco {
+ color: #000;
+ margin: 0px 0.5em;
+ padding: 0px 0.25em;
+ background-color: #ccccff;
+ border: solid 1px #000077;
+}
+
+div#cgit a.deco {
+ color: #000;
+ margin: 0px 0.5em;
+ padding: 0px 0.25em;
+ background-color: #ff8888;
+ border: solid 1px #770000;
+}
+
+div#cgit div.commit-subject a.branch-deco,
+div#cgit div.commit-subject a.tag-deco,
+div#cgit div.commit-subject a.tag-annotated-deco,
+div#cgit div.commit-subject a.remote-deco,
+div#cgit div.commit-subject a.deco {
+ margin-left: 1em;
+ font-size: 75%;
+}
+
+div#cgit table.stats {
+ border: solid 1px black;
+ border-collapse: collapse;
+}
+
+div#cgit table.stats th {
+ text-align: left;
+ padding: 1px 0.5em;
+ background-color: #eee;
+ border: solid 1px black;
+}
+
+div#cgit table.stats td {
+ text-align: right;
+ padding: 1px 0.5em;
+ border: solid 1px black;
+}
+
+div#cgit table.stats td.total {
+ font-weight: bold;
+ text-align: left;
+}
+
+div#cgit table.stats td.sum {
+ color: #c00;
+ font-weight: bold;
+ /* background-color: #eee; */
+}
+
+div#cgit table.stats td.left {
+ text-align: left;
+}
+
+div#cgit table.vgraph {
+ border-collapse: separate;
+ border: solid 1px black;
+ height: 200px;
+}
+
+div#cgit table.vgraph th {
+ background-color: #eee;
+ font-weight: bold;
+ border: solid 1px white;
+ padding: 1px 0.5em;
+}
+
+div#cgit table.vgraph td {
+ vertical-align: bottom;
+ padding: 0px 10px;
+}
+
+div#cgit table.vgraph div.bar {
+ background-color: #eee;
+}
+
+div#cgit table.hgraph {
+ border: solid 1px black;
+ width: 800px;
+}
+
+div#cgit table.hgraph th {
+ background-color: #eee;
+ font-weight: bold;
+ border: solid 1px black;
+ padding: 1px 0.5em;
+}
+
+div#cgit table.hgraph td {
+ vertical-align: middle;
+ padding: 2px 2px;
+}
+
+div#cgit table.hgraph div.bar {
+ background-color: #eee;
+ height: 1em;
+}
+
+div#cgit table.ssdiff {
+ width: 100%;
+}
+
+div#cgit table.ssdiff td {
+ font-size: 75%;
+ font-family: "Source Code Pro", "Courier New", monospace;
+ white-space: pre;
+ padding: 1px 4px 1px 4px;
+ border-left: solid 1px #aaa;
+ border-right: solid 1px #aaa;
+}
+
+div#cgit table.ssdiff td.add {
+ color: black;
+ background: #cfc;
+ min-width: 50%;
+}
+
+div#cgit table.ssdiff td.add_dark {
+ color: black;
+ background: #aca;
+ min-width: 50%;
+}
+
+div#cgit table.ssdiff span.add {
+ background: #cfc;
+ font-weight: bold;
+}
+
+div#cgit table.ssdiff td.del {
+ color: black;
+ background: #fcc;
+ min-width: 50%;
+}
+
+div#cgit table.ssdiff td.del_dark {
+ color: black;
+ background: #caa;
+ min-width: 50%;
+}
+
+div#cgit table.ssdiff span.del {
+ background: #fcc;
+ font-weight: bold;
+}
+
+div#cgit table.ssdiff td.changed {
+ color: black;
+ background: #ffc;
+ min-width: 50%;
+}
+
+div#cgit table.ssdiff td.changed_dark {
+ color: black;
+ background: #cca;
+ min-width: 50%;
+}
+
+div#cgit table.ssdiff td.lineno {
+ color: black;
+ background: #eee;
+ text-align: right;
+ width: 3em;
+ min-width: 3em;
+}
+
+div#cgit table.ssdiff td.hunk {
+ color: black;
+ background: #ccf;
+ border-top: solid 1px #aaa;
+ border-bottom: solid 1px #aaa;
+}
+
+div#cgit table.ssdiff td.head {
+ border-top: solid 1px #aaa;
+ border-bottom: solid 1px #aaa;
+}
+
+div#cgit table.ssdiff td.head div.head {
+ font-weight: bold;
+ color: black;
+}
+
+div#cgit table.ssdiff td.foot {
+ border-top: solid 1px #aaa;
+ border-left: none;
+ border-right: none;
+ border-bottom: none;
+}
+
+div#cgit table.ssdiff td.space {
+ border: none;
+}
+
+div#cgit table.ssdiff td.space div {
+ min-height: 3em;
+}
+div#cgit span.libravatar img.onhover {
+ display: none;
+ border: 1px solid gray;
+ padding: 0px;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ width: 128px;
+ height: 128px;
+}
+
+div#cgit span.libravatar img.inline {
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+ width: 13px;
+ height: 13px;
+ margin-right: 0.2em;
+ opacity: 0.6;
+}
+
+div#cgit span.libravatar:hover > img.onhover {
+ display: block;
+ position: absolute;
+ margin-left: 1.5em;
+ background-color: #eeeeee;
+ box-shadow: 2px 2px 7px rgba(100, 100, 100, 0.75);
+}
+
+/*
+ Color overrides for browsers running in dark mode.
+ "only all and ..." forces very old browsers to ignore the media query:
+ https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries#improving_compatibility_with_older_browsers
+*/
+:root {
+ color-scheme: light dark;
+}
+@media only all and (prefers-color-scheme: dark) {
+ html,
+ div#cgit {
+ color: #eee;
+ background: #171717;
+ }
+ div#cgit a {
+ color: #3af;
+ }
+ div#cgit .diffstat-header a {
+ color: #28d;
+ }
+ div#cgit table#header td.main a {
+ color: #eee;
+ }
+ div#cgit table#header td.sub {
+ color: #999;
+ }
+ div#cgit table.tabs {
+ border-bottom-color: #444;
+ }
+ div#cgit table.tabs td a {
+ color: #888;
+ }
+ div#cgit table.tabs td a.active {
+ color: #fff;
+ background-color: #444;
+ }
+ div#cgit div.path {
+ color: #eee;
+ background-color: #333;
+ }
+ div#cgit div.content {
+ border-bottom-color: #bbb;
+ }
+ div#cgit table.list tr {
+ background: #171717;
+ }
+ div#cgit table.list tr.logheader {
+ background: #171717;
+ }
+ div#cgit table.list tr:nth-child(even) {
+ background: #171717;
+ }
+ div#cgit table.list tr:nth-child(odd) {
+ background: #1f1f1f;
+ }
+ div#cgit table.list tr:hover {
+ background: #333;
+ }
+ div#cgit table.list tr.nohover {
+ background: #171717;
+ }
+ div#cgit table.list tr.nohover:hover {
+ background: #171717;
+ }
+ div#cgit table.list tr.nohover-highlight:hover:nth-child(even) {
+ background: #171717;
+ }
+ div#cgit table.list tr.nohover-highlight:hover:nth-child(odd) {
+ background: #1f1f1f;
+ }
+ div#cgit table.list td.commitgraph .column1 {
+ color: #f55;
+ }
+ div#cgit table.list td.commitgraph .column2 {
+ color: #5f5;
+ }
+ div#cgit table.list td.commitgraph .column3 {
+ color: #ff5;
+ }
+ div#cgit table.list td.commitgraph .column4 {
+ color: #55f;
+ }
+ div#cgit table.list td.commitgraph .column5 {
+ color: #f5f;
+ }
+ div#cgit table.list td.commitgraph .column6 {
+ color: #5ff;
+ }
+ div#cgit table.list td a {
+ color: #eee;
+ }
+ div#cgit table.list td a.ls-dir {
+ color: #28d;
+ }
+ div#cgit table.list td a:hover {
+ color: #3af;
+ }
+ div#cgit table#downloads {
+ border-color: #888;
+ }
+ div#cgit table#downloads th {
+ background-color: #333;
+ }
+ div#cgit div#blob {
+ border-color: #eee;
+ }
+ div#cgit table.blob {
+ border-top-color: #eee;
+ }
+ div#cgit table.blob td.hashes,
+ div#cgit table.blob td.lines {
+ color: #eee;
+ }
+ div#cgit table.blob td.linenumbers {
+ border-right-color: gray;
+ }
+ div#cgit table.blob td.linenumbers a,
+ div#cgit table.ssdiff td.lineno a {
+ color: gray;
+ }
+ div#cgit table.blob td.linenumbers a:hover,
+ div#cgit table.ssdiff td.lineno a:hover {
+ color: #eee;
+ }
+ div#cgit table.blame div.alt:nth-child(even) {
+ background: #171717;
+ }
+ div#cgit table.blame div.alt:nth-child(odd) {
+ background: #1f1f1f;
+ }
+ div#cgit table.bin-blob {
+ border-color: #eee;
+ }
+ div#cgit table.bin-blob th {
+ border-color: #888;
+ }
+ div#cgit table.bin-blob td {
+ border-left-color: #888;
+ }
+ div#cgit div.cgit-panel table {
+ border-color: #555;
+ background-color: #282828;
+ }
+ div#cgit div.notes {
+ border-color: #661;
+ background-color: #220;
+ }
+ div#cgit table.diffstat {
+ border-color: #555;
+ background-color: #282828;
+ }
+ div#cgit table.diffstat td span.modechange {
+ color: #c66;
+ }
+ div#cgit table.diffstat td.add a {
+ color: #6c6;
+ }
+ div#cgit table.diffstat td.del a {
+ color: #c66;
+ }
+ div#cgit table.diffstat td.upd a {
+ color: #3af;
+ }
+ div#cgit table.diffstat td.graph td.add {
+ background-color: #3a3;
+ }
+ div#cgit table.diffstat td.graph td.rem {
+ background-color: #a33;
+ }
+ div#cgit div.diffstat-summary {
+ color: #777;
+ }
+ div#cgit table.diff td div.head {
+ color: #eee;
+ }
+ div#cgit table.diff td div.hunk {
+ color: #28d;
+ }
+ div#cgit table.diff td div.add {
+ color: #6c6;
+ }
+ div#cgit table.diff td div.del {
+ color: #c66;
+ }
+ div#cgit table.list td.reposection {
+ color: #777;
+ }
+ div#cgit ul.pager a {
+ color: #888;
+ }
+ div#cgit span.age-mins {
+ color: #7f7;
+ }
+ div#cgit span.age-hours {
+ color: #7f7;
+ }
+ div#cgit span.age-days {
+ color: #9d9;
+ }
+ div#cgit span.age-weeks {
+ color: #bbb;
+ }
+ div#cgit span.age-months {
+ color: #888;
+ }
+ div#cgit span.age-years {
+ color: #666;
+ }
+ div#cgit span.insertions {
+ color: #7f7;
+ }
+ div#cgit span.deletions {
+ color: #e33;
+ }
+ div#cgit div.footer {
+ color: #555;
+ }
+ div#cgit div.footer a {
+ color: #555;
+ }
+ div#cgit a.branch-deco {
+ color: #fff;
+ background-color: #361;
+ border-color: #3b2;
+ }
+ div#cgit a.tag-deco {
+ color: #fff;
+ background-color: #650;
+ border-color: #ba3;
+ }
+ div#cgit a.tag-annotated-deco {
+ color: #fff;
+ background-color: #840;
+ border-color: #b96;
+ }
+ div#cgit a.remote-deco {
+ color: #fff;
+ background-color: #348;
+ border-color: #67c;
+ }
+ div#cgit a.deco {
+ color: #fff;
+ background-color: #922;
+ border-color: #d55;
+ }
+ div#cgit a.branch-deco:hover,
+ div#cgit table.list td a.branch-deco:hover,
+ div#cgit a.tag-deco:hover,
+ div#cgit table.list td a.tag-deco:hover,
+ div#cgit a.tag-annotated-deco:hover,
+ div#cgit table.list td a.tag-annotated-deco:hover,
+ div#cgit a.remote-deco:hover,
+ div#cgit table.list td a.remote-deco:hover,
+ div#cgit a.deco:hover,
+ div#cgit table.list td a.deco:hover {
+ color: #fff;
+ }
+ div#cgit table.stats {
+ border-color: #555;
+ }
+ div#cgit table.stats th {
+ background-color: #333;
+ border-color: #555;
+ }
+ div#cgit table.stats td {
+ border-color: #555;
+ }
+ div#cgit table.stats td.sum {
+ color: #5c7e9b;
+ }
+ div#cgit table.vgraph {
+ border-color: #eee;
+ }
+ div#cgit table.vgraph th {
+ background-color: #1f1f1f;
+ border-color: black;
+ }
+ div#cgit table.vgraph div.bar {
+ background-color: #1f1f1f;
+ }
+ div#cgit table.hgraph {
+ border-color: #eee;
+ }
+ div#cgit table.hgraph th {
+ background-color: #1f1f1f;
+ border-color: #eee;
+ }
+ div#cgit table.hgraph div.bar {
+ background-color: #1f1f1f;
+ }
+ div#cgit table.ssdiff td {
+ border-left-color: #555;
+ border-right-color: #555;
+ }
+ div#cgit table.ssdiff td.add {
+ color: #eee;
+ background: #353;
+ }
+ div#cgit table.ssdiff td.add_dark {
+ color: #eee;
+ background: #030;
+ }
+ div#cgit table.ssdiff span.add {
+ background: #030;
+ }
+ div#cgit table.ssdiff td.del {
+ color: #eee;
+ background: #533;
+ }
+ div#cgit table.ssdiff td.del_dark {
+ color: #eee;
+ background: #411;
+ }
+ div#cgit table.ssdiff span.del {
+ background: #300;
+ }
+ div#cgit table.ssdiff td.changed {
+ color: #eee;
+ background: #553;
+ }
+ div#cgit table.ssdiff td.changed_dark {
+ color: #eee;
+ background: #330;
+ }
+ div#cgit table.ssdiff td.lineno {
+ color: #eee;
+ background: #1f1f1f;
+ }
+ div#cgit table.ssdiff td.hunk {
+ color: #eee;
+ background: #0d3d64;
+ border-top-color: #555;
+ border-bottom-color: #555;
+ }
+ div#cgit table.ssdiff td.head {
+ border-top-color: #555;
+ border-bottom-color: #555;
+ }
+ div#cgit table.ssdiff td.head div.head {
+ color: #eee;
+ }
+ div#cgit table.ssdiff td.foot {
+ border-top-color: #555;
+ }
+}
+/* Style definition file generated by highlight 3.13, http://www.andre-simon.de/ */
+
+/* Highlighting theme: Kwrite Editor */
+
+body.hl {
+ background-color: #e0eaee;
+}
+pre.hl {
+ color: #000000;
+ background-color: #e0eaee;
+ font-size: 10pt;
+ font-family: "Courier New", monospace;
+}
+.hl.num {
+ color: #b07e00;
+}
+.hl.esc {
+ color: #ff00ff;
+}
+.hl.str {
+ color: #bf0303;
+}
+.hl.pps {
+ color: #818100;
+}
+.hl.slc {
+ color: #838183;
+ font-style: italic;
+}
+.hl.com {
+ color: #838183;
+ font-style: italic;
+}
+.hl.ppc {
+ color: #008200;
+}
+.hl.opt {
+ color: #000000;
+}
+.hl.ipl {
+ color: #0057ae;
+}
+.hl.lin {
+ color: #555555;
+}
+.hl.kwa {
+ color: #000000;
+ font-weight: bold;
+}
+.hl.kwb {
+ color: #0057ae;
+}
+.hl.kwc {
+ color: #000000;
+ font-weight: bold;
+}
+.hl.kwd {
+ color: #010181;
+}
+
diff --git a/modules/server/cgit/static/favicon.png b/modules/server/cgit/static/favicon.png
new file mode 100755
index 0000000..a9c1396
--- /dev/null
+++ b/modules/server/cgit/static/favicon.png
Binary files differ
diff --git a/modules/server/cgit/static/logo.png b/modules/server/cgit/static/logo.png
new file mode 100755
index 0000000..a9c1396
--- /dev/null
+++ b/modules/server/cgit/static/logo.png
Binary files differ
diff --git a/modules/server/default.nix b/modules/server/default.nix
new file mode 100644
index 0000000..60b7681
--- /dev/null
+++ b/modules/server/default.nix
@@ -0,0 +1,53 @@
+{
+ imports = [
+ ./adguard
+ ./calibre
+ ./cgit
+ ./forgejo
+ ./gemini
+ ./grafana
+ ./immich
+ ./jellyfin
+ ./ollama
+ ./searx
+ ];
+
+ services = {
+ nginx = {
+ enable = true;
+ recommendedGzipSettings = true;
+ recommendedOptimisation = true;
+ recommendedProxySettings = true;
+ };
+
+ sshguard.enable = true;
+
+ openssh = {
+ enable = false;
+ settings = {
+ PermitRootLogin = false;
+ PasswordAuthentication = false;
+ AllowTcpForwarding = false;
+ X11Forwarding = false;
+ };
+ };
+ };
+
+ networking = {
+ firewall.allowedTCPPorts = [ 80 ];
+
+ hosts = {
+ "127.0.0.1" = [
+ "library.internal"
+ "media.internal"
+ "photos.internal"
+ "chat.internal"
+ "ollama.internal"
+ "code.internal"
+ "forge.internal"
+ "search.internal"
+ "monitor.internal"
+ ];
+ };
+ };
+}
diff --git a/modules/server/forgejo/default.nix b/modules/server/forgejo/default.nix
new file mode 100644
index 0000000..cf611ce
--- /dev/null
+++ b/modules/server/forgejo/default.nix
@@ -0,0 +1,42 @@
+{
+ services = {
+ forgejo = {
+ enable = true;
+
+ dump.enable = true;
+
+ settings = {
+ DEFAULT = {
+ APP_NAME = "apothēke";
+ RUN_MODE = "prod";
+ APP_SLOGAN = "a place for storing objects.";
+ RUN_USER = "forgejo";
+ };
+
+ server = {
+ HTTP_ADDR = "forge.internal";
+ HTTP_PORT = 3000;
+ DISABLE_SSH = true;
+ };
+
+ service = {
+ DISABLE_REGISTRATION = false;
+ DEFAULT_KEEP_EMAIL_PRIVATE = true;
+ };
+
+ lfs = {
+ enable = true;
+ };
+ };
+ };
+
+ nginx = {
+ virtualHosts."forge.internal" = {
+ locations."/" = {
+ proxyPass = "http://127.0.0.1:3000";
+ proxyWebsockets = true;
+ };
+ };
+ };
+ };
+}
diff --git a/modules/server/gemini/default.nix b/modules/server/gemini/default.nix
new file mode 100644
index 0000000..d59f65f
--- /dev/null
+++ b/modules/server/gemini/default.nix
@@ -0,0 +1,57 @@
+{ config, pkgs, lib, ... }:
+{
+ services.agate = {
+ enable = true;
+
+ hostnames = [ "aethrvmn.gr" ];
+ addresses = [ "0.0.0.0:1965" ];
+ language = "en";
+ contentDir = "/srv/gemini";
+ };
+
+ networking.firewall.allowedTCPPorts = [ 1965 ];
+
+ users = {
+ groups.agate = { };
+ users = {
+ agate = {
+ isSystemUser = true;
+ description = "gemini user";
+ group = "agate";
+ home = "/srv/gemini";
+ createHome = true;
+ shell = "${pkgs.git}/bin/git-shell";
+ };
+ };
+ };
+
+ systemd = {
+ # set service
+ services."gemini" = {
+ description = "Update Gemini site from repo";
+
+ script = ''
+ if [ -d /srv/gemini/.git ]; then
+ ${pkgs.git}/bin/git -C /srv/gemini pull
+ else
+ ${pkgs.git}/bin/git clone https://apo.theke.ml/aethrvmn/gemini.git /srv/gemini
+ fi
+ '';
+
+ serviceConfig = {
+ Type = "oneshot";
+ User = "agate";
+ };
+ };
+
+ timers."gemini" = {
+ description = "Hourly Gemini-site update";
+ wantedBy = [ "timers.target" ];
+
+ timerConfig = {
+ OnCalendar = "hourly";
+ Persistent = true;
+ };
+ };
+ };
+}
diff --git a/modules/server/grafana/default.nix b/modules/server/grafana/default.nix
new file mode 100644
index 0000000..056221a
--- /dev/null
+++ b/modules/server/grafana/default.nix
@@ -0,0 +1,23 @@
+{ config, pkgs, ... }:
+{
+ services = {
+ grafana = {
+ enable = false;
+ settings.server = {
+ domain = "monitor.internal";
+ http_port = 3050;
+ http_addr = "127.0.0.1";
+ };
+ };
+
+ nginx = {
+ virtualHosts."monitor.internal" = {
+ locations."/" = {
+ proxyPass = "http://127.0.0.1:3050";
+ proxyWebsockets = true;
+ };
+ };
+ };
+ };
+}
+
diff --git a/modules/server/immich/default.nix b/modules/server/immich/default.nix
new file mode 100644
index 0000000..fac75f9
--- /dev/null
+++ b/modules/server/immich/default.nix
@@ -0,0 +1,28 @@
+{ config, lib, ... }:
+{
+ services = {
+ # Immich setup
+ immich = {
+ enable = true;
+ openFirewall = false;
+
+ host = "127.0.0.1";
+ port = 3010;
+ };
+
+ nginx = {
+ virtualHosts."photos.internal" = {
+ locations."/" = {
+ proxyPass = "http://127.0.0.1:3010";
+ proxyWebsockets = true;
+ };
+ };
+ };
+ };
+
+ hardware.graphics.enable = lib.mkForce true;
+
+ users.users.immich = {
+ extraGroups = [ "video" "render" ];
+ };
+}
diff --git a/modules/server/jellyfin/default.nix b/modules/server/jellyfin/default.nix
new file mode 100644
index 0000000..424b4d8
--- /dev/null
+++ b/modules/server/jellyfin/default.nix
@@ -0,0 +1,27 @@
+{ config, pkgs, lib, ...}:
+{
+ environment.systemPackages = with pkgs; [
+ jellyfin
+ jellyfin-web
+ jellyfin-ffmpeg
+ logrotate
+ ];
+
+ services = {
+ jellyfin = {
+ enable = true;
+ openFirewall = false;
+ };
+
+ logrotate.enable = true;
+
+ nginx = {
+ virtualHosts."media.internal" = {
+ locations."/" = {
+ proxyPass = "http://127.0.0.1:8096";
+ proxyWebsockets = true;
+ };
+ };
+ };
+ };
+}
diff --git a/modules/server/ollama/default.nix b/modules/server/ollama/default.nix
new file mode 100644
index 0000000..3b99daf
--- /dev/null
+++ b/modules/server/ollama/default.nix
@@ -0,0 +1,69 @@
+{ config, pkgs, lib, ... }:
+{
+ services = {
+ ollama = {
+ enable = true;
+ loadModels = [
+ "qwen3:14b"
+ "gemma3:12b"
+ "gpt-oss:20b"
+ "deepseek-r1:14b"
+ "phi4-reasoning:14b"
+ ];
+
+ acceleration = "rocm";
+ environmentVariables = {
+ HCC_AMDGPU_TARGET = "gfx1031";
+ };
+ rocmOverrideGfx = "10.3.0";
+ };
+
+ open-webui = {
+ enable = true;
+ port = 3030;
+ environment = {
+ ANONYMIZED_TELEMETRY = "False";
+ DO_NOT_TRACK = "True";
+ SCARF_NO_ANALYTICS = "True";
+ WEBUI_AUTH = "False";
+ OLLAMA_API_BASE_URL = "http://localhost:11434";
+
+ #dir stuff
+ STATIC_DIR = "${config.services.open-webui.stateDir}/static";
+ DATA_DIR = "${config.services.open-webui.stateDir}/data";
+ HF_HOME = "${config.services.open-webui.stateDir}/hf_home";
+ SENTENCE_TRANSFORMERS_HOME = "${config.services.open-webui.stateDir}/transformers_home";
+ };
+ };
+
+ xserver.videoDrivers = [ "amdgpu" ];
+
+ nginx.virtualHosts = {
+ "chat.internal" = {
+ locations."/" = {
+ proxyPass = "http://127.0.0.1:3030";
+ proxyWebsockets = true;
+ };
+ };
+
+ "ollama.internal" = {
+ locations."/" = {
+ proxyPass = "http://127.0.0.1:11434";
+ proxyWebsockets = true;
+ };
+ };
+ };
+ };
+
+ nixpkgs.config = {
+ allowUnfree = lib.mkForce true;
+ rocmSupport = lib.mkForce true;
+ rocmTargets = [ "gfx1031" ];
+ };
+
+ environment.systemPackages = with pkgs; [
+ rocmPackages.rocminfo
+ rocmPackages.rocm-smi
+ rocmPackages.hipcc
+ ];
+}
Directive (EU) 2019/790, Article 4(3); all rights regarding Text and Data Mining (TDM) are reserved.