<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Noor Latif</title>
    <description>The latest articles on DEV Community by Noor Latif (@noorlatif).</description>
    <link>https://dev.to/noorlatif</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3673642%2F24d3d7f0-384c-4539-a393-b209f6bd8b50.png</url>
      <title>DEV Community: Noor Latif</title>
      <link>https://dev.to/noorlatif</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/noorlatif"/>
    <language>en</language>
    <item>
      <title>sops-nix secrets with NixOS using home-manager, the git-safe way</title>
      <dc:creator>Noor Latif</dc:creator>
      <pubDate>Tue, 17 Feb 2026 08:57:32 +0000</pubDate>
      <link>https://dev.to/noorlatif/sops-nix-secrets-with-nixos-using-home-manager-the-git-safe-way-h3i</link>
      <guid>https://dev.to/noorlatif/sops-nix-secrets-with-nixos-using-home-manager-the-git-safe-way-h3i</guid>
      <description>&lt;h2&gt;
  
  
  How to git track sensitive secrets without using env vars?
&lt;/h2&gt;

&lt;p&gt;When you track your NixOS configuration in git, or any config for that matter, your entire system is version-controlled and reproducible. Any API keys or passwords in those files, however, would be pushed to your repo in plaintext for anyone to see. You can't just &lt;code&gt;.gitignore&lt;/code&gt; them either, because NixOS needs those values at build/activation time. I use NixOS because it allowed me to have a code defined laptop environment that I can easily bring with me. I was tired of my Linux distros breaking, and I wasn't happy with Fedora Atomics way of doing things with rpm-ostree and RedHat image bootc feature.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;sops-nix&lt;/strong&gt; solves this: you encrypt secrets with &lt;a href="https://github.com/getsops/sops" rel="noopener noreferrer"&gt;SOPS&lt;/a&gt; and commit the &lt;em&gt;encrypted&lt;/em&gt; files to git. At system activation, sops-nix decrypts them using keys that only exist on your machine (never in the repo). Your dotfiles stay fully reproducible and pushable, with zero secret leakage.&lt;/p&gt;

&lt;p&gt;The first secret I needed to manage is &lt;code&gt;EXA_API_KEY&lt;/code&gt; for &lt;a href="https://exa.ai" rel="noopener noreferrer"&gt;Exa.ai&lt;/a&gt;, which powers web research and crawling capabilities through an MCP server.&lt;/p&gt;

&lt;p&gt;This guide covers a simple single-machine setup using age keys derived from SSH keys, based on &lt;a href="https://michael.stapelberg.ch/posts/2025-08-24-secret-management-with-sops-nix/" rel="noopener noreferrer"&gt;Michael Stapelberg's approach&lt;/a&gt;. But with some fixes to outdated methods.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preparation: Add Trusted User (optional, recommended)
&lt;/h2&gt;

&lt;p&gt;To avoid build warnings, add yourself as trusted user in &lt;code&gt;configuration.nix&lt;/code&gt; (optional):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;nix&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;trusted-users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"@wheel"&lt;/span&gt; &lt;span class="s2"&gt;"noor"&lt;/span&gt; &lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then rebuild:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nixos-rebuild switch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This lets &lt;code&gt;nix run&lt;/code&gt; use additional substituters (binary caches) without warnings. Speeds up the next steps and future ones too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1-3: Create age key and get both recipients
&lt;/h2&gt;

&lt;p&gt;Prepare:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ~/.config/sops/age/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enter a nix shell with all needed tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nix shell nixpkgs#ssh-to-age nixpkgs#age
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside the shell:&lt;/p&gt;

&lt;p&gt;Create an age identity file derived from your SSH private key.&lt;/p&gt;

