<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <author>
    <name>Qugstart</name>
  </author>
  <generator uri="https://hexo.io/">Hexo</generator>
  <id>https://qugstart.com/</id>
  <link href="https://qugstart.com/" rel="alternate"/>
  <link href="https://qugstart.com/atom.xml" rel="self"/>
  <rights>All rights reserved 2026, Qugstart</rights>
  <subtitle>Practical engineering field notes</subtitle>
  <title>Qugstart</title>
  <updated>2026-04-03T09:00:00.000Z</updated>
  <entry>
    <author>
      <name>Qugstart</name>
    </author>
    <category term="ruby-and-rails" scheme="https://qugstart.com/categories/ruby-and-rails/"/>
    <category term="git" scheme="https://qugstart.com/tags/git/"/>
    <category term="remote" scheme="https://qugstart.com/tags/remote/"/>
    <category term="bare-repository" scheme="https://qugstart.com/tags/bare-repository/"/>
    <content>
      <![CDATA[<p>This guide shows how to create a remote Git repository from a local project and push it cleanly without origin confusion, permission failures, or missing branches. It is a practical step-by-step flow with setup, verification, error recovery, and post-push checks I have used repeatedly on Linux and Rails deployment projects. We will cover bare repository creation, remote wiring, first push behavior, permission fixes, and validation checks, then point to the <a href="/blog/git-and-svn/">Git and SVN hub</a> for next steps.</p><h2 id="When-this-workflow-is-the-right-fit"><a href="#When-this-workflow-is-the-right-fit" class="headerlink" title="When this workflow is the right fit"></a>When this workflow is the right fit</h2><p>Use this path when your code already exists locally and you need a shared remote now. Typical triggers:</p><ul><li>A solo project is becoming a team project.</li><li>A server-side repository is needed for deployment pulls.</li><li>You are replacing ad-hoc zip transfer habits with proper versioned collaboration.</li></ul><p>If your local folder is not a repository yet, initialize first and make a baseline commit.</p><h2 id="Step-1-Prepare-the-local-repository"><a href="#Step-1-Prepare-the-local-repository" class="headerlink" title="Step 1: Prepare the local repository"></a>Step 1: Prepare the local repository</h2><p>Confirm state before creating the remote. A clean starting point prevents accidental omissions.</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">git status</span><br><span class="line">git <span class="built_in">log</span> --oneline -n 5</span><br><span class="line">git branch -vv</span><br></pre></td></tr></table></figure><p>If there is no repository yet:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">git init</span><br><span class="line">git add .</span><br><span class="line">git commit -m <span class="string">&quot;Initial commit&quot;</span></span><br></pre></td></tr></table></figure><h2 id="Step-2-Create-a-bare-repository-on-the-remote-host"><a href="#Step-2-Create-a-bare-repository-on-the-remote-host" class="headerlink" title="Step 2: Create a bare repository on the remote host"></a>Step 2: Create a bare repository on the remote host</h2><p>A shared push target is usually a bare repository. Bare means no checked-out working tree, which prevents accidental edits on the remote endpoint. The official concept is documented in the Git documentation at <a href="https://git-scm.com/docs/git-init" rel="noopener">git-scm.com</a>.</p><p>On the target server:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">mkdir</span> -p /srv/git/project.git</span><br><span class="line"><span class="built_in">cd</span> /srv/git/project.git</span><br><span class="line">git init --bare</span><br></pre></td></tr></table></figure><p>Set directory ownership so your push user can write objects and refs.</p><h2 id="Step-3-Wire-the-remote-in-your-local-repository"><a href="#Step-3-Wire-the-remote-in-your-local-repository" class="headerlink" title="Step 3: Wire the remote in your local repository"></a>Step 3: Wire the remote in your local repository</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git remote add origin user@your-host:/srv/git/project.git</span><br><span class="line">git remote -v</span><br></pre></td></tr></table></figure><p>If <code>origin</code> already exists, inspect it. Do not blindly overwrite unless you intend to replace it.</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git remote set-url origin user@your-host:/srv/git/project.git</span><br></pre></td></tr></table></figure><h2 id="Step-4-Push-branches-intentionally"><a href="#Step-4-Push-branches-intentionally" class="headerlink" title="Step 4: Push branches intentionally"></a>Step 4: Push branches intentionally</h2><p>For first push, set upstream and send only the branch you want as the initial baseline.</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git push -u origin main</span><br></pre></td></tr></table></figure><p>If the repository uses <code>master</code> or a custom branch name, push that branch explicitly.</p><h2 id="Step-5-Verify-remote-state"><a href="#Step-5-Verify-remote-state" class="headerlink" title="Step 5: Verify remote state"></a>Step 5: Verify remote state</h2><p>On local:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git branch -vv</span><br><span class="line">git ls-remote --heads origin</span><br></pre></td></tr></table></figure><p>On remote:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> /srv/git/project.git</span><br><span class="line">git for-each-ref --format=<span class="string">&quot;%(refname:short) %(objectname:short)&quot;</span></span><br></pre></td></tr></table></figure><p>The branch hashes should match what you expect from local history.</p><h2 id="Common-errors-and-fast-recovery"><a href="#Common-errors-and-fast-recovery" class="headerlink" title="Common errors and fast recovery"></a>Common errors and fast recovery</h2><h3 id="Permission-denied-publickey"><a href="#Permission-denied-publickey" class="headerlink" title="Permission denied (publickey)"></a><code>Permission denied (publickey)</code></h3><p>Check SSH key presence, <code>authorized_keys</code>, and file permissions in the remote user account.</p><h3 id="remote-fatal-unable-to-create-temporary-object-directory"><a href="#remote-fatal-unable-to-create-temporary-object-directory" class="headerlink" title="remote: fatal: unable to create temporary object directory"></a><code>remote: fatal: unable to create temporary object directory</code></h3><p>Ownership on the bare repo path is wrong. Fix owner and group, then retry push.</p><h3 id="src-refspec-main-does-not-match-any"><a href="#src-refspec-main-does-not-match-any" class="headerlink" title="src refspec main does not match any"></a><code>src refspec main does not match any</code></h3><p>No commit exists on that branch yet, or you are using a different branch name.</p><h3 id="Push-rejected-due-to-non-fast-forward"><a href="#Push-rejected-due-to-non-fast-forward" class="headerlink" title="Push rejected due to non-fast-forward"></a>Push rejected due to non-fast-forward</h3><p>The remote branch has commits you do not have locally. Fetch and reconcile first:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git fetch origin</span><br><span class="line">git <span class="built_in">log</span> --oneline --left-right --graph origin/main...main</span><br></pre></td></tr></table></figure><h2 id="Practical-caution"><a href="#Practical-caution" class="headerlink" title="Practical caution"></a>Practical caution</h2><p>Do not store a bare repo under random home directories with mixed permissions. It works until the first maintenance rotation. Use one stable directory, one operational group, and explicit ownership policy.</p><h2 id="FAQ"><a href="#FAQ" class="headerlink" title="FAQ"></a>FAQ</h2><h2 id="Should-I-create-one-bare-repo-per-project"><a href="#Should-I-create-one-bare-repo-per-project" class="headerlink" title="Should I create one bare repo per project?"></a>Should I create one bare repo per project?</h2><p>Yes. Keep one dedicated bare repository per project for clean access boundaries.</p><h2 id="Can-I-push-tags-now-or-later"><a href="#Can-I-push-tags-now-or-later" class="headerlink" title="Can I push tags now or later?"></a>Can I push tags now or later?</h2><p>Either is fine. I usually push tags after branch baseline verification.</p><h2 id="Is-HTTPS-remote-better-than-SSH"><a href="#Is-HTTPS-remote-better-than-SSH" class="headerlink" title="Is HTTPS remote better than SSH?"></a>Is HTTPS remote better than SSH?</h2><p>For automation and server-side operations, SSH is usually simpler to maintain.</p><h2 id="Related-reading"><a href="#Related-reading" class="headerlink" title="Related reading"></a>Related reading</h2><ul><li><a href="/blog/git-and-svn/">Git and SVN hub</a></li><li><a href="/reference/migration-patterns/">Migration patterns</a></li><li><a href="/playbooks/deployment/">Deployment playbook</a></li></ul>]]>
    </content>
    <id>https://qugstart.com/blog/ruby-and-rails/create-a-new-git-remote-repository-from-some-local-files-or-local-git-repository/</id>
    <link href="https://qugstart.com/blog/ruby-and-rails/create-a-new-git-remote-repository-from-some-local-files-or-local-git-repository/"/>
    <published>2024-11-05T10:00:00.000Z</published>
    <summary>Step-by-step guide to create a remote repository from an existing local project, push safely, and recover from common origin and permission errors.</summary>
    <title>Create a New Git Remote Repository from Some Local Files or Local Git Repository</title>
    <updated>2026-04-03T09:00:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Qugstart</name>
    </author>
    <category term="git-and-svn" scheme="https://qugstart.com/categories/git-and-svn/"/>
    <category term="git" scheme="https://qugstart.com/tags/git/"/>
    <category term="bash" scheme="https://qugstart.com/tags/bash/"/>
    <category term="prompt" scheme="https://qugstart.com/tags/prompt/"/>
    <content>
      <![CDATA[<p>This guide covers how to show the current Git branch in your shell prompt without breaking line wrapping, history navigation, or prompt speed. It is a troubleshooting-first setup walkthrough with clean examples, escape rules, and lightweight branch detection logic tested across Linux jump hosts and local development machines. We will cover PS1 escape handling, branch display strategy, performance tradeoffs, and readable color choices, with follow-up context in the <a href="/reference/shell-snippets/">shell snippets reference</a>.</p><h2 id="Why-most-prompt-snippets-break-over-time"><a href="#Why-most-prompt-snippets-break-over-time" class="headerlink" title="Why most prompt snippets break over time"></a>Why most prompt snippets break over time</h2><p>The common copy-paste prompt one-liner works for a while, then you see weird cursor jumps or broken wrapping after long commands. That usually means non-printing color sequences were not wrapped correctly, so Bash miscounts prompt width.</p><p>Bash escape behavior is documented in the GNU Bash manual at <a href="https://www.gnu.org/software/bash/manual/" rel="noopener">gnu.org</a>. Use it as the source of truth whenever prompt behavior looks inconsistent.</p><h2 id="Step-1-Add-a-branch-helper"><a href="#Step-1-Add-a-branch-helper" class="headerlink" title="Step 1: Add a branch helper"></a>Step 1: Add a branch helper</h2><p>Put this in your shell rc file:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="title">parse_git_branch</span></span>() &#123;</span><br><span class="line">  git symbolic-ref --short HEAD 2&gt;/dev/null || git rev-parse --short HEAD 2&gt;/dev/null</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>This returns branch name when available and short commit id in detached HEAD state.</p><h2 id="Step-2-Wrap-color-escapes-correctly"><a href="#Step-2-Wrap-color-escapes-correctly" class="headerlink" title="Step 2: Wrap color escapes correctly"></a>Step 2: Wrap color escapes correctly</h2><p>For Bash, non-printing sequences must be wrapped in <code>\[</code> and <code>\]</code>.</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">GREEN=<span class="string">&#x27;\[\e[32m\]&#x27;</span></span><br><span class="line">GRAY=<span class="string">&#x27;\[\e[90m\]&#x27;</span></span><br><span class="line">RESET=<span class="string">&#x27;\[\e[0m\]&#x27;</span></span><br></pre></td></tr></table></figure><h2 id="Step-3-Build-PS1-with-conditional-branch-display"><a href="#Step-3-Build-PS1-with-conditional-branch-display" class="headerlink" title="Step 3: Build PS1 with conditional branch display"></a>Step 3: Build PS1 with conditional branch display</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">export</span> PS1=<span class="string">&#x27;$&#123;GRAY&#125;\u@\h $&#123;RESET&#125;\w$&#123;GREEN&#125;$(b=$(parse_git_branch); [ -n &quot;$b&quot; ] &amp;&amp; echo &quot; [$b]&quot;)$&#123;RESET&#125;\$ &#x27;</span></span><br></pre></td></tr></table></figure><p>Keep it simple. If you load many subprocess-heavy helpers in PS1, every prompt draw gets slower.</p><h2 id="Readability-tips"><a href="#Readability-tips" class="headerlink" title="Readability tips"></a>Readability tips</h2><ul><li>Avoid bright saturated colors that obscure directory context.</li><li>Keep branch marker compact, for example <code>[main]</code>.</li><li>Use one branch color across machines for quick visual consistency.</li></ul><h2 id="Performance-notes"><a href="#Performance-notes" class="headerlink" title="Performance notes"></a>Performance notes</h2><p>On large repositories, Git status calls can be expensive. Prefer branch-only detection unless you specifically need dirty-state indicators.</p><h2 id="Caution"><a href="#Caution" class="headerlink" title="Caution"></a>Caution</h2><p>If your prompt appears to split lines in the wrong place, review escaping first. Most prompt bugs are formatting math bugs, not shell bugs.</p><h2 id="FAQ"><a href="#FAQ" class="headerlink" title="FAQ"></a>FAQ</h2><h3 id="Does-this-work-in-zsh"><a href="#Does-this-work-in-zsh" class="headerlink" title="Does this work in zsh?"></a>Does this work in zsh?</h3><p>The logic is similar, but prompt escape syntax differs. Use zsh-native prompt formatting there.</p><h3 id="Can-I-show-dirty-state-too"><a href="#Can-I-show-dirty-state-too" class="headerlink" title="Can I show dirty state too?"></a>Can I show dirty state too?</h3><p>Yes, but test speed in large repositories before keeping it enabled.</p><h3 id="Should-I-use-global-shell-config-for-all-machines"><a href="#Should-I-use-global-shell-config-for-all-machines" class="headerlink" title="Should I use global shell config for all machines?"></a>Should I use global shell config for all machines?</h3><p>Use a shared base and machine-specific overrides for paths and host tags.</p><h2 id="Related-reading"><a href="#Related-reading" class="headerlink" title="Related reading"></a>Related reading</h2><ul><li><a href="/blog/git-and-svn/">Git and SVN hub</a></li><li><a href="/reference/shell-snippets/">Shell snippets</a></li><li><a href="/reference/migration-patterns/">Migration patterns</a></li></ul>]]>
    </content>
    <id>https://qugstart.com/blog/git-and-svn/add-colored-git-branch-name-to-your-shell-prompt/</id>
    <link href="https://qugstart.com/blog/git-and-svn/add-colored-git-branch-name-to-your-shell-prompt/"/>
    <published>2024-10-14T09:20:00.000Z</published>
    <summary>Practical guide to display the current Git branch in Bash prompt with safe escaping, low overhead, and readable color design.</summary>
    <title>Add Colored Git Branch Name to Your Shell Prompt</title>
    <updated>2026-04-03T09:15:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Qugstart</name>
    </author>
    <category term="node-js" scheme="https://qugstart.com/categories/node-js/"/>
    <category term="nodejs" scheme="https://qugstart.com/tags/nodejs/"/>
    <category term="restify" scheme="https://qugstart.com/tags/restify/"/>
    <category term="https" scheme="https://qugstart.com/tags/https/"/>
    <content>
      <![CDATA[<p>This guide explains how to run a Node.js service on both HTTP and HTTPS during a controlled transition, then tighten traffic toward HTTPS once behavior is verified. It is a migration and troubleshooting walkthrough based on production cutovers where certificate chain mistakes and redirect loops caused outages. We cover listener setup, certificate loading, redirect strategy, proxy headers, and test sequence, with follow-up depth in the <a href="/playbooks/ssl-and-certificates/">SSL playbook</a>.</p><h2 id="Why-dual-protocol-windows-still-matter"><a href="#Why-dual-protocol-windows-still-matter" class="headerlink" title="Why dual-protocol windows still matter"></a>Why dual-protocol windows still matter</h2><p>In ideal systems, you flip to HTTPS-only instantly. In real systems, old clients, webhook providers, or stale integrations often need a short transition window. Serving both protocols buys control, as long as you enforce a clear timeline and monitor actively.</p><p>The Node.js HTTPS server API reference is in the official docs at <a href="https://nodejs.org/api/https.html" rel="noopener">nodejs.org</a>.</p><h2 id="Step-1-Load-key-certificate-and-chain-safely"><a href="#Step-1-Load-key-certificate-and-chain-safely" class="headerlink" title="Step 1: Load key, certificate, and chain safely"></a>Step 1: Load key, certificate, and chain safely</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> fs = <span class="built_in">require</span>(<span class="string">&#x27;fs&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> https = <span class="built_in">require</span>(<span class="string">&#x27;https&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> http = <span class="built_in">require</span>(<span class="string">&#x27;http&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> restify = <span class="built_in">require</span>(<span class="string">&#x27;restify&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> app = restify.<span class="title function_">createServer</span>();</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> tls = &#123;</span><br><span class="line">  <span class="attr">key</span>: fs.<span class="title function_">readFileSync</span>(<span class="string">&#x27;/etc/ssl/private/service.key&#x27;</span>),</span><br><span class="line">  <span class="attr">cert</span>: fs.<span class="title function_">readFileSync</span>(<span class="string">&#x27;/etc/ssl/certs/service.crt&#x27;</span>),</span><br><span class="line">  <span class="attr">ca</span>: fs.<span class="title function_">readFileSync</span>(<span class="string">&#x27;/etc/ssl/certs/chain.crt&#x27;</span>)</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>Use absolute paths and restrictive file permissions.</p><h2 id="Step-2-Run-HTTPS-app-and-HTTP-redirect-endpoint"><a href="#Step-2-Run-HTTPS-app-and-HTTP-redirect-endpoint" class="headerlink" title="Step 2: Run HTTPS app and HTTP redirect endpoint"></a>Step 2: Run HTTPS app and HTTP redirect endpoint</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">https.<span class="title function_">createServer</span>(tls, app).<span class="title function_">listen</span>(<span class="number">443</span>);</span><br><span class="line"></span><br><span class="line">http.<span class="title function_">createServer</span>(<span class="function">(<span class="params">req, res</span>) =&gt;</span> &#123;</span><br><span class="line">  <span class="keyword">const</span> host = req.<span class="property">headers</span>.<span class="property">host</span> ? req.<span class="property">headers</span>.<span class="property">host</span>.<span class="title function_">replace</span>(<span class="regexp">/:\d+$/</span>, <span class="string">&#x27;&#x27;</span>) : <span class="string">&#x27;qugstart.com&#x27;</span>;</span><br><span class="line">  res.<span class="title function_">writeHead</span>(<span class="number">301</span>, &#123; <span class="title class_">Location</span>: <span class="string">`https://<span class="subst">$&#123;host&#125;</span><span class="subst">$&#123;req.url&#125;</span>`</span> &#125;);</span><br><span class="line">  res.<span class="title function_">end</span>();</span><br><span class="line">&#125;).<span class="title function_">listen</span>(<span class="number">80</span>);</span><br></pre></td></tr></table></figure><p>If you are behind a reverse proxy, ensure forwarded protocol headers are handled consistently.</p><h2 id="Step-3-Verify-locally-and-externally"><a href="#Step-3-Verify-locally-and-externally" class="headerlink" title="Step 3: Verify locally and externally"></a>Step 3: Verify locally and externally</h2><ul><li>Verify cert chain from command line.</li><li>Verify redirect status and location headers.</li><li>Verify application routes through both paths.</li><li>Verify no mixed-content links in rendered pages.</li></ul><h2 id="Redirect-caveats-that-trigger-loops"><a href="#Redirect-caveats-that-trigger-loops" class="headerlink" title="Redirect caveats that trigger loops"></a>Redirect caveats that trigger loops</h2><ul><li>Proxy terminates TLS but app still thinks request is HTTP.</li><li>Redirect middleware runs on already secure requests.</li><li>Host header includes unexpected port and generates malformed location.</li></ul><h2 id="Operational-checklist"><a href="#Operational-checklist" class="headerlink" title="Operational checklist"></a>Operational checklist</h2><ul><li>Track request counts on HTTP after redirect policy starts.</li><li>Watch for handshake errors and unknown CA events.</li><li>Log redirect target URL during rollout to catch malformed rules early.</li></ul><h2 id="FAQ"><a href="#FAQ" class="headerlink" title="FAQ"></a>FAQ</h2><h3 id="Should-HTTP-stay-enabled-forever"><a href="#Should-HTTP-stay-enabled-forever" class="headerlink" title="Should HTTP stay enabled forever?"></a>Should HTTP stay enabled forever?</h3><p>No. Keep it only for transition, then remove once all critical clients are confirmed.</p><h3 id="Can-I-use-one-Restify-server-for-both-ports"><a href="#Can-I-use-one-Restify-server-for-both-ports" class="headerlink" title="Can I use one Restify server for both ports?"></a>Can I use one Restify server for both ports?</h3><p>You can share handlers, but create distinct HTTP and HTTPS listeners for control.</p><h3 id="What-breaks-most-often"><a href="#What-breaks-most-often" class="headerlink" title="What breaks most often?"></a>What breaks most often?</h3><p>Certificate chain order, proxy header assumptions, and broad redirect middleware.</p><h2 id="Related-reading"><a href="#Related-reading" class="headerlink" title="Related reading"></a>Related reading</h2><ul><li><a href="/blog/node-js/">Node.js hub</a></li><li><a href="/playbooks/ssl-and-certificates/">SSL and certificates playbook</a></li><li><a href="/playbooks/deployment/">Deployment playbook</a></li></ul>]]>
    </content>
    <id>https://qugstart.com/blog/node-js/node-js-restify-server-with-both-http-and-https/</id>
    <link href="https://qugstart.com/blog/node-js/node-js-restify-server-with-both-http-and-https/"/>
    <published>2024-08-01T08:40:00.000Z</published>
    <summary>Practical migration approach for serving HTTP and HTTPS side by side in Node.js with certificate handling and redirect control.</summary>
    <title>Node.js Restify Server with Both HTTP and HTTPS</title>
    <updated>2026-04-03T09:30:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Qugstart</name>
    </author>
    <category term="git-and-svn" scheme="https://qugstart.com/categories/git-and-svn/"/>
    <category term="git" scheme="https://qugstart.com/tags/git/"/>
    <category term="svn" scheme="https://qugstart.com/tags/svn/"/>
    <category term="migration" scheme="https://qugstart.com/tags/migration/"/>
    <content>
      <![CDATA[<p>This guide covers a full SVN-to-Git migration path that preserves branch and tag structure while keeping history understandable for teams that still need to maintain old release lines. It is a practical migration and validation walkthrough based on multiple cutovers where the dangerous part was never the command itself, it was branch mapping assumptions and weak verification. We will cover repository audit, author maps, <code>git svn</code> import strategy, branch and tag reconstruction checks, dry-run method, and post-cutover hygiene, then connect to <a href="/reference/migration-patterns/">migration patterns</a> for repeated use.</p><h2 id="Migration-goals-to-lock-before-touching-data"><a href="#Migration-goals-to-lock-before-touching-data" class="headerlink" title="Migration goals to lock before touching data"></a>Migration goals to lock before touching data</h2><p>Define these in writing first:</p><ul><li>What counts as a successful migration</li><li>Which paths map to trunk, branches, and tags</li><li>How author identities are translated</li><li>How rollback works if validation fails</li></ul><p>If this is not explicit, debates happen during cutover and risk spikes.</p><h2 id="Step-1-Audit-SVN-layout-and-naming-anomalies"><a href="#Step-1-Audit-SVN-layout-and-naming-anomalies" class="headerlink" title="Step 1: Audit SVN layout and naming anomalies"></a>Step 1: Audit SVN layout and naming anomalies</h2><p>Inspect repository structure and confirm conventions.</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">svn <span class="built_in">ls</span> -R &lt;repo-url&gt;</span><br></pre></td></tr></table></figure><p>Look for:</p><ul><li>non-standard branch folders</li><li>tags that were edited after creation</li><li>vendor import paths mixed with active code</li></ul><h2 id="Step-2-Build-author-mapping-file"><a href="#Step-2-Build-author-mapping-file" class="headerlink" title="Step 2: Build author mapping file"></a>Step 2: Build author mapping file</h2><p>Create <code>authors.txt</code> with stable identity mapping:</p><figure class="highlight txt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">jdoe = Jane Doe &lt;jane@example.com&gt;</span><br><span class="line">asmith = Alex Smith &lt;alex@example.com&gt;</span><br></pre></td></tr></table></figure><p>If identities are incomplete, gather them before import. Post-import fixes are possible but painful.</p><h2 id="Step-3-Run-an-initial-git-svn-clone"><a href="#Step-3-Run-an-initial-git-svn-clone" class="headerlink" title="Step 3: Run an initial git svn clone"></a>Step 3: Run an initial <code>git svn</code> clone</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git svn <span class="built_in">clone</span> &lt;repo-url&gt; --stdlayout --authors-file=authors.txt project-git</span><br><span class="line"><span class="built_in">cd</span> project-git</span><br></pre></td></tr></table></figure><p>For non-standard layouts, provide explicit trunk, branch, and tag paths.</p><h2 id="Step-4-Convert-and-clean-tag-representation"><a href="#Step-4-Convert-and-clean-tag-representation" class="headerlink" title="Step 4: Convert and clean tag representation"></a>Step 4: Convert and clean tag representation</h2><p>SVN tags are directories. In Git they should become immutable refs.</p><p>Typical pattern:</p><ul><li>identify imported remote refs</li><li>create local tags from expected tag points</li><li>remove accidental branch-like tag refs</li></ul><h2 id="Step-5-Validate-branch-topology-and-history"><a href="#Step-5-Validate-branch-topology-and-history" class="headerlink" title="Step 5: Validate branch topology and history"></a>Step 5: Validate branch topology and history</h2><p>Use targeted comparisons, not visual guesswork.</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git branch -a</span><br><span class="line">git <span class="built_in">log</span> --graph --decorate --oneline --all | <span class="built_in">head</span> -n 200</span><br></pre></td></tr></table></figure><p>Pick known milestones from SVN and confirm equivalent commits in Git.</p><h2 id="Step-6-Dry-run-cutover-with-team-workflow"><a href="#Step-6-Dry-run-cutover-with-team-workflow" class="headerlink" title="Step 6: Dry run cutover with team workflow"></a>Step 6: Dry run cutover with team workflow</h2><p>Dry run should include:</p><ul><li>clone from candidate Git remote</li><li>build and test from representative branches</li><li>CI trigger checks</li><li>merge flow rehearsal</li></ul><p>If one team path fails in dry run, cutover is not ready.</p><h2 id="Step-7-Final-cutover-checklist"><a href="#Step-7-Final-cutover-checklist" class="headerlink" title="Step 7: Final cutover checklist"></a>Step 7: Final cutover checklist</h2><ul><li>Freeze SVN writes during final sync window.</li><li>Execute final fetch&#x2F;import and validate counts.</li><li>Push to canonical Git remote.</li><li>Communicate new remote URLs and branch policy.</li><li>Keep SVN read-only for reference period.</li></ul><h2 id="Post-cutover-hygiene"><a href="#Post-cutover-hygiene" class="headerlink" title="Post-cutover hygiene"></a>Post-cutover hygiene</h2><ul><li>Remove obsolete SVN bridge scripts from active workflow.</li><li>Standardize branch naming rules.</li><li>Add protected branch settings in remote platform.</li><li>Document rollback and recovery strategy.</li></ul><h2 id="High-risk-mistakes-to-avoid"><a href="#High-risk-mistakes-to-avoid" class="headerlink" title="High-risk mistakes to avoid"></a>High-risk mistakes to avoid</h2><ol><li>Assuming <code>--stdlayout</code> matches reality without audit.</li><li>Ignoring rewritten tags that were mutable in SVN.</li><li>Skipping author map review until after import.</li><li>Declaring done before team workflow dry run.</li></ol><h2 id="FAQ"><a href="#FAQ" class="headerlink" title="FAQ"></a>FAQ</h2><h3 id="Should-we-migrate-every-historical-branch"><a href="#Should-we-migrate-every-historical-branch" class="headerlink" title="Should we migrate every historical branch?"></a>Should we migrate every historical branch?</h3><p>No. Migrate branches with operational value, and archive the rest intentionally.</p><h3 id="How-long-should-SVN-remain-available"><a href="#How-long-should-SVN-remain-available" class="headerlink" title="How long should SVN remain available?"></a>How long should SVN remain available?</h3><p>Keep read-only access through a defined confidence window and audit period.</p><h3 id="Can-we-rerun-import-if-mapping-is-wrong"><a href="#Can-we-rerun-import-if-mapping-is-wrong" class="headerlink" title="Can we rerun import if mapping is wrong?"></a>Can we rerun import if mapping is wrong?</h3><p>Yes. Start from a clean Git repository and rerun with corrected mappings.</p><h2 id="Related-reading"><a href="#Related-reading" class="headerlink" title="Related reading"></a>Related reading</h2><ul><li><a href="/blog/git-and-svn/">Git and SVN hub</a></li><li><a href="/reference/migration-patterns/">Migration patterns</a></li><li><a href="/reference/checklists/">Checklists</a></li></ul>]]>
    </content>
    <id>https://qugstart.com/blog/git-and-svn/migrate-an-svn-repository-to-git-while-maintaining-branches-and-tags-structure/</id>
    <link href="https://qugstart.com/blog/git-and-svn/migrate-an-svn-repository-to-git-while-maintaining-branches-and-tags-structure/"/>
    <published>2024-05-02T13:00:00.000Z</published>
    <summary>End-to-end SVN to Git migration guide with branch and tag mapping, author translation, dry runs, and post-cutover validation.</summary>
    <title>Migrate an SVN Repository to Git while Maintaining Branches and Tags Structure</title>
    <updated>2026-04-03T11:00:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Qugstart</name>
    </author>
    <category term="amazon-web-services" scheme="https://qugstart.com/categories/amazon-web-services/"/>
    <category term="aws" scheme="https://qugstart.com/tags/aws/"/>
    <category term="ec2" scheme="https://qugstart.com/tags/ec2/"/>
    <category term="ebs" scheme="https://qugstart.com/tags/ebs/"/>
    <category term="xfs" scheme="https://qugstart.com/tags/xfs/"/>
    <content>
      <![CDATA[<p>This guide walks through a practical EC2 database host pattern that stores data on an attached EBS volume formatted with XFS, including persistent mount setup and rollback-minded verification. It is a migration and operations checklist based on inherited environments where root volume growth, device naming assumptions, and boot ordering caused avoidable incidents. We cover volume attachment, XFS format, mount persistence, ownership, and runtime checks, with follow-up in the <a href="/playbooks/data-moves/">data moves playbook</a>.</p><h2 id="Why-this-pattern-still-appears"><a href="#Why-this-pattern-still-appears" class="headerlink" title="Why this pattern still appears"></a>Why this pattern still appears</h2><p>Separating system and data volumes keeps replacement and recovery cleaner. It also reduces pressure to mutate root disks during data growth events.</p><p>For current EBS operational guidance, AWS documentation is available at <a href="https://docs.aws.amazon.com/ebs/latest/userguide/ebs-volumes.html" rel="noopener">docs.aws.amazon.com</a>.</p><h2 id="Step-1-Provision-EC2-instance-and-attach-EBS-volume"><a href="#Step-1-Provision-EC2-instance-and-attach-EBS-volume" class="headerlink" title="Step 1: Provision EC2 instance and attach EBS volume"></a>Step 1: Provision EC2 instance and attach EBS volume</h2><p>Pick instance type according to database profile and throughput needs. Attach data volume in the same availability zone as the instance.</p><h2 id="Step-2-Identify-device-and-confirm-block-mapping"><a href="#Step-2-Identify-device-and-confirm-block-mapping" class="headerlink" title="Step 2: Identify device and confirm block mapping"></a>Step 2: Identify device and confirm block mapping</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">lsblk -f</span><br></pre></td></tr></table></figure><p>Do not assume fixed device names across all instance families.</p><h2 id="Step-3-Format-volume-with-XFS"><a href="#Step-3-Format-volume-with-XFS" class="headerlink" title="Step 3: Format volume with XFS"></a>Step 3: Format volume with XFS</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> mkfs.xfs /dev/nvme1n1</span><br></pre></td></tr></table></figure><p>Run once, and only on the correct target device.</p><h2 id="Step-4-Mount-and-assign-ownership"><a href="#Step-4-Mount-and-assign-ownership" class="headerlink" title="Step 4: Mount and assign ownership"></a>Step 4: Mount and assign ownership</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> <span class="built_in">mkdir</span> -p /data/db</span><br><span class="line"><span class="built_in">sudo</span> mount /dev/nvme1n1 /data/db</span><br><span class="line"><span class="built_in">sudo</span> <span class="built_in">chown</span> -R dbuser:dbgroup /data/db</span><br></pre></td></tr></table></figure><h2 id="Step-5-Persist-mount-through-reboot"><a href="#Step-5-Persist-mount-through-reboot" class="headerlink" title="Step 5: Persist mount through reboot"></a>Step 5: Persist mount through reboot</h2><p>Find UUID and place in fstab:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> blkid /dev/nvme1n1</span><br></pre></td></tr></table></figure><p>Then set:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">UUID=&lt;your-uuid&gt; /data/db xfs defaults,nofail 0 2</span><br></pre></td></tr></table></figure><p>Test before relying on it:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> umount /data/db</span><br><span class="line"><span class="built_in">sudo</span> mount -a</span><br></pre></td></tr></table></figure><h2 id="Operational-caveats"><a href="#Operational-caveats" class="headerlink" title="Operational caveats"></a>Operational caveats</h2><ul><li><code>nofail</code> avoids boot hard-stop but can hide mount failure if monitoring is weak.</li><li>Database service should fail fast when mount is missing, not silently write to root.</li><li>Snapshot policies should be tested with restore drills, not only scheduled.</li></ul><h2 id="Verification-after-reboot"><a href="#Verification-after-reboot" class="headerlink" title="Verification after reboot"></a>Verification after reboot</h2><ul><li>Confirm mount is present and type is XFS.</li><li>Confirm database writes hit <code>/data/db</code>.</li><li>Confirm free space and I&#x2F;O metrics are expected.</li></ul><h2 id="FAQ"><a href="#FAQ" class="headerlink" title="FAQ"></a>FAQ</h2><h3 id="Why-XFS-here-instead-of-ext4"><a href="#Why-XFS-here-instead-of-ext4" class="headerlink" title="Why XFS here instead of ext4?"></a>Why XFS here instead of ext4?</h3><p>XFS performs well for large files and growth scenarios, but choose based on workload and team familiarity.</p><h3 id="Should-logs-be-on-the-same-volume"><a href="#Should-logs-be-on-the-same-volume" class="headerlink" title="Should logs be on the same volume?"></a>Should logs be on the same volume?</h3><p>Usually separate concerns where possible. Keep critical logs accessible during data-volume incidents.</p><h3 id="What-breaks-most-often"><a href="#What-breaks-most-often" class="headerlink" title="What breaks most often?"></a>What breaks most often?</h3><p>Wrong device mapping in fstab, service startup before mount, and missing post-reboot verification.</p><h2 id="Related-reading"><a href="#Related-reading" class="headerlink" title="Related reading"></a>Related reading</h2><ul><li><a href="/blog/amazon-web-services/">AWS hub</a></li><li><a href="/playbooks/data-moves/">Data moves playbook</a></li><li><a href="/playbooks/deployment/">Deployment playbook</a></li></ul>]]>
    </content>
    <id>https://qugstart.com/blog/amazon-web-services/how-to-set-up-db-server-on-amazon-ec2-with-data-stored-on-ebs-drive-formatted-with-xfs/</id>
    <link href="https://qugstart.com/blog/amazon-web-services/how-to-set-up-db-server-on-amazon-ec2-with-data-stored-on-ebs-drive-formatted-with-xfs/"/>
    <published>2024-03-08T14:00:00.000Z</published>
    <summary>Practical EC2 database host setup with XFS on EBS, including mount persistence, verification, and operational caveats.</summary>
    <title>How to Set Up DB Server on Amazon EC2 with Data Stored on EBS Drive Formatted with XFS</title>
    <updated>2026-04-03T10:45:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Qugstart</name>
    </author>
    <category term="ruby-and-rails" scheme="https://qugstart.com/categories/ruby-and-rails/"/>
    <category term="ruby" scheme="https://qugstart.com/tags/ruby/"/>
    <category term="rails" scheme="https://qugstart.com/tags/rails/"/>
    <category term="security" scheme="https://qugstart.com/tags/security/"/>
    <content>
      <![CDATA[<p>This guide covers URL-safe Base64 decoding for <code>signed_request</code> payload handling and explains a practical validation path that avoids common signature mistakes. It is a security-aware troubleshooting guide based on production maintenance of older integration flows where payload format looked valid but verification failed under edge-case input. We will cover payload split rules, URL-safe decoding conversion, signature checks, and safe failure behavior, with companion checks in <a href="/reference/checklists/">reference checklists</a>.</p><h2 id="Why-these-payloads-fail-in-real-systems"><a href="#Why-these-payloads-fail-in-real-systems" class="headerlink" title="Why these payloads fail in real systems"></a>Why these payloads fail in real systems</h2><p>The request value usually contains two segments separated by a dot:</p><ol><li>encoded signature</li><li>encoded payload JSON</li></ol><p>Developers often decode one piece correctly and still fail verification because of URL-safe alphabet conversion or padding assumptions.</p><p>For Base64 behavior details, MDN has a clear reference section at <a href="https://developer.mozilla.org/en-US/docs/Glossary/Base64" rel="noopener">developer.mozilla.org</a>.</p><h2 id="Step-1-Split-the-payload-safely"><a href="#Step-1-Split-the-payload-safely" class="headerlink" title="Step 1: Split the payload safely"></a>Step 1: Split the payload safely</h2><figure class="highlight ruby"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">encoded_sig, encoded_payload = signed_request.to_s.split(<span class="string">&#x27;.&#x27;</span>, <span class="number">2</span>)</span><br><span class="line"><span class="keyword">raise</span> <span class="string">&#x27;invalid signed_request format&#x27;</span> <span class="keyword">unless</span> encoded_sig &amp;&amp; encoded_payload</span><br></pre></td></tr></table></figure><p>Reject malformed values immediately.</p><h2 id="Step-2-Convert-URL-safe-Base64-to-standard-form"><a href="#Step-2-Convert-URL-safe-Base64-to-standard-form" class="headerlink" title="Step 2: Convert URL-safe Base64 to standard form"></a>Step 2: Convert URL-safe Base64 to standard form</h2><figure class="highlight ruby"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">urlsafe_base64_decode</span>(<span class="params">str</span>)</span><br><span class="line">  str += <span class="string">&#x27;=&#x27;</span> * ((<span class="number">4</span> - str.length % <span class="number">4</span>) % <span class="number">4</span>)</span><br><span class="line">  <span class="title class_">Base64</span>.decode64(str.tr(<span class="string">&#x27;-_&#x27;</span>, <span class="string">&#x27;+/&#x27;</span>))</span><br><span class="line"><span class="keyword">end</span></span><br></pre></td></tr></table></figure><p>The <code>-</code> and <code>_</code> substitutions plus optional padding are the critical details.</p><h2 id="Step-3-Verify-signature-before-trusting-payload"><a href="#Step-3-Verify-signature-before-trusting-payload" class="headerlink" title="Step 3: Verify signature before trusting payload"></a>Step 3: Verify signature before trusting payload</h2><figure class="highlight ruby"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">sig = urlsafe_base64_decode(encoded_sig)</span><br><span class="line">payload_raw = urlsafe_base64_decode(encoded_payload)</span><br><span class="line">expected = <span class="title class_">Open</span>SSL::<span class="variable constant_">HMAC</span>.digest(<span class="string">&#x27;sha256&#x27;</span>, app_secret, encoded_payload)</span><br><span class="line"><span class="keyword">raise</span> <span class="string">&#x27;invalid signature&#x27;</span> <span class="keyword">unless</span> <span class="title class_">Rack</span><span class="symbol">:</span><span class="symbol">:Utils</span>.secure_compare(sig, expected)</span><br></pre></td></tr></table></figure><p>Only parse JSON after signature verification passes.</p><h2 id="Step-4-Parse-payload-and-validate-claims"><a href="#Step-4-Parse-payload-and-validate-claims" class="headerlink" title="Step 4: Parse payload and validate claims"></a>Step 4: Parse payload and validate claims</h2><p>Check expected fields and expiration values. Do not trust optional attributes by default.</p><h2 id="Caution"><a href="#Caution" class="headerlink" title="Caution"></a>Caution</h2><p>Fail closed. If parsing or signature verification fails, reject request and log structured diagnostics without leaking secrets.</p><h2 id="FAQ"><a href="#FAQ" class="headerlink" title="FAQ"></a>FAQ</h2><h3 id="Why-not-decode-with-plain-Base64-decode64-directly"><a href="#Why-not-decode-with-plain-Base64-decode64-directly" class="headerlink" title="Why not decode with plain Base64.decode64 directly?"></a>Why not decode with plain <code>Base64.decode64</code> directly?</h3><p>URL-safe variants need alphabet conversion and optional padding normalization first.</p><h3 id="Should-I-still-support-this-flow-in-new-builds"><a href="#Should-I-still-support-this-flow-in-new-builds" class="headerlink" title="Should I still support this flow in new builds?"></a>Should I still support this flow in new builds?</h3><p>Use current provider guidance for new integrations. Keep this only where existing traffic requires it.</p><h3 id="What-should-be-logged"><a href="#What-should-be-logged" class="headerlink" title="What should be logged?"></a>What should be logged?</h3><p>Timestamp, request id, failure type, and high-level reason. Avoid logging raw payload secrets.</p><h2 id="Related-reading"><a href="#Related-reading" class="headerlink" title="Related reading"></a>Related reading</h2><ul><li><a href="/blog/ruby-and-rails/">Ruby and Rails hub</a></li><li><a href="/reference/checklists/">Checklists</a></li><li><a href="/reference/migration-patterns/">Migration patterns</a></li></ul>]]>
    </content>
    <id>https://qugstart.com/blog/ruby-and-rails/facebook-base64-url-decode-for-signed_request/</id>
    <link href="https://qugstart.com/blog/ruby-and-rails/facebook-base64-url-decode-for-signed_request/"/>
    <published>2024-02-11T15:10:00.000Z</published>
    <summary>Practical signed_request decoding and validation guide with URL-safe Base64 details and security-focused checks.</summary>
    <title>Facebook Base64 URL Decode for signed_request</title>
    <updated>2026-04-03T10:30:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Qugstart</name>
    </author>
    <category term="node-js" scheme="https://qugstart.com/categories/node-js/"/>
    <category term="tls" scheme="https://qugstart.com/tags/tls/"/>
    <category term="ssl" scheme="https://qugstart.com/tags/ssl/"/>
    <category term="nodejs" scheme="https://qugstart.com/tags/nodejs/"/>
    <content>
      <![CDATA[<p>This guide explains how to install a PositiveSSL certificate chain for Node.js and verify that clients complete handshake cleanly. It is a practical troubleshooting walkthrough based on recurring production incidents where cert and chain files were valid individually but wrong in combination. We cover chain order, PEM formatting, file permissions, startup checks, and client-side verification, with companion controls in the <a href="/playbooks/ssl-and-certificates/">SSL and certificates playbook</a>.</p><h2 id="What-usually-goes-wrong"><a href="#What-usually-goes-wrong" class="headerlink" title="What usually goes wrong"></a>What usually goes wrong</h2><p>Most TLS incidents are not caused by bad keys. They come from chain order mistakes, mixed encoding, or incomplete deployment bundles.</p><h2 id="Step-1-Prepare-files"><a href="#Step-1-Prepare-files" class="headerlink" title="Step 1: Prepare files"></a>Step 1: Prepare files</h2><p>You typically need:</p><ul><li>private key file</li><li>server certificate file</li><li>intermediate chain file</li></ul><p>Store with strict permissions and predictable paths.</p><h2 id="Step-2-Confirm-key-and-cert-pairing"><a href="#Step-2-Confirm-key-and-cert-pairing" class="headerlink" title="Step 2: Confirm key and cert pairing"></a>Step 2: Confirm key and cert pairing</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">openssl x509 -noout -modulus -<span class="keyword">in</span> server.crt | openssl md5</span><br><span class="line">openssl rsa  -noout -modulus -<span class="keyword">in</span> server.key | openssl md5</span><br></pre></td></tr></table></figure><p>Hashes should match.</p><h2 id="Step-3-Load-TLS-options-in-Node-js"><a href="#Step-3-Load-TLS-options-in-Node-js" class="headerlink" title="Step 3: Load TLS options in Node.js"></a>Step 3: Load TLS options in Node.js</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> options = &#123;</span><br><span class="line">  <span class="attr">key</span>: fs.<span class="title function_">readFileSync</span>(<span class="string">&#x27;/etc/ssl/private/server.key&#x27;</span>),</span><br><span class="line">  <span class="attr">cert</span>: fs.<span class="title function_">readFileSync</span>(<span class="string">&#x27;/etc/ssl/certs/server.crt&#x27;</span>),</span><br><span class="line">  <span class="attr">ca</span>: fs.<span class="title function_">readFileSync</span>(<span class="string">&#x27;/etc/ssl/certs/intermediate.crt&#x27;</span>)</span><br><span class="line">&#125;;</span><br><span class="line">https.<span class="title function_">createServer</span>(options, app).<span class="title function_">listen</span>(<span class="number">443</span>);</span><br></pre></td></tr></table></figure><p>If your provider gives multiple intermediates, keep order explicit.</p><h2 id="Step-4-Test-handshake-and-chain-exposure"><a href="#Step-4-Test-handshake-and-chain-exposure" class="headerlink" title="Step 4: Test handshake and chain exposure"></a>Step 4: Test handshake and chain exposure</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">openssl s_client -connect your-host:443 -servername your-host -showcerts</span><br></pre></td></tr></table></figure><p>Review chain blocks and verification result.</p><h2 id="Troubleshooting-patterns"><a href="#Troubleshooting-patterns" class="headerlink" title="Troubleshooting patterns"></a>Troubleshooting patterns</h2><ul><li><code>unable to get local issuer certificate</code> means intermediate chain is missing or wrong.</li><li>Browser works but CLI fails can indicate client trust-store differences.</li><li>Intermittent failure after deploy can mean mixed old&#x2F;new cert files on multi-node rollout.</li></ul><h2 id="Caution"><a href="#Caution" class="headerlink" title="Caution"></a>Caution</h2><p>Certificate updates should be deployed atomically with restart and verification. Partial rollout with mixed certificate sets can create hard-to-diagnose behavior.</p><h2 id="FAQ"><a href="#FAQ" class="headerlink" title="FAQ"></a>FAQ</h2><h3 id="Should-chain-cert-be-concatenated-into-cert"><a href="#Should-chain-cert-be-concatenated-into-cert" class="headerlink" title="Should chain cert be concatenated into cert?"></a>Should chain cert be concatenated into <code>cert</code>?</h3><p>Depends on stack. In Node.js, separate <code>ca</code> is generally clearer for maintenance.</p><h3 id="Do-I-need-full-service-restart"><a href="#Do-I-need-full-service-restart" class="headerlink" title="Do I need full service restart?"></a>Do I need full service restart?</h3><p>Yes, unless your process explicitly supports safe live cert reload.</p><h3 id="What-should-I-log-during-rollout"><a href="#What-should-I-log-during-rollout" class="headerlink" title="What should I log during rollout?"></a>What should I log during rollout?</h3><p>Handshake errors by client IP and protocol version, plus startup read-path checks.</p><h2 id="Related-reading"><a href="#Related-reading" class="headerlink" title="Related reading"></a>Related reading</h2><ul><li><a href="/blog/node-js/">Node.js hub</a></li><li><a href="/playbooks/ssl-and-certificates/">SSL and certificates playbook</a></li><li><a href="/playbooks/deployment/">Deployment playbook</a></li></ul>]]>
    </content>
    <id>https://qugstart.com/blog/node-js/install-comodo-positivessl-certificate-with-node-js/</id>
    <link href="https://qugstart.com/blog/node-js/install-comodo-positivessl-certificate-with-node-js/"/>
    <published>2024-01-19T10:35:00.000Z</published>
    <summary>Practical certificate chain installation for Node.js services with troubleshooting for handshake and chain order issues.</summary>
    <title>Install Comodo PositiveSSL Certificate with Node.js</title>
    <updated>2026-04-03T10:15:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Qugstart</name>
    </author>
    <category term="linux" scheme="https://qugstart.com/categories/linux/"/>
    <category term="centos" scheme="https://qugstart.com/tags/centos/"/>
    <category term="s3" scheme="https://qugstart.com/tags/s3/"/>
    <category term="filesystem" scheme="https://qugstart.com/tags/filesystem/"/>
    <content>
      <![CDATA[<p>This guide explains the older pattern of mounting an S3 bucket as a filesystem path on CentOS 5.2, then adds current operational context so you know where this approach still helps and where it fails fast. It is a step-by-step troubleshooting piece based on maintenance of inherited systems, with clear checks for permissions, latency side effects, and service-account behavior. We cover setup flow, mount validation, failure modes, and safer alternatives, with related planning notes in the <a href="/playbooks/data-moves/">data moves playbook</a>.</p><h2 id="Context-first"><a href="#Context-first" class="headerlink" title="Context first"></a>Context first</h2><p>Teams used this pattern when applications expected local filesystem paths and object-storage-native rewrites were not feasible. It can work for limited cases, but it has sharp edges around metadata semantics, latency, and retry behavior.</p><h2 id="Step-1-Install-FUSE-tooling-and-mount-helper"><a href="#Step-1-Install-FUSE-tooling-and-mount-helper" class="headerlink" title="Step 1: Install FUSE tooling and mount helper"></a>Step 1: Install FUSE tooling and mount helper</h2><p>On older CentOS, package combinations vary. Confirm FUSE is available and loaded before touching bucket mount tools.</p><h2 id="Step-2-Configure-credentials-with-strict-permissions"><a href="#Step-2-Configure-credentials-with-strict-permissions" class="headerlink" title="Step 2: Configure credentials with strict permissions"></a>Step 2: Configure credentials with strict permissions</h2><p>Use dedicated IAM credentials with the least required access. Protect credential files so only the service account can read them.</p><h2 id="Step-3-Create-mount-point-and-mount-command"><a href="#Step-3-Create-mount-point-and-mount-command" class="headerlink" title="Step 3: Create mount point and mount command"></a>Step 3: Create mount point and mount command</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">mkdir</span> -p /mnt/s3-data</span><br><span class="line">s3fs your-bucket /mnt/s3-data -o allow_other -o use_cache=/tmp/s3fs-cache</span><br></pre></td></tr></table></figure><p>Adjust options according to your mount helper capabilities.</p><h2 id="Step-4-Verify-behavior-under-application-account"><a href="#Step-4-Verify-behavior-under-application-account" class="headerlink" title="Step 4: Verify behavior under application account"></a>Step 4: Verify behavior under application account</h2><p>Many setups appear to work as root but fail under app user. Always test with the same account and process model used in production.</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> -u appuser <span class="built_in">touch</span> /mnt/s3-data/write-test.txt</span><br><span class="line"><span class="built_in">sudo</span> -u appuser <span class="built_in">ls</span> -la /mnt/s3-data</span><br></pre></td></tr></table></figure><h2 id="Known-failure-modes"><a href="#Known-failure-modes" class="headerlink" title="Known failure modes"></a>Known failure modes</h2><ul><li>Directory listings are slower than local disk expectations.</li><li>Rename operations can behave differently than local POSIX assumptions.</li><li>Partial network failures surface as filesystem errors in surprising places.</li></ul><h2 id="Practical-cautions"><a href="#Practical-cautions" class="headerlink" title="Practical cautions"></a>Practical cautions</h2><p>Treat this as a compatibility layer, not a high-throughput filesystem. For write-heavy workloads, use direct SDK access to S3 or stage to local&#x2F;EBS and sync.</p><h2 id="Modern-alternatives"><a href="#Modern-alternatives" class="headerlink" title="Modern alternatives"></a>Modern alternatives</h2><ul><li>Keep hot data on EBS&#x2F;XFS and sync to S3 for retention.</li><li>Use object storage APIs directly in application code.</li><li>Use transfer jobs for batched upload instead of mounted write paths.</li></ul><h2 id="FAQ"><a href="#FAQ" class="headerlink" title="FAQ"></a>FAQ</h2><h3 id="Is-this-pattern-still-recommended"><a href="#Is-this-pattern-still-recommended" class="headerlink" title="Is this pattern still recommended?"></a>Is this pattern still recommended?</h3><p>Only for constrained compatibility scenarios.</p><h3 id="What-should-I-monitor"><a href="#What-should-I-monitor" class="headerlink" title="What should I monitor?"></a>What should I monitor?</h3><p>Mount availability, I&#x2F;O latency, and application retry&#x2F;error behavior.</p><h3 id="Can-I-put-this-in-fstab"><a href="#Can-I-put-this-in-fstab" class="headerlink" title="Can I put this in fstab?"></a>Can I put this in fstab?</h3><p>You can, but boot-order and network readiness must be tested carefully.</p><h2 id="Related-reading"><a href="#Related-reading" class="headerlink" title="Related reading"></a>Related reading</h2><ul><li><a href="/blog/linux/">Linux hub</a></li><li><a href="/playbooks/data-moves/">Data moves playbook</a></li><li><a href="/playbooks/deployment/">Deployment playbook</a></li></ul>]]>
    </content>
    <id>https://qugstart.com/blog/linux/how-to-mount-an-amazon-s3-bucket-as-virtual-drive-on-centos-5-2/</id>
    <link href="https://qugstart.com/blog/linux/how-to-mount-an-amazon-s3-bucket-as-virtual-drive-on-centos-5-2/"/>
    <published>2023-12-09T07:30:00.000Z</published>
    <summary>Period-specific guide for S3 bucket mounts on older CentOS environments, with practical caveats and modern alternatives.</summary>
    <title>How to Mount an Amazon S3 Bucket as Virtual Drive on CentOS 5.2</title>
    <updated>2026-04-03T09:45:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>Qugstart</name>
    </author>
    <category term="linux" scheme="https://qugstart.com/categories/linux/"/>
    <category term="openoffice" scheme="https://qugstart.com/tags/openoffice/"/>
    <category term="conversion" scheme="https://qugstart.com/tags/conversion/"/>
    <category term="headless" scheme="https://qugstart.com/tags/headless/"/>
    <content>
      <![CDATA[<p>This guide covers server-side Word-to-PDF conversion using OpenOffice in headless mode, with a practical sequence for installation, daemon setup, and output validation. It is a troubleshooting-oriented walkthrough based on real conversion pipelines where font packages, lock files, and process supervision caused inconsistent results. We will cover package setup, command execution, batch handling, and rendering pitfalls, then link to the <a href="/playbooks/deployment/">deployment playbook</a> for rollout controls.</p><h2 id="Why-this-workflow-still-appears"><a href="#Why-this-workflow-still-appears" class="headerlink" title="Why this workflow still appears"></a>Why this workflow still appears</h2><p>Many teams inherit systems that depend on deterministic document output and cannot rewrite immediately. Headless conversion remains useful when isolated, monitored, and constrained.</p><h2 id="Step-1-Install-office-packages-and-fonts"><a href="#Step-1-Install-office-packages-and-fonts" class="headerlink" title="Step 1: Install office packages and fonts"></a>Step 1: Install office packages and fonts</h2><p>Conversion quality depends heavily on fonts. Missing fonts do not always throw hard errors. They often produce layout drift that only appears during manual review.</p><h2 id="Step-2-Run-a-direct-conversion-test"><a href="#Step-2-Run-a-direct-conversion-test" class="headerlink" title="Step 2: Run a direct conversion test"></a>Step 2: Run a direct conversion test</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">soffice --headless --convert-to pdf sample.docx --outdir /tmp</span><br></pre></td></tr></table></figure><p>Test with representative documents, not a trivial one-page sample.</p><h2 id="Step-3-Design-service-model"><a href="#Step-3-Design-service-model" class="headerlink" title="Step 3: Design service model"></a>Step 3: Design service model</h2><p>Options:</p><ul><li>Execute one-off conversion command per document.</li><li>Run supervised worker process that consumes queued jobs.</li></ul><p>For moderate load, queue-based workers are easier to monitor and restart safely.</p><h2 id="Step-4-Handle-temp-paths-and-lock-files"><a href="#Step-4-Handle-temp-paths-and-lock-files" class="headerlink" title="Step 4: Handle temp paths and lock files"></a>Step 4: Handle temp paths and lock files</h2><p>Use dedicated working directories. Clear stale lock files between retries. Do not run all jobs in shared <code>/tmp</code> without namespacing.</p><h2 id="Rendering-issues-to-expect"><a href="#Rendering-issues-to-expect" class="headerlink" title="Rendering issues to expect"></a>Rendering issues to expect</h2><ul><li>Font substitution changes line wrapping.</li><li>Embedded images can shift due to decoder differences.</li><li>Complex table layouts vary across office suite versions.</li></ul><h2 id="Operational-caution"><a href="#Operational-caution" class="headerlink" title="Operational caution"></a>Operational caution</h2><p>Treat conversion as an isolated service with clear resource limits. Batch jobs can spike memory and trigger cascading failures if they share resources with web workers.</p><h2 id="Verification-checklist"><a href="#Verification-checklist" class="headerlink" title="Verification checklist"></a>Verification checklist</h2><ul><li>Compare output against baseline templates.</li><li>Validate file count and naming for batch jobs.</li><li>Confirm worker restarts do not duplicate conversions.</li></ul><h2 id="FAQ"><a href="#FAQ" class="headerlink" title="FAQ"></a>FAQ</h2><h3 id="Is-LibreOffice-better-for-current-systems"><a href="#Is-LibreOffice-better-for-current-systems" class="headerlink" title="Is LibreOffice better for current systems?"></a>Is LibreOffice better for current systems?</h3><p>Usually yes, but migration should include output comparison testing before switch.</p><h3 id="How-do-I-avoid-stuck-conversion-processes"><a href="#How-do-I-avoid-stuck-conversion-processes" class="headerlink" title="How do I avoid stuck conversion processes?"></a>How do I avoid stuck conversion processes?</h3><p>Use supervision, timeouts, and explicit job-level retries with idempotent storage paths.</p><h3 id="Can-this-run-in-containers"><a href="#Can-this-run-in-containers" class="headerlink" title="Can this run in containers?"></a>Can this run in containers?</h3><p>Yes, but include fonts and locale packages explicitly.</p><h2 id="Related-reading"><a href="#Related-reading" class="headerlink" title="Related reading"></a>Related reading</h2><ul><li><a href="/blog/linux/">Linux hub</a></li><li><a href="/playbooks/deployment/">Deployment playbook</a></li><li><a href="/reference/shell-snippets/">Shell snippets</a></li></ul>]]>
    </content>
    <id>https://qugstart.com/blog/linux/openoffice-headless-mode-installation-word-doc-to-pdf-conversion/</id>
    <link href="https://qugstart.com/blog/linux/openoffice-headless-mode-installation-word-doc-to-pdf-conversion/"/>
    <published>2023-10-22T11:10:00.000Z</published>
    <summary>Practical Linux guide for running headless OpenOffice conversion jobs from Word documents to PDF with stable service behavior.</summary>
    <title>OpenOffice Headless Mode Installation Word Doc to PDF Conversion</title>
    <updated>2026-04-03T10:00:00.000Z</updated>
  </entry>
</feed>
