<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Macos on Carlos Vaz</title>
    <link>https://carlosvaz.com/tags/macos/</link>
    <description>Recent content in Macos on Carlos Vaz</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-US</language>
    <managingEditor>carlos@carjorvaz.com (Carlos Vaz)</managingEditor>
    <webMaster>carlos@carjorvaz.com (Carlos Vaz)</webMaster>
    <lastBuildDate>Mon, 21 Apr 2025 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://carlosvaz.com/tags/macos/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>NixOS Samba shares for macOS Time Machine</title>
      <link>https://carlosvaz.com/posts/nixos-samba-shares-for-macos-time-machine/</link>
      <pubDate>Mon, 21 Apr 2025 00:00:00 +0000</pubDate><author>carlos@carjorvaz.com (Carlos Vaz)</author>
      <guid>https://carlosvaz.com/posts/nixos-samba-shares-for-macos-time-machine/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been wanting to set up proper backups for my Mac for quite some time now.&#xA;Not only that, I also would like to take advantage of the storage space I have available on my home server to store and archive miscellaneous files, in a way that&amp;rsquo;s easily accessible from my Mac, properly integrated within finder but without having a copy of every file locally (as I would with Nextcloud sync, for example).&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I&rsquo;ve been wanting to set up proper backups for my Mac for quite some time now.
Not only that, I also would like to take advantage of the storage space I have available on my home server to store and archive miscellaneous files, in a way that&rsquo;s easily accessible from my Mac, properly integrated within finder but without having a copy of every file locally (as I would with Nextcloud sync, for example).</p>
<p>For backups, I was considering setting up borgmatic with its home-manager integration, so that it would also work on my Linux desktops.</p>
<p>But I later found that you can use macOS&rsquo;s native backups mechanism &ldquo;Time Machine&rdquo; with remote Samba shares, so I looked further into that, to have a better and more nicely integrated experience.
By setting up Samba on my home server, I could make a share for my time machine backups and another share for miscelleanous files, integrated within Finder.</p>
<p>So here&rsquo;s how I did it.</p>
<h2 id="setting-up-the-server">Setting up the server</h2>
<p>Following the NixOS wiki page, here&rsquo;s a basic setup for the Samba server:</p>





<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nix" data-lang="nix"><span style="display:flex;"><span>services <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>  samba <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    settings <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>      global <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;workgroup&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;WORKGROUP&#34;</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;server string&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;smbnix&#34;</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;netbios name&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;smbnix&#34;</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;security&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;user&#34;</span>;
</span></span><span style="display:flex;"><span>      };
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      <span style="color:#e6db74">&#34;my_share&#34;</span> <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;path&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;/home/john&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;valid users&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;john&#34;</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;force user&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;john&#34;</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;public&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;no&#34;</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;writeable&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;yes&#34;</span>;
</span></span><span style="display:flex;"><span>      };
</span></span><span style="display:flex;"><span>    };
</span></span><span style="display:flex;"><span>  };
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  samba-wsdd <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>    discovery <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>  };
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  avahi <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    publish<span style="color:#f92672">.</span>enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>    publish<span style="color:#f92672">.</span>userServices <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>    nssmdns4 <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>  };
</span></span><span style="display:flex;"><span>};</span></span></code></pre></div><p>With this, you should now be able to access the on Samba clients at <code>smb://&lt;ip_address&gt;/my_share</code>.
And the nice part is that Gnome Files, macOS Finder, and other applications can use this directly.</p>
<p>And here&rsquo;s my own setup, where I also add some options for better macOS compatibility, and declaratively set ownership of the shares&rsquo; directories on the server system:</p>





<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nix" data-lang="nix"><span style="display:flex;"><span><span style="color:#66d9ef">let</span>
</span></span><span style="display:flex;"><span>  user <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;samba&#34;</span>;
</span></span><span style="display:flex;"><span>  privatePath <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;/mnt/samba/private&#34;</span>;
</span></span><span style="display:flex;"><span>  tmPath <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;/mnt/samba/tm_share&#34;</span>;
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">in</span>
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>  <span style="color:#75715e"># https://wiki.nixos.org/wiki/Samba#Server_setup</span>
</span></span><span style="display:flex;"><span>  services <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    samba <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>      enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      settings <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>        global <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">&#34;workgroup&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;WORKGROUP&#34;</span>;
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">&#34;server string&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;smbnix&#34;</span>;
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">&#34;netbios name&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;smbnix&#34;</span>;
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">&#34;security&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;user&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>          <span style="color:#75715e"># Only available on localhost and Tailscale</span>
</span></span><span style="display:flex;"><span>          <span style="color:#75715e"># note: localhost is the ipv6 localhost ::1</span>
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">&#34;hosts allow&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;100.64.0.0/10 127.0.0.1 localhost&#34;</span>;
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">&#34;hosts deny&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;0.0.0.0/0&#34;</span>;
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">&#34;guest account&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;nobody&#34;</span>;
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">&#34;map to guest&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;bad user&#34;</span>;
</span></span><span style="display:flex;"><span>        };
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;private&#34;</span> <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">&#34;path&#34;</span> <span style="color:#f92672">=</span> privatePath;
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">&#34;valid users&#34;</span> <span style="color:#f92672">=</span> user;
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">&#34;public&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;no&#34;</span>;
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">&#34;writeable&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;yes&#34;</span>;
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">&#34;force user&#34;</span> <span style="color:#f92672">=</span> user;
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">&#34;fruit:aapl&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;yes&#34;</span>;
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">&#34;vfs objects&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;catia fruit streams_xattr&#34;</span>;
</span></span><span style="display:flex;"><span>        };
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;tm_share&#34;</span> <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">&#34;path&#34;</span> <span style="color:#f92672">=</span> tmPath;
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">&#34;valid users&#34;</span> <span style="color:#f92672">=</span> user;
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">&#34;public&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;no&#34;</span>;
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">&#34;writeable&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;yes&#34;</span>;
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">&#34;force user&#34;</span> <span style="color:#f92672">=</span> user;
</span></span><span style="display:flex;"><span>          <span style="color:#75715e"># Below are the most imporant for macOS compatibility</span>
</span></span><span style="display:flex;"><span>          <span style="color:#75715e"># Change the above to suit your needs</span>
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">&#34;fruit:aapl&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;yes&#34;</span>;
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">&#34;fruit:time machine&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;yes&#34;</span>;
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">&#34;vfs objects&#34;</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;catia fruit streams_xattr&#34;</span>;
</span></span><span style="display:flex;"><span>        };
</span></span><span style="display:flex;"><span>      };
</span></span><span style="display:flex;"><span>    };
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    samba-wsdd <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>      enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>      discovery <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>    };
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    avahi <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>      enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      publish<span style="color:#f92672">.</span>enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>      publish<span style="color:#f92672">.</span>userServices <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>      nssmdns4 <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      <span style="color:#75715e"># https://wiki.nixos.org/wiki/Samba#Apple_Time_Machine</span>
</span></span><span style="display:flex;"><span>      extraServiceFiles <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>        timemachine <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;&#39;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">          &lt;?xml version=&#34;1.0&#34; standalone=&#39;no&#39;?&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">          &lt;!DOCTYPE service-group SYSTEM &#34;avahi-service.dtd&#34;&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">          &lt;service-group&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">            &lt;name replace-wildcards=&#34;yes&#34;&gt;%h&lt;/name&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">            &lt;service&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">              &lt;type&gt;_smb._tcp&lt;/type&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">              &lt;port&gt;445&lt;/port&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">            &lt;/service&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">              &lt;service&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">              &lt;type&gt;_device-info._tcp&lt;/type&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">              &lt;port&gt;0&lt;/port&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">              &lt;txt-record&gt;model=TimeCapsule8,119&lt;/txt-record&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">            &lt;/service&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">            &lt;service&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">              &lt;type&gt;_adisk._tcp&lt;/type&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">              &lt;!--
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">                change tm_share to share name, if you changed it.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">              --&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">              &lt;txt-record&gt;dk0=adVN=tm_share,adVF=0x82&lt;/txt-record&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">              &lt;txt-record&gt;sys=waMa=0,adVF=0x100&lt;/txt-record&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">            &lt;/service&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">          &lt;/service-group&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">        &#39;&#39;</span>;
</span></span><span style="display:flex;"><span>      };
</span></span><span style="display:flex;"><span>    };
</span></span><span style="display:flex;"><span>  };
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  fileSystems<span style="color:#f92672">.</span><span style="color:#e6db74">&#34;</span><span style="color:#e6db74">${</span>privatePath<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span> <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    device <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;zsafe/samba&#34;</span>;
</span></span><span style="display:flex;"><span>    fsType <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;zfs&#34;</span>;
</span></span><span style="display:flex;"><span>    options <span style="color:#f92672">=</span> [ <span style="color:#e6db74">&#34;zfsutil&#34;</span> ];
</span></span><span style="display:flex;"><span>  };
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  fileSystems<span style="color:#f92672">.</span><span style="color:#e6db74">&#34;</span><span style="color:#e6db74">${</span>tmPath<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span> <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    device <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;zsafe/timemachine&#34;</span>;
</span></span><span style="display:flex;"><span>    fsType <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;zfs&#34;</span>;
</span></span><span style="display:flex;"><span>    options <span style="color:#f92672">=</span> [ <span style="color:#e6db74">&#34;zfsutil&#34;</span> ];
</span></span><span style="display:flex;"><span>  };
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e"># Set up password: https://wiki.nixos.org/wiki/Samba#User_Authentication</span>
</span></span><span style="display:flex;"><span>  users<span style="color:#f92672">.</span>users<span style="color:#f92672">.</span><span style="color:#e6db74">${</span>user<span style="color:#e6db74">}</span><span style="color:#f92672">.</span>isNormalUser <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e"># Share path must be owned by the respective unix user. (e.g. ❯ chown -R samba: /samba)</span>
</span></span><span style="display:flex;"><span>  systemd<span style="color:#f92672">.</span>tmpfiles<span style="color:#f92672">.</span>rules <span style="color:#f92672">=</span> [
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;d </span><span style="color:#e6db74">${</span>privatePath<span style="color:#e6db74">}</span><span style="color:#e6db74"> 0755 </span><span style="color:#e6db74">${</span>user<span style="color:#e6db74">}</span><span style="color:#e6db74"> users&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;d </span><span style="color:#e6db74">${</span>tmPath<span style="color:#e6db74">}</span><span style="color:#e6db74"> 0755 </span><span style="color:#e6db74">${</span>user<span style="color:#e6db74">}</span><span style="color:#e6db74"> users&#34;</span>
</span></span><span style="display:flex;"><span>  ];
</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><p>In my setup, I also make it so that only devices in my Tailscale network can access the shares.
Unfortunately, I couldn&rsquo;t seem to connect to Samba shares using Tailscale&rsquo;s MagicDNS, so I had to fallback to using the server&rsquo;s Tailscale IP instead.</p>
<p>I also created a separate user just for this, as I would prefer not to connect directly as root.
Something that wasn&rsquo;t immediately obvious is that each Samba user needs to have a corresponding unix user on the host system and also that the directories must be accessible by that user.
So I also added systemd-tmpfiles rules to do that automatically.</p>
<p>To set the samba user&rsquo;s password: <code>sudo smbpasswd -a samba</code></p>
<p>This version also has a separate share just for Time Machine backups.
To set that up, first connect through Finder &gt; Go &gt; Connect to Server (CMD + K) &gt; <code>smb://&lt;ip_address&gt;/tm_share</code> and connect with the Samba user and its samba password.</p>
<p>Finally, this should now show up as an available backup disk in Time Machine settings.
Here, I set up a more or less arbitrary quota of 1TB (which you can&rsquo;t seem to easily change later) and also enabled encryption.
After that, Time Machine should be set up and you can now use the fancy interface to show the contents of a directory in the past and restore files (and also just fully restore on freshly set up Mac).</p>
<p>Some little tricks that weren&rsquo;t immediately obvious were how to pin a Samba folder to Finder&rsquo;s sidebar and Time Machine complaining that it lost access to the share (because I became offline and/or suspended the computer).</p>
<p>To pin the folder to Finder&rsquo;s sidebar, open a terminal and do <code>open /Volumes/&lt;share_name&gt;</code> after mounting it through Finder as described above.
Now, on Finder &gt; View &gt; Show Path Bar (CMD + OPT + P) and drag the icon next to the share&rsquo;s name to the Sidebar.</p>
<p>After becoming offline, accessing (and therefore mounting) the share didnt&rsquo; seem to be enough.
I still quite haven&rsquo;t figured out how to recover reliably, but manually opening the share and mounting/opening its Sparse Bundle file seems to allow Time Machine to be able to see it again.</p>
<h2 id="closing-remarks">Closing remarks</h2>
<p>I&rsquo;m happy that after some configuration and troubleshooting, all appears to be working smoothly.</p>
<p>It seems that time machine backups are basically APFS snapshots, which themselves seem to be analagous to ZFS snapshots.
So I&rsquo;m happy that, in a way, my setup is similar to having automatic snapshots on my Mac and then sending them encrypted to some remote server, as I&rsquo;ve been meaning to do on my remaining NixOS servers with a Sanoid/Syncoid setup.</p>
<h2 id="references">References</h2>
<ul>
<li><a href="https://wiki.nixos.org/wiki/Samba">https://wiki.nixos.org/wiki/Samba</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>Local LLMs with llama.cpp and Open WebUI</title>
      <link>https://carlosvaz.com/posts/local-llms-with-llama-cpp-and-open-webui/</link>
      <pubDate>Sat, 08 Mar 2025 00:00:00 +0000</pubDate><author>carlos@carjorvaz.com (Carlos Vaz)</author>
      <guid>https://carlosvaz.com/posts/local-llms-with-llama-cpp-and-open-webui/</guid>
      <description>&lt;p&gt;Running DeepSeek and other LLMs locally has become very trendy recently.&#xA;However, I found that sometimes it wasn&amp;rsquo;t obvious on how to set up and run these locally, so I&amp;rsquo;m sharing my current setup in this blog post.&lt;/p&gt;&#xA;&lt;p&gt;A popular approach seems to be just using Ollama or LM Studio but I&amp;rsquo;d like to avoid both.&#xA;I&amp;rsquo;ve been getting a bad impresison of Ollama for multiple reasons, such as their use of misleading names and tags for the models, and seemingly leveraging llama.cpp without giving proper credit.&#xA;As for LM Studio, I&amp;rsquo;m mainly avoiding it because it isn&amp;rsquo;t free software.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Running DeepSeek and other LLMs locally has become very trendy recently.
However, I found that sometimes it wasn&rsquo;t obvious on how to set up and run these locally, so I&rsquo;m sharing my current setup in this blog post.</p>
<p>A popular approach seems to be just using Ollama or LM Studio but I&rsquo;d like to avoid both.
I&rsquo;ve been getting a bad impresison of Ollama for multiple reasons, such as their use of misleading names and tags for the models, and seemingly leveraging llama.cpp without giving proper credit.
As for LM Studio, I&rsquo;m mainly avoiding it because it isn&rsquo;t free software.</p>
<p>This post while focus on llama.cpp and Open WebUI.
The instructions are tailored to Homebrew on macOS but I believe it should work mostly the same in Linux, just with different ways of installing the tools.</p>
<h2 id="setting-up-docker">Setting up Docker</h2>
<p>Because, as of March 2025, I&rsquo;m unable to use the <code>open-webui</code> package from Nix, we&rsquo;ll be using Docker for that.</p>
<p>Docker Desktop on macOS seems to be having some issues lately, so I took the chance to try out colima for a leaner setup.
We can install it like so:</p>





<pre tabindex="0"><code class="language-nil" data-lang="nil">brew install colima docker</code></pre><p>After that, we can just do:</p>





<pre tabindex="0"><code class="language-nil" data-lang="nil">colima start</code></pre><p>And the <code>docker</code> command will work as expected.</p>
<h2 id="installing-llama-dot-cpp">Installing llama.cpp</h2>
<p>To run the model, we&rsquo;ll be using llama.cpp, a leading open-source project for running LLMs locally.</p>
<p>Again, we can install it with Homebrew:</p>





<pre tabindex="0"><code class="language-nil" data-lang="nil">brew install llama.cpp</code></pre><h2 id="running-a-model">Running a model</h2>
<p>For a more minimalist setup, it is possible to run the model with <code>llama-cli</code> from llama.cpp and interact with it directly in the terminal.</p>
<p>However, I&rsquo;ll show you how to run the model with <code>llama-server</code> so that it hosts an API to connect with Open WebUI, where we&rsquo;ll have niceties like conversation history.</p>
<p>For example, here&rsquo;s how we can run the freshly released Qwen QwQ model:</p>





<pre tabindex="0"><code class="language-nil" data-lang="nil">llama-server \
    -hf bartowski/Qwen_QwQ-32B-GGUF:q4_k_m \
    --host 127.0.0.1 \
    --port 10000</code></pre><p>I haven&rsquo;t found this <code>-hf</code> flag mentioned very often but I find it useful to have llama.cpp download the model directly from Hugging Face.
If at a later point you wish to move or delete these models, on macOS they&rsquo;re stored at <code>~/Library/Caches/llama.cpp</code>.</p>
<p>From my (superficial) research, the <code>Q4_K_M</code> level of quantization seems to provide a nice balance of small size while keeping decent results.
I tend to search for models in the form of GGUFs by <code>bartowski</code> on Hugging Face.
On my MacBook Pro 14 M1 Pro with 32GB of RAM, I find models of size 32B with Q4_K_M quantization to be the sweet spot.</p>
<p>There&rsquo;s also lots of room for exploration and tuning with llama.cpp&rsquo;s other flags and parameters.
However, because I currently don&rsquo;t really know what those do, I prefer to keep them to their default values.</p>
<h2 id="running-open-webui">Running Open WebUI</h2>
<p>Finally, to interact with the model, we&rsquo;ll use Open WebUI.</p>
<p>We can launch it like this:</p>





<pre tabindex="0"><code class="language-nil" data-lang="nil">docker run --pull=always --rm -p 3000:8080 -e WEBUI_AUTH=False -v ~/Documents/open-webui:/app/backend/data --name open-webui ghcr.io/open-webui/open-webui:main</code></pre><p>This will launch an Open WebUI instance, without logins, accessible on <code>localhost:3000</code> in a Web Browser.
Stateful data is kept in  the <code>~/Documents/open-webui</code> directory.</p>
<p>Opening up <code>localhost:3000</code> on your Web Browser of choice will now leave you with the Open WebUI interface.
All that&rsquo;s left to do is to connect it to the llama.cpp we left running:</p>
<ol>
<li>Admin Settings</li>
<li>Connections &gt; OpenAI Connections</li>
<li>Add Connection:
<ul>
<li>URL: <a href="http://host.docker.internal:10000/v1">http://host.docker.internal:10000/v1</a></li>
<li>API Key: none</li>
</ul>
</li>
</ol>
<p>And now you should be able to start a new chat with the model.
I find it sometimes takes a while to &ldquo;warm up&rdquo; but then it starts giving faster responses.</p>
<h2 id="closing-thoughts">Closing thoughts</h2>
<p>Very exciting times ahead in the local LLM space.
It seems that while state of the art commercial models are plateauing, open-source models are increasingly achieving better performance at smaller sizes.
A world where everyone is able to run excellent models on their own computers is rapidly approaching.</p>
<p>I&rsquo;m definitely instered in digging further.\
I&rsquo;d like to try out mlx models instead of GGUFs on llama.cpp, to see if I can get faster speed out of my MacBook.
It would also be interesting to see if it is possible to setup a local SearxNG instance for setting up Web Search on Open WebUI.
Finally, I&rsquo;d like to check out tools like aider and tabby for local code assistance and completion.</p>
<h2 id="references">References</h2>
<ul>
<li><a href="https://docs.openwebui.com/">https://docs.openwebui.com/</a></li>
<li><a href="https://docs.openwebui.com/tutorials/integrations/llm-providers/deepseekr1-dynamic/#step-5-connect-llamacpp-to-open-webui">https://docs.openwebui.com/tutorials/integrations/llm-providers/deepseekr1-dynamic/#step-5-connect-llamacpp-to-open-webui</a></li>
<li><a href="https://unsloth.ai/blog/deepseekr1-dynamic#running%20r1">https://unsloth.ai/blog/deepseekr1-dynamic#running%20r1</a></li>
<li><a href="https://reddit.com/r/localllama">https://reddit.com/r/localllama</a></li>
<li><a href="https://github.com/ggml-org/llama.cpp">https://github.com/ggml-org/llama.cpp</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>Declarative macOS management with nix-darwin and home-manager</title>
      <link>https://carlosvaz.com/posts/declarative-macos-management-with-nix-darwin-and-home-manager/</link>
      <pubDate>Sun, 05 May 2024 00:00:00 +0000</pubDate><author>carlos@carjorvaz.com (Carlos Vaz)</author>
      <guid>https://carlosvaz.com/posts/declarative-macos-management-with-nix-darwin-and-home-manager/</guid>
      <description>&lt;p&gt;For the past year, I&amp;rsquo;ve been daily driving the M1 Macbook Air with 8GB of RAM and 240GB of storage.&#xA;Most of my life I&amp;rsquo;ve mostly been an Apple skeptic but this laptop changed my views in some aspects.&lt;/p&gt;&#xA;&lt;p&gt;But having just come from NixOS, I was missing that declarative mindset in being able to manage my system from a single file.&#xA;Luckily, with nix-darwin and home-manager I was able to get my system mostly declarative, at least declarative enough for my needs.&#xA;This also allowed to manage the Mac with my existing NixOS flake, so I could reuse existing configurations, like my zsh home-manager configuration.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>For the past year, I&rsquo;ve been daily driving the M1 Macbook Air with 8GB of RAM and 240GB of storage.
Most of my life I&rsquo;ve mostly been an Apple skeptic but this laptop changed my views in some aspects.</p>
<p>But having just come from NixOS, I was missing that declarative mindset in being able to manage my system from a single file.
Luckily, with nix-darwin and home-manager I was able to get my system mostly declarative, at least declarative enough for my needs.
This also allowed to manage the Mac with my existing NixOS flake, so I could reuse existing configurations, like my zsh home-manager configuration.</p>
<h2 id="installation">Installation</h2>
<p>Starting from a fresh macOS installation, this is how I bootstrapped my nix-darwin configuration:</p>
<ol>
<li>
<p>Install Nix:</p>





<pre tabindex="0"><code class="language-nil" data-lang="nil">curl -L https://nixos.org/nix/install | sh</code></pre><p>For this step, you could also try to use the <a href="https://github.com/DeterminateSystems/nix-installer">Determinate Systems nix-installer</a>, which I&rsquo;ve read good things about, although the official installer also worked just fine.</p>
</li>
<li>
<p>Enable flakes:</p>





<pre tabindex="0"><code class="language-nil" data-lang="nil">mkdir -p ~/.config/nix
cat &lt;&lt;EOF &gt; ~/.config/nix/nix.conf
experimental-features = nix-command flakes
EOF</code></pre></li>
<li>
<p>Use nix run to run the first rebuild:</p>





<pre tabindex="0"><code class="language-nil" data-lang="nil">nix run nix-darwin -- switch --flake &lt;path_to_nix_darwin_configuration&gt;</code></pre></li>
<li>
<p>Use darwin-rebuild normally:</p>





<pre tabindex="0"><code class="language-nil" data-lang="nil">darwin-rebuild switch --flake &lt;path_to_nix_darwin_configuration&gt;</code></pre></li>
</ol>
<h2 id="declarative-homebrew-package-management">Declarative Homebrew package management</h2>
<p>One of the key reasons for using nix-darwin is not only access to the nix package manager, but being able to use Homebrew declaratively.</p>
<p>Homebrew is the de facto package manager for macOS.
Most programs you can think are available over there, especially CLI tools but also GUI apps in the form of casks.</p>
<p>So we would very much like to keep access to those apps, only adding declarativeness to the workflow.</p>
<p>Another reason for using Homebrew is simply because nixpkgs cannot yet replace it, especially when it comes to GUI apps.
Some could say that this will never happen because it&rsquo;s out of scope of the nixpkgs project, which I guess is reasonable.</p>
<p>To use Homebrew, we first have to <a href="https://brew.sh/">install it manually</a>:</p>





<pre tabindex="0"><code class="language-nil" data-lang="nil">$ /bin/bash -c &#34;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)&#34;</code></pre><p>After that, we can use the <code>homebrew</code> module from nix-darwin, like the following example:</p>





<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nix" data-lang="nix"><span style="display:flex;"><span><span style="color:#75715e"># I&#39;d rather not have telemetry on my package manager.</span>
</span></span><span style="display:flex;"><span>environment<span style="color:#f92672">.</span>variables<span style="color:#f92672">.</span>HOMEBREW_NO_ANALYTICS <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;1&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>homebrew <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>  enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  onActivation <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    autoUpdate <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>    cleanup <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;zap&#34;</span>;
</span></span><span style="display:flex;"><span>    upgrade <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>  };
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  brews <span style="color:#f92672">=</span> [
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;coreutils&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;direnv&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;fd&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;gcc&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;git&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;grep&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;ripgrep&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;trash&#34;</span>
</span></span><span style="display:flex;"><span>  ];
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e"># Update these applicatons manually.</span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e"># As brew would update them by unninstalling and installing the newest</span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e"># version, it could lead to data loss.</span>
</span></span><span style="display:flex;"><span>  casks <span style="color:#f92672">=</span> [
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;docker&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;emacs-mac&#34;</span> <span style="color:#75715e"># Emacs fork with better macOS support</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;firefox&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;iterm2&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;monitorcontrol&#34;</span> <span style="color:#75715e"># Brightness and volume controls for external monitors.</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;ukelele&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;unnaturalscrollwheels&#34;</span> <span style="color:#75715e"># Enable natural scrolling in the trackpad but regular scroll on an external mouse</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;utm&#34;</span> <span style="color:#75715e"># Virtual Machine Manager</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;visual-studio-code&#34;</span>
</span></span><span style="display:flex;"><span>  ];
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  taps <span style="color:#f92672">=</span> [
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;railwaycat/emacsmacport&#34;</span> <span style="color:#75715e"># emacs-mac</span>
</span></span><span style="display:flex;"><span>  ];
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  masApps <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    Tailscale <span style="color:#f92672">=</span> <span style="color:#ae81ff">1475387142</span>; <span style="color:#75715e"># App Store URL id</span>
</span></span><span style="display:flex;"><span>  };
</span></span><span style="display:flex;"><span>};</span></span></code></pre></div><p>One of the most important features in managing packages this way is that <em>removing</em> packages from the configuration above also uninstalls them, which is one of the big features I was missing from NixOS.
This avoids the traditional buildup of unused and forgotten packages in the system.</p>
<p>You supposedly can also use this to manage App Store apps but I found that I always needed to manually install them first (so they could be registered to my account?), so it wasn&rsquo;t as useful.</p>
<h2 id="other-noteworthy-options">Other noteworthy options</h2>
<p>The <a href="https://daiderd.com/nix-darwin/manual/index.html">list of options is quite extensive</a>, here are some that I found useful:</p>
<h3 id="nix-management">Nix management</h3>





<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nix" data-lang="nix"><span style="display:flex;"><span><span style="color:#75715e"># Auto upgrade nix package and the daemon service.</span>
</span></span><span style="display:flex;"><span>services<span style="color:#f92672">.</span>nix-daemon<span style="color:#f92672">.</span>enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>nix <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>  package <span style="color:#f92672">=</span> pkgs<span style="color:#f92672">.</span>nix;
</span></span><span style="display:flex;"><span>  gc<span style="color:#f92672">.</span>automatic <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>  optimise<span style="color:#f92672">.</span>automatic <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>  settings <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    auto-optimise-store <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>    experimental-features <span style="color:#f92672">=</span> [ <span style="color:#e6db74">&#34;nix-command&#34;</span> <span style="color:#e6db74">&#34;flakes&#34;</span> ];
</span></span><span style="display:flex;"><span>  };
</span></span><span style="display:flex;"><span>};</span></span></code></pre></div><h3 id="sudo-with-touch-id"><code>sudo</code> with Touch ID</h3>
<p>Just like when macOS asks for elevated privileges, this makes <code>sudo</code> also work with Touch ID, which I find quite ergonomic:</p>





<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nix" data-lang="nix"><span style="display:flex;"><span>security<span style="color:#f92672">.</span>pam<span style="color:#f92672">.</span>enableSudoTouchIdAuth <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;</span></span></code></pre></div><h3 id="keyboard-tweaks">Keyboard tweaks</h3>
<p>These are some keyboard tweaks like turning caps lock into ctrl and disabling press and hold for diacritics:</p>





<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nix" data-lang="nix"><span style="display:flex;"><span>system<span style="color:#f92672">.</span>keyboard<span style="color:#f92672">.</span>enableKeyMapping <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>system<span style="color:#f92672">.</span>keyboard<span style="color:#f92672">.</span>remapCapsLockToControl <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Disable press and hold for diacritics.</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># I want to be able to press and hold j and k</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># in VSCode with vim keys to move around.</span>
</span></span><span style="display:flex;"><span>system<span style="color:#f92672">.</span>defaults<span style="color:#f92672">.</span>NSGlobalDomain<span style="color:#f92672">.</span>ApplePressAndHoldEnabled <span style="color:#f92672">=</span> <span style="color:#66d9ef">false</span>;</span></span></code></pre></div><h2 id="simple-nix-darwin-flake">Simple nix-darwin flake</h2>
<p>Flakes are all the rage right now but they can be daunting to new users.</p>
<p>Here&rsquo;s a simple nix-darwin flake to get you started, which also makes it easy to use home-manager:</p>
<p><code>flake.nix</code>:</p>





<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nix" data-lang="nix"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>  inputs <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    nixpkgs<span style="color:#f92672">.</span>url <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;github:nixos/nixpkgs/nixos-23.11&#34;</span>;
</span></span><span style="display:flex;"><span>    nixpkgs-darwin<span style="color:#f92672">.</span>url <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;github:NixOS/nixpkgs/nixpkgs-23.11-darwin&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    nix-darwin<span style="color:#f92672">.</span>url <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;github:LnL7/nix-darwin/master&#34;</span>;
</span></span><span style="display:flex;"><span>    nix-darwin<span style="color:#f92672">.</span>inputs<span style="color:#f92672">.</span>nixpkgs<span style="color:#f92672">.</span>follows <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;nixpkgs-darwin&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    home-manager<span style="color:#f92672">.</span>url <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;github:nix-community/home-manager/release-23.11&#34;</span>;
</span></span><span style="display:flex;"><span>    home-manager<span style="color:#f92672">.</span>inputs<span style="color:#f92672">.</span>nixpkgs<span style="color:#f92672">.</span>follows <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;nixpkgs&#34;</span>;
</span></span><span style="display:flex;"><span>  };
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  outputs <span style="color:#f92672">=</span> { self<span style="color:#f92672">,</span> <span style="color:#f92672">...</span> }<span style="color:#f92672">@</span>inputs:
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>      darwinConfigurations<span style="color:#f92672">.</span><span style="color:#e6db74">&#34;&lt;hostname&gt;&#34;</span> <span style="color:#f92672">=</span> inputs<span style="color:#f92672">.</span>nix-darwin<span style="color:#f92672">.</span>lib<span style="color:#f92672">.</span>darwinSystem {
</span></span><span style="display:flex;"><span>        system <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;aarch64-darwin&#34;</span>;
</span></span><span style="display:flex;"><span>        specialArgs <span style="color:#f92672">=</span> { <span style="color:#66d9ef">inherit</span> inputs self; };
</span></span><span style="display:flex;"><span>        modules <span style="color:#f92672">=</span> [
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">./hosts/mac.nix</span>
</span></span><span style="display:flex;"><span>          inputs<span style="color:#f92672">.</span>home-manager<span style="color:#f92672">.</span>darwinModules<span style="color:#f92672">.</span>home-manager
</span></span><span style="display:flex;"><span>          {
</span></span><span style="display:flex;"><span>            home-manager<span style="color:#f92672">.</span>useGlobalPkgs <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>            home-manager<span style="color:#f92672">.</span>useUserPackages <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>          }
</span></span><span style="display:flex;"><span>        ];
</span></span><span style="display:flex;"><span>      };
</span></span><span style="display:flex;"><span>    };
</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><p>Where <code>./hosts/mac.nix</code> would be your nix-darwin configuration file, with the previous snippets.</p>
<h3 id="home-manager">home-manager</h3>
<p>Now, we can use home-manager in our configuration.</p>
<p>Here are some examples:</p>





<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nix" data-lang="nix"><span style="display:flex;"><span><span style="color:#75715e"># Import existing home-manager configuration</span>
</span></span><span style="display:flex;"><span>imports <span style="color:#f92672">=</span> [ <span style="color:#e6db74">&#34;</span><span style="color:#e6db74">${</span>self<span style="color:#e6db74">}</span><span style="color:#e6db74">/profiles/home/zsh.nix&#34;</span> ];
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Required by home-manager.</span>
</span></span><span style="display:flex;"><span>users<span style="color:#f92672">.</span>users<span style="color:#f92672">.</span>john<span style="color:#f92672">.</span>home <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;/Users/john&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>home-manager<span style="color:#f92672">.</span>users<span style="color:#f92672">.</span>john <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    programs <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>      zsh <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>        enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>        autocd <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>        defaultKeymap <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;emacs&#34;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        enableCompletion <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>        enableVteIntegration <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>        enableAutosuggestions <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>        syntaxHighlighting<span style="color:#f92672">.</span>enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        history <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>          expireDuplicatesFirst <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>          extended <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>          ignoreDups <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>        };
</span></span><span style="display:flex;"><span>      };
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      direnv <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>        enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>        nix-direnv<span style="color:#f92672">.</span>enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>      };
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      dircolors<span style="color:#f92672">.</span>enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>      fzf<span style="color:#f92672">.</span>enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>      starship<span style="color:#f92672">.</span>enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>      zoxide<span style="color:#f92672">.</span>enable <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      initExtra <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;&#39;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">        # Enable iTerm2 shell integration.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">        test -e &#34;~/.iterm2_shell_integration.zsh&#34; &amp;&amp; source &#34;~/.iterm2_shell_integration.zsh&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">      &#39;&#39;</span>;
</span></span><span style="display:flex;"><span>    };
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  home<span style="color:#f92672">.</span>stateVersion <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;23.11&#34;</span>;
</span></span><span style="display:flex;"><span>};</span></span></code></pre></div><p>This allows you to consolidate your dispersed dotfiles into a single source of truth, the nix-darwin config file.
To find options for other programs home-manager supports, I found the (unofficial?) <a href="https://home-manager-options.extranix.com/">home manager options search</a> quite useful.</p>
<p>I believe you can also use the <code>home.file</code> options to write to arbitrary files in your home directory.</p>
<h2 id="closing-remarks">Closing remarks</h2>
<p>This experience turned the macOS experience much more tolerable.</p>
<p>And it really is true: Apple Silicon is game-changing.
Compared to the ThinkPads I was used to, the MacBook had a great screen (brightness, color and HiDPI, although I would skip the glossy finish), great speakers, was way faster, and didn&rsquo;t heat up even though it&rsquo;s passively cooled, which also means that there&rsquo;s no fan noise.</p>
<p>I managed to buy this one used for 550€, which is probably the best deal for a laptop in mid-2024 for most people.
But despite all of that, there&rsquo;s a dealbreaker: the keyboard was starting to give me symptoms of RSI, just like <a href="https://fortintam.com/blog/apple-aluminium-keyboard-and-repetitive-strain-injury-rsi/">this anecdote</a>.
My experience was pretty much the same and now that I&rsquo;ve stopped using it, my hands feel much better.
I really can&rsquo;t justify using the laptop if that has implications on my physical health.</p>
<p>Also, even though I really tried, I didn&rsquo;t find macOS window management very ergonomic.
Full-screen apps being workspaces, the workspaces shuffling around chaotically (most recently used? but only if you click the app from the dock?), having to swipe around looking for what I wanted or always having to go to Mission Control.
I found it really confusing, perhaps because I&rsquo;m not the kind of user to always be using a single window at once.</p>
<p>I&rsquo;m aware that there are tiling window managers for macOS, some that even work without disable System Integrity Protection, but by that point: why even use macOS if you&rsquo;re not using like it was designed?</p>
<p>But if you dislike macOS but tolerate the keyboard, then an Apple Silicon Macbook is probably one of the greatest Linux laptops I&rsquo;ve ever used, but I&rsquo;ll leave that to a future blog post.</p>
<p>Finally, Apple has some questionable practices, although they&rsquo;re mostly hardware-related instead of software-related, which I do prefer, if I had to pick my poison from the selection of behaviours of big tech companies.
What I mean by this is that, until now, Apple&rsquo;s software although proprietary, (seems to) respect user privacy, doesn&rsquo;t fill available screen space with ads and doesn&rsquo;t force updates on its users while they&rsquo;re working.</p>
<p>The reason for this seems to be that Apple&rsquo;s business model is selling expensive hardware, so they don&rsquo;t need to monetize their software as much as other companies.
This also means that, if you&rsquo;re buying new, you&rsquo;ll have to pay 200€ for 8GB RAM upgrade increments and 200€ for a 240GB SSD storage increment, because they&rsquo;re both soldered in.
You can avoid falling into the scam by only buying the base models, which will make the most out of your money, or by buying used.
The problem is: I also found 8GB way too restricting, I&rsquo;d really recommend going for 16GB minimum.
I managed to make the experience a bit better by using <a href="https://github.com/rNeomy/auto-tab-discard">Auto Tab Discard</a> in Firefox but I still seemed to be under intense memory pressure all the time.</p>
<p>Besides that, I felt no need to buy anything more recent than the M1 MacBook Air.
Not only that, it seems that the M1 MacBook Air is better than the M2 MacBook Air in some aspects, like having greater memory bandwidth and faster storage, because it has 2 NAND chips instead of just 1.</p>
<p>Bottom line is that despite Apple arguably running a hardware upgrade pricing scam, trying to lock you in to the walled garden/ecosystem and muffling down right to repair (while making their hardware harder to repair, especially by soldering in SSDs that do have a very finite lifespan), I find their laptops are really good, if you can tolerate the keyboards.</p>
<h2 id="references">References</h2>
<ul>
<li><a href="https://gist.github.com/jmatsushita/5c50ef14b4b96cb24ae5268dab613050">https://gist.github.com/jmatsushita/5c50ef14b4b96cb24ae5268dab613050</a></li>
<li><a href="https://github.com/LnL7/nix-darwin">https://github.com/LnL7/nix-darwin</a></li>
<li><a href="https://daiderd.com/nix-darwin/manual/index.html#sec-options">https://daiderd.com/nix-darwin/manual/index.html#sec-options</a></li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>US International (with AltGr dead-keys) on macOS</title>
      <link>https://carlosvaz.com/posts/us-international-with-altgr-dead-keys-on-macos/</link>
      <pubDate>Mon, 26 Feb 2024 00:00:00 +0000</pubDate><author>carlos@carjorvaz.com (Carlos Vaz)</author>
      <guid>https://carlosvaz.com/posts/us-international-with-altgr-dead-keys-on-macos/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve recently started using a MacBook Air M1 2020 as my main laptop.&#xA;Overall and to my surprise, it&amp;rsquo;s been a more or less pleasant experience.&lt;/p&gt;&#xA;&lt;p&gt;But the one thing I really missed from Linux was the US &lt;code&gt;altgr-intl&lt;/code&gt; variant keyboard layout, which simply is the US layout where you can make dead-keys (for diacritics and other special characters) by pressing the AltGr modifier beforehand.&lt;/p&gt;&#xA;&lt;p&gt;Apple only includes the regular US International layout by default, which I find painful to use, as it requires double tapping the keys to actually output them instead of only being dead-keys when pressed with a modifier.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I&rsquo;ve recently started using a MacBook Air M1 2020 as my main laptop.
Overall and to my surprise, it&rsquo;s been a more or less pleasant experience.</p>
<p>But the one thing I really missed from Linux was the US <code>altgr-intl</code> variant keyboard layout, which simply is the US layout where you can make dead-keys (for diacritics and other special characters) by pressing the AltGr modifier beforehand.</p>
<p>Apple only includes the regular US International layout by default, which I find painful to use, as it requires double tapping the keys to actually output them instead of only being dead-keys when pressed with a modifier.</p>
<p>Some other people have also felt this, but I was always missing something with their solutions:</p>
<p><a href="https://github.com/xv0x7c0/osx-us-altgr-intl">osx-us-altgr-intl</a> was working fine for the most apart, until I found out that Ctrl chords weren&rsquo;t working in <a href="https://github.com/railwaycat/homebrew-emacsmacport">emacs-macport</a> (but were otherwise working perfectly fine in regular emacs).
With <a href="https://software.sil.org/ukelele/">Ukelele</a>, I later found that the Ctrl layer was completely missing.</p>
<p>I also used <a href="https://altgr-weur.eu/macos.html">altgr-weur</a> for some time but my main gripe was that it makes my layouts inconsistent between Linux and macOS, which gets quite confusing.</p>
<p>Finally, I found this <a href="https://www.twam.info/hardware/us-international-on-os-x">blog post</a> with another attempt at altgr-intl for macOS.
However, this version was missing some dead-key layers.</p>
<p>So I took this last one as a base and added the dead key layers from osx-us-altgr-intl and it&rsquo;s working quite well.</p>
<p>Here&rsquo;s the <a href="https://github.com/carjorvaz/macos-us-altgr-intl">repo with the file</a> so others don&rsquo;t have to go through this as well.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