&lt;p&gt;If your SSH key is passphrase-protected, &lt;code&gt;ssh-to-age&lt;/code&gt; will prompt you for it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-to-age &lt;span class="nt"&gt;-private-key&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; ~/.ssh/id_ed25519 &lt;span class="nt"&gt;-o&lt;/span&gt; ~/.config/sops/age/keys.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lock down permissions (recommended):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod &lt;/span&gt;600 ~/.config/sops/age/keys.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Get your personal age recipient (copy the output, e.g., age1xxxxx...)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;age-keygen &lt;span class="nt"&gt;-y&lt;/span&gt; ~/.config/sops/age/keys.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check if system SSH host keys exist&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; /etc/ssh/ssh_host_ed25519_key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;If not found, generate them: &lt;code&gt;sudo ssh-keygen -A&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Get your system's SSH host key recipient (copy the output, e.g., age1yyyyy...)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /etc/ssh/ssh_host_ed25519_key.pub | ssh-to-age
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exit the shell&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll need both recipients for &lt;code&gt;.sops.yaml&lt;/code&gt; in the next step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Create &lt;code&gt;.sops.yaml&lt;/code&gt; in nixos-dotfiles root
&lt;/h2&gt;

&lt;p&gt;Create the file at &lt;code&gt;~/nixos-dotfiles/.sops.yaml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;keys&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;admin&lt;/span&gt; &lt;span class="s"&gt;age1xxxxx...&lt;/span&gt;        &lt;span class="c1"&gt;# Your personal age recipient&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;system&lt;/span&gt; &lt;span class="s"&gt;age1yyyyy...&lt;/span&gt;       &lt;span class="c1"&gt;# Your system's SSH host key&lt;/span&gt;

&lt;span class="na"&gt;creation_rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;path_regex&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;secrets/[^/]+\.yaml$&lt;/span&gt;
    &lt;span class="na"&gt;key_groups&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;*admin&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;*system&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why both keys?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Your personal key&lt;/strong&gt; (&lt;code&gt;&amp;amp;admin&lt;/code&gt;): Lets you decrypt and edit secrets as a regular user, no sudo or repeated SSH passphrase needed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;System SSH host key&lt;/strong&gt; (&lt;code&gt;&amp;amp;system&lt;/code&gt;): Lets the system decrypt secrets at boot automatically and make them available in &lt;code&gt;/run/secrets/&lt;/code&gt; without your intervention&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With both:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;System boots and decrypts secrets automatically (no passphrase needed)&lt;/li&gt;
&lt;li&gt;You can edit secrets locally without root&lt;/li&gt;
&lt;li&gt;Single secrets file works for both use cases&lt;/li&gt;
&lt;li&gt;Most flexible and practical approach&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Caveat:&lt;/strong&gt; If you ever rotate/regenerate your SSH host key (&lt;code&gt;/etc/ssh/ssh_host_ed25519_key&lt;/code&gt;), you must re-encrypt your secrets to the new host recipient, otherwise boot-time decryption will fail.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Create the secrets file at &lt;code&gt;~/nixos-dotfiles/secrets/secrets.yaml&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Create the secrets directory and open the encrypted editor&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/nixos-dotfiles
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; secrets
nix run nixpkgs#sops &lt;span class="nt"&gt;--&lt;/span&gt; secrets/secrets.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the editor opens, add this content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;EXA_API_KEY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your_actual_api_key_here"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save and exit. File is now encrypted.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verify it's encrypted:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;secrets/secrets.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll see encrypted gibberish (values start with &lt;code&gt;ENC[AES256_GCM...&lt;/code&gt;). This proves the secret is encrypted.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Only you can decrypt it&lt;/strong&gt; because you have the private key at &lt;code&gt;~/.config/sops/age/keys.txt&lt;/code&gt;. Without it, the file is useless to anyone else.&lt;/p&gt;

&lt;p&gt;To edit or view it again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nix run nixpkgs#sops &lt;span class="nt"&gt;--&lt;/span&gt; secrets/secrets.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only works because sops finds your private key and decrypts it automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Add sops-nix to flake.nix
&lt;/h2&gt;

