From 1a5158094d916a9de2cf49b5792ba6c2d197ea09 Mon Sep 17 00:00:00 2001 From: Lukasz Date: Wed, 14 Aug 2024 14:51:10 +0200 Subject: [PATCH] first commit --- .github/workflows/ci.yaml | 17 +++ .github/workflows/update-flake-lock.yaml | 20 +++ .gitignore | 54 ++++++++ README.md | 96 ++++++++++++++ flake.lock | 122 +++++++++++++++++ flake.nix | 73 +++++++++++ home/adguardhome.nix | 14 ++ home/default.nix | 159 +++++++++++++++++++++++ home/nix-index.nix | 8 ++ home/squid.nix | 74 +++++++++++ justfile | 40 ++++++ nix/template.nix | 30 +++++ nix/toplevel.nix | 45 +++++++ 13 files changed, 752 insertions(+) create mode 100644 .github/workflows/ci.yaml create mode 100644 .github/workflows/update-flake-lock.yaml create mode 100644 .gitignore create mode 100644 README.md create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 home/adguardhome.nix create mode 100644 home/default.nix create mode 100644 home/nix-index.nix create mode 100644 home/squid.nix create mode 100644 justfile create mode 100644 nix/template.nix create mode 100644 nix/toplevel.nix diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..81492de --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,17 @@ +name: "CI" +on: + push: + branches: + - main + pull_request: +jobs: + nix: + runs-on: ${{ matrix.system }} + strategy: + matrix: + system: [aarch64-darwin, x86_64-darwin, x86_64-linux] + fail-fast: false + steps: + - uses: actions/checkout@v4 + - name: nixci + run: nixci --extra-access-tokens "github.com=${{ secrets.GITHUB_TOKEN }}" build --systems "${{ matrix.system }}" diff --git a/.github/workflows/update-flake-lock.yaml b/.github/workflows/update-flake-lock.yaml new file mode 100644 index 0000000..0650a41 --- /dev/null +++ b/.github/workflows/update-flake-lock.yaml @@ -0,0 +1,20 @@ +name: update-flake-lock +on: + workflow_dispatch: # allows manual triggering + schedule: + - cron: '0 0 * * 0' # runs weekly on Sunday at 00:00 + +jobs: + example-lock: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Install Nix + uses: DeterminateSystems/nix-installer-action@main + - name: Update flake.lock + uses: DeterminateSystems/update-flake-lock@main + with: + pr-title: "Update flake.lock" + pr-labels: | + automated diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c8760da --- /dev/null +++ b/.gitignore @@ -0,0 +1,54 @@ + +# Nix-specific +result +result-* +.direnv + +# Home Manager +.home-manager-generation + +# Editor and OS files +.vscode/ +.idea/ +*.swp +*~ +.DS_Store + +# Logs +*.log + +# Nix build outputs +result +result-* + +# Python-related (for custom Python packages) +__pycache__/ +*.py[cod] +*.egg-info/ +.installed.cfg +*.egg + +# Node.js (for nodejs_22) +node_modules/ + +# Temporary files +*.tmp +*.temp + +# Squid cache and logs (from squid.nix) +.squid/cache/ +.squid/logs/ + +# AdGuard Home data (from adguardhome.nix) +.adguardhome/ + +# nix-index database +.cache/nix-index + +# Any local overrides or user-specific configs +*.local +*.override + +# Flake-related +.envrc + diff --git a/README.md b/README.md new file mode 100644 index 0000000..a905ee1 --- /dev/null +++ b/README.md @@ -0,0 +1,96 @@ +# NixOS Darwin Home Manager + +- **NixOS:** v2.23.3 +- **Home Manager:** v24.05 +- **Nixpkgs:** v24.05 + +Extra addons: +- **Squid proxy** (currently not available on MacOS Silicon - missing binaries) +- **AdGuardHome** (configuration not yet complete) + +## Development Environment Manual (devenv and devbox) + +This manual outlines the tools and configurations in your Nix-based development environment, focusing on devenv and devbox. + +### Core Components + +1. **Nixpkgs**: The primary package collection for Nix. +2. **Home Manager**: Manages user-specific configurations. + +### Key Development Tools + +#### devenv +devenv is not explicitly listed in your configuration, but if you want to use it, you can add it to your setup. devenv provides reproducible development environments. + +#### devbox +Devbox is included in your setup. It's a tool for creating isolated, reproducible development environments. + +Usage: +```bash +devbox init # Initialize a new project +devbox add # Add a package to your project +devbox shell # Enter the development environment +``` + +### Other Development Tools + +- **ripgrep**: Fast search tool for recursive searching. +- **fd**: User-friendly alternative to `find`. +- **sd**: Intuitive find & replace CLI. +- **tree**: Displays directory contents in a tree-like format. +- **cachix**: Binary cache for Nix. +- **nil**: Nix language server. +- **nix-info**, **nixpkgs-fmt**, **nixci**, **nix-health**: Various Nix utilities. + +### Version Control +- **Git**: Configured with user details and aliases. +- **LazyGit**: Terminal UI for Git commands. + +### Programming Languages +- **Python**: + - **Poetry**: Dependency management for Python. +- **Node.js**: + - **node2nix**: Converts Node.js packages to Nix expressions. + - **nodejs_22**: Node.js version 22. + +### Shell and Scripting +- **Bash** and **Zsh**: Configured shells with custom aliases and PATH modifications. +- **Xonsh**: Python-based shell. +- **any-nix-shell**: Allows using Nix shells with any shell. +- **direnv**: Automatically loads and unloads environment variables. + +### Proxy and Networking +- **AdGuard Home**: Network-wide ad blocker. + +### Configuration Files +- **home/default.nix**: Primary configuration for Home Manager. + +### Usage Instructions + +1. Edit `home/default.nix` to customize your Home Manager configuration. +2. Run `nix run` to apply the configuration. +3. Use `devbox` to manage project-specific development environments: + ```bash + devbox init # In your project directory + devbox add python nodejs # Add required tools + devbox shell # Enter the environment + ``` +4. Use `direnv` to automatically load environment variables: + ```bash + echo "use devbox" > .envrc + direnv allow + ``` + +### Customization + +- Add or modify packages in the `home.packages` section of `home/default.nix`. +- Create project-specific environments using devbox. +- Use direnv to automatically load project environments. + +Remember to rebuild your environment after making changes to apply the new configuration: + +```bash +just run +``` + +This setup provides a flexible development environment using devbox for project-specific setups and Home Manager for system-wide configurations. Adjust as needed for your specific development workflows. \ No newline at end of file diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..6412276 --- /dev/null +++ b/flake.lock @@ -0,0 +1,122 @@ +{ + "nodes": { + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1722555600, + "narHash": "sha256-XOQkdLafnb/p9ij77byFQjDf5m5QYl9b2REiVClC+x4=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "8471fe90ad337a8074e957b69ca4d0089218391d", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1723399884, + "narHash": "sha256-97wn0ihhGqfMb8WcUgzzkM/TuAxce2Gd20A8oiruju4=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "086f619dd991a4d355c07837448244029fc2d9ab", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "nix-darwin": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1722924007, + "narHash": "sha256-+CQDamNwqO33REJLft8c26NbUi2Td083hq6SvAm2xkU=", + "owner": "lnl7", + "repo": "nix-darwin", + "rev": "91010a5613ffd7ee23ee9263213157a1c422b705", + "type": "github" + }, + "original": { + "owner": "lnl7", + "ref": "master", + "repo": "nix-darwin", + "type": "github" + } + }, + "nix-index-database": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1723352546, + "narHash": "sha256-WTIrvp0yV8ODd6lxAq4F7EbrPQv0gscBnyfn559c3k8=", + "owner": "Mic92", + "repo": "nix-index-database", + "rev": "ec78079a904d7d55e81a0468d764d0fffb50ac06", + "type": "github" + }, + "original": { + "owner": "Mic92", + "repo": "nix-index-database", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1723362943, + "narHash": "sha256-dFZRVSgmJkyM0bkPpaYRtG/kRMRTorUIDj8BxoOt1T4=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "a58bc8ad779655e790115244571758e8de055e3d", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1722555339, + "narHash": "sha256-uFf2QeW7eAHlYXuDktm9c25OxOyCoUOQmh5SZ9amE5Q=", + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/a5d394176e64ab29c852d03346c1fc9b0b7d33eb.tar.gz" + }, + "original": { + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/a5d394176e64ab29c852d03346c1fc9b0b7d33eb.tar.gz" + } + }, + "root": { + "inputs": { + "flake-parts": "flake-parts", + "home-manager": "home-manager", + "nix-darwin": "nix-darwin", + "nix-index-database": "nix-index-database", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..763fd81 --- /dev/null +++ b/flake.nix @@ -0,0 +1,73 @@ +{ + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + home-manager = { + url = "github:nix-community/home-manager"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + nix-darwin = { + url = "github:lnl7/nix-darwin/master"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + flake-parts.url = "github:hercules-ci/flake-parts"; + nix-index-database = { + url = "github:Mic92/nix-index-database"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = inputs@{ self, nixpkgs, flake-parts, home-manager, nix-darwin, nix-index-database, ... }: + flake-parts.lib.mkFlake { inherit inputs; } { + systems = [ "aarch64-darwin" "x86_64-darwin" ]; + + perSystem = { pkgs, system, ... }: { + formatter = pkgs.nixpkgs-fmt; + + devShells.default = pkgs.mkShell { + buildInputs = with pkgs; [ nixpkgs-fmt just ]; + }; + + packages.default = pkgs.writeShellApplication { + name = "activate"; + runtimeInputs = [ inputs.home-manager.packages.${system}.default ]; + text = '' + ${pkgs.lib.getExe inputs.home-manager.packages.${system}.default} switch --flake .#lukasz@${system} + ''; + }; + }; + + flake = { + homeConfigurations."lukasz@aarch64-darwin" = home-manager.lib.homeManagerConfiguration { + pkgs = nixpkgs.legacyPackages.aarch64-darwin; + extraSpecialArgs = { inherit inputs; }; + modules = [ + ./home + nix-index-database.hmModules.nix-index + { + home = { + username = "lukasz"; + homeDirectory = "/Users/lukasz"; + stateVersion = "24.05"; + }; + } + ]; + }; + + darwinConfigurations."lukasz-macbook-pro-13" = nix-darwin.lib.darwinSystem { + system = "aarch64-darwin"; + modules = [ + home-manager.darwinModules.home-manager + { + home-manager.useGlobalPkgs = true; + home-manager.useUserPackages = true; + home-manager.users.lukasz = import ./home; + } + { + security.pam.enableSudoTouchIdAuth = true; + system.stateVersion = 4; + } + ]; + }; + }; + }; +} diff --git a/home/adguardhome.nix b/home/adguardhome.nix new file mode 100644 index 0000000..5473dd1 --- /dev/null +++ b/home/adguardhome.nix @@ -0,0 +1,14 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.services.adguardhome; +in +{ + options.services.adguardhome = { + enable = lib.mkEnableOption "AdGuard Home"; + }; + + config = lib.mkIf cfg.enable { + home.packages = [ pkgs.adguardhome ]; + }; +} diff --git a/home/default.nix b/home/default.nix new file mode 100644 index 0000000..c662eac --- /dev/null +++ b/home/default.nix @@ -0,0 +1,159 @@ +{ pkgs, inputs, ... }: +{ + # Import configurations + imports = [ + ./squid.nix + ./adguardhome.nix + ./nix-index.nix + ]; + + # Set the state version + home.stateVersion = "24.05"; + + # Recommended Nix settings + nix = { + registry = { + nixpkgs = { + flake = { + outPath = inputs.nixpkgs; + }; + }; + }; + gc = { + automatic = true; # Enable automatic garbage collection + }; + }; + + # Define packages to install + home.packages = with pkgs; [ + # Development tools + devbox + direnv + git + gh + lazygit + nodejs_22 + python3 + poetry + cachix + nil + nixpkgs-fmt + nix-info + nixci + nix-health + # File and text manipulation + ripgrep + fd + sd + tree + bat + # Navigation and shell enhancements + fzf + zoxide + btop + any-nix-shell + # Graphviz for dot + graphviz + # Custom Python package + (python3Packages.buildPythonPackage rec { + pname = "xontrib-vox"; + version = "0.0.1"; + src = fetchFromGitHub { + owner = "xonsh"; + repo = "xontrib-vox"; + rev = "0.0.1"; + hash = "sha256-OB1O5GZYkg7Ucaqak3MncnQWXhMD4BM4wXsYCDD0mhk="; + }; + prePatch = '' + substituteInPlace pyproject.toml --replace '"xonsh>=0.12.5"' "" + ''; + meta = with lib; { + description = "Direnv support for Xonsh"; + homepage = "https://github.com/74th/xonsh-direnv/"; + license = licenses.mit; + maintainers = [ ]; + }; + patchPhase = "sed -i -e 's/^dependencies.*$/dependencies = []/' pyproject.toml"; + doCheck = false; + nativeBuildInputs = [ git ]; + }) + ]; + + # Programs natively supported by home-manager + programs = { + bash = { + enable = true; + initExtra = '' + export PATH=/run/current-system/sw/bin/:/nix/var/nix/profiles/default/bin:$HOME/.nix-profile/bin:/etc/profiles/per-user/$USER/bin:$PATH + ''; + }; + zsh = { + enable = true; + autosuggestion.enable = true; + syntaxHighlighting.enable = true; + envExtra = '' + export PATH=/run/current-system/sw/bin/:/nix/var/nix/profiles/default/bin:$HOME/.nix-profile/bin:/etc/profiles/per-user/$USER/bin:$PATH + ''; + }; + bat.enable = true; + zoxide.enable = true; + fzf.enable = true; + jq.enable = true; + btop.enable = true; + starship = { + enable = true; + settings = { + username = { + style_user = "blue bold"; + style_root = "red bold"; + format = "[$user]($style) "; + disabled = false; + show_always = true; + }; + hostname = { + ssh_only = false; + ssh_symbol = "🌐 "; + format = "on [$hostname](bold red) "; + trim_at = ".local"; + disabled = false; + }; + }; + }; + direnv = { + enable = true; + nix-direnv.enable = true; + config.global = { + hide_env_diff = true; # Make direnv messages less verbose + }; + }; + git = { + enable = true; + userName = "Lukasz"; + userEmail = "lukasz@tulikowski.email"; + aliases = { + co = "checkout"; + ci = "commit"; + st = "status"; + br = "branch"; + }; + }; + }; + + # Xonsh configuration + home.file.".xonshrc".text = '' + execx($(${pkgs.any-nix-shell}/bin/any-nix-shell xonsh --info-right)) + execx($(${pkgs.zoxide}/bin/zoxide init xonsh)) + aliases['update'] = 'home-manager switch' + ''; + + # Shell aliases + home.shellAliases = { + xonsh = "${pkgs.xonsh}/bin/xonsh"; + }; + + # Allow unfree packages + nixpkgs.config.allowUnfree = true; + + # Enable AdGuard Home service + services.adguardhome.enable = true; +} diff --git a/home/nix-index.nix b/home/nix-index.nix new file mode 100644 index 0000000..3e2828a --- /dev/null +++ b/home/nix-index.nix @@ -0,0 +1,8 @@ +{ pkgs, ... }: +{ + programs.nix-index = { + enable = true; + enableZshIntegration = true; + }; + # nix-index-database.comma.enable = true; +} diff --git a/home/squid.nix b/home/squid.nix new file mode 100644 index 0000000..72a9043 --- /dev/null +++ b/home/squid.nix @@ -0,0 +1,74 @@ +{ config, pkgs, lib, ... }: + +let + squidCacheDir = "${config.home.homeDirectory}/.squid/cache"; + squidLogDir = "${config.home.homeDirectory}/.squid/logs"; + isSquidSupported = !(pkgs.stdenv.isDarwin && pkgs.stdenv.isAarch64); +in +{ + config = lib.mkIf isSquidSupported { + home.packages = [ pkgs.squid ]; + + home.file.".squid/squid.conf".text = '' + visible_hostname ${config.networking.hostName} + + http_port 3128 + cache_dir ufs ${squidCacheDir} 100 16 256 + coredump_dir ${squidCacheDir} + cache_access_log ${squidLogDir}/access.log + cache_log ${squidLogDir}/cache.log + cache_store_log ${squidLogDir}/store.log + + acl localnet src 0.0.0.1-0.255.255.255 + acl localnet src 10.0.0.0/8 + acl localnet src 100.64.0.0/10 + acl localnet src 169.254.0.0/16 + acl localnet src 172.16.0.0/12 + acl localnet src 192.168.0.0/16 + acl localnet src fc00::/7 + acl localnet src fe80::/10 + + acl SSL_ports port 443 + acl Safe_ports port 80 21 443 70 210 1025-65535 280 488 591 777 + + http_access deny !Safe_ports + http_access deny CONNECT !SSL_ports + http_access allow localhost manager + http_access deny manager + http_access allow localnet + http_access allow localhost + http_access deny all + + cache_mem 256 MB + + refresh_pattern ^ftp: 1440 20% 10080 + refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 + refresh_pattern . 0 20% 4320 + ''; + + home.activation = { + createSquidDirs = lib.hm.dag.entryAfter [ "writeBoundary" ] '' + mkdir -p ${squidCacheDir} + mkdir -p ${squidLogDir} + ''; + }; + + systemd.user.services.squid = lib.mkIf pkgs.stdenv.isLinux { + Unit = { + Description = "Squid caching proxy"; + After = [ "network.target" ]; + }; + Service = { + ExecStart = "${pkgs.squid}/bin/squid -N -d 1 -f ${config.home.homeDirectory}/.squid/squid.conf"; + Restart = "always"; + }; + Install = { + WantedBy = [ "default.target" ]; + }; + }; + + programs.zsh.shellAliases = { + start-squid = "squid -f ~/.squid/squid.conf"; + }; + }; +} diff --git a/justfile b/justfile new file mode 100644 index 0000000..3561116 --- /dev/null +++ b/justfile @@ -0,0 +1,40 @@ +# Like GNU `make`, but `just` rustier. +# https://just.systems/man/en/chapter_19.html +# run `just` from this directory to see available commands + +# Default command when 'just' is run without arguments +default: + @just --list + +# Print nix flake inputs and outputs +io: + nix flake metadata + nix flake show + +# Update nix flake +update: + nix flake update + +# Lint nix files +lint: + nix fmt + +# Check nix flake +check: + nix flake check + +# Manually enter dev shell +dev: + nix develop + +# Build nix flake +build: lint check + nix build + +# Remove build output link (no garbage collection) +clean: + rm -f ./result + +# Run nix flake to setup environment +run: lint check + nix run \ No newline at end of file diff --git a/nix/template.nix b/nix/template.nix new file mode 100644 index 0000000..43564ec --- /dev/null +++ b/nix/template.nix @@ -0,0 +1,30 @@ +# Allow using this repo in `nix flake init` +{ inputs, ... }: +{ + flake.templates.default = { + description = "A `home-manager` template providing useful tools & settings for Nix-based development"; + welcomeText = '' + You have just created a home-manager flake.nix. + + - Edit `home/default.nix` to customize your home-manager configuration. + - Run `nix run` to apply the configuration. + + Enjoy! + ''; + path = builtins.path { + path = inputs.self; + filter = path: _: with inputs.nixpkgs.lib; + !(hasSuffix "LICENSE" path || + hasSuffix "README.md" path || + hasSuffix ".github/" path); + }; + }; + + perSystem = { pkgs, ... }: { + # Used to replace username in flake.nix (see README.md) + # + # This is better than `nix run nixpkgs#sd` which will fetch the latest + # nixpkgs, not the one pinned in flake.nix. + packages.sd = pkgs.sd; + }; +} diff --git a/nix/toplevel.nix b/nix/toplevel.nix new file mode 100644 index 0000000..2e29054 --- /dev/null +++ b/nix/toplevel.nix @@ -0,0 +1,45 @@ +# Top-level flake glue to get our home-manager configuration working +{ self, inputs, lib, ... }: + +{ + flake = { + # cf. https://nixos.asia/en/nix-modules + options = { + nix-dev-home.username = lib.mkOption { + type = lib.types.str; + description = "The username to use for the home-manager configuration"; + }; + }; + }; + perSystem = { self', pkgs, ... }: { + legacyPackages.homeConfigurations.${self.nix-dev-home.username} = + inputs.self.nixos-flake.lib.mkHomeConfiguration + pkgs + ({ pkgs, ... }: { + # Edit the contents of the ./home directory to install packages and modify dotfile configuration in your + # $HOME. + # + # https://nix-community.github.io/home-manager/index.html#sec-usage-configuration + imports = [ ../home ]; + home.username = self.nix-dev-home.username; + home.homeDirectory = lib.mkForce ( + if pkgs.stdenv.isDarwin then "/Users/${self.nix-dev-home.username}" + else "/home/${self.nix-dev-home.username}" + ); + home.stateVersion = "24.05"; + }); + + # Enables 'nix run' to activate. + apps.default.program = pkgs.writeShellApplication { + name = "activate"; + text = '' + set -x + ${lib.getExe self'.packages.activate} "${self.nix-dev-home.username}"@; + ''; + }; + + # Enable 'nix build' to build the home configuration, but without + # activating. + packages.default = self'.legacyPackages.homeConfigurations.${self.nix-dev-home.username}.activationPackage; + }; +}