commit b79d352847d1eb852f92ff2792459bbf1f3631c0 Author: Artyom Belousov Date: Tue Jan 13 15:34:28 2026 +0300 Initial commit diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..6cead53 --- /dev/null +++ b/LICENSE @@ -0,0 +1,15 @@ +BSD Zero Clause License + +Copyright (c) 2026 Artyom Belousov + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..d83e04b --- /dev/null +++ b/flake.lock @@ -0,0 +1,303 @@ +{ + "nodes": { + "agenix": { + "inputs": { + "darwin": "darwin", + "home-manager": "home-manager", + "nixpkgs": [ + "nixpkgs" + ], + "systems": "systems" + }, + "locked": { + "lastModified": 1770165109, + "narHash": "sha256-9VnK6Oqai65puVJ4WYtCTvlJeXxMzAp/69HhQuTdl/I=", + "owner": "ryantm", + "repo": "agenix", + "rev": "b027ee29d959fda4b60b57566d64c98a202e0feb", + "type": "github" + }, + "original": { + "owner": "ryantm", + "repo": "agenix", + "type": "github" + } + }, + "catppuccin": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1771587924, + "narHash": "sha256-eVYOGmF8nQBhudJyU6lHdgJI87kvGz8JyCq5/Vi9Mjk=", + "owner": "catppuccin", + "repo": "nix", + "rev": "b0c65edbf31c2ad3d84438d82c2310f2c28373f3", + "type": "github" + }, + "original": { + "owner": "catppuccin", + "repo": "nix", + "type": "github" + } + }, + "darwin": { + "inputs": { + "nixpkgs": [ + "agenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1744478979, + "narHash": "sha256-dyN+teG9G82G+m+PX/aSAagkC+vUv0SgUw3XkPhQodQ=", + "owner": "lnl7", + "repo": "nix-darwin", + "rev": "43975d782b418ebf4969e9ccba82466728c2851b", + "type": "github" + }, + "original": { + "owner": "lnl7", + "ref": "master", + "repo": "nix-darwin", + "type": "github" + } + }, + "deploy-rs": { + "inputs": { + "flake-compat": "flake-compat", + "nixpkgs": [ + "nixpkgs" + ], + "utils": "utils" + }, + "locked": { + "lastModified": 1770019181, + "narHash": "sha256-hwsYgDnby50JNVpTRYlF3UR/Rrpt01OrxVuryF40CFY=", + "owner": "serokell", + "repo": "deploy-rs", + "rev": "77c906c0ba56aabdbc72041bf9111b565cdd6171", + "type": "github" + }, + "original": { + "owner": "serokell", + "repo": "deploy-rs", + "type": "github" + } + }, + "disko": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1771469470, + "narHash": "sha256-GnqdqhrguKNN3HtVfl6z+zbV9R9jhHFm3Z8nu7R6ml0=", + "owner": "nix-community", + "repo": "disko", + "rev": "4707eec8d1d2db5182ea06ed48c820a86a42dc13", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "disko", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1733328505, + "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "nixvim", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1769996383, + "narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "57928607ea566b5db3ad13af0e57e921e6b12381", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "agenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1745494811, + "narHash": "sha256-YZCh2o9Ua1n9uCvrvi5pRxtuVNml8X2a03qIFfRKpFs=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "abfad3d2958c9e6300a883bd443512c55dfeb1be", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "home-manager_2": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1771531206, + "narHash": "sha256-1R3Wx6KUkMb4x4E5UOhW9p6rqiexzSGGWxZqSHqW5n0=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "91be7cce763fa4022c7cf025a71b0c366d1b6e77", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1771369470, + "narHash": "sha256-0NBlEBKkN3lufyvFegY4TYv5mCNHbi5OmBDrzihbBMQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "0182a361324364ae3f436a63005877674cf45efb", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixvim": { + "inputs": { + "flake-parts": "flake-parts", + "nixpkgs": [ + "nixpkgs" + ], + "systems": "systems_3" + }, + "locked": { + "lastModified": 1771135771, + "narHash": "sha256-wyvBIhDuyCRyjB3yPg77qoyxrlgQtBR1rVW3c9knV3E=", + "owner": "nix-community", + "repo": "nixvim", + "rev": "ed0424f0b08d303a7348f52f7850ad1b2704f9ba", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixvim", + "type": "github" + } + }, + "root": { + "inputs": { + "agenix": "agenix", + "catppuccin": "catppuccin", + "deploy-rs": "deploy-rs", + "disko": "disko", + "home-manager": "home-manager_2", + "nixpkgs": "nixpkgs", + "nixvim": "nixvim" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_3": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "utils": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..4b3e903 --- /dev/null +++ b/flake.nix @@ -0,0 +1,97 @@ +{ + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + home-manager = { + url = "github:nix-community/home-manager"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + catppuccin = { + url = "github:catppuccin/nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + disko = { + url = "github:nix-community/disko"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + deploy-rs = { + url = "github:serokell/deploy-rs"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + nixvim = { + url = "github:nix-community/nixvim"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + agenix = { + url = "github:ryantm/agenix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + outputs = + { + self, + nixpkgs, + home-manager, + catppuccin, + disko, + deploy-rs, + nixvim, + agenix, + ... + }: + { + homeConfigurations."flygrounder@work" = home-manager.lib.homeManagerConfiguration { + pkgs = import nixpkgs { system = "x86_64-linux"; }; + modules = [ + ./home + catppuccin.homeModules.catppuccin + nixvim.homeModules.nixvim + ( + { ... }: + { + catppuccin.enable = true; + programs.ssh.enable = nixpkgs.lib.mkForce false; + custom = { + cli.enable = true; + neovim.enable = true; + }; + } + ) + ]; + }; + nixosConfigurations = + let + mkConfig = + hostName: + nixpkgs.lib.nixosSystem { + modules = [ + disko.nixosModules.disko + catppuccin.nixosModules.catppuccin + agenix.nixosModules.default + ./nixos + ./hosts/${hostName}/configuration.nix + home-manager.nixosModules.home-manager + + { + home-manager.users.flygrounder.imports = [ + ./home + catppuccin.homeModules.catppuccin + nixvim.homeModules.nixvim + ]; + networking.hostName = hostName; + } + ]; + }; + configurations = builtins.mapAttrs (hostName: _: mkConfig hostName) (builtins.readDir ./hosts); + in + configurations; + deploy.nodes.server = { + hostname = "62.109.27.62"; + profiles.system = { + user = "root"; + path = deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.server; + }; + }; + + checks = builtins.mapAttrs (system: deployLib: deployLib.deployChecks self.deploy) deploy-rs.lib; + }; +} diff --git a/home/catppuccin/default.nix b/home/catppuccin/default.nix new file mode 100644 index 0000000..c13870a --- /dev/null +++ b/home/catppuccin/default.nix @@ -0,0 +1,79 @@ +{ + lib, + config, + ... +}: +{ + options = { + custom.catppuccin.enable = lib.mkEnableOption "Enable catppuccin theme"; + }; + config = lib.mkIf config.custom.catppuccin.enable { + gtk = { + enable = true; + colorScheme = "dark"; + }; + programs.hyprlock = { + enable = true; + settings = { + background = { + color = "$base"; + }; + + label = { + color = "$text"; + }; + + image = { + border_color = "$accent"; + }; + + input-field = { + outer_color = "$accent"; + inner_color = "$surface0"; + font_color = "$text"; + check_color = "$accent"; + fail_color = "$red"; + capslock_color = "$yellow"; + }; + }; + }; + catppuccin = { + enable = true; + hyprlock.useDefaultConfig = false; + cursors.enable = true; + }; + wayland.windowManager.hyprland.settings.general = { + "col.inactive_border" = "$surface2"; + "col.active_border" = "$accent"; + }; + xdg = { + dataFile = { + wallpaper = { + source = ./wallpaper.jpg; + target = "images/wallpaper.jpg"; + }; + }; + configFile = { + hyprtoolkit = { + source = ./hyprtoolkit.conf; + target = "hypr/hyprtoolkit.conf"; + }; + mocha = { + source = ./mocha.conf; + target = "hypr/mocha.conf"; + }; + waybarColorscheme = { + source = ./waybar.css; + }; + }; + }; + services.hyprpaper = { + settings = { + wallpaper = { + monitor = ""; + path = "$HOME/.local/share/images/wallpaper.jpg"; + }; + }; + }; + }; +} diff --git a/home/catppuccin/hyprtoolkit.conf b/home/catppuccin/hyprtoolkit.conf new file mode 100644 index 0000000..ae5cb1d --- /dev/null +++ b/home/catppuccin/hyprtoolkit.conf @@ -0,0 +1,6 @@ +source=~/.config/hypr/mocha.conf + +base = $overlay0 +background = $surface0 +text = $text +accent = $mauve diff --git a/home/catppuccin/mocha.conf b/home/catppuccin/mocha.conf new file mode 100644 index 0000000..8ccb56a --- /dev/null +++ b/home/catppuccin/mocha.conf @@ -0,0 +1,78 @@ + +$rosewater = rgb(f5e0dc) +$rosewaterAlpha = f5e0dc + +$flamingo = rgb(f2cdcd) +$flamingoAlpha = f2cdcd + +$pink = rgb(f5c2e7) +$pinkAlpha = f5c2e7 + +$mauve = rgb(cba6f7) +$mauveAlpha = cba6f7 + +$red = rgb(f38ba8) +$redAlpha = f38ba8 + +$maroon = rgb(eba0ac) +$maroonAlpha = eba0ac + +$peach = rgb(fab387) +$peachAlpha = fab387 + +$yellow = rgb(f9e2af) +$yellowAlpha = f9e2af + +$green = rgb(a6e3a1) +$greenAlpha = a6e3a1 + +$teal = rgb(94e2d5) +$tealAlpha = 94e2d5 + +$sky = rgb(89dceb) +$skyAlpha = 89dceb + +$sapphire = rgb(74c7ec) +$sapphireAlpha = 74c7ec + +$blue = rgb(89b4fa) +$blueAlpha = 89b4fa + +$lavender = rgb(b4befe) +$lavenderAlpha = b4befe + +$text = rgb(cdd6f4) +$textAlpha = cdd6f4 + +$subtext1 = rgb(bac2de) +$subtext1Alpha = bac2de + +$subtext0 = rgb(a6adc8) +$subtext0Alpha = a6adc8 + +$overlay2 = rgb(9399b2) +$overlay2Alpha = 9399b2 + +$overlay1 = rgb(7f849c) +$overlay1Alpha = 7f849c + +$overlay0 = rgb(6c7086) +$overlay0Alpha = 6c7086 + +$surface2 = rgb(585b70) +$surface2Alpha = 585b70 + +$surface1 = rgb(45475a) +$surface1Alpha = 45475a + +$surface0 = rgb(313244) +$surface0Alpha = 313244 + +$base = rgb(1e1e2e) +$baseAlpha = 1e1e2e + +$mantle = rgb(181825) +$mantleAlpha = 181825 + +$crust = rgb(11111b) +$crustAlpha = 11111b diff --git a/home/catppuccin/wallpaper.jpg b/home/catppuccin/wallpaper.jpg new file mode 100644 index 0000000..9555421 Binary files /dev/null and b/home/catppuccin/wallpaper.jpg differ diff --git a/home/catppuccin/waybar.css b/home/catppuccin/waybar.css new file mode 100644 index 0000000..dd6d97c --- /dev/null +++ b/home/catppuccin/waybar.css @@ -0,0 +1,17 @@ +@import "catppuccin.css"; + +* { + color: @text; +} + +window#waybar { + background-color: @base; +} + +#workspaces button.active { + background-color: @surface0; +} + +#workspaces button.active:hover { + background-color: @surface0; +} diff --git a/home/cli/default.nix b/home/cli/default.nix new file mode 100644 index 0000000..afbb75e --- /dev/null +++ b/home/cli/default.nix @@ -0,0 +1,116 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + options = { + custom.cli.enable = lib.mkEnableOption "Enable CLI config"; + }; + config = lib.mkIf config.custom.cli.enable { + programs.ssh = { + enable = true; + enableDefaultConfig = false; + matchBlocks."*" = { + setEnv = { + TERM = "xterm-256color"; + }; + }; + }; + home.packages = with pkgs; [ + bottom + clang + deploy-rs + devbox + dig + dust + fastfetch + imagemagick + nh + termusic + ]; + home = { + shell.enableFishIntegration = true; + }; + xdg.configFile = { + termusicServerConfig = { + source = ./termusic/server.toml; + target = "termusic/server.toml"; + }; + termusicTuiConfig = { + source = ./termusic/tui.toml; + target = "termusic/tui.toml"; + }; + }; + programs = { + opencode = { + enable = true; + settings = { + provider = { + ai-tunnel = { + options = { + baseURL = "https://api.aitunnel.ru/v1/"; + }; + models = { + "glm-5" = { + name = "glm-5"; + }; + "glm-4.7-flash" = { + name = "glm-4.7-flash"; + }; + }; + }; + }; + }; + }; + bat.enable = true; + eza.enable = true; + fd = { + enable = true; + hidden = true; + extraOptions = [ + "--hidden" + "-g" + "!*.git/" + ]; + }; + yazi = { + enable = true; + shellWrapperName = "y"; + }; + ripgrep = { + enable = true; + arguments = [ + "--hidden" + "-g" + "!*.git/" + ]; + }; + lazygit.enable = true; + direnv.enable = true; + home-manager.enable = true; + delta = { + enable = true; + enableGitIntegration = true; + }; + fish = { + enable = true; + interactiveShellInit = '' + set fish_greeting + ''; + }; + zoxide.enable = true; + starship.enable = true; + git = { + enable = true; + settings = { + user = { + email = "flygrounder@flygrounder.ru"; + name = "Артём Белоусов"; + }; + }; + }; + }; + }; +} diff --git a/home/cli/termusic/server.toml b/home/cli/termusic/server.toml new file mode 100644 index 0000000..7fd7901 --- /dev/null +++ b/home/cli/termusic/server.toml @@ -0,0 +1,45 @@ +version = "2" + +[com] +protocol = "uds" +socket_path = "/tmp/termusic.socket" +port = 50101 +address = "::1" + +[player] +music_dirs = ["/home/flygrounder/Музыка"] +loop_mode = "playlist" +volume = 30 +speed = 10 +gapless = true +use_mediacontrols = true +set_discord_status = false +random_track_quantity = 20 +random_album_min_quantity = 5 +backend = "rusty" + +[player.remember_position] +music = "no" +podcast = "yes" + +[player.seek_step] +short_tracks = 5 +long_tracks = 30 + +[podcast] +concurrent_downloads_max = 3 +max_download_retries = 3 +download_dir = "/home/flygrounder/Музыка" + +[backends.rusty] +soundtouch = true +file_buffer_size = "4.0 MiB" +decoded_buffer_size = "750.0 KiB" +output_sample_rate = 48000 + +[backends.mpv] +audio_device = "auto" + +[metadata] +directory_scan_depth = 10 +artist_separators = [",", ";", "&", "ft.", "feat.", "/", "|", "×", "、", " x "] diff --git a/home/cli/termusic/tui.toml b/home/cli/termusic/tui.toml new file mode 100644 index 0000000..a0ca2a3 --- /dev/null +++ b/home/cli/termusic/tui.toml @@ -0,0 +1,173 @@ +version = "2" +com = "same" + +[behavior] +quit_server_on_exit = false +confirm_quit = false + +[coverart] +align = "bottom right" +size_scale = 0 +hidden = false +protocols = ["kitty", "sixel", "ueberzug", "iterm2"] + +[style.library] +foreground_color = "Foreground" +background_color = "Reset" +border_color = "Blue" +highlight_color = "LightYellow" +highlight_symbol = "🦄" + +[style.playlist] +foreground_color = "Foreground" +background_color = "Reset" +border_color = "Blue" +highlight_color = "LightYellow" +highlight_symbol = "🚀" +current_track_symbol = "►" +use_loop_mode_symbol = true + +[style.lyric] +foreground_color = "Foreground" +background_color = "Reset" +border_color = "Blue" + +[style.progress] +foreground_color = "LightBlack" +background_color = "Reset" +border_color = "Blue" + +[style.important_popup] +foreground_color = "Yellow" +background_color = "Reset" +border_color = "Yellow" + +[style.fallback] +foreground_color = "Foreground" +background_color = "Reset" +border_color = "Blue" +highlight_color = "LightYellow" + +[theme] +name = "empty name" +author = "empty author" + +[theme.primary] +background = "#101421" +foreground = "#fffbf6" + +[theme.cursor] +text = "#1e1e1e" +cursor = "#ffffff" + +[theme.normal] +black = "#2e2e2e" +red = "#eb4129" +green = "#abe047" +yellow = "#f6c744" +blue = "#47a0f3" +magenta = "#7b5cb0" +cyan = "#64dbed" +white = "#e5e9f0" + +[theme.bright] +black = "#565656" +red = "#ec5357" +green = "#c0e17d" +yellow = "#f9da6a" +blue = "#49a4f8" +magenta = "#a47de9" +cyan = "#99faf2" +white = "#ffffff" + +[keys] +escape = "escape" +quit = "q" + +[keys.view] +view_library = "1" +view_database = "2" +view_podcasts = "3" +open_config = "shift+C" +open_help = "control+h" + +[keys.navigation] +up = "k" +down = "j" +left = "h" +right = "l" +goto_top = "g" +goto_bottom = "shift+G" + +[keys.global_player] +toggle_pause = "space" +next_track = "n" +previous_track = "shift+N" +volume_up = "+" +volume_down = "-" +seek_forward = "f" +seek_backward = "b" +speed_up = "control+f" +speed_down = "control+b" +toggle_prefetch = "control+g" +save_playlist = "control+s" + +[keys.global_lyric] +adjust_offset_forwards = "shift+F" +adjust_offset_backwards = "shift+B" +cycle_frames = "shift+T" + +[keys.library] +load_track = "l" +load_dir = "shift+L" +delete = "d" +yank = "y" +paste = "p" +cycle_root = "o" +add_root = "a" +remove_root = "shift+A" +search = "/" +youtube_search = "s" +open_tag_editor = "t" + +[keys.playlist] +delete = "d" +delete_all = "shift+D" +shuffle = "r" +cycle_loop_mode = "m" +play_selected = "l" +search = "/" +swap_up = "shift+K" +swap_down = "shift+J" +add_random_songs = "s" +add_random_album = "shift+S" + +[keys.database] +add_selected = "l" +add_all = "shift+L" + +[keys.podcast] +search = "s" +mark_played = "m" +mark_all_played = "shift+M" +refresh_feed = "r" +refresh_all_feeds = "shift+R" +download_episode = "d" +delete_local_episode = "shift+D" +delete_feed = "x" +delete_all_feeds = "shift+X" + +[keys.adjust_cover_art] +move_left = "control+shift+arrowleft" +move_right = "control+shift+arrowright" +move_up = "control+shift+arrowup" +move_down = "control+shift+arrowdown" +increase_size = "control+shift+pageup" +decrease_size = "control+shift+pagedown" +toggle_hide = "control+shift+end" + +[keys.config] +save = "control+s" + +[ytdlp] +extra_args = "" diff --git a/home/default.nix b/home/default.nix new file mode 100644 index 0000000..abfbe41 --- /dev/null +++ b/home/default.nix @@ -0,0 +1,19 @@ +{ ... }: +{ + imports = [ + ./catppuccin + ./cli + ./hyprland + ./low-battery-notify + ./waybar + ./gui.nix + ./neovim.nix + ]; + + home = { + username = "flygrounder"; + homeDirectory = "/home/flygrounder"; + stateVersion = "25.11"; + }; + programs.home-manager.enable = true; +} diff --git a/home/gui.nix b/home/gui.nix new file mode 100644 index 0000000..3fbff85 --- /dev/null +++ b/home/gui.nix @@ -0,0 +1,26 @@ +{ + pkgs, + config, + lib, + ... +}: +{ + options = { + custom.gui.enable = lib.mkEnableOption "Enable GUI apps"; + }; + config = lib.mkIf config.custom.gui.enable { + home.packages = with pkgs; [ + brave + feather + fluffychat + libreoffice + obsidian + pavucontrol + qbittorrent + telegram-desktop + thunderbird + trezor-suite + vesktop + ]; + }; +} diff --git a/home/hyprland/avatar.png b/home/hyprland/avatar.png new file mode 100644 index 0000000..3dd3035 Binary files /dev/null and b/home/hyprland/avatar.png differ diff --git a/home/hyprland/default.nix b/home/hyprland/default.nix new file mode 100644 index 0000000..ed65029 --- /dev/null +++ b/home/hyprland/default.nix @@ -0,0 +1,221 @@ +{ + lib, + pkgs, + config, + ... +}: +{ + options = { + custom.hyprland.enable = lib.mkEnableOption "Enable hyprland config"; + }; + config = lib.mkIf config.custom.hyprland.enable { + xdg.dataFile = { + avatar = { + source = ./avatar.png; + target = "images/avatar.png"; + }; + }; + programs = { + vicinae.enable = true; + ghostty = { + enable = true; + settings = { + font-family = "FiraCode Nerd Font"; + window-padding-x = 15; + window-padding-y = 10; + confirm-close-surface = false; + resize-overlay = "never"; + app-notifications = "no-clipboard-copy"; + }; + }; + hyprlock = { + enable = true; + settings = { + "$font" = "Roboto"; + + general = { + hide_cursor = true; + }; + + background = { + monitor = ""; + }; + + label = { + monitor = ""; + text = "$LAYOUT[EN,RU]"; + font_size = 18; + font_family = "$font"; + position = "0, -120"; + halign = "center"; + valign = "center"; + }; + + image = { + monitor = ""; + path = "$HOME/.local/share/images/avatar.png"; + size = 120; + rounding = 10; + border_size = 2; + position = "0, 100"; + halign = "center"; + valign = "center"; + }; + + input-field = { + monitor = ""; + size = "300, 60"; + outline_thickness = 2; + dots_size = 0.2; + dots_spacing = 0.2; + dots_center = true; + placeholder_text = "Введите пароль"; + fade_on_empty = false; + hide_input = false; + fail_text = "Неверный пароль"; + position = "0, -47"; + halign = "center"; + valign = "center"; + }; + }; + }; + }; + home.packages = with pkgs; [ + acpi + grim + jq + slurp + wl-clipboard + ]; + wayland.windowManager.hyprland = { + enable = true; + settings = { + general = { + layout = "master"; + border_size = 3; + gaps_in = 7; + gaps_out = 14; + }; + decoration.rounding = 10; + input = { + kb_layout = "us,ru"; + kb_options = "grp:alt_shift_toggle"; + touchpad.natural_scroll = true; + }; + "$mainMod" = "SUPER"; + bindm = [ + "$mainMod, mouse:272, movewindow" + "$mainMod, mouse:273, resizewindow" + ]; + bind = [ + "$mainMod SHIFT, Q, exit," + + "$mainMod, RETURN, exec, ghostty" + "$mainMod, D, exec, vicinae open" + + "$mainMod, Q, killactive," + "$mainMod, V, togglefloating," + "$mainMod, F, fullscreen" + + "$mainMod, K, layoutmsg, cycleprev" + "$mainMod, J, layoutmsg, cyclenext" + + "$mainMod SHIFT, K, layoutmsg, swapprev" + "$mainMod SHIFT, J, layoutmsg, swapnext" + + "$mainMod, L, exec, loginctl lock-session" + + "$mainMod, 1, workspace, 1" + "$mainMod, 2, workspace, 2" + "$mainMod, 3, workspace, 3" + "$mainMod, 4, workspace, 4" + "$mainMod, 5, workspace, 5" + "$mainMod, 6, workspace, 6" + "$mainMod, 7, workspace, 7" + "$mainMod, 8, workspace, 8" + "$mainMod, 9, workspace, 9" + "$mainMod, 0, workspace, 10" + + "$mainMod SHIFT, 1, movetoworkspace, 1" + "$mainMod SHIFT, 2, movetoworkspace, 2" + "$mainMod SHIFT, 3, movetoworkspace, 3" + "$mainMod SHIFT, 4, movetoworkspace, 4" + "$mainMod SHIFT, 5, movetoworkspace, 5" + "$mainMod SHIFT, 6, movetoworkspace, 6" + "$mainMod SHIFT, 7, movetoworkspace, 7" + "$mainMod SHIFT, 8, movetoworkspace, 8" + "$mainMod SHIFT, 9, movetoworkspace, 9" + "$mainMod SHIFT, 0, movetoworkspace, 10" + + ", Print, exec, mkdir -p ~/Изображения/Скриншоты && grim -o \"$(hyprctl activeworkspace -j | jq -r '.monitor')\" - | tee ~/Изображения/Скриншоты/`date +'%Y_%m_%d_%H_%M_%S_%3N.png'` | wl-copy && dunstify \"Снимок всего экрана сделан\"" + "SHIFT, Print, exec, mkdir -p ~/Изображения/Скриншоты && grim -g \"$(slurp -d)\" - | tee ~/Изображения/Скриншоты/`date +'%Y_%m_%d_%H_%M_%S_%3N.png'` | wl-copy && dunstify 'Снимок области сделан'" + + ", XF86AudioRaiseVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+" + ", XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-" + ", XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle" + + ", XF86MonBrightnessUp, exec, brightnessctl set +10%" + ", XF86MonBrightnessDown, exec, brightnessctl set 10%-" + ]; + gesture = [ + "3, horizontal, workspace" + ]; + exec-once = [ + "dunst" + "waybar" + "vicinae server" + ]; + }; + }; + services = { + hyprpaper = { + enable = true; + settings = { + splash = false; + }; + }; + network-manager-applet.enable = true; + blueman-applet.enable = true; + dunst = { + enable = true; + settings = { + global = { + font = "Roboto 12"; + corner_radius = 16; + }; + }; + }; + hypridle = { + enable = true; + settings = { + general = { + lock_cmd = "pidof hyprlock || hyprlock"; + before_sleep_cmd = "loginctl lock-session"; + after_sleep_cmd = "hyprctl dispatch dpms on"; + }; + + listener = [ + { + timeout = 150; + on-timeout = "brightnessctl -s set 10"; + on-resume = "brightnessctl -r"; + } + { + timeout = 300; + on-timeout = "loginctl lock-session"; + } + { + timeout = 330; + on-timeout = "hyprctl dispatch dpms off"; + on-resume = "hyprctl dispatch dpms on && brightnessctl -r"; + } + { + timeout = 1800; + on-timeout = "systemctl suspend"; + } + ]; + }; + }; + }; + }; +} diff --git a/home/low-battery-notify/default.nix b/home/low-battery-notify/default.nix new file mode 100644 index 0000000..20c010d --- /dev/null +++ b/home/low-battery-notify/default.nix @@ -0,0 +1,47 @@ +{ config, lib, pkgs, ... }: +{ + options = { + custom.low-battery-notify.enable = lib.mkEnableOption "Enable low battery notification"; + }; + config = lib.mkIf config.custom.low-battery-notify.enable { + home.packages = with pkgs; [ + python3 + ]; + systemd.user = { + services = { + low-battery-notify = { + Unit = { + Description = "Low battery notify"; + }; + + Service = { + Type = "oneshot"; + ExecStart = "/home/flygrounder/.local/share/scripts/low-battery-notify.py"; + }; + }; + }; + timers = { + low-battery-notify = { + Unit = { + Description = "test"; + }; + + Timer = { + OnUnitActiveSec = "10m"; + OnBootSec = "10m"; + }; + + Install = { + WantedBy = [ "timers.target" ]; + }; + }; + }; + }; + xdg.dataFile = { + low-battery-notify = { + source = ./script.py; + target = "scripts/low-battery-notify.py"; + }; + }; + }; +} diff --git a/home/low-battery-notify/script.py b/home/low-battery-notify/script.py new file mode 100755 index 0000000..c2d2e60 --- /dev/null +++ b/home/low-battery-notify/script.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python3 +import subprocess +import re + +output = subprocess.check_output(["acpi", "-b"]).decode() +m = re.match(r'.*Discharging, (\d+)%', output) +if m is None: + exit() +charge = int(m.group(1)) +if charge <= 20: + subprocess.run(["dunstify", "-u", "critical", f"Низкий уровень заряда: {charge}%"]) diff --git a/home/neovim.nix b/home/neovim.nix new file mode 100644 index 0000000..e87878b --- /dev/null +++ b/home/neovim.nix @@ -0,0 +1,141 @@ +{ lib, config, ... }: +{ + options = { + custom.neovim.enable = lib.mkEnableOption "My neovim config"; + }; + config = lib.mkIf config.custom.neovim.enable { + home = { + sessionVariables = { + EDITOR = "nvim"; + }; + }; + programs.nixvim = { + enable = true; + plugins = { + dropbar.enable = true; + lspconfig.enable = true; + guess-indent.enable = true; + oil.enable = true; + mini-statusline.enable = true; + mini-pairs.enable = true; + mini-pick.enable = true; + mini-diff.enable = true; + mini-indentscope.enable = true; + mini-surround.enable = true; + ts-autotag.enable = true; + blink-cmp = { + enable = true; + settings = { + signature = { + enabled = true; + }; + }; + }; + treesitter = { + enable = true; + highlight.enable = true; + indent.enable = true; + }; + harpoon.enable = true; + }; + keymaps = [ + { + action = "Oil"; + key = "o"; + } + { + action = "lua require('mini.pick').builtin.files()"; + key = "f"; + } + { + action = "lua require('mini.pick').builtin.grep_live()"; + key = "g"; + } + { + action = "lua require('mini.pick').builtin.help()"; + key = "h"; + } + { + action = "lua require('mini.pick').builtin.resume()"; + key = "r"; + } + { + action = "lua vim.lsp.buf.format()"; + key = "i"; + } + { + action = "lua vim.lsp.buf.code_action()"; + key = "a"; + } + { + action = "lua vim.diagnostic.goto_prev({ float = true })"; + key = "[d"; + } + { + action = "lua vim.diagnostic.goto_next({ float = true })"; + key = "]d"; + } + { + action = "lua vim.diagnostic.setqflist()"; + key = "d"; + } + { + action = "lua require('harpoon'):list():add()"; + key = "k"; + } + { + action = "lua require('harpoon'):list():select(1)"; + key = ""; + } + { + action = "lua require('harpoon'):list():select(2)"; + key = ""; + } + { + action = "lua require('harpoon'):list():select(3)"; + key = ""; + } + { + action = "lua require('harpoon'):list():select(4)"; + key = ""; + } + { + action = "lua require('harpoon').ui:toggle_quick_menu(require('harpoon'):list())"; + key = "j"; + } + { + action = "CopyRelativePath"; + key = "p"; + } + ]; + globals.mapleader = " "; + opts = { + number = true; + relativenumber = true; + ignorecase = true; + smartcase = true; + swapfile = false; + exrc = true; + }; + colorschemes.catppuccin.enable = true; + clipboard.register = "unnamedplus"; + userCommands = { + CopyRelativePath = { + command = "call setreg('+', expand('%'))"; + }; + }; + lsp.servers = { + basedpyright.enable = true; + gopls.enable = true; + nil_ls.enable = true; + rust_analyzer.enable = true; + html.enable = true; + jsonls.enable = true; + yamlls.enable = true; + cssls.enable = true; + tailwindcss.enable = true; + vtsls.enable = true; + }; + }; + }; +} diff --git a/home/waybar/default.nix b/home/waybar/default.nix new file mode 100644 index 0000000..0240fc3 --- /dev/null +++ b/home/waybar/default.nix @@ -0,0 +1,86 @@ +{ + pkgs, + lib, + config, + ... +}: +{ + options = { + custom.waybar.enable = lib.mkEnableOption "Enable waybar config"; + }; + config = lib.mkIf config.custom.waybar.enable { + xdg.configFile = { + waybarColorscheme = { + text = ""; + target = "waybar/colorscheme.css"; + }; + }; + catppuccin.waybar.mode = "createLink"; + programs.waybar = { + enable = true; + style = ./style.css; + settings = { + mainBar = { + margin-top = 14; + margin-left = 14; + margin-right = 14; + layer = "top"; + modules-left = [ + "custom/logo" + "hyprland/workspaces" + ]; + modules-center = [ "hyprland/window" ]; + modules-right = [ + "hyprland/language" + "wireplumber" + "backlight" + "battery" + "clock" + "tray" + ]; + clock = { + format = " {:%d.%m.%Y %H:%M}"; + }; + backlight = { + format = " {percent}%"; + }; + "hyprland/language" = { + format = " {}"; + format-en = "EN"; + format-ru = "RU"; + }; + wireplumber = { + format = "{icon} {volume}%"; + format-icons = [ + "" + "" + "" + ]; + format-muted = " {volume}%"; + }; + "custom/logo" = { + format = ""; + }; + tray = { + spacing = 10; + }; + "hyprland/window" = { + max-length = 50; + }; + battery = { + format = "{icon} {capacity}% {time}"; + format-icons = [ + "" + "" + "" + "" + "" + ]; + format-time = "{H}:{m}"; + format-charging = "󱐋 {capacity}% {time}"; + }; + }; + }; + }; + }; +} diff --git a/home/waybar/style.css b/home/waybar/style.css new file mode 100644 index 0000000..35ff3e2 --- /dev/null +++ b/home/waybar/style.css @@ -0,0 +1,44 @@ +@import "colorscheme.css"; + +* { + font-size: 18px; + font-family: + Roboto, "Font Awesome 7 Free Solid", "Font Awesome 6 Free Solid"; +} + +#custom-logo { + font-size: 20px; + font-family: "FiraCode Nerd Font"; + margin-left: 16px; + margin-right: 16px; +} + +.modules-right { + margin-right: 20px; +} + +.modules-right .module { + margin-left: 20px; +} + +window#waybar { + border-radius: 16px; +} + +#workspaces button.active { + border-radius: 100%; +} + +#workspaces button:hover { + border-color: transparent; + box-shadow: none; + text-shadow: none; + background: none; + transition: none; +} + +#workspaces button { + min-width: 20px; + min-height: 20px; + padding: 7px; +} diff --git a/hosts/captain/configuration.nix b/hosts/captain/configuration.nix new file mode 100644 index 0000000..44d1af1 --- /dev/null +++ b/hosts/captain/configuration.nix @@ -0,0 +1,23 @@ +{ + pkgs, + ... +}: +{ + imports = [ + ./disko-config.nix + ./hardware-configuration.nix + ]; + + custom.desktop.enable = true; + + home-manager.users.flygrounder = { + custom = { + catppuccin.enable = true; + cli.enable = true; + gui.enable = true; + hyprland.enable = true; + neovim.enable = true; + waybar.enable = true; + }; + }; +} diff --git a/hosts/captain/disko-config.nix b/hosts/captain/disko-config.nix new file mode 100644 index 0000000..eded093 --- /dev/null +++ b/hosts/captain/disko-config.nix @@ -0,0 +1,33 @@ +{ + disko.devices = { + disk = { + main = { + device = "/dev/nvme0n1"; + type = "disk"; + content = { + type = "gpt"; + partitions = { + ESP = { + type = "EF00"; + size = "1G"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = [ "umask=0077" ]; + }; + }; + root = { + size = "100%"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + }; + }; + }; + }; + }; + }; + }; +} diff --git a/hosts/captain/hardware-configuration.nix b/hosts/captain/hardware-configuration.nix new file mode 100644 index 0000000..4d2d77a --- /dev/null +++ b/hosts/captain/hardware-configuration.nix @@ -0,0 +1,18 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usb_storage" "usbhid" "sd_mod" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-intel" ]; + boot.extraModulePackages = [ ]; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/hosts/home/configuration.nix b/hosts/home/configuration.nix new file mode 100644 index 0000000..f13bb51 --- /dev/null +++ b/hosts/home/configuration.nix @@ -0,0 +1,60 @@ +{ + pkgs, + ... +}: +{ + imports = [ + ./disko-config.nix + ./hardware-configuration.nix + ]; + + custom.desktop.enable = true; + + services = { + desktopManager.plasma6.enable = true; + printing = { + enable = true; + drivers = with pkgs; [ hplipWithPlugin ]; + }; + }; + + home-manager.users.flygrounder = { + custom = { + catppuccin.enable = true; + cli.enable = true; + gui.enable = true; + hyprland.enable = true; + neovim.enable = true; + waybar.enable = true; + }; + wayland.windowManager.hyprland.settings = { + monitor = [ + "DP-1, 2560x1440@180.00Hz, 0x0, 1" + ]; + exec-once = [ + "${pkgs.kdePackages.kwallet-pam}/libexec/pam_kwallet_init" + ]; + }; + }; + + users.users = { + dmitry = { + isNormalUser = true; + description = "Дмитрий"; + extraGroups = [ "networkmanager" ]; + packages = with pkgs; [ + brave + blender + libreoffice + ]; + }; + }; + + security.pam.services = { + greetd.kwallet = { + enable = true; + package = pkgs.kdePackages.kwallet-pam; + forceRun = true; + }; + }; +} diff --git a/hosts/home/disko-config.nix b/hosts/home/disko-config.nix new file mode 100644 index 0000000..eded093 --- /dev/null +++ b/hosts/home/disko-config.nix @@ -0,0 +1,33 @@ +{ + disko.devices = { + disk = { + main = { + device = "/dev/nvme0n1"; + type = "disk"; + content = { + type = "gpt"; + partitions = { + ESP = { + type = "EF00"; + size = "1G"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = [ "umask=0077" ]; + }; + }; + root = { + size = "100%"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + }; + }; + }; + }; + }; + }; + }; +} diff --git a/hosts/home/hardware-configuration.nix b/hosts/home/hardware-configuration.nix new file mode 100644 index 0000000..dd3fd25 --- /dev/null +++ b/hosts/home/hardware-configuration.nix @@ -0,0 +1,18 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usbhid" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-amd" ]; + boot.extraModulePackages = [ ]; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/hosts/laptop/configuration.nix b/hosts/laptop/configuration.nix new file mode 100644 index 0000000..b9d4b63 --- /dev/null +++ b/hosts/laptop/configuration.nix @@ -0,0 +1,23 @@ +{ + ... +}: +{ + imports = [ + ./disko-config.nix + ./hardware-configuration.nix + ]; + + custom.desktop.enable = true; + + home-manager.users.flygrounder = { + custom = { + catppuccin.enable = true; + cli.enable = true; + gui.enable = true; + hyprland.enable = true; + neovim.enable = true; + waybar.enable = true; + low-battery-notify.enable = true; + }; + }; +} diff --git a/hosts/laptop/disko-config.nix b/hosts/laptop/disko-config.nix new file mode 100644 index 0000000..5409ea5 --- /dev/null +++ b/hosts/laptop/disko-config.nix @@ -0,0 +1,39 @@ +{ + disko.devices = { + disk = { + main = { + type = "disk"; + device = "/dev/nvme0n1"; + content = { + type = "gpt"; + partitions = { + ESP = { + size = "1G"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = [ "umask=0077" ]; + }; + }; + luks = { + size = "100%"; + content = { + type = "luks"; + name = "crypted"; + settings.allowDiscards = true; + askPassword = true; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + }; + }; + }; + }; + }; + }; + }; + }; +} diff --git a/hosts/laptop/hardware-configuration.nix b/hosts/laptop/hardware-configuration.nix new file mode 100644 index 0000000..dbeeab2 --- /dev/null +++ b/hosts/laptop/hardware-configuration.nix @@ -0,0 +1,18 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "usb_storage" "sd_mod" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-amd" ]; + boot.extraModulePackages = [ ]; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/hosts/server/configuration.nix b/hosts/server/configuration.nix new file mode 100644 index 0000000..54341d4 --- /dev/null +++ b/hosts/server/configuration.nix @@ -0,0 +1,195 @@ +{ ... }: +let + myKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIArRfRumAbMcRypGundddfVg7t+VOwVeQ+HUQfI9AFbX flygrounder@home"; +in +{ + age.secrets.stalwart-admin-password = { + file = ../../secrets/stalwart-admin-password.age; + owner = "stalwart-mail"; + }; + + users.users = { + flygrounder = { + openssh.authorizedKeys.keys = [ + myKey + ]; + }; + root = { + openssh.authorizedKeys.keys = [ + myKey + ]; + }; + }; + + home-manager.users.flygrounder.custom = { + catppuccin.enable = true; + cli.enable = true; + neovim.enable = true; + }; + + services = { + caddy = { + enable = true; + virtualHosts = { + "flygrounder.ru" = { + extraConfig = '' + reverse_proxy localhost:1234 + ''; + }; + "mtg-bot.flygrounder.ru" = { + extraConfig = '' + reverse_proxy localhost:3000 + ''; + }; + "syncthing.flygrounder.ru" = { + extraConfig = '' + reverse_proxy localhost:8384 { + header_up Host localhost + } + ''; + }; + "vaultwarden.flygrounder.ru" = { + extraConfig = '' + encode zstd gzip + + reverse_proxy localhost:8222 { + header_up X-Real-IP {remote_host} + } + ''; + }; + "mail.flygrounder.ru" = { + extraConfig = '' + reverse_proxy localhost:8080 + ''; + }; + }; + }; + stalwart = { + enable = true; + openFirewall = true; + settings = { + server = { + hostname = "mail.flygrounder.ru"; + tls = { + enable = true; + implicit = true; + }; + listener = { + smtp = { + protocol = "smtp"; + bind = "0.0.0.0:25"; + }; + submissions = { + bind = "0.0.0.0:465"; + protocol = "smtp"; + tls.implicit = true; + }; + imaps = { + bind = "0.0.0.0:993"; + protocol = "imap"; + tls.implicit = true; + }; + jmap = { + bind = "127.0.0.1:8080"; + protocol = "http"; + }; + }; + }; + certificate."default" = { + cert = "%{file:/var/lib/stalwart-mail/certs/mail.flygrounder.ru.crt}%"; + private-key = "%{file:/var/lib/stalwart-mail/certs/mail.flygrounder.ru.key}%"; + }; + + authentication.fallback-admin = { + user = "admin"; + secret = "%{file:/run/agenix/stalwart-admin-password}%"; + }; + tracer."log" = { + type = "log"; + path = "/var/log/stalwart-mail"; + }; + }; + }; + openssh = { + enable = true; + settings = { + PasswordAuthentication = false; + }; + }; + vaultwarden = { + enable = true; + config = { + DOMAIN = "https://vaultwarden.flygrounder.ru"; + SIGNUPS_ALLOWED = false; + + ROCKET_ADDRESS = "127.0.0.1"; + ROCKET_PORT = 8222; + ROCKET_LOG = "critical"; + }; + }; + }; + + systemd.paths.stalwart-certs = { + wantedBy = [ "multi-user.target" ]; + pathConfig = { + PathModified = "/var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.flygrounder.ru/mail.flygrounder.ru.crt"; + }; + }; + + systemd.services.stalwart-certs = { + after = [ "caddy.service" ]; + before = [ "stalwart.service" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "oneshot"; + }; + script = '' + mkdir -p /var/lib/stalwart-mail/certs + cp -L /var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.flygrounder.ru/mail.flygrounder.ru.crt /var/lib/stalwart-mail/certs/ + cp -L /var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/mail.flygrounder.ru/mail.flygrounder.ru.key /var/lib/stalwart-mail/certs/ + chown stalwart-mail:stalwart-mail /var/lib/stalwart-mail/certs/* + chmod 600 /var/lib/stalwart-mail/certs/* + ''; + postStop = '' + if systemctl is-active --quiet stalwart.service; then + systemctl --no-block restart stalwart.service + fi + ''; + }; + + systemd.services.stalwart.after = [ "stalwart-certs.service" ]; + systemd.services.stalwart.requires = [ "stalwart-certs.service" ]; + + imports = [ + ./hardware-configuration.nix + ./disko-config.nix + ]; + + nix.settings.trusted-users = [ "flygrounder" ]; + + networking = { + firewall = { + allowedTCPPorts = [ + 80 + 443 + 25 + 465 + 993 + ]; + }; + nameservers = [ + "1.1.1.1" + "8.8.8.8" + ]; + interfaces.ens3.ipv4.addresses = [ + { + address = "62.109.27.62"; + prefixLength = 32; + } + ]; + defaultGateway = { + address = "10.0.0.1"; + interface = "ens3"; + }; + }; +} diff --git a/hosts/server/disko-config.nix b/hosts/server/disko-config.nix new file mode 100644 index 0000000..36349df --- /dev/null +++ b/hosts/server/disko-config.nix @@ -0,0 +1,33 @@ +{ + disko.devices = { + disk = { + main = { + device = "/dev/vda"; + type = "disk"; + content = { + type = "gpt"; + partitions = { + ESP = { + type = "EF00"; + size = "1G"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = [ "umask=0077" ]; + }; + }; + root = { + size = "100%"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + }; + }; + }; + }; + }; + }; + }; +} diff --git a/hosts/server/hardware-configuration.nix b/hosts/server/hardware-configuration.nix new file mode 100644 index 0000000..d6d2835 --- /dev/null +++ b/hosts/server/hardware-configuration.nix @@ -0,0 +1,17 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/profiles/qemu-guest.nix") + ]; + + boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "sr_mod" "virtio_blk" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ ]; + boot.extraModulePackages = [ ]; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; +} diff --git a/nixos/core.nix b/nixos/core.nix new file mode 100644 index 0000000..785bf3d --- /dev/null +++ b/nixos/core.nix @@ -0,0 +1,74 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + time.timeZone = "Europe/Moscow"; + programs.nix-ld.enable = true; + + i18n.defaultLocale = "ru_RU.UTF-8"; + + i18n.extraLocaleSettings = { + LC_ADDRESS = "ru_RU.UTF-8"; + LC_IDENTIFICATION = "ru_RU.UTF-8"; + LC_MEASUREMENT = "ru_RU.UTF-8"; + LC_MONETARY = "ru_RU.UTF-8"; + LC_NAME = "ru_RU.UTF-8"; + LC_NUMERIC = "ru_RU.UTF-8"; + LC_PAPER = "ru_RU.UTF-8"; + LC_TELEPHONE = "ru_RU.UTF-8"; + LC_TIME = "ru_RU.UTF-8"; + }; + + system.stateVersion = "25.11"; + + nix = { + gc = { + automatic = true; + dates = "weekly"; + options = "--delete-older-than 7d"; + }; + settings.experimental-features = [ + "nix-command" + "flakes" + ]; + }; + + nix.package = pkgs.lixPackageSets.stable.lix; + + boot.loader.systemd-boot.configurationLimit = 5; + + programs.fish.enable = true; + virtualisation.docker.enable = true; + + security.sudo.wheelNeedsPassword = false; + + home-manager = { + useGlobalPkgs = true; + useUserPackages = true; + }; + + users.users.flygrounder = { + shell = pkgs.fish; + isNormalUser = true; + description = "Артём"; + extraGroups = [ + "wheel" + "docker" + ]; + }; + + services.syncthing = { + enable = true; + dataDir = "/home/flygrounder"; + user = "flygrounder"; + }; + + programs.dconf.enable = true; + +} diff --git a/nixos/default.nix b/nixos/default.nix new file mode 100644 index 0000000..cd82fd0 --- /dev/null +++ b/nixos/default.nix @@ -0,0 +1,7 @@ +{ ... }: +{ + imports = [ + ./core.nix + ./desktop.nix + ]; +} diff --git a/nixos/desktop.nix b/nixos/desktop.nix new file mode 100644 index 0000000..3206a5a --- /dev/null +++ b/nixos/desktop.nix @@ -0,0 +1,60 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + options = { + custom.desktop.enable = lib.mkEnableOption "Enable desktop config"; + }; + config = lib.mkIf config.custom.desktop.enable { + networking = { + networkmanager.enable = true; + firewall = + let + qbittorrentPort = 12613; + in + { + allowedTCPPorts = [ qbittorrentPort ]; + allowedUDPPorts = [ qbittorrentPort ]; + }; + }; + + users.users.flygrounder.extraGroups = [ + "networkmanager" + ]; + + services = { + pulseaudio.enable = false; + pipewire = { + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + }; + greetd.enable = true; + flatpak.enable = true; + trezord.enable = true; + }; + + security.rtkit.enable = true; + + programs = { + regreet = { + enable = true; + theme.name = "Adwaita-dark"; + }; + hyprland.enable = true; + steam.enable = true; + amnezia-vpn.enable = true; + }; + nixpkgs.config.allowUnfree = true; + fonts.packages = with pkgs; [ + roboto + font-awesome + font-awesome_6 + nerd-fonts.fira-code + ]; + }; +} diff --git a/secrets.nix b/secrets.nix new file mode 100644 index 0000000..c886d02 --- /dev/null +++ b/secrets.nix @@ -0,0 +1,7 @@ +let + flygrounder = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIArRfRumAbMcRypGundddfVg7t+VOwVeQ+HUQfI9AFbX flygrounder@home"; + server = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOO6lKCmpKEarta4hBOcjHWznpf/RbCWuLS88/ZV1OeX root@nixos"; +in +{ + "secrets/stalwart-admin-password.age".publicKeys = [ flygrounder server ]; +} diff --git a/secrets/stalwart-admin-password.age b/secrets/stalwart-admin-password.age new file mode 100644 index 0000000..9407e95 --- /dev/null +++ b/secrets/stalwart-admin-password.age @@ -0,0 +1,9 @@ +age-encryption.org/v1 +-> ssh-ed25519 hPdT4Q SgN1qv5Gla2nEKic0s9smOtFfe/XNSS8iFB5Dp3hp0k +zKrWXjQos4sIdfiLv+LnBBA9t16cnSFSVe7E9K8hATk +-> ssh-ed25519 HTO34g iP+n9cG0RwWYI25fzfIB7ypZzGjnQmHRB/YuBYYdXyw +U+nmcAoLGOe2X+cGfp2jAZkmATGy2arb8zlA86ygxOU +--- DT25zdelj78pyssKus9/SFnYdiSMo7CCrLWJpSUXCNI +4 o],>BB8Ą{ +\j?pEtraPFaLٛ2%{w Mb-Tpz6䮼;.2>r + \ No newline at end of file