&lt;p&gt;Add sops-nix to inputs and modules:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;inputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"github:nixos/nixpkgs/nixos-unstable"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;home-manager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"github:nix-community/home-manager"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;home-manager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;inputs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;follows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"nixpkgs"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;sops-nix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"github:Mic92/sops-nix"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nv"&gt;inputs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;follows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"nixpkgs"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nv"&gt;outputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;home-manager&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;sops-nix&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt;
    &lt;span class="nv"&gt;system&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"x86_64-linux"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kn"&gt;in&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;nixosConfigurations&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;nixos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;nixosSystem&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kn"&gt;inherit&lt;/span&gt; &lt;span class="nv"&gt;system&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nv"&gt;modules&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nv"&gt;sops-nix&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;nixosModules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;sops&lt;/span&gt;
        &lt;span class="sx"&gt;./configuration.nix&lt;/span&gt;
        &lt;span class="nv"&gt;home-manager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;nixosModules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;home-manager&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nv"&gt;home-manager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;useGlobalPkgs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="nv"&gt;home-manager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;useUserPackages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="nv"&gt;home-manager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;noor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;imports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
              &lt;span class="nv"&gt;sops-nix&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;homeManagerModules&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;sops&lt;/span&gt;
              &lt;span class="sx"&gt;./home.nix&lt;/span&gt;
            &lt;span class="p"&gt;];&lt;/span&gt;
          &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; Include &lt;code&gt;sops-nix.homeManagerModules.sops&lt;/code&gt; in home-manager imports so the &lt;code&gt;sops&lt;/code&gt; options are available in &lt;code&gt;home.nix&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7: Configure sops-nix in home.nix
&lt;/h2&gt;

&lt;p&gt;In &lt;code&gt;~/nixos-dotfiles/home.nix&lt;/code&gt;, add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;# sops-nix secret management&lt;/span&gt;
  &lt;span class="c"&gt;# Decrypt secrets and expose as environment variables&lt;/span&gt;
  &lt;span class="nv"&gt;sops&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;age&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;keyFile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;home&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;homeDirectory&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/.config/sops/age/keys.txt"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;sops&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;defaultSopsFile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sx"&gt;./secrets/secrets.yaml&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;sops&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;EXA_API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nv"&gt;home&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;sessionVariables&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;EXA_API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;sops&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;EXA_API_KEY&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;code&gt;EXA_API_KEY&lt;/code&gt; will contain the &lt;em&gt;path&lt;/em&gt; to the decrypted secret file (e.g., &lt;code&gt;/run/user/1000/secrets/EXA_API_KEY&lt;/code&gt;), not the key value itself. Use &lt;code&gt;cat $EXA_API_KEY&lt;/code&gt; to read the actual key. This is how sops-nix works: secrets are files, and programs that support reading secrets from file paths will work seamlessly.&lt;/p&gt;

&lt;p&gt;If a program expects the raw key value in &lt;code&gt;EXA_API_KEY&lt;/code&gt; (not a file path), you’ll need to either (a) configure that program to read from a file (some support &lt;code&gt;*_FILE&lt;/code&gt; patterns), or (b) wrap/launch it in a way that reads the file contents into an environment variable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; After rebuilding, close all existing terminal windows. The environment variables won't update in shells that were open before the rebuild. Open a fresh terminal to get the new variables.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7b: Enable sops in configuration.nix
&lt;/h2&gt;

&lt;p&gt;Also add this in &lt;code&gt;~/nixos-dotfiles/configuration.nix&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;sops&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;age&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;sshKeyPaths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"/etc/ssh/ssh_host_ed25519_key"&lt;/span&gt; &lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt; This is a system-level setting that tells the NixOS sops module which SSH key to use for decryption. It must go in &lt;code&gt;configuration.nix&lt;/code&gt; (NixOS-level), not &lt;code&gt;home.nix&lt;/code&gt;. The home-manager sops module uses its own &lt;code&gt;sops.age.keyFile&lt;/code&gt; (set in Step 7). This system-level setting is needed so the system's SSH host key can also decrypt the secrets, enabling decryption at boot without user interaction and supporting future system-level secrets if you add any.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 8: Rebuild NixOS
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nixos-rebuild switch &lt;span class="nt"&gt;--flake&lt;/span&gt; ~/nixos-dotfiles#nixos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 9: Reboot (or restart home-manager service)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Option A: Reboot&lt;/strong&gt; (simplest)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;reboot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Option B: Restart the service.&lt;/strong&gt; Don't remember this working for me though.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl &lt;span class="nt"&gt;--user&lt;/span&gt; daemon-reload
systemctl &lt;span class="nt"&gt;--user&lt;/span&gt; restart sops-nix.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Due to a known home-manager issue, the service may not auto-restart during &lt;code&gt;nixos-rebuild switch&lt;/code&gt; if it wasn't previously active.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 10: Test it works
&lt;/h2&gt;

&lt;p&gt;Open a fresh terminal and verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$EXA_API_KEY&lt;/span&gt;
&lt;span class="c"&gt;# Should print the path, e.g., /run/user/1000/secrets/EXA_API_KEY&lt;/span&gt;

&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="nv"&gt;$EXA_API_KEY&lt;/span&gt;
&lt;span class="c"&gt;# Should print your actual API key value&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Editing secrets later
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/nixos-dotfiles
nix run nixpkgs#sops &lt;span class="nt"&gt;--&lt;/span&gt; secrets/secrets.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit, save, commit, rebuild.&lt;/p&gt;

&lt;h2&gt;
  
  
  Git workflow
&lt;/h2&gt;

&lt;p&gt;Commit everything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add flake.nix configuration.nix home.nix .sops.yaml secrets/secrets.yaml
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add EXA_API_KEY secret with sops-nix"&lt;/span&gt;
git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your &lt;strong&gt;age private key&lt;/strong&gt; (&lt;code&gt;~/.config/sops/age/keys.txt&lt;/code&gt;) is &lt;strong&gt;never&lt;/strong&gt; committed. It lives outside the repo. The encrypted secrets file (&lt;code&gt;secrets/secrets.yaml&lt;/code&gt;) is safe to commit since it's useless without the private key.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;We set up &lt;strong&gt;sops-nix&lt;/strong&gt; so API keys can live in our git-tracked NixOS dotfiles without leaking:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Derived an age key&lt;/strong&gt; from our existing SSH key (&lt;code&gt;ssh-to-age&lt;/code&gt;), stored at &lt;code&gt;~/.config/sops/age/keys.txt&lt;/code&gt; (never committed)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configured &lt;code&gt;.sops.yaml&lt;/code&gt;&lt;/strong&gt; with two recipients: personal age key (for editing) and system SSH host key (for boot-time decryption)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Created an encrypted secrets file&lt;/strong&gt; (&lt;code&gt;secrets/secrets.yaml&lt;/code&gt;) using &lt;code&gt;sops&lt;/code&gt;, committed to git and only readable with the private key&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wired sops-nix into the flake&lt;/strong&gt;: NixOS module in &lt;code&gt;configuration.nix&lt;/code&gt;, Home Manager module in &lt;code&gt;home.nix&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exposed the secret as an env var&lt;/strong&gt; (&lt;code&gt;$EXA_API_KEY&lt;/code&gt;) pointing to the decrypted file path at &lt;code&gt;/run/user/1000/secrets/EXA_API_KEY&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The encrypted file is safe to push. The private key never leaves the machine. (In a feature article, I'll show to to leverage sops in a kubernetes cluster inside yaml files.)&lt;/p&gt;

</description>
      <category>nix</category>
      <category>sops</category>
      <category>gitops</category>
      <category>declarative</category>
    </item>
    <item>
      <title>Running Local AI with Flox and Ollama</title>
      <dc:creator>Noor Latif</dc:creator>
      <pubDate>Wed, 21 Jan 2026 11:00:31 +0000</pubDate>
      <link>https://dev.to/noorlatif/use-flox-for-quick-local-ai-inference-2bi2</link>
      <guid>https://dev.to/noorlatif/use-flox-for-quick-local-ai-inference-2bi2</guid>
      <description>&lt;p&gt;&lt;a href="https://flox.dev/" rel="noopener noreferrer"&gt;Flox&lt;/a&gt; released a guide on how and why you should &lt;a href="https://flox.dev/popular-packages/llms-in-your-project-with-ollama-flox/" rel="noopener noreferrer"&gt;use Flox to run Ollama&lt;/a&gt; and how it creates reproducible development environments that work the same on any machine. Without the overhead of containers and a Dockerfile build process. This guide is slightly different in that it simplifies the setup process to run a local AI model. Flox runs on Nix underneath. Some people say Nix is so efficient at isolated environments that they think Docker would never have been created if the inventors knew about Nix.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Flox
&lt;/h2&gt;

&lt;p&gt;The easy way with my &lt;a href="https://github.com/noor-latif/get-flox" rel="noopener noreferrer"&gt;community maintained installer&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sSf&lt;/span&gt; https://raw.githubusercontent.com/noor-latif/get-flox/refs/heads/main/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Set Up Your Environment
&lt;/h2&gt;

&lt;p&gt;Initialize Flox in a folder of your choice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flox init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install Python and Ollama:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flox &lt;span class="nb"&gt;install &lt;/span&gt;python3 ollama
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configure Ollama as a Service
&lt;/h2&gt;

&lt;p&gt;Edit your Flox environment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flox edit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add these configurations:&lt;/p&gt;

&lt;p&gt;Under &lt;code&gt;[services]&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;ollama.command&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"ollama serve"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Under &lt;code&gt;[vars]&lt;/code&gt; (to make the API accessible on your network):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;OLLAMA_HOST&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.0.0.0:11434"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Start Everything
&lt;/h2&gt;

&lt;p&gt;Activate Flox with services:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flox activate &lt;span class="nt"&gt;-s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;-s&lt;/code&gt; flag automatically starts services (like Ollama) when you enter the environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run an AI Model
&lt;/h2&gt;

&lt;p&gt;Deploy a lightweight model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama run tinyllama
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This starts an interactive chat. Press &lt;code&gt;Ctrl+D&lt;/code&gt; to exit. The model API remains available at &lt;code&gt;http://localhost:11434&lt;/code&gt; while the service is running.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verify Service Status
&lt;/h2&gt;

&lt;p&gt;Check if Ollama is running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flox services status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you need to manually stop/start:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flox services stop
flox services start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why This Works Better
&lt;/h2&gt;

&lt;p&gt;Flox handles the complexity automatically. When you exit the environment with &lt;code&gt;exit&lt;/code&gt;, Flox cleanly stops all services. No orphaned background processes to track down.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus: Auto-Activate with Direnv
&lt;/h2&gt;

&lt;p&gt;Tired of forgetting &lt;code&gt;flox activate&lt;/code&gt;? Install direnv to automatically activate environments when you &lt;code&gt;cd&lt;/code&gt; into project folders.&lt;/p&gt;

&lt;p&gt;Create a default environment and install direnv on the home folder level:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flox init &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;
flox &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt; direnv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add to your &lt;code&gt;~/.bashrc&lt;/code&gt; (or &lt;code&gt;~/.zshrc&lt;/code&gt; for zsh, etc...):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;flox activate &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;direnv hook bash&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="c"&gt;# bash or zsh/fish/tcsh/starship&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reload your shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source&lt;/span&gt; ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In any Flox project, create an &lt;code&gt;.envrc&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'use flox'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .envrc &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; direnv allow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the environment activates automatically when you enter the directory and deactivates when you leave.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://flox.dev" rel="noopener noreferrer"&gt;Flox Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ollama.com/search" rel="noopener noreferrer"&gt;Ollama Models&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>devops</category>
      <category>python</category>
      <category>ollama</category>
    </item>
    <item>
      <title>Run Rancher Desktop on Fedora Atomic Desktops (Toolbox Container Method)</title>
      <dc:creator>Noor Latif</dc:creator>
      <pubDate>Mon, 22 Dec 2025 11:49:32 +0000</pubDate>
      <link>https://dev.to/noorlatif/run-rancher-desktop-on-fedora-atomic-desktops-toolbox-container-method-9oi</link>
      <guid>https://dev.to/noorlatif/run-rancher-desktop-on-fedora-atomic-desktops-toolbox-container-method-9oi</guid>
      <description>&lt;p&gt;Complete guide for running Rancher Desktop GUI app on Fedora Atomic (Silverblue/Sway Atomic) using &lt;a href="https://docs.fedoraproject.org/en-US/fedora-silverblue/toolbox/" rel="noopener noreferrer"&gt;toolbox&lt;/a&gt; without rpm-ostree layering that can slow down system upgrades and clutter your system. &lt;br&gt;
Everything is installed into a toolbox container, leaving your main OS free from 3GB+ of rancher desktop clutter.&lt;br&gt;
If you don't have toolbox, you can easily install it using &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;sudo dnf install toolbox&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Step 1: Prepare: GPG Key and Pinentry Setup
&lt;/h2&gt;

&lt;p&gt;Preparation for installing rancher desktop according to official docs, with some quirk fixes for installing inside a toolbox container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;toolbox create rancher
toolbox enter rancher
sudo dnf install -y gnupg2 pinentry-curses pass
echo 'pinentry-program /usr/bin/pinentry-curses' &amp;gt; ~/.gnupg/gpg-agent.conf
gpg-connect-agent reloadagent /bye
pkill gpg-agent
gpg --generate-key  # Enter name and email, take Note key ID output
pass init &amp;lt;YOUR_KEY_ID_HERE&amp;gt;  # Replace with key from gpg output for pub key 
(something like E810C79064F7F543E517F1397DBD5336E1F45F32)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Host Sysctl Configuration
&lt;/h2&gt;

&lt;p&gt;Exit toolbox, run on host:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo sysctl -w net.ipv4.ip_unprivileged_port_start=80
echo 'net.ipv4.ip_unprivileged_port_start=80' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will enable port 80 usage by non-root apps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Install Rancher Desktop
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;toolbox enter rancher
sudo dnf config-manager addrepo --from-repofile=https://download.opensuse.org/repositories/isv:/Rancher:/stable/fedora/isv:Rancher:stable.repo
sudo dnf install rancher-desktop -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Launch and Configure
&lt;/h2&gt;

&lt;p&gt;Run this from inside your toolbox:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rancher-desktop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;GUI launches in your Fedora desktop environment&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 5: Verify Kubernetes Installation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;toolbox enter rancher
kubectl create deployment my-app --image=nginx --replicas=3
kubectl expose deployment my-app --port=80 --type=NodePort
kubectl get svc my-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note the NodePort (e.g., 31912)&lt;/strong&gt;, then test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl localhost:31912  # Replace 31912 with your NodePort
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Visit &lt;a href="http://localhost:31912" rel="noopener noreferrer"&gt;http://localhost:31912&lt;/a&gt; in your browser&lt;/strong&gt; to see nginx welcome page!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get pods
kubectl delete deployment my-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;NodePort access&lt;/strong&gt;: Rancher Desktop forwards NodePorts to localhost.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dashboard&lt;/strong&gt;: Open Rancher Desktop app &amp;gt; Cluster Dashboard button at bottom left.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frcexlaq2h7mhiaofrxee.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frcexlaq2h7mhiaofrxee.png" alt=" " width="529" height="297"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Optional step: Quickstart Aliases
&lt;/h2&gt;

&lt;p&gt;Add to &lt;code&gt;~/.bashrc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;rd&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'toolbox enter rancher'&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;rancher&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'toolbox run -c rancher rancher-desktop'&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;dc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'toolbox run -c rancher nerdctl'&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;k&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'toolbox run -c rancher kubectl'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To activate the changes, don't forget to run &lt;code&gt;source ~/.bashrc&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Good luck!&lt;/p&gt;

</description>
      <category>fedora</category>
      <category>kubernetes</category>
      <category>containers</category>
      <category>rancher</category>
    </item>
  </channel>
</rss>
