<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Github on homelab</title>
    <link>https://homelab.nbkelley.com/tags/github/</link>
    <description>Recent content in Github on homelab</description>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Fri, 01 May 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://homelab.nbkelley.com/tags/github/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Git Push Authentication</title>
      <link>https://homelab.nbkelley.com/docs/administration/git-push-authentication/</link>
      <pubDate>Fri, 01 May 2026 00:00:00 +0000</pubDate>
      <guid>https://homelab.nbkelley.com/docs/administration/git-push-authentication/</guid>
      <description>&lt;h1 id=&#34;git-push-authentication&#34;&gt;Git Push Authentication&lt;a class=&#34;anchor&#34; href=&#34;#git-push-authentication&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;h2 id=&#34;what-was-established&#34;&gt;What Was Established&lt;a class=&#34;anchor&#34; href=&#34;#what-was-established&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;GitHub deprecated password authentication for Git over HTTPS. Even if passwords worked previously, they are now rejected with &lt;code&gt;password not supported&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Personal Access Tokens (PAT) or SSH keys are required for authentication.&lt;/li&gt;&#xA;&lt;li&gt;403 Permission Denied errors typically indicate stale cached credentials or insufficient token scopes.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;key-decisions&#34;&gt;Key Decisions&lt;a class=&#34;anchor&#34; href=&#34;#key-decisions&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Use Personal Access Tokens (PAT) for HTTPS Git operations.&lt;/li&gt;&#xA;&lt;li&gt;Classic tokens require the &lt;code&gt;repo&lt;/code&gt; scope for private repositories.&lt;/li&gt;&#xA;&lt;li&gt;Fine-grained tokens require &lt;code&gt;Contents&lt;/code&gt; (Read and write) and &lt;code&gt;Metadata&lt;/code&gt; (Read) permissions, explicitly scoped to the target repository.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;current-configuration&#34;&gt;Current Configuration&lt;a class=&#34;anchor&#34; href=&#34;#current-configuration&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;GitHub Username&lt;/strong&gt;: &lt;code&gt;NK-Iluvatar&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Target Repository&lt;/strong&gt;: &lt;code&gt;MBTADashboard&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Remote URL&lt;/strong&gt;: &lt;code&gt;https://github.com/NK-Iluvatar/MBTADashboard.git&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;historical-notes&#34;&gt;Historical Notes&lt;a class=&#34;anchor&#34; href=&#34;#historical-notes&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Password Deprecation&lt;/strong&gt;: GitHub enforced its 2021 policy change retroactively, blocking account passwords for Git operations over HTTPS.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;403 Troubleshooting&lt;/strong&gt;: Resolved by clearing cached credentials (&lt;code&gt;git credential reject&lt;/code&gt; or OS credential manager) and verifying token scopes (&lt;code&gt;repo&lt;/code&gt; for classic, &lt;code&gt;Contents&lt;/code&gt; for fine-grained).&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Token Testing&lt;/strong&gt;: Verified token validity using &lt;code&gt;curl -H &amp;quot;Authorization: token TOKEN&amp;quot; https://api.github.com/user&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;open-questions&#34;&gt;Open Questions&lt;a class=&#34;anchor&#34; href=&#34;#open-questions&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;None.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;related-pages&#34;&gt;Related Pages&lt;a class=&#34;anchor&#34; href=&#34;#related-pages&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Git Pull Strategies&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://homelab.nbkelley.com/docs/services/homelab-dashboard/&#34;&gt;Homelab Dashboard&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;sources&#34;&gt;Sources&lt;a class=&#34;anchor&#34; href=&#34;#sources&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;DeepSeek conversation (2026-02-18) regarding &lt;code&gt;MBTADashboard&lt;/code&gt; push failures and PAT configuration.&lt;/li&gt;&#xA;&lt;/ul&gt;</description>
    </item>
    <item>
      <title>Git Push Authentication</title>
      <link>https://homelab.nbkelley.com/docs/development/git-push-authentication/</link>
      <pubDate>Fri, 01 May 2026 00:00:00 +0000</pubDate>
      <guid>https://homelab.nbkelley.com/docs/development/git-push-authentication/</guid>
      <description>&lt;h1 id=&#34;git-push-authentication&#34;&gt;Git Push Authentication&lt;a class=&#34;anchor&#34; href=&#34;#git-push-authentication&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;h2 id=&#34;what-was-established&#34;&gt;What Was Established&lt;a class=&#34;anchor&#34; href=&#34;#what-was-established&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;Patterns for resolving Git push authentication issues and handling divergent branches when working across multiple machines.&lt;/p&gt;&#xA;&lt;h2 id=&#34;key-decisions&#34;&gt;Key Decisions&lt;a class=&#34;anchor&#34; href=&#34;#key-decisions&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Multi-machine workflow&lt;/strong&gt;: Always &lt;code&gt;git pull&lt;/code&gt; before starting work; commit and push when done.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Divergent branch resolution&lt;/strong&gt;: When local and remote have diverged, use &lt;code&gt;git pull --no-rebase&lt;/code&gt; (merge) for safety or &lt;code&gt;git fetch origin &amp;amp;&amp;amp; git reset --hard origin/main&lt;/code&gt; to discard local commits for remote-only state.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;resolving-divergent-branches&#34;&gt;Resolving Divergent Branches&lt;a class=&#34;anchor&#34; href=&#34;#resolving-divergent-branches&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;h3 id=&#34;symptom&#34;&gt;Symptom&lt;a class=&#34;anchor&#34; href=&#34;#symptom&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;hint: You have divergent branches and need to specify how to reconcile them.&#xA;fatal: Need to specify how to reconcile divergent branches.&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;option-1-merge-preserves-both-histories&#34;&gt;Option 1: Merge (preserves both histories)&lt;a class=&#34;anchor&#34; href=&#34;#option-1-merge-preserves-both-histories&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git pull --no-rebase&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Or set as default:&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git config pull.rebase false&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;option-2-rebase-local-commits-on-top-of-remote&#34;&gt;Option 2: Rebase (local commits on top of remote)&lt;a class=&#34;anchor&#34; href=&#34;#option-2-rebase-local-commits-on-top-of-remote&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git pull --rebase&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Or set as default:&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git config pull.rebase true&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;option-3-discard-local-use-remote-only&#34;&gt;Option 3: Discard local, use remote only&lt;a class=&#34;anchor&#34; href=&#34;#option-3-discard-local-use-remote-only&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git fetch origin&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git reset --hard origin/main&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;option-4-fast-forward-only-fails-if-diverged&#34;&gt;Option 4: Fast-forward only (fails if diverged)&lt;a class=&#34;anchor&#34; href=&#34;#option-4-fast-forward-only-fails-if-diverged&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git pull --ff-only&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;multi-machine-workflow&#34;&gt;Multi-Machine Workflow&lt;a class=&#34;anchor&#34; href=&#34;#multi-machine-workflow&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;When working from multiple machines on the same repo:&lt;/p&gt;</description>
    </item>
    <item>
      <title>MBTA Dashboard - Setup</title>
      <link>https://homelab.nbkelley.com/docs/services/mbta-dashboard-setup/</link>
      <pubDate>Fri, 01 May 2026 00:00:00 +0000</pubDate>
      <guid>https://homelab.nbkelley.com/docs/services/mbta-dashboard-setup/</guid>
      <description>&lt;h1 id=&#34;mbta-dashboard---setup&#34;&gt;MBTA Dashboard - Setup&lt;a class=&#34;anchor&#34; href=&#34;#mbta-dashboard---setup&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;h2 id=&#34;what-was-established&#34;&gt;What Was Established&lt;a class=&#34;anchor&#34; href=&#34;#what-was-established&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;Office transit dashboard deployed on a self-hosted Debian VM (&lt;code&gt;PLT-MBTADisplay&lt;/code&gt;, &lt;code&gt;192.168.168.42&lt;/code&gt;). Nginx serves static files from &lt;code&gt;/var/www/MBTADisplay/public&lt;/code&gt; and proxies &lt;code&gt;/api/&lt;/code&gt; requests to a Node/Express caching proxy on port 3000. API keys are stored server-side and never exposed to the browser. Process managed via pm2 with a systemd service.&lt;/p&gt;&#xA;&lt;h2 id=&#34;architecture&#34;&gt;Architecture&lt;a class=&#34;anchor&#34; href=&#34;#architecture&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Browser (Anthias/Desktop)&#xA;    → Nginx (:80) → / → static files (/var/www/MBTADisplay/public)&#xA;                   → /api/ → Node/Express proxy (:3000)&#xA;                                → MBTA v3 API&#xA;                                → OpenWeatherMap API&#xA;                                → RSS feeds&#xA;                                → Caches responses&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;nginx-configuration&#34;&gt;Nginx Configuration&lt;a class=&#34;anchor&#34; href=&#34;#nginx-configuration&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;server {&#xA;    listen 80;&#xA;    server_name transit.intra.plgt.com 192.168.168.42;&#xA;&#xA;    root /var/www/MBTADisplay/public;&#xA;    index index.html;&#xA;&#xA;    location / {&#xA;        try_files $uri $uri/ =404;&#xA;    }&#xA;&#xA;    location /api/ {&#xA;        proxy_pass http://localhost:3000;&#xA;        proxy_http_version 1.1;&#xA;        proxy_set_header Host $host;&#xA;        proxy_set_header X-Real-IP $remote_addr;&#xA;    }&#xA;}&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;nodeexpress-proxy&#34;&gt;Node/Express Proxy&lt;a class=&#34;anchor&#34; href=&#34;#nodeexpress-proxy&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;h3 id=&#34;setup&#34;&gt;Setup&lt;a class=&#34;anchor&#34; href=&#34;#setup&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkdir -p /opt/mbta-proxy&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd /opt/mbta-proxy&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;npm init -y&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;npm install express node-fetch&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;api-key-management&#34;&gt;API Key Management&lt;a class=&#34;anchor&#34; href=&#34;#api-key-management&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;API keys stored in &lt;code&gt;/opt/mbta-proxy/.env&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Loaded via &lt;code&gt;process.env.MBTA_API_KEY&lt;/code&gt; in server.js&lt;/li&gt;&#xA;&lt;li&gt;pm2 started with &lt;code&gt;--env&lt;/code&gt; flag to load .env file&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Critical&lt;/strong&gt;: API key must survive server.js overwrites from GitHub syncs&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;pm2-process-manager&#34;&gt;pm2 Process Manager&lt;a class=&#34;anchor&#34; href=&#34;#pm2-process-manager&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pm2 start server.js --name mbta-proxy&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pm2 save&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;pm2 startup systemd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;systemd-service-etcsystemdsystempm2-administratorservice&#34;&gt;systemd Service (&lt;code&gt;/etc/systemd/system/pm2-administrator.service&lt;/code&gt;)&lt;a class=&#34;anchor&#34; href=&#34;#systemd-service-etcsystemdsystempm2-administratorservice&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[Unit]&#xA;Description=PM2 process manager&#xA;After=network.target&#xA;&#xA;[Service]&#xA;Type=forking&#xA;User=administrator&#xA;ExecStart=/usr/local/bin/pm2 resurrect&#xA;ExecReload=/usr/local/bin/pm2 reload all&#xA;ExecStop=/usr/local/bin/pm2 kill&#xA;Restart=on-failure&#xA;&#xA;[Install]&#xA;WantedBy=multi-user.target&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;github-deployment&#34;&gt;GitHub Deployment&lt;a class=&#34;anchor&#34; href=&#34;#github-deployment&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;h3 id=&#34;repository&#34;&gt;Repository&lt;a class=&#34;anchor&#34; href=&#34;#repository&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Repo: &lt;code&gt;https://github.com/bich-nguyen/MBTADisplay.git&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Cloned to &lt;code&gt;/var/www/MBTADisplay&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Static files in &lt;code&gt;public/&lt;/code&gt; subdirectory&lt;/li&gt;&#xA;&lt;li&gt;Server files in &lt;code&gt;/opt/mbta-proxy/&lt;/code&gt; (separate from web root)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;ownership&#34;&gt;Ownership&lt;a class=&#34;anchor&#34; href=&#34;#ownership&#34;&gt;#&lt;/a&gt;&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sudo chown -R administrator:administrator /var/www/MBTADisplay&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note: &lt;code&gt;www-data&lt;/code&gt; ownership breaks git operations from administrator user.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
