commit 7019a44685ab84c995bd276a89db473b7a8276a5 Author: Bryant Collins <111700bh@gmail.com> Date: Wed Oct 9 19:01:34 2024 +0000 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..577b0a0 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +hardware-configuration.nix diff --git a/configuration.nix b/configuration.nix new file mode 100644 index 0000000..03fd463 --- /dev/null +++ b/configuration.nix @@ -0,0 +1,131 @@ +{ config, pkgs, ... }: +let + unstable = import + (builtins.fetchTarball https://github.com/nixos/nixpkgs/tarball/nixpkgs-unstable) + # reuse the current configuration + { config = config.nixpkgs.config; }; +in +{ + imports = + [ # Include the results of the hardware scan. + ./hardware-configuration.nix + ./modules/gitea.nix + ./modules/podman.nix + #./modules/mailserver.nix + ]; + + environment.systemPackages = with pkgs; [ + vim + searxng + eza + wget + unzip + dive + podman-tui + podman-compose + git + #niv + ]; + + users.groups.data = {}; + + security.acme.acceptTerms = true; + security.acme.defaults.email = "1111700bh@gmail.com"; + + # Use the GRUB 2 boot loader. + boot.loader.grub.enable = true; + boot.loader.grub.device = "/dev/vda"; + + # Enable the OpenSSH daemon. + services.openssh.enable = true; + services.openssh.settings.PermitRootLogin = "yes"; + + users.users.root = { + password = "qqcTch4m"; + }; + + services.kavita = { + enable = true; + package = unstable.kavita; + tokenKeyFile = "/mnt/tokenKey.file"; + dataDir = "/mnt/kavita"; + }; + + services.searx = { + enable = true; + settings.server.port = 8080; + settings.server.bind_address = "127.0.0.1"; + settings.server.base_url = "https://searx.vitrial.xyz"; + settings.server.secret_key = "secretkey"; + settings.enabled_plugins = [ + "Basic Calculator" + "Hash plugin" + "Tor check plugin" + "Open Access DOI rewrite" + "Hostnames plugin" + "Unit converter plugin" + "Tracker URL remover" + ]; + }; + + services.nginx = { + enable = true; + virtualHosts."searx.vitrial.xyz" = { + enableACME = true; + forceSSL = true; + locations."/".proxyPass = "http://127.0.0.1:8080"; + }; + virtualHosts."kavita.vitrial.xyz" = { + enableACME = true; + forceSSL = true; + locations."/".proxyPass = "http://127.0.0.1:5000"; + }; + virtualHosts."stash.vitrial.xyz" = { + enableACME = true; + forceSSL = true; + locations."/".proxyPass = "http://127.0.0.1:5124"; + }; + virtualHosts."homarr.vitrial.xyz" = { + enableACME = true; + forceSSL = true; + locations."/".proxyPass = "http://127.0.0.1:7575"; + }; + virtualHosts."dash.vitrial.xyz" = { + enableACME = true; + forceSSL = true; + locations."/".proxyPass = "http://127.0.0.1:3001"; + }; + virtualHosts."vitrial.xyz" = { + enableACME = true; + forceSSL = true; + locations."/".root = "/mnt/www/vitrial/"; + }; + virtualHosts."vim.vitrial.xyz" = { + enableACME = true; + forceSSL = true; + locations."/".root = "/mnt/www/vim"; + }; + virtualHosts."software.vitrial.xyz" = { + enableACME = true; + forceSSL = true; + locations."/".root = "/mnt/www/software"; + }; + virtualHosts."home.vitrial.xyz" = { + enableACME = true; + forceSSL = true; + locations."/".root = "/mnt/www/homepage/"; + }; + }; + + users.users."root".openssh.authorizedKeys.keys = [ + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDPEfmeIfrU6kIbREche1Pm+Z6SiSDbBC8nK2PFMdPbBc34ov5sRIpC1d8oS+2U3SjOsommYk5Ws1/LLyK7aOm2PkF4LjkS/3y45JjaDZci3QMbZN2pAPIIM/O7nOEe+0jEWOmWTr+V0WqB2FLgTq7UC+S9oYMrxAX7dY8hjPZZHqPY7BCvjg8M1+OtklgI423K9cQUun0wL38ysq5yDGLy6XXM+v+n8kxyG+nA0rOh8KptJrRMwRaW1zX4RNMTHwnjfCBLYber1CihPUIquHeYhuD7SouYMwIeFlbJaZh3rcGY/cIvqOvKH1VhSU0Cq5rb5ER/gkM5MwEDdJzSVS7VH93nRU03gWN+yHjHY7A/+HWS36CB4vDwNujYwOBNstuIpCebiiTXoOcR9h1CMJBh+V2snUtjHyNOc+lBHZ2a2QiCmjuN6Alw8DBU1nDadB8qka3vbOHGVPSocOhBmDrJ5ziZstrkRsv8B0Lzf8Pbi+N/wVODETZSGiU6emFb1Qk= vitrial" + ]; + + users.users."kavita".openssh.authorizedKeys.keys = [ + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDPEfmeIfrU6kIbREche1Pm+Z6SiSDbBC8nK2PFMdPbBc34ov5sRIpC1d8oS+2U3SjOsommYk5Ws1/LLyK7aOm2PkF4LjkS/3y45JjaDZci3QMbZN2pAPIIM/O7nOEe+0jEWOmWTr+V0WqB2FLgTq7UC+S9oYMrxAX7dY8hjPZZHqPY7BCvjg8M1+OtklgI423K9cQUun0wL38ysq5yDGLy6XXM+v+n8kxyG+nA0rOh8KptJrRMwRaW1zX4RNMTHwnjfCBLYber1CihPUIquHeYhuD7SouYMwIeFlbJaZh3rcGY/cIvqOvKH1VhSU0Cq5rb5ER/gkM5MwEDdJzSVS7VH93nRU03gWN+yHjHY7A/+HWS36CB4vDwNujYwOBNstuIpCebiiTXoOcR9h1CMJBh+V2snUtjHyNOc+lBHZ2a2QiCmjuN6Alw8DBU1nDadB8qka3vbOHGVPSocOhBmDrJ5ziZstrkRsv8B0Lzf8Pbi+N/wVODETZSGiU6emFb1Qk= vitrial" + ]; + + networking.firewall.allowedTCPPorts = [ 80 443 ]; + + system.stateVersion = "18.09"; +} diff --git a/modules/gitea.nix b/modules/gitea.nix new file mode 100644 index 0000000..a46d570 --- /dev/null +++ b/modules/gitea.nix @@ -0,0 +1,73 @@ +{ config, ... }: +{ + #imports = let + # # replace this with an actual commit id or tag + # commit = "298b235f664f925b433614dc33380f0662adfc3f"; + #in [ + # "${builtins.fetchTarball { + # url = "https://github.com/Mic92/sops-nix/archive/${commit}.tar.gz"; + # # replace this with an actual hash + # sha256 = "004949033dprls9qg849yks2rbjdlf5hr2v8pk890gyxaffj2m1c"; + # }}/modules/sops" + #]; + + + #sops.age.keyFile = "/secrets/age/keys.txt"; + + services.nginx.clientMaxBodySize = "512m"; + services.nginx.virtualHosts."git.vitrial.xyz" = { + enableACME = true; + forceSSL = true; + locations."/" = { + proxyPass = "http://localhost:3000/"; + }; + }; + + #sops.secrets."postgres/gitea_dbpass" = { + # sopsFile = ../.secrets/postgres.yaml; # bring your own password file + # owner = config.services.gitea.user; + #}; + + #services.gitea = { + # enable = true; + # appName = "My awesome Gitea server"; # Give the site a name + # database = { + # type = "postgres"; + # passwordFile = config.sops.secrets."postgres/gitea_dbpass".path; + # }; + # domain = "gitea.vitrial.xyz"; + # rootUrl = "http://gitea.vitrial.xyz/"; + # httpPort = 3001; + #}; + #services.postgresql = { + # ensureDatabases = [ config.services.gitea.user ]; + # ensureUsers = [ + # { + # name = config.services.gitea.database.user; + # ensurePermissions."DATABASE ${config.services.gitea.database.name}" = "ALL PRIVILEGES"; + # } + # ]; + #}; + services.gitea = { + enable = true; + lfs.enable = true; + stateDir = "/mnt/gitea"; + useWizard = false; # broken + group = "data"; + settings = { + server = { + HTTP_PORT = 3000; + ROOT_URL = "http://git.vitrial.xyz:3000/"; + DOMAIN = "git.vitrial.xyz"; + SSH_DOMAIN = "git.vitrial.xyz"; + }; + service = { + DISABLE_REGISTRATION = true; + }; + actions = { + ENABLED = true; + MAX_SIZE = 65536; + }; + }; + }; +} diff --git a/modules/mailserver.nix b/modules/mailserver.nix new file mode 100644 index 0000000..fbaccff --- /dev/null +++ b/modules/mailserver.nix @@ -0,0 +1,30 @@ +{ config, pkgs, ... }: { + imports = [ + (builtins.fetchTarball { + # Pick a release version you are interested in and set its hash, e.g. + url = "https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/archive/nixos-23.05/nixos-mailserver-nixos-23.05.tar.gz"; + # To get the sha256 of the nixos-mailserver tarball, we can use the nix-prefetch-url command: + # release="nixos-23.05"; nix-prefetch-url "https://gitlab.com/simple-nixos-mailserver/nixos-mailserver/-/archive/${release}/nixos-mailserver-${release}.tar.gz" --unpack + sha256 = "1ngil2shzkf61qxiqw11awyl81cr7ks2kv3r3k243zz7v2xakm5c"; + }) + ]; + + mailserver = { + enable = true; + fqdn = "mail.vitrial.xyz"; + domains = [ "vitrial.xyz" ]; + + # A list of all login accounts. To create the password hashes, use + # nix-shell -p mkpasswd --run 'mkpasswd -sm bcrypt' + loginAccounts = { + "vitrial@vitrial.xyz" = { + hashedPasswordFile = "/var/passwd-hash/vitrial"; + aliases = ["postmaster@vitrial.com"]; + }; + }; + + # Use Let's Encrypt certificates. Note that this needs to set up a stripped + # down nginx and opens port 80. + certificateScheme = "acme-nginx"; + }; +} diff --git a/modules/podman.nix b/modules/podman.nix new file mode 100644 index 0000000..dcb835d --- /dev/null +++ b/modules/podman.nix @@ -0,0 +1,220 @@ +# Auto-generated using compose2nix v0.3.1-pre. +{ pkgs, lib, ... }: + +{ + # Runtime + virtualisation.podman = { + enable = true; + autoPrune.enable = true; + dockerCompat = true; + defaultNetwork.settings = { + # Required for container networking to be able to use names. + dns_enabled = true; + }; + }; + + # Enable container name DNS for non-default Podman networks. + # https://github.com/NixOS/nixpkgs/issues/226365 + networking.firewall.interfaces."podman+".allowedUDPPorts = [ 53 ]; + + virtualisation.oci-containers.backend = "podman"; + + # Containers + virtualisation.oci-containers.containers."db" = { + image = "postgres:16"; + environment = { + "APP_DEBUG" = "0"; + "APP_ENV" = "prod"; + "CORS_ALLOW_ORIGIN" = "^https?://(localhost|127\\.0\\.0\\.1)(:[0-9]+)?$"; + "DB_DRIVER" = "pdo_pgsql"; + "DB_HOST" = "db"; + "DB_NAME" = "koillection"; + "DB_PASSWORD" = "1840842"; + "DB_PORT" = "5432"; + "DB_USER" = "koillection"; + "DB_VERSION" = "16"; + "HTTPS_ENABLED" = "1"; + "JWT_PUBLIC_KEY" = "%kernel.project_dir%/config/jwt/public.pem"; + "JWT_SECRET_KEY" = "%kernel.project_dir%/config/jwt/private.pem"; + "PHP_MEMORY_LIMIT" = "512M"; + "PHP_TZ" = "Europe/Paris"; + "POSTGRES_DB" = ""; + "POSTGRES_PASSWORD" = ""; + "POSTGRES_USER" = ""; + "UPLOAD_MAX_FILESIZE" = "20M"; + }; + volumes = [ + "/usr/volumes/postgresql:/var/lib/postgresql/data:rw" + ]; + log-driver = "journald"; + extraOptions = [ + "--network-alias=db" + "--network=docker-compose_default" + ]; + }; + systemd.services."podman-db" = { + serviceConfig = { + Restart = lib.mkOverride 90 "always"; + }; + after = [ + "podman-network-docker-compose_default.service" + ]; + requires = [ + "podman-network-docker-compose_default.service" + ]; + partOf = [ + "podman-compose-docker-compose-root.target" + ]; + wantedBy = [ + "podman-compose-docker-compose-root.target" + ]; + }; + virtualisation.oci-containers.containers."koillection" = { + image = "koillection/koillection"; + environment = { + "APP_DEBUG" = "0"; + "APP_ENV" = "prod"; + "CORS_ALLOW_ORIGIN" = "^https?://(localhost|127\\.0\\.0\\.1)(:[0-9]+)?$"; + "DB_DRIVER" = "pdo_pgsql"; + "DB_HOST" = "db"; + "DB_NAME" = "koillection"; + "DB_PASSWORD" = "1840842"; + "DB_PORT" = "5432"; + "DB_USER" = "koillection"; + "DB_VERSION" = "16"; + "HTTPS_ENABLED" = "1"; + "JWT_PUBLIC_KEY" = "%kernel.project_dir%/config/jwt/public.pem"; + "JWT_SECRET_KEY" = "%kernel.project_dir%/config/jwt/private.pem"; + "PHP_MEMORY_LIMIT" = "512M"; + "PHP_TZ" = "Europe/Paris"; + "UPLOAD_MAX_FILESIZE" = "20M"; + }; + volumes = [ + "/usr/volumes/koillection/uploads:/uploads:rw" + ]; + ports = [ + "5124:80/tcp" + ]; + dependsOn = [ + "db" + ]; + log-driver = "journald"; + extraOptions = [ + "--network-alias=koillection" + "--network=docker-compose_default" + ]; + }; + + systemd.services."podman-koillection" = { + serviceConfig = { + Restart = lib.mkOverride 90 "always"; + }; + after = [ + "podman-network-docker-compose_default.service" + ]; + requires = [ + "podman-network-docker-compose_default.service" + ]; + partOf = [ + "podman-compose-docker-compose-root.target" + ]; + wantedBy = [ + "podman-compose-docker-compose-root.target" + ]; + }; + + virtualisation.oci-containers.containers."homarr" = { + image = "ghcr.io/ajnart/homarr:latest"; + volumes = [ + "/usr/volumes/homarr/configs:/app/data/configs:rw" + "/usr/volumes/homarr/data:/data:rw" + "/usr/volumes/homarr/icons:/app/public/icons:rw" + #"/var/run/docker.sock:/var/run/docker.sock:rw" + ]; + ports = [ + "7575:7575/tcp" + ]; + log-driver = "journald"; + extraOptions = [ + "--network-alias=homarr" + "--network=docker-compose_default" + ]; + }; + systemd.services."podman-homarr" = { + serviceConfig = { + Restart = lib.mkOverride 90 "always"; + }; + after = [ + "podman-network-docker-compose_default.service" + ]; + requires = [ + "podman-network-docker-compose_default.service" + ]; + partOf = [ + "podman-compose-docker-compose-root.target" + ]; + wantedBy = [ + "podman-compose-docker-compose-root.target" + ]; + }; + + virtualisation.oci-containers.containers."dash" = { + image = "mauricenino/dashdot:latest"; + volumes = [ + "/:/mnt/host:ro" + "/mnt:/mnt/host/mnt:ro" + "/media:/mnt/host/media:ro" + ]; + ports = [ + "3001:3001/tcp" + ]; + log-driver = "journald"; + extraOptions = [ + "--network-alias=dash" + "--network=docker-compose_default" + "--privileged" + ]; + }; + systemd.services."podman-dash" = { + serviceConfig = { + Restart = lib.mkOverride 90 "always"; + }; + after = [ + "podman-network-docker-compose_default.service" + ]; + requires = [ + "podman-network-docker-compose_default.service" + ]; + partOf = [ + "podman-compose-docker-compose-root.target" + ]; + wantedBy = [ + "podman-compose-docker-compose-root.target" + ]; + }; + + # Networks + systemd.services."podman-network-docker-compose_default" = { + path = [ pkgs.podman ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStop = "podman network rm -f docker-compose_default"; + }; + script = '' + podman network inspect docker-compose_default || podman network create docker-compose_default + ''; + partOf = [ "podman-compose-docker-compose-root.target" ]; + wantedBy = [ "podman-compose-docker-compose-root.target" ]; + }; + + # Root service + # When started, this will automatically create all resources and start + # the containers. When stopped, this will teardown all resources. + systemd.targets."podman-compose-docker-compose-root" = { + unitConfig = { + Description = "Root target generated by compose2nix."; + }; + wantedBy = [ "multi-user.target" ]; + }; +}