<!-- CANARY: REQ=REQ-DOCS-001; FEATURE="Docs"; ASPECT=Documentation; STATUS=TESTED; OWNER=docs; UPDATED=2026-01-15 --> <p>DevOps practices integrate development and operations workflows through automation, continuous integration, infrastructure as code, and systematic deployment processes. For Geode graph database deployments, DevOps enables reliable, repeatable deployments while maintaining high availability and rapid iteration cycles across development, staging, and production environments.</p> <h3 id="understanding-devops-for-graph-databases" class="position-relative d-flex align-items-center group"> <span>Understanding DevOps for Graph Databases</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="understanding-devops-for-graph-databases" aria-haspopup="dialog" aria-label="Share link: Understanding DevOps for Graph Databases"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><div id="headingShareModal" class="heading-share-modal" role="dialog" aria-modal="true" aria-labelledby="headingShareTitle" hidden> <div class="hsm-dialog" role="document"> <div class="hsm-header"> <h2 id="headingShareTitle" class="h6 mb-0 fw-bold">Share this section</h2> <button type="button" class="hsm-close" aria-label="Close"> <i class="fa-solid fa-xmark"></i> </button> </div> <div class="hsm-body"> <label for="headingShareInput" class="form-label small text-muted mb-1 text-uppercase fw-bold" style="font-size: 0.7rem; letter-spacing: 0.5px;">Permalink</label> <div class="input-group mb-4 hsm-url-group"> <input id="headingShareInput" type="text" class="form-control font-monospace" readonly aria-readonly="true" style="font-size: 0.85rem;" /> <button class="btn btn-primary hsm-copy" type="button" aria-label="Copy" title="Copy"> <i class="fa-duotone fa-clipboard" aria-hidden="true"></i> </button> </div> <div class="small fw-bold mb-2 text-muted text-uppercase" style="font-size: 0.7rem; letter-spacing: 0.5px;">Share via</div> <div class="hsm-share-grid"> <a id="share-twitter" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-twitter me-2"></i>Twitter </a> <a id="share-linkedin" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-linkedin me-2"></i>LinkedIn </a> <a id="share-facebook" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-facebook me-2"></i>Facebook </a> </div> </div> </div> </div> <style> .heading-share-modal { position: fixed; inset: 0; display: flex; justify-content: center; align-items: center; background: rgba(0, 0, 0, 0.6); z-index: 1050; padding: 1rem; backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); } .heading-share-modal[hidden] { display: none !important; } .hsm-dialog { max-width: 420px; width: 100%; background: var(--bs-body-bg, #fff); color: var(--bs-body-color, #212529); border: 1px solid var(--bs-border-color, rgba(0,0,0,0.1)); border-radius: 1rem; box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); overflow: hidden; animation: hsm-fade-in 0.2s ease-out; } @keyframes hsm-fade-in { from { opacity: 0; transform: scale(0.95); } to { opacity: 1; transform: scale(1); } } [data-bs-theme="dark"] .hsm-dialog { background: #1e293b; border-color: rgba(255,255,255,0.1); color: #f8f9fa; } .hsm-header { display: flex; justify-content: space-between; align-items: center; padding: 1rem 1.5rem; border-bottom: 1px solid var(--bs-border-color, rgba(0,0,0,0.1)); background: rgba(0,0,0,0.02); } [data-bs-theme="dark"] .hsm-header { background: rgba(255,255,255,0.02); border-color: rgba(255,255,255,0.1); } .hsm-close { background: transparent; border: none; color: inherit; opacity: 0.5; padding: 0.25rem 0.5rem; border-radius: 0.25rem; font-size: 1.2rem; line-height: 1; transition: opacity 0.2s; } .hsm-close:hover { opacity: 1; } .hsm-body { padding: 1.5rem; } .hsm-url-group { display: flex !important; align-items: stretch; } .hsm-url-group .form-control { flex: 1; min-width: 0; margin: 0; background: var(--bs-secondary-bg, #f8f9fa); border-color: var(--bs-border-color, #dee2e6); border-top-right-radius: 0; border-bottom-right-radius: 0; height: 42px; } .hsm-url-group .btn { flex: 0 0 auto; margin: 0; margin-left: -1px; border-top-left-radius: 0; border-bottom-left-radius: 0; height: 42px; display: flex; align-items: center; justify-content: center; padding: 0 1.25rem; z-index: 2; } [data-bs-theme="dark"] .hsm-url-group .form-control { background: #0f172a; border-color: #334155; color: #e2e8f0; } .hsm-share-grid { display: flex; flex-direction: column; gap: 0.5rem; } .hsm-share-grid .btn { display: flex; align-items: center; justify-content: center; font-size: 0.9rem; padding: 0.6rem; border-color: var(--bs-border-color); width: 100%; } [data-bs-theme="dark"] .hsm-share-grid .btn { color: #e2e8f0; border-color: #475569; } [data-bs-theme="dark"] .hsm-share-grid .btn:hover { background: #334155; border-color: #cbd5e1; } </style> <script> (function(){ const modal = document.getElementById('headingShareModal'); if(!modal) return; const input = modal.querySelector('#headingShareInput'); const copyBtn = modal.querySelector('.hsm-copy'); const twitter = modal.querySelector('#share-twitter'); const linkedin = modal.querySelector('#share-linkedin'); const facebook = modal.querySelector('#share-facebook'); const closeBtn = modal.querySelector('.hsm-close'); let lastFocus=null; let trapBound=false; function buildUrl(id){ return window.location.origin + window.location.pathname + '#' + id; } function isOpen(){ return !modal.hasAttribute('hidden'); } function hydrate(id){ const url=buildUrl(id); input.value=url; const enc=encodeURIComponent(url); const text=encodeURIComponent(document.title); if(twitter) twitter.href=`https://twitter.com/intent/tweet?url=${enc}&text=${text}`; if(linkedin) linkedin.href=`https://www.linkedin.com/sharing/share-offsite/?url=${enc}`; if(facebook) facebook.href=`https://www.facebook.com/sharer/sharer.php?u=${enc}`; } function openModal(id){ lastFocus=document.activeElement; hydrate(id); if(!isOpen()){ modal.removeAttribute('hidden'); } requestAnimationFrame(()=>{ input.focus(); }); trapFocus(); } function closeModal(){ if(!isOpen()) return; modal.setAttribute('hidden',''); if(lastFocus && typeof lastFocus.focus==='function') lastFocus.focus(); } function copyCurrent(){ try{ navigator.clipboard.writeText(input.value).then(()=>feedback(true),()=>fallback()); } catch(e){ fallback(); } } function fallback(){ input.select(); try{ document.execCommand('copy'); feedback(true);}catch(e){ feedback(false);} } function feedback(ok){ if(!copyBtn) return; const icon=copyBtn.querySelector('i'); if(!icon) return; const prev=copyBtn.getAttribute('data-prev')||icon.className; if(!copyBtn.getAttribute('data-prev')) copyBtn.setAttribute('data-prev',prev); icon.className= ok ? 'fa-duotone fa-clipboard-check':'fa-duotone fa-circle-exclamation'; setTimeout(()=>{ icon.className=prev; },1800); } function handleShareClick(e){ e.preventDefault(); const btn=e.currentTarget; const id=btn.getAttribute('data-share-target'); if(id) openModal(id); } function bindShareButtons(){ document.querySelectorAll('.h-share').forEach(btn=>{ if(!btn.dataset.hShareBound){ btn.addEventListener('click', handleShareClick); btn.dataset.hShareBound='1'; } }); } bindShareButtons(); if(document.readyState==='loading'){ document.addEventListener('DOMContentLoaded', bindShareButtons); } else { requestAnimationFrame(bindShareButtons); } document.addEventListener('click', function(e){ const shareBtn=e.target.closest && e.target.closest('.h-share'); if(shareBtn && !shareBtn.dataset.hShareBound){ handleShareClick.call(shareBtn, e); } }, true); document.addEventListener('click', e=>{ if(e.target===modal) closeModal(); if(e.target.closest && e.target.closest('.hsm-close')){ e.preventDefault(); closeModal(); } if(copyBtn && (e.target===copyBtn || (e.target.closest && e.target.closest('.hsm-copy')))) { e.preventDefault(); copyCurrent(); } }); document.addEventListener('keydown', e=>{ if(e.key==='Escape' && isOpen()) closeModal(); }); function trapFocus(){ if(trapBound) return; trapBound=true; modal.addEventListener('keydown', f=>{ if(f.key==='Tab' && isOpen()){ const focusable=[...modal.querySelectorAll('a[href],button,input,textarea,select,[tabindex]:not([tabindex="-1"])')].filter(el=>!el.hasAttribute('disabled')); if(!focusable.length) return; const first=focusable[0]; const last=focusable[focusable.length-1]; if(f.shiftKey && document.activeElement===first){ f.preventDefault(); last.focus(); } else if(!f.shiftKey && document.activeElement===last){ f.preventDefault(); first.focus(); } } }); } if(closeBtn) closeBtn.addEventListener('click', e=>{ e.preventDefault(); closeModal(); }); })(); </script><p>DevOps transforms database deployment from manual, error-prone procedures into automated, testable workflows. Traditional database operations often involve manual configuration, untested deployment scripts, and reactive incident response. Modern DevOps practices automate these processes, validate changes before production deployment, and enable rapid recovery from failures.</p> <h4 id="devops-principles" class="position-relative d-flex align-items-center group"> <span>DevOps Principles</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="devops-principles" aria-haspopup="dialog" aria-label="Share link: DevOps Principles"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Core DevOps principles guide Geode deployment automation. Infrastructure as Code (IaC) defines all infrastructure through version-controlled configuration files, enabling reproducible deployments and change tracking. Continuous Integration validates every code change through automated testing. Continuous Deployment automates the path from code commit to production deployment. Monitoring and observability provide visibility into system behavior and health.</p> <h4 id="devops-benefits" class="position-relative d-flex align-items-center group"> <span>DevOps Benefits</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="devops-benefits" aria-haspopup="dialog" aria-label="Share link: DevOps Benefits"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Implementing DevOps practices for Geode yields concrete benefits. Automated deployments reduce human error and deployment time from hours to minutes. Automated testing catches regressions before production deployment. Version-controlled infrastructure configurations enable rapid environment reproduction and disaster recovery. Monitoring integration detects issues proactively rather than reactively.</p> <h3 id="continuous-integration" class="position-relative d-flex align-items-center group"> <span>Continuous Integration</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="continuous-integration" aria-haspopup="dialog" aria-label="Share link: Continuous Integration"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p>Continuous Integration (CI) validates code changes through automated building and testing.</p> <h4 id="ci-pipeline-architecture" class="position-relative d-flex align-items-center group"> <span>CI Pipeline Architecture</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="ci-pipeline-architecture" aria-haspopup="dialog" aria-label="Share link: CI Pipeline Architecture"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>A typical Geode CI pipeline includes multiple stages, each validating different aspects of code quality:</p> <ol> <li>Build stage compiles Geode from source</li> <li>Unit test stage runs fast, isolated tests</li> <li>Integration test stage validates component interactions</li> <li>Performance test stage detects performance regressions</li> <li>Security scan stage identifies vulnerabilities</li> </ol> <h4 id="gitlab-ci-configuration" class="position-relative d-flex align-items-center group"> <span>GitLab CI Configuration</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="gitlab-ci-configuration" aria-haspopup="dialog" aria-label="Share link: GitLab CI Configuration"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Geode&rsquo;s monorepo uses GitLab CI for continuous integration:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># .gitlab-ci.yml</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">stages</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">build</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">test</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">integration</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">deploy</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">variables</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">ZIG_VERSION</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;0.1.0&#34;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c"># Build Geode</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">build</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">stage</span><span class="p">:</span><span class="w"> </span><span class="l">build</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">debian:bookworm</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">before_script</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">apt-get update &amp;&amp; apt-get install -y wget xz-utils make</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">wget https://ziglang.org/download/${ZIG_VERSION}/zig-linux-x86_64-${ZIG_VERSION}.tar.xz</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">tar -xf zig-linux-x86_64-${ZIG_VERSION}.tar.xz</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">export PATH=&#34;$(pwd)/zig-linux-x86_64-${ZIG_VERSION}:$PATH&#34;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">script</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">cd geode</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">make release</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">artifacts</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">paths</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">geode/zig-out/bin/geode</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">expire_in</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w"> </span><span class="l">day</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c"># Unit tests</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">test:unit</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">stage</span><span class="p">:</span><span class="w"> </span><span class="l">test</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">dependencies</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">build</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">script</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">cd geode</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">make test</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c"># Integration tests</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">test:integration</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">stage</span><span class="p">:</span><span class="w"> </span><span class="l">integration</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">dependencies</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">build</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">script</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">cd geode</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">geode serve --listen 127.0.0.1:3141 &amp;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">sleep 5</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">make geodetestlab-comprehensive</span><span class="w"> </span></span></span></code></pre></div> <h4 id="github-actions-alternative" class="position-relative d-flex align-items-center group"> <span>GitHub Actions Alternative</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="github-actions-alternative" aria-haspopup="dialog" aria-label="Share link: GitHub Actions Alternative"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>For GitHub-hosted repositories:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># .github/workflows/ci.yml</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">CI</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">on</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">push</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">branches</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="l">main, develop ]</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">pull_request</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">branches</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="l">main ]</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">jobs</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">build</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">runs-on</span><span class="p">:</span><span class="w"> </span><span class="l">ubuntu-latest</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">steps</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/checkout@v3</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Install Zig</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">goto-bus-stop/setup-zig@v2</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">with</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">version</span><span class="p">:</span><span class="w"> </span><span class="m">0.1.0</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Build Geode</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd"> </span></span></span><span class="line"><span class="cl"><span class="sd"> cd geode </span></span></span><span class="line"><span class="cl"><span class="sd"> make release</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Upload artifacts</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/upload-artifact@v3</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">with</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">geode-binary</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l">geode/zig-out/bin/geode</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">test</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">needs</span><span class="p">:</span><span class="w"> </span><span class="l">build</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">runs-on</span><span class="p">:</span><span class="w"> </span><span class="l">ubuntu-latest</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">steps</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/checkout@v3</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Download binary</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/download-artifact@v3</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">with</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">geode-binary</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l">geode/zig-out/bin/</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Run tests</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd"> </span></span></span><span class="line"><span class="cl"><span class="sd"> cd geode </span></span></span><span class="line"><span class="cl"><span class="sd"> make test</span><span class="w"> </span></span></span></code></pre></div> <h4 id="automated-testing-strategy" class="position-relative d-flex align-items-center group"> <span>Automated Testing Strategy</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="automated-testing-strategy" aria-haspopup="dialog" aria-label="Share link: Automated Testing Strategy"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Comprehensive automated testing catches issues before production:</p> <p><strong>Unit Tests</strong>: Fast, isolated component tests run on every commit:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Quick feedback loop</span> </span></span><span class="line"><span class="cl">make <span class="nb">test</span> </span></span></code></pre></div><p><strong>Integration Tests</strong>: Validate component interactions:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Test client-server communication</span> </span></span><span class="line"><span class="cl"><span class="nb">cd</span> geode-test-harness </span></span><span class="line"><span class="cl">make test-all </span></span></code></pre></div><p><strong>Performance Tests</strong>: Detect performance regressions:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Run benchmark suite</span> </span></span><span class="line"><span class="cl">./scripts/benchmark.sh </span></span><span class="line"><span class="cl"><span class="c1"># Compare to baseline</span> </span></span><span class="line"><span class="cl">./scripts/compare_performance.sh baseline.json current.json </span></span></code></pre></div> <h4 id="test-quality-gates" class="position-relative d-flex align-items-center group"> <span>Test Quality Gates</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="test-quality-gates" aria-haspopup="dialog" aria-label="Share link: Test Quality Gates"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Establish quality gates that must pass before merging:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># GitLab CI quality gates</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">test:quality-gate</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">stage</span><span class="p">:</span><span class="w"> </span><span class="l">test</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">script</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">cd geode</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">make test</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c"># Require &gt;90% test pass rate</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">./scripts/check_test_coverage.sh 90</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">only</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">merge_requests</span><span class="w"> </span></span></span></code></pre></div> <h3 id="continuous-deployment" class="position-relative d-flex align-items-center group"> <span>Continuous Deployment</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="continuous-deployment" aria-haspopup="dialog" aria-label="Share link: Continuous Deployment"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p>Continuous Deployment (CD) automates the delivery of validated code to production.</p> <h4 id="deployment-pipeline" class="position-relative d-flex align-items-center group"> <span>Deployment Pipeline</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="deployment-pipeline" aria-haspopup="dialog" aria-label="Share link: Deployment Pipeline"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>A multi-stage deployment pipeline promotes code through environments:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># .gitlab-ci.yml deployment stages</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">deploy:staging</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">stage</span><span class="p">:</span><span class="w"> </span><span class="l">deploy</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">environment</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">staging</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">script</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">./scripts/deploy_to_staging.sh</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">only</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">develop</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">deploy:production</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">stage</span><span class="p">:</span><span class="w"> </span><span class="l">deploy</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">environment</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">production</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">script</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">./scripts/deploy_to_production.sh</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">only</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">main</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">when</span><span class="p">:</span><span class="w"> </span><span class="l">manual </span><span class="w"> </span><span class="c"># Require manual approval for production</span><span class="w"> </span></span></span></code></pre></div> <h4 id="deployment-script-example" class="position-relative d-flex align-items-center group"> <span>Deployment Script Example</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="deployment-script-example" aria-haspopup="dialog" aria-label="Share link: Deployment Script Example"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Automated deployment script with validation:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash </span></span></span><span class="line"><span class="cl"><span class="cp"></span><span class="c1"># deploy_to_production.sh</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nb">set</span> -e </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nv">DEPLOY_HOST</span><span class="o">=</span><span class="s2">&#34;production-geode.example.com&#34;</span> </span></span><span class="line"><span class="cl"><span class="nv">BACKUP_DIR</span><span class="o">=</span><span class="s2">&#34;/backup/geode/</span><span class="k">$(</span>date +%Y%m%d-%H%M%S<span class="k">)</span><span class="s2">&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Starting production deployment...&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Create backup</span> </span></span><span class="line"><span class="cl">ssh <span class="nv">$DEPLOY_HOST</span> <span class="s2">&#34;sudo systemctl stop geode&#34;</span> </span></span><span class="line"><span class="cl">ssh <span class="nv">$DEPLOY_HOST</span> <span class="s2">&#34;sudo rsync -av /var/lib/geode/data/ </span><span class="nv">$BACKUP_DIR</span><span class="s2">/&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Deploy new binary</span> </span></span><span class="line"><span class="cl">scp geode/zig-out/bin/geode <span class="nv">$DEPLOY_HOST</span>:/tmp/geode </span></span><span class="line"><span class="cl">ssh <span class="nv">$DEPLOY_HOST</span> <span class="s2">&#34;sudo mv /tmp/geode /opt/geode/bin/geode&#34;</span> </span></span><span class="line"><span class="cl">ssh <span class="nv">$DEPLOY_HOST</span> <span class="s2">&#34;sudo chown geode:geode /opt/geode/bin/geode&#34;</span> </span></span><span class="line"><span class="cl">ssh <span class="nv">$DEPLOY_HOST</span> <span class="s2">&#34;sudo chmod 755 /opt/geode/bin/geode&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Start service</span> </span></span><span class="line"><span class="cl">ssh <span class="nv">$DEPLOY_HOST</span> <span class="s2">&#34;sudo systemctl start geode&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Verify deployment</span> </span></span><span class="line"><span class="cl">sleep <span class="m">10</span> </span></span><span class="line"><span class="cl">ssh <span class="nv">$DEPLOY_HOST</span> <span class="s2">&#34;systemctl is-active geode&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Health check</span> </span></span><span class="line"><span class="cl"><span class="k">if</span> ! curl -s <span class="s2">&#34;http://</span><span class="nv">$DEPLOY_HOST</span><span class="s2">:3141/health&#34;</span> <span class="p">|</span> grep -q <span class="s2">&#34;ok&#34;</span><span class="p">;</span> <span class="k">then</span> </span></span><span class="line"><span class="cl"> <span class="nb">echo</span> <span class="s2">&#34;Health check failed, rolling back...&#34;</span> </span></span><span class="line"><span class="cl"> ssh <span class="nv">$DEPLOY_HOST</span> <span class="s2">&#34;sudo systemctl stop geode&#34;</span> </span></span><span class="line"><span class="cl"> ssh <span class="nv">$DEPLOY_HOST</span> <span class="s2">&#34;sudo cp </span><span class="nv">$BACKUP_DIR</span><span class="s2">/geode /opt/geode/bin/geode&#34;</span> </span></span><span class="line"><span class="cl"> ssh <span class="nv">$DEPLOY_HOST</span> <span class="s2">&#34;sudo systemctl start geode&#34;</span> </span></span><span class="line"><span class="cl"> <span class="nb">exit</span> <span class="m">1</span> </span></span><span class="line"><span class="cl"><span class="k">fi</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Deployment successful!&#34;</span> </span></span></code></pre></div> <h4 id="blue-green-deployment" class="position-relative d-flex align-items-center group"> <span>Blue-Green Deployment</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="blue-green-deployment" aria-haspopup="dialog" aria-label="Share link: Blue-Green Deployment"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Minimize downtime with blue-green deployments:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash </span></span></span><span class="line"><span class="cl"><span class="cp"></span><span class="c1"># blue-green-deploy.sh</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Deploy to inactive environment</span> </span></span><span class="line"><span class="cl"><span class="k">if</span> systemctl is-active geode-blue<span class="p">;</span> <span class="k">then</span> </span></span><span class="line"><span class="cl"> <span class="nv">ACTIVE</span><span class="o">=</span><span class="s2">&#34;blue&#34;</span> </span></span><span class="line"><span class="cl"> <span class="nv">INACTIVE</span><span class="o">=</span><span class="s2">&#34;green&#34;</span> </span></span><span class="line"><span class="cl"><span class="k">else</span> </span></span><span class="line"><span class="cl"> <span class="nv">ACTIVE</span><span class="o">=</span><span class="s2">&#34;green&#34;</span> </span></span><span class="line"><span class="cl"> <span class="nv">INACTIVE</span><span class="o">=</span><span class="s2">&#34;blue&#34;</span> </span></span><span class="line"><span class="cl"><span class="k">fi</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Update inactive environment</span> </span></span><span class="line"><span class="cl">sudo systemctl stop geode-<span class="nv">$INACTIVE</span> </span></span><span class="line"><span class="cl">sudo cp new-binary /opt/geode-<span class="nv">$INACTIVE</span>/bin/geode </span></span><span class="line"><span class="cl">sudo systemctl start geode-<span class="nv">$INACTIVE</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Validate inactive environment</span> </span></span><span class="line"><span class="cl">sleep <span class="m">10</span> </span></span><span class="line"><span class="cl"><span class="k">if</span> systemctl is-active geode-<span class="nv">$INACTIVE</span><span class="p">;</span> <span class="k">then</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Switch load balancer to inactive (now active)</span> </span></span><span class="line"><span class="cl"> curl -X POST http://loadbalancer/switch-to/<span class="nv">$INACTIVE</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Stop previous active environment</span> </span></span><span class="line"><span class="cl"> sudo systemctl stop geode-<span class="nv">$ACTIVE</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nb">echo</span> <span class="s2">&#34;Switched to </span><span class="nv">$INACTIVE</span><span class="s2"> environment&#34;</span> </span></span><span class="line"><span class="cl"><span class="k">else</span> </span></span><span class="line"><span class="cl"> <span class="nb">echo</span> <span class="s2">&#34;Deployment to </span><span class="nv">$INACTIVE</span><span class="s2"> failed&#34;</span> </span></span><span class="line"><span class="cl"> <span class="nb">exit</span> <span class="m">1</span> </span></span><span class="line"><span class="cl"><span class="k">fi</span> </span></span></code></pre></div> <h3 id="infrastructure-as-code" class="position-relative d-flex align-items-center group"> <span>Infrastructure as Code</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="infrastructure-as-code" aria-haspopup="dialog" aria-label="Share link: Infrastructure as Code"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p>Define infrastructure through version-controlled code rather than manual configuration.</p> <h4 id="terraform-configuration" class="position-relative d-flex align-items-center group"> <span>Terraform Configuration</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="terraform-configuration" aria-haspopup="dialog" aria-label="Share link: Terraform Configuration"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Provision Geode infrastructure with Terraform:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-hcl" data-lang="hcl"><span class="line"><span class="cl"><span class="c1"># geode.tf </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">terraform</span> { </span></span><span class="line"><span class="cl"> <span class="k">required_providers</span> { </span></span><span class="line"><span class="cl"><span class="n"> aws</span> <span class="o">=</span> { </span></span><span class="line"><span class="cl"><span class="n"> source</span> <span class="o">=</span> <span class="s2">&#34;hashicorp/aws&#34;</span> </span></span><span class="line"><span class="cl"><span class="n"> version</span> <span class="o">=</span> <span class="s2">&#34;~&gt; 5.0&#34;</span> </span></span><span class="line"><span class="cl"> } </span></span><span class="line"><span class="cl"> } </span></span><span class="line"><span class="cl">} </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="k">provider</span> <span class="s2">&#34;aws&#34;</span> { </span></span><span class="line"><span class="cl"><span class="n"> region</span> <span class="o">=</span> <span class="s2">&#34;us-west-2&#34;</span> </span></span><span class="line"><span class="cl">}<span class="c1"> </span></span></span><span class="line"><span class="cl"><span class="c1"> </span></span></span><span class="line"><span class="cl"><span class="c1"># Geode server instance </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">resource</span> <span class="s2">&#34;aws_instance&#34; &#34;geode&#34;</span> { </span></span><span class="line"><span class="cl"><span class="n"> ami</span> <span class="o">=</span> <span class="s2">&#34;ami-0c55b159cbfafe1f0&#34;</span> </span></span><span class="line"><span class="cl"><span class="n"> instance_type</span> <span class="o">=</span> <span class="s2">&#34;t3.xlarge&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="n"> tags</span> <span class="o">=</span> { </span></span><span class="line"><span class="cl"><span class="n"> Name</span> <span class="o">=</span> <span class="s2">&#34;geode-production&#34;</span> </span></span><span class="line"><span class="cl"><span class="n"> Environment</span> <span class="o">=</span> <span class="s2">&#34;production&#34;</span> </span></span><span class="line"><span class="cl"> } </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="n"> user_data</span> <span class="o">=</span> <span class="k">templatefile</span><span class="p">(</span><span class="s2">&#34;${path.module}/user-data.sh&#34;</span><span class="p">,</span> { </span></span><span class="line"><span class="cl"><span class="n"> geode_version</span> <span class="o">=</span> <span class="k">var</span><span class="p">.</span><span class="k">geode_version</span> </span></span><span class="line"><span class="cl"> }<span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="n"> vpc_security_group_ids</span> <span class="o">=</span> <span class="p">[</span><span class="k">aws_security_group</span><span class="p">.</span><span class="k">geode</span><span class="p">.</span><span class="k">id</span><span class="p">]</span> </span></span><span class="line"><span class="cl">}<span class="c1"> </span></span></span><span class="line"><span class="cl"><span class="c1"> </span></span></span><span class="line"><span class="cl"><span class="c1"># Security group </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">resource</span> <span class="s2">&#34;aws_security_group&#34; &#34;geode&#34;</span> { </span></span><span class="line"><span class="cl"><span class="n"> name</span> <span class="o">=</span> <span class="s2">&#34;geode-sg&#34;</span> </span></span><span class="line"><span class="cl"><span class="n"> description</span> <span class="o">=</span> <span class="s2">&#34;Security group for Geode database&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">ingress</span> { </span></span><span class="line"><span class="cl"><span class="n"> from_port</span> <span class="o">=</span> <span class="m">3141</span> </span></span><span class="line"><span class="cl"><span class="n"> to_port</span> <span class="o">=</span> <span class="m">3141</span> </span></span><span class="line"><span class="cl"><span class="n"> protocol</span> <span class="o">=</span> <span class="s2">&#34;udp&#34;</span> </span></span><span class="line"><span class="cl"><span class="n"> cidr_blocks</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&#34;10.0.0.0/8&#34;</span><span class="p">]</span> </span></span><span class="line"><span class="cl"> } </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">egress</span> { </span></span><span class="line"><span class="cl"><span class="n"> from_port</span> <span class="o">=</span> <span class="m">0</span> </span></span><span class="line"><span class="cl"><span class="n"> to_port</span> <span class="o">=</span> <span class="m">0</span> </span></span><span class="line"><span class="cl"><span class="n"> protocol</span> <span class="o">=</span> <span class="s2">&#34;-1&#34;</span> </span></span><span class="line"><span class="cl"><span class="n"> cidr_blocks</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&#34;0.0.0.0/0&#34;</span><span class="p">]</span> </span></span><span class="line"><span class="cl"> } </span></span><span class="line"><span class="cl">}<span class="c1"> </span></span></span><span class="line"><span class="cl"><span class="c1"> </span></span></span><span class="line"><span class="cl"><span class="c1"># Elastic IP </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">resource</span> <span class="s2">&#34;aws_eip&#34; &#34;geode&#34;</span> { </span></span><span class="line"><span class="cl"><span class="n"> instance</span> <span class="o">=</span> <span class="k">aws_instance</span><span class="p">.</span><span class="k">geode</span><span class="p">.</span><span class="k">id</span> </span></span><span class="line"><span class="cl"><span class="n"> domain</span> <span class="o">=</span> <span class="s2">&#34;vpc&#34;</span> </span></span><span class="line"><span class="cl">} </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="k">output</span> <span class="s2">&#34;geode_public_ip&#34;</span> { </span></span><span class="line"><span class="cl"><span class="n"> value</span> <span class="o">=</span> <span class="k">aws_eip</span><span class="p">.</span><span class="k">geode</span><span class="p">.</span><span class="k">public_ip</span> </span></span><span class="line"><span class="cl">} </span></span></code></pre></div><p>User data script for instance initialization:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash </span></span></span><span class="line"><span class="cl"><span class="cp"></span><span class="c1"># user-data.sh</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Install dependencies</span> </span></span><span class="line"><span class="cl">apt-get update </span></span><span class="line"><span class="cl">apt-get install -y wget ca-certificates </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Install Zig</span> </span></span><span class="line"><span class="cl">wget https://ziglang.org/download/0.1.0/zig-linux-x86_64-0.1.0.tar.xz </span></span><span class="line"><span class="cl">tar -xf zig-linux-x86_64-0.1.0.tar.xz -C /opt </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Clone and build Geode</span> </span></span><span class="line"><span class="cl"><span class="nb">cd</span> /opt </span></span><span class="line"><span class="cl">git clone https://github.com/codeprosorg/geode </span></span><span class="line"><span class="cl"><span class="nb">cd</span> geode </span></span><span class="line"><span class="cl">/opt/zig-linux-x86_64-0.1.0/zig build -Doptimize<span class="o">=</span>ReleaseSafe </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Install as service</span> </span></span><span class="line"><span class="cl">cp zig-out/bin/geode /usr/local/bin/ </span></span><span class="line"><span class="cl">systemctl <span class="nb">enable</span> geode </span></span><span class="line"><span class="cl">systemctl start geode </span></span></code></pre></div> <h4 id="ansible-configuration" class="position-relative d-flex align-items-center group"> <span>Ansible Configuration</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="ansible-configuration" aria-haspopup="dialog" aria-label="Share link: Ansible Configuration"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Manage Geode configuration with Ansible:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># playbook.yml</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nn">---</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Deploy Geode Graph Database</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">hosts</span><span class="p">:</span><span class="w"> </span><span class="l">geode_servers</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">become</span><span class="p">:</span><span class="w"> </span><span class="kc">yes</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">vars</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">geode_version</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;0.2.18&#34;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">geode_data_dir</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/var/lib/geode/data&#34;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">geode_user</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;geode&#34;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">tasks</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Create geode user</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">user</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;{{ geode_user }}&#34;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">system</span><span class="p">:</span><span class="w"> </span><span class="kc">yes</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">create_home</span><span class="p">:</span><span class="w"> </span><span class="kc">no</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">shell</span><span class="p">:</span><span class="w"> </span><span class="l">/sbin/nologin</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Create data directory</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">file</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;{{ geode_data_dir }}&#34;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">state</span><span class="p">:</span><span class="w"> </span><span class="l">directory</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">owner</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;{{ geode_user }}&#34;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">group</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;{{ geode_user }}&#34;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">mode</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;0750&#39;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Copy Geode binary</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">copy</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">src</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;zig-out/bin/geode&#34;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">dest</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/usr/local/bin/geode&#34;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">owner</span><span class="p">:</span><span class="w"> </span><span class="l">root</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">group</span><span class="p">:</span><span class="w"> </span><span class="l">root</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">mode</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;0755&#39;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Install systemd service</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">template</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">src</span><span class="p">:</span><span class="w"> </span><span class="l">templates/geode.service.j2</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">dest</span><span class="p">:</span><span class="w"> </span><span class="l">/etc/systemd/system/geode.service</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">notify</span><span class="p">:</span><span class="w"> </span><span class="l">reload systemd</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Start Geode service</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">systemd</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">geode</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">state</span><span class="p">:</span><span class="w"> </span><span class="l">started</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="kc">yes</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">handlers</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">reload systemd</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">systemd</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">daemon_reload</span><span class="p">:</span><span class="w"> </span><span class="kc">yes</span><span class="w"> </span></span></span></code></pre></div> <h4 id="docker-compose-infrastructure" class="position-relative d-flex align-items-center group"> <span>Docker Compose Infrastructure</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="docker-compose-infrastructure" aria-haspopup="dialog" aria-label="Share link: Docker Compose Infrastructure"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Define multi-container Geode deployments:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># docker-compose.yml</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">version</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;3.8&#39;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">services</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">geode-primary</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">geode:0.2.18</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">container_name</span><span class="p">:</span><span class="w"> </span><span class="l">geode-primary</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">ports</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="s2">&#34;3141:3141/udp&#34;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">volumes</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">geode-primary-data:/var/lib/geode/data</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">./config/cert.pem:/etc/geode/cert.pem:ro</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">./config/key.pem:/etc/geode/key.pem:ro</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">environment</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">GEODE_LOG_LEVEL=info</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">GEODE_MAX_CONNECTIONS=1000</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">restart</span><span class="p">:</span><span class="w"> </span><span class="l">always</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">networks</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">geode-net</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">healthcheck</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">test</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;CMD&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;geode&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;ping&#34;</span><span class="p">]</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">interval</span><span class="p">:</span><span class="w"> </span><span class="l">30s</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">timeout</span><span class="p">:</span><span class="w"> </span><span class="l">10s</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">retries</span><span class="p">:</span><span class="w"> </span><span class="m">3</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">geode-replica</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">geode:0.2.18</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">container_name</span><span class="p">:</span><span class="w"> </span><span class="l">geode-replica</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">ports</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="s2">&#34;3142:3141/udp&#34;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">volumes</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">geode-replica-data:/var/lib/geode/data</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">environment</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">GEODE_REPLICA_OF=geode-primary:3141</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">depends_on</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">geode-primary</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">restart</span><span class="p">:</span><span class="w"> </span><span class="l">always</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">networks</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">geode-net</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">prometheus</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">prom/prometheus:latest</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">ports</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="s2">&#34;9090:9090&#34;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">volumes</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">./config/prometheus.yml:/etc/prometheus/prometheus.yml</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">prometheus-data:/prometheus</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">networks</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">geode-net</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">grafana</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">grafana/grafana:latest</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">ports</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="s2">&#34;3000:3000&#34;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">volumes</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">grafana-data:/var/lib/grafana</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">./config/grafana-dashboards:/etc/grafana/provisioning/dashboards</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">environment</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">GF_SECURITY_ADMIN_PASSWORD=admin</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">networks</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">geode-net</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">volumes</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">geode-primary-data</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">geode-replica-data</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">prometheus-data</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">grafana-data</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">networks</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">geode-net</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">driver</span><span class="p">:</span><span class="w"> </span><span class="l">bridge</span><span class="w"> </span></span></span></code></pre></div> <h3 id="configuration-management" class="position-relative d-flex align-items-center group"> <span>Configuration Management</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="configuration-management" aria-haspopup="dialog" aria-label="Share link: Configuration Management"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p>Manage Geode configuration across environments.</p> <h4 id="environment-specific-configuration" class="position-relative d-flex align-items-center group"> <span>Environment-Specific Configuration</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="environment-specific-configuration" aria-haspopup="dialog" aria-label="Share link: Environment-Specific Configuration"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Separate configuration for different environments:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># config/development.env</span> </span></span><span class="line"><span class="cl"><span class="nv">GEODE_LISTEN</span><span class="o">=</span>127.0.0.1:3141 </span></span><span class="line"><span class="cl"><span class="nv">GEODE_DATA_DIR</span><span class="o">=</span>./data </span></span><span class="line"><span class="cl"><span class="nv">GEODE_LOG_LEVEL</span><span class="o">=</span>debug </span></span><span class="line"><span class="cl"><span class="nv">GEODE_MAX_CONNECTIONS</span><span class="o">=</span><span class="m">100</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># config/staging.env</span> </span></span><span class="line"><span class="cl"><span class="nv">GEODE_LISTEN</span><span class="o">=</span>0.0.0.0:3141 </span></span><span class="line"><span class="cl"><span class="nv">GEODE_DATA_DIR</span><span class="o">=</span>/var/lib/geode/data </span></span><span class="line"><span class="cl"><span class="nv">GEODE_LOG_LEVEL</span><span class="o">=</span>info </span></span><span class="line"><span class="cl"><span class="nv">GEODE_MAX_CONNECTIONS</span><span class="o">=</span><span class="m">500</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># config/production.env</span> </span></span><span class="line"><span class="cl"><span class="nv">GEODE_LISTEN</span><span class="o">=</span>0.0.0.0:3141 </span></span><span class="line"><span class="cl"><span class="nv">GEODE_DATA_DIR</span><span class="o">=</span>/var/lib/geode/data </span></span><span class="line"><span class="cl"><span class="nv">GEODE_LOG_LEVEL</span><span class="o">=</span>warn </span></span><span class="line"><span class="cl"><span class="nv">GEODE_MAX_CONNECTIONS</span><span class="o">=</span><span class="m">1000</span> </span></span></code></pre></div> <h4 id="secret-management" class="position-relative d-flex align-items-center group"> <span>Secret Management</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="secret-management" aria-haspopup="dialog" aria-label="Share link: Secret Management"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Store sensitive configuration securely:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Use HashiCorp Vault</span> </span></span><span class="line"><span class="cl">vault kv put secret/geode/production <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> <span class="nv">tls_cert</span><span class="o">=</span>@/path/to/cert.pem <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> <span class="nv">tls_key</span><span class="o">=</span>@/path/to/key.pem </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Retrieve in deployment script</span> </span></span><span class="line"><span class="cl">vault kv get -field<span class="o">=</span>tls_cert secret/geode/production &gt; /etc/geode/cert.pem </span></span><span class="line"><span class="cl">vault kv get -field<span class="o">=</span>tls_key secret/geode/production &gt; /etc/geode/key.pem </span></span></code></pre></div> <h3 id="monitoring-and-observability" class="position-relative d-flex align-items-center group"> <span>Monitoring and Observability</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="monitoring-and-observability" aria-haspopup="dialog" aria-label="Share link: Monitoring and Observability"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p>Integrate monitoring into DevOps workflows.</p> <h4 id="prometheus-integration" class="position-relative d-flex align-items-center group"> <span>Prometheus Integration</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="prometheus-integration" aria-haspopup="dialog" aria-label="Share link: Prometheus Integration"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Expose Geode metrics for Prometheus:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># prometheus.yml</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">global</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">scrape_interval</span><span class="p">:</span><span class="w"> </span><span class="l">15s</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">scrape_configs</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">job_name</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;geode&#39;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">static_configs</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">targets</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s1">&#39;geode:9091&#39;</span><span class="p">]</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">metrics_path</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;/metrics&#39;</span><span class="w"> </span></span></span></code></pre></div> <h4 id="logging-aggregation" class="position-relative d-flex align-items-center group"> <span>Logging Aggregation</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="logging-aggregation" aria-haspopup="dialog" aria-label="Share link: Logging Aggregation"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Centralize logs with ELK stack:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># filebeat.yml</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">filebeat.inputs</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">log</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">paths</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="l">/var/log/geode/*.log</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">fields</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">app</span><span class="p">:</span><span class="w"> </span><span class="l">geode</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">environment</span><span class="p">:</span><span class="w"> </span><span class="l">production</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">output.elasticsearch</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">hosts</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;elasticsearch:9200&#34;</span><span class="p">]</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">index</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;geode-logs-%{+yyyy.MM.dd}&#34;</span><span class="w"> </span></span></span></code></pre></div> <h4 id="alerting" class="position-relative d-flex align-items-center group"> <span>Alerting</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="alerting" aria-haspopup="dialog" aria-label="Share link: Alerting"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Configure alerts for critical conditions:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># alertmanager.yml</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">groups</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">geode</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">interval</span><span class="p">:</span><span class="w"> </span><span class="l">30s</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">rules</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">alert</span><span class="p">:</span><span class="w"> </span><span class="l">GeodeDown</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">expr</span><span class="p">:</span><span class="w"> </span><span class="l">up{job=&#34;geode&#34;} == 0</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">for</span><span class="p">:</span><span class="w"> </span><span class="l">1m</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">annotations</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">summary</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Geode instance down&#34;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Geode on {{ $labels.instance }} has been down for 1 minute&#34;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">alert</span><span class="p">:</span><span class="w"> </span><span class="l">HighQueryLatency</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">expr</span><span class="p">:</span><span class="w"> </span><span class="l">geode_query_duration_seconds &gt; 1</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">for</span><span class="p">:</span><span class="w"> </span><span class="l">5m</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">annotations</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">summary</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;High query latency detected&#34;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Query latency on {{ $labels.instance }} exceeds 1 second&#34;</span><span class="w"> </span></span></span></code></pre></div> <h3 id="backup-automation" class="position-relative d-flex align-items-center group"> <span>Backup Automation</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="backup-automation" aria-haspopup="dialog" aria-label="Share link: Backup Automation"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p>Automate backup processes.</p> <h4 id="automated-backup-script" class="position-relative d-flex align-items-center group"> <span>Automated Backup Script</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="automated-backup-script" aria-haspopup="dialog" aria-label="Share link: Automated Backup Script"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash </span></span></span><span class="line"><span class="cl"><span class="cp"></span><span class="c1"># backup-geode.sh</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nv">BACKUP_DIR</span><span class="o">=</span><span class="s2">&#34;/backup/geode&#34;</span> </span></span><span class="line"><span class="cl"><span class="nv">DATE</span><span class="o">=</span><span class="k">$(</span>date +%Y%m%d-%H%M%S<span class="k">)</span> </span></span><span class="line"><span class="cl"><span class="nv">RETENTION_DAYS</span><span class="o">=</span><span class="m">7</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Create backup</span> </span></span><span class="line"><span class="cl">rsync -av /var/lib/geode/data/ <span class="si">${</span><span class="nv">BACKUP_DIR</span><span class="si">}</span>/<span class="si">${</span><span class="nv">DATE</span><span class="si">}</span>/ </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Upload to S3</span> </span></span><span class="line"><span class="cl">aws s3 sync <span class="si">${</span><span class="nv">BACKUP_DIR</span><span class="si">}</span>/<span class="si">${</span><span class="nv">DATE</span><span class="si">}</span>/ s3://geode-backups/<span class="si">${</span><span class="nv">DATE</span><span class="si">}</span>/ </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Cleanup old backups</span> </span></span><span class="line"><span class="cl">find <span class="si">${</span><span class="nv">BACKUP_DIR</span><span class="si">}</span> -type d -mtime +<span class="si">${</span><span class="nv">RETENTION_DAYS</span><span class="si">}</span> -exec rm -rf <span class="o">{}</span> <span class="se">\;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Verify backup</span> </span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[</span> -f <span class="s2">&#34;</span><span class="si">${</span><span class="nv">BACKUP_DIR</span><span class="si">}</span><span class="s2">/</span><span class="si">${</span><span class="nv">DATE</span><span class="si">}</span><span class="s2">/data.db&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span> </span></span><span class="line"><span class="cl"> <span class="nb">echo</span> <span class="s2">&#34;Backup successful: </span><span class="si">${</span><span class="nv">DATE</span><span class="si">}</span><span class="s2">&#34;</span> </span></span><span class="line"><span class="cl"><span class="k">else</span> </span></span><span class="line"><span class="cl"> <span class="nb">echo</span> <span class="s2">&#34;Backup failed: </span><span class="si">${</span><span class="nv">DATE</span><span class="si">}</span><span class="s2">&#34;</span> </span></span><span class="line"><span class="cl"> <span class="nb">exit</span> <span class="m">1</span> </span></span><span class="line"><span class="cl"><span class="k">fi</span> </span></span></code></pre></div> <h4 id="backup-monitoring" class="position-relative d-flex align-items-center group"> <span>Backup Monitoring</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="backup-monitoring" aria-haspopup="dialog" aria-label="Share link: Backup Monitoring"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Monitor backup success:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># check-backup.sh</span> </span></span><span class="line"><span class="cl"><span class="nv">LATEST_BACKUP</span><span class="o">=</span><span class="k">$(</span>ls -t /backup/geode <span class="p">|</span> head -1<span class="k">)</span> </span></span><span class="line"><span class="cl"><span class="nv">BACKUP_AGE</span><span class="o">=</span><span class="k">$((</span> <span class="o">(</span><span class="k">$(</span>date +%s<span class="k">)</span> <span class="o">-</span> <span class="k">$(</span>stat -c %Y /backup/geode/<span class="nv">$LATEST_BACKUP</span><span class="k">)</span><span class="o">)</span> <span class="o">/</span> <span class="m">3600</span> <span class="k">))</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[</span> <span class="nv">$BACKUP_AGE</span> -gt <span class="m">24</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span> </span></span><span class="line"><span class="cl"> <span class="nb">echo</span> <span class="s2">&#34;CRITICAL: Last backup is </span><span class="nv">$BACKUP_AGE</span><span class="s2"> hours old&#34;</span> </span></span><span class="line"><span class="cl"> <span class="nb">exit</span> <span class="m">2</span> </span></span><span class="line"><span class="cl"><span class="k">fi</span> </span></span></code></pre></div> <h3 id="related-topics" class="position-relative d-flex align-items-center group"> <span>Related Topics</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="related-topics" aria-haspopup="dialog" aria-label="Share link: Related Topics"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p>DevOps connects to several operational areas:</p> <ul> <li><strong>CI/CD</strong> - Continuous integration and deployment pipelines</li> <li><strong>Automation</strong> - Workflow automation and scripting</li> <li><strong>Monitoring</strong> - System observability and alerting</li> <li><strong>Deployment</strong> - Production deployment strategies</li> <li><strong>Operations</strong> - Ongoing operational management</li> </ul> <h3 id="resources" class="position-relative d-flex align-items-center group"> <span>Resources</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="resources" aria-haspopup="dialog" aria-label="Share link: Resources"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p>Additional DevOps resources:</p> <ul> <li>CI/CD platform documentation (GitLab CI, GitHub Actions)</li> <li>Infrastructure as Code tools (Terraform, Ansible)</li> <li>Container orchestration guides (Docker, Kubernetes)</li> <li>Monitoring and observability platforms (Prometheus, Grafana)</li> </ul> <p>DevOps practices transform Geode deployment from manual processes into reliable, automated workflows that enable rapid iteration while maintaining production stability and operational excellence.</p>

Related Articles