Skip to content

Remote deploy with deploy‐rs

Marlinc edited this page Dec 29, 2024 · 2 revisions
  1. SSH Setup Setup SSH on nix-on-droid if not done already. Add your desktop's SSH public key to the nix-on-droid user's ~/.ssh/authorized_keys file.

  2. UID/GID Handling The primary issue is ensuring the correct uid and gid for the nix-on-droid user on your phone. When building on your desktop, these might not match, leading to permission issues.

    • Find the UID and GID on your Android device:

      id nix-on-droid

      This command returns the uid and gid of the nix-on-droid user on your device.

    • Set the UID and GID explicitly in your nix-on-droid configuration:

      { 
        user.uid = <uid>;
        user.gid = <gid>;
      } # Replace <uid> and <gid> with the values from your device
  3. Set Up the deploy-rs Configuration The activation comes from above in this thread itself. Here's a helper to make it a little less repetitive.

    let
      activateNixOnDroid =
        configuration:
        inputs.deploy-rs.lib.aarch64-linux.activate.custom
          configuration.activationPackage
          "${configuration.activationPackage}/activate";
    in

    Here's how to configure your deploy-rs for nix-on-droid:

    deploy.nodes = {
      "pioneer" = {
        hostname = "pioneer.nixus.net"; # Replace with your device's hostname or IP (I use `dnsmaq` for local DNS)
        profiles.system = {
          sshUser = "nix-on-droid";
          user = "nix-on-droid";
          magicRollback = true;
          sshOpts = [ "-p" "8022" ]; # Adjust port if necessary (Step 1 dependent)
          path = activateNixOnDroid self.nixOnDroidConfigurations.pioneer;
        };
      };
    };
  4. Handle Multiple Devices If deploying to multiple devices, define specific configurations for each, especially if they have different uid and gid values.

    nixOnDroidConfigurations = {
      "pioneer" = nix-on-droid.lib.nixOnDroidConfiguration {
        pkgs = pkgsFor "aarch64-linux";
        modules = [
          ./nix/hosts/pioneer.nix
          # Include other modules like Home Manager if needed
          { 
            user.uid = 10701;
            user.gid = 10701;
          } # Replace with the UID and GID from your device
        ];
      };
    
      "voyager" = nix-on-droid.lib.nixOnDroidConfiguration {
        pkgs = pkgsFor "aarch64-linux";
        modules = [
          ./nix/hosts/voyager.nix
          { 
            user.uid = 10403;
            user.gid = 10403;
          } # Replace with the UID and GID from your other device
        ];
      };
    };
  5. Set Up Cachix for Substitutes and support building of aarch64 packages To satisfy dependencies like static-proot, ensure the Nix settings (on the host were you run deploy-rs) include the necessary substituters and trusted public keys. This is crucial because nix-on-droid relies on prebuilt cross-compiled binaries for proot-static, which are specified by hard-coded Nix store paths in the configuration.

    To support building aarch64 packages from a x86_64 host we can enable emulation of aarch64 using QEMU.

    Nix Settings:

    {
      # Building for aarch64
      boot.binfmt.emulatedSystems = ["aarch64-linux"];
      nix.settings.extra-platforms = ["aarch64-linux" "arm-linux"];
    
      nix.settings = {
        substituters = [
          # "https://cache.nixos.org/"
          # "https://nix-community.cachix.org"
          "https://nix-on-droid.cachix.org" <----
        ];
    
        trusted-public-keys = [
          # "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
          # "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
          "nix-on-droid.cachix.org-1:56snoMJTXmE7wm+67YySRoTY64Zkivk9RT4QaKYgpkE=" # <---
        ];
      };
    } # Pretty sure you only need what's pointed out, but I kept my full Cachix config in case I'm missing something else.

    Reason for the Cache: The nix-on-droid configuration specifies the prootStatic binary using hardcoded Nix store paths that point to prebuilt cross-compiled binaries:

    environment.files = {
      prootStatic =
        let
          crossCompiledPaths = {
            aarch64-linux = "/nix/store/7qd99m1w65x2vgqg453nd70y60sm3kay-proot-termux-static-aarch64-unknown-linux-android-unstable-2024-05-04";
            x86_64-linux = "/nix/store/pakj3svvw84rhkzdc6211yhc2cgvc21f-proot-termux-static-x86_64-unknown-linux-android-unstable-2024-05-04";
          };
        in
        "${crossCompiledPaths.${targetSystem}}";
    };

    (Reference: nix-on-droid/modules/environment/login/default.nix#L90) These binaries are not built locally during deployment (I have no idea how it would be setup), so having the cache set up ensures they can be fetched from the nix-on-droid Cachix cache.

  6. Configure Overlays for nix-on-droid Ensure your overlays are properly set up to include nix-on-droid:

    pkgsFor = system: import nixpkgs {
      inherit system;
      config = {
        allowUnfree = true;
        overlays = [
          (import ./nix/overlays)              # Your custom overlays
          # (final: prev: { nix-on-droid = nix-on-droid.packages.${system}; }) # not necessary, I use it in one of my flake apps
        ] ++ lib.optional (custom.isAndroid system) nix-on-droid.overlays.default; 
      };
    }; # isAndroid is just checking against a list of [ "aarch64-linux" ], as I believe only that is really supported here
  7. Finalize and Deploy With all configurations in place, deploy using:

    deploy --targets ".#pioneer" -- --impure

    Replace pioneer with the appropriate node name from your deploy.nodes configuration. (let me know if this can be done without --impure)

    Deployment Log

    ℹ️  [deploy] [INFO] Evaluating flake in .
    trace: Loading overlays: better-icons.nix shared-cargo-gptcommit.nix sops-injection-key-fetcher.nix sops-ssh-wrapper.nix
    trace: Loading overlays: better-icons.nix shared-cargo-gptcommit.nix sops-injection-key-fetcher.nix sops-ssh-wrapper.nix
    🚀 ℹ️  [deploy] [INFO] The following profiles are going to be deployed:
    [pioneer.system]
    user = "nix-on-droid"
    ssh_user = "nix-on-droid"
    path = "/nix/store/p2jbjbr1lksk2aa26cfhxlzs0rxnbfgm-activatable-nix-on-droid-generation"
    hostname = "pioneer.nixus.net"
    ssh_opts = ["-p", "8022"]
    
    🚀 ℹ️  [deploy] [INFO] Building profile `system` for node `pioneer`
    🚀 ℹ️  [deploy] [INFO] Copying profile `system` to node `pioneer`
    🚀 ℹ️  [deploy] [INFO] Activating profile `system` for node `pioneer`
    🚀 ℹ️  [deploy] [INFO] Creating activation waiter
    ⭐ ℹ️  [activate] [INFO] Activating profile
    👀 ℹ️  [wait] [INFO] Waiting for confirmation event...
    Activating linkBinSh
    Activating linkUsrBinEnv
    Activating setPriorityHomeManagerPath
    Activating installLogin
    Activating installLoginInner
    Activating installPackages
    replacing old 'nix-on-droid-path'
    installing 'nix-on-droid-path'
    Activating installProotStatic
    Activating linkColors
    Activating linkFont
    Activating setUpEtc
    Activating sops-nix
    sops-install-secrets: Imported /data/data/com.termux.nix/files/home/.ssh/id_ed25519 as age key with fingerprint `***KEY_CENSORED***`
    Activating sshd
    Setting up OpenSSH...
    Authorized keys file already exists. Skipping...
    Setting correct permissions...
    OpenSSH setup complete.
    Activating homeManager
    Starting Home Manager activation
    Activating checkFilesChanged
    Activating checkLinkTargets
    Activating writeBoundary
    Activating installPackages
    Activating migrateGhAccounts
    Activating linkGeneration
    Cleaning up orphan links from /data/data/com.termux.nix/files/home
    No change so reusing latest profile generation 48
    Creating home file links in /data/data/com.termux.nix/files/home
    Activating onFilesChange
    Activating reloadSystemd
    User systemd daemon not running. Skipping reload.
    Activating sops-nix
    User systemd daemon not running. Probably executed on boot where no manual start/reload is needed.
    Activating linkProfile
    ⭐ ℹ️  [activate] [INFO] Activation succeeded!
    ⭐ ℹ️  [activate] [INFO] Magic rollback is enabled, setting up confirmation hook...
    👀 ℹ️  [wait] [INFO] Found canary file, done waiting!
    ⭐ ℹ️  [activate] [INFO] Waiting for confirmation event...
    🚀 ℹ️  [deploy] [INFO] Success activating, attempting to confirm activation
    🚀 ℹ️  [deploy] [INFO] Deployment confirmed.
    
    .dotfiles on  develop [$?] took 49s
Clone this wiki locally