gentelella/docs/_site/deployment/index.html

1618 lines
94 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<link rel="stylesheet" href="/gentelella/assets/css/just-the-docs-default.css">
<link rel="stylesheet" href="/gentelella/assets/css/just-the-docs-head-nav.css" id="jtd-head-nav-stylesheet">
<style id="jtd-nav-activation">
.site-nav > ul.nav-list:first-child > li:not(:nth-child(5)) > a,
.site-nav > ul.nav-list:first-child > li > ul > li a {
background-image: none;
}
.site-nav > ul.nav-list:not(:first-child) a,
.site-nav li.external a {
background-image: none;
}
.site-nav > ul.nav-list:first-child > li:nth-child(5) > a {
font-weight: 600;
text-decoration: none;
}.site-nav > ul.nav-list:first-child > li:nth-child(5) > button svg {
transform: rotate(-90deg);
}.site-nav > ul.nav-list:first-child > li.nav-list-item:nth-child(5) > ul.nav-list {
display: block;
}
</style>
<script src="/gentelella/assets/js/vendor/lunr.min.js"></script>
<script src="/gentelella/assets/js/just-the-docs.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="/gentelella/favicon.ico" type="image/x-icon">
<!-- Begin Jekyll SEO tag v2.8.0 -->
<title>Deployment Guide | Gentelella Admin Template</title>
<meta name="generator" content="Jekyll v3.10.0" />
<meta property="og:title" content="Deployment Guide" />
<meta property="og:locale" content="en_US" />
<meta name="description" content="Modern Bootstrap 5 Admin Dashboard Template with Performance Optimizations" />
<meta property="og:description" content="Modern Bootstrap 5 Admin Dashboard Template with Performance Optimizations" />
<link rel="canonical" href="https://puikinsh.github.io/gentelella/deployment/" />
<meta property="og:url" content="https://puikinsh.github.io/gentelella/deployment/" />
<meta property="og:site_name" content="Gentelella Admin Template" />
<meta property="og:image" content="https://puikinsh.github.io/gentelella/assets/images/gentelella-preview.jpg" />
<meta property="og:type" content="website" />
<meta name="twitter:card" content="summary_large_image" />
<meta property="twitter:image" content="https://puikinsh.github.io/gentelella/assets/images/gentelella-preview.jpg" />
<meta property="twitter:title" content="Deployment Guide" />
<script type="application/ld+json">
{"@context":"https://schema.org","@type":"WebPage","description":"Modern Bootstrap 5 Admin Dashboard Template with Performance Optimizations","headline":"Deployment Guide","image":"https://puikinsh.github.io/gentelella/assets/images/gentelella-preview.jpg","url":"https://puikinsh.github.io/gentelella/deployment/"}</script>
<!-- End Jekyll SEO tag -->
</head>
<body>
<a class="skip-to-main" href="#main-content">Skip to main content</a>
<svg xmlns="http://www.w3.org/2000/svg" class="d-none">
<symbol id="svg-link" viewBox="0 0 24 24">
<title>Link</title>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link">
<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path>
</svg>
</symbol>
<symbol id="svg-menu" viewBox="0 0 24 24">
<title>Menu</title>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-menu">
<line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line>
</svg>
</symbol>
<symbol id="svg-arrow-right" viewBox="0 0 24 24">
<title>Expand</title>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-chevron-right">
<polyline points="9 18 15 12 9 6"></polyline>
</svg>
</symbol>
<!-- Feather. MIT License: https://github.com/feathericons/feather/blob/master/LICENSE -->
<symbol id="svg-external-link" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-external-link">
<title id="svg-external-link-title">(external link)</title>
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line>
</symbol>
<symbol id="svg-doc" viewBox="0 0 24 24">
<title>Document</title>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file">
<path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path><polyline points="13 2 13 9 20 9"></polyline>
</svg>
</symbol>
<symbol id="svg-search" viewBox="0 0 24 24">
<title>Search</title>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search">
<circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line>
</svg>
</symbol>
<!-- Bootstrap Icons. MIT License: https://github.com/twbs/icons/blob/main/LICENSE.md -->
<symbol id="svg-copy" viewBox="0 0 16 16">
<title>Copy</title>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-clipboard" viewBox="0 0 16 16">
<path d="M4 1.5H3a2 2 0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1h1a1 1 0 0 1 1 1V14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V3.5a1 1 0 0 1 1-1h1v-1z"/>
<path d="M9.5 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5h3zm-3-1A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3z"/>
</svg>
</symbol>
<symbol id="svg-copied" viewBox="0 0 16 16">
<title>Copied</title>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-clipboard-check-fill" viewBox="0 0 16 16">
<path d="M6.5 0A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3Zm3 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5h3Z"/>
<path d="M4 1.5H3a2 2 0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1A2.5 2.5 0 0 1 9.5 5h-3A2.5 2.5 0 0 1 4 2.5v-1Zm6.854 7.354-3 3a.5.5 0 0 1-.708 0l-1.5-1.5a.5.5 0 0 1 .708-.708L7.5 10.793l2.646-2.647a.5.5 0 0 1 .708.708Z"/>
</svg>
</symbol>
</svg>
<div class="side-bar">
<div class="site-header" role="banner">
<a href="/gentelella/" class="site-title lh-tight">
Gentelella Admin Template
</a>
<button id="menu-button" class="site-button btn-reset" aria-label="Toggle menu" aria-pressed="false">
<svg viewBox="0 0 24 24" class="icon" aria-hidden="true"><use xlink:href="#svg-menu"></use></svg>
</button>
</div>
<nav aria-label="Main" id="site-nav" class="site-nav">
<ul class="nav-list"><li class="nav-list-item"><a href="/gentelella/" class="nav-list-link">Gentelella Admin Template Documentation</a></li><li class="nav-list-item"><a href="/gentelella/installation/" class="nav-list-link">Installation Guide</a></li><li class="nav-list-item"><a href="/gentelella/configuration/" class="nav-list-link">Configuration</a></li><li class="nav-list-item"><a href="/gentelella/components/" class="nav-list-link">Components Guide</a></li><li class="nav-list-item"><a href="/gentelella/deployment/" class="nav-list-link">Deployment Guide</a></li><li class="nav-list-item"><a href="/gentelella/customization/" class="nav-list-link">Customization Guide</a></li><li class="nav-list-item"><a href="/gentelella/api-integration/" class="nav-list-link">API Integration</a></li><li class="nav-list-item"><a href="/gentelella/bundle-analysis/" class="nav-list-link">Bundle Analysis Guide</a></li><li class="nav-list-item"><a href="/gentelella/jquery-elimination-complete/" class="nav-list-link">Complete jQuery Elimination Achievement 🎉</a></li><li class="nav-list-item"><a href="/gentelella/daterangepicker-fix/" class="nav-list-link">Date Range Picker Fix Documentation</a></li><li class="nav-list-item"><a href="/gentelella/security-headers/" class="nav-list-link">Security Headers Implementation Guide</a></li></ul>
</nav>
<footer class="site-footer">
This site uses <a href="https://github.com/just-the-docs/just-the-docs">Just the Docs</a>, a documentation theme for Jekyll.
</footer>
</div>
<div class="main" id="top">
<div id="main-header" class="main-header">
<div class="search" role="search">
<div class="search-input-wrap">
<input type="text" id="search-input" class="search-input" tabindex="0" placeholder="Search Gentelella Admin Template" aria-label="Search Gentelella Admin Template" autocomplete="off">
<label for="search-input" class="search-label"><svg viewBox="0 0 24 24" class="search-icon"><use xlink:href="#svg-search"></use></svg></label>
</div>
<div id="search-results" class="search-results"></div>
</div>
<nav aria-label="Auxiliary" class="aux-nav">
<ul class="aux-nav-list">
<li class="aux-nav-list-item">
<a href="//github.com/puikinsh/gentelella" class="site-button"
>
Gentelella on GitHub
</a>
</li>
<li class="aux-nav-list-item">
<a href="//colorlib.com" class="site-button"
>
Colorlib
</a>
</li>
</ul>
</nav>
</div>
<div class="main-content-wrap">
<div id="main-content" class="main-content">
<main>
<h1 class="no_toc" id="deployment-guide">
<a href="#deployment-guide" class="anchor-heading" aria-labelledby="deployment-guide"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Deployment Guide
</h1>
<p class="fs-6 fw-300">Complete guide to deploying Gentelella Admin Template to production environments</p>
<h2 class="no_toc text-delta" id="table-of-contents">
<a href="#table-of-contents" class="anchor-heading" aria-labelledby="table-of-contents"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Table of contents
</h2>
<ol id="markdown-toc">
<li><a href="#pre-deployment-checklist" id="markdown-toc-pre-deployment-checklist">Pre-Deployment Checklist</a> <ol>
<li><a href="#build-optimization" id="markdown-toc-build-optimization">Build Optimization</a></li>
<li><a href="#environment-configuration" id="markdown-toc-environment-configuration">Environment Configuration</a> <ol>
<li><a href="#production-environment-variables" id="markdown-toc-production-environment-variables">Production Environment Variables</a></li>
<li><a href="#build-configuration" id="markdown-toc-build-configuration">Build Configuration</a></li>
</ol>
</li>
</ol>
</li>
<li><a href="#static-hosting-platforms" id="markdown-toc-static-hosting-platforms">Static Hosting Platforms</a> <ol>
<li><a href="#netlify-deployment" id="markdown-toc-netlify-deployment">Netlify Deployment</a> <ol>
<li><a href="#method-1-git-integration-recommended" id="markdown-toc-method-1-git-integration-recommended">Method 1: Git Integration (Recommended)</a></li>
<li><a href="#method-2-manual-deploy" id="markdown-toc-method-2-manual-deploy">Method 2: Manual Deploy</a></li>
<li><a href="#netlify-configuration" id="markdown-toc-netlify-configuration">Netlify Configuration</a></li>
</ol>
</li>
<li><a href="#vercel-deployment" id="markdown-toc-vercel-deployment">Vercel Deployment</a> <ol>
<li><a href="#git-integration" id="markdown-toc-git-integration">Git Integration</a></li>
<li><a href="#manual-deployment" id="markdown-toc-manual-deployment">Manual Deployment</a></li>
<li><a href="#vercel-configuration" id="markdown-toc-vercel-configuration">Vercel Configuration</a></li>
</ol>
</li>
<li><a href="#github-pages" id="markdown-toc-github-pages">GitHub Pages</a> <ol>
<li><a href="#github-actions-deployment" id="markdown-toc-github-actions-deployment">GitHub Actions Deployment</a></li>
<li><a href="#update-vite-configuration-for-github-pages" id="markdown-toc-update-vite-configuration-for-github-pages">Update Vite Configuration for GitHub Pages</a></li>
</ol>
</li>
</ol>
</li>
<li><a href="#server-hosting" id="markdown-toc-server-hosting">Server Hosting</a> <ol>
<li><a href="#nginx-configuration" id="markdown-toc-nginx-configuration">Nginx Configuration</a> <ol>
<li><a href="#basic-setup" id="markdown-toc-basic-setup">Basic Setup</a></li>
<li><a href="#ssl-with-lets-encrypt" id="markdown-toc-ssl-with-lets-encrypt">SSL with Lets Encrypt</a></li>
</ol>
</li>
<li><a href="#apache-configuration" id="markdown-toc-apache-configuration">Apache Configuration</a> <ol>
<li><a href="#virtual-host-setup" id="markdown-toc-virtual-host-setup">Virtual Host Setup</a></li>
</ol>
</li>
</ol>
</li>
<li><a href="#container-deployment" id="markdown-toc-container-deployment">Container Deployment</a> <ol>
<li><a href="#docker-setup" id="markdown-toc-docker-setup">Docker Setup</a> <ol>
<li><a href="#dockerfile" id="markdown-toc-dockerfile">Dockerfile</a></li>
<li><a href="#docker-nginx-configuration" id="markdown-toc-docker-nginx-configuration">Docker Nginx Configuration</a></li>
<li><a href="#docker-compose" id="markdown-toc-docker-compose">Docker Compose</a></li>
</ol>
</li>
<li><a href="#kubernetes-deployment" id="markdown-toc-kubernetes-deployment">Kubernetes Deployment</a> <ol>
<li><a href="#deployment-configuration" id="markdown-toc-deployment-configuration">Deployment Configuration</a></li>
<li><a href="#service-configuration" id="markdown-toc-service-configuration">Service Configuration</a></li>
<li><a href="#ingress-configuration" id="markdown-toc-ingress-configuration">Ingress Configuration</a></li>
</ol>
</li>
</ol>
</li>
<li><a href="#cicd-pipelines" id="markdown-toc-cicd-pipelines">CI/CD Pipelines</a> <ol>
<li><a href="#github-actions" id="markdown-toc-github-actions">GitHub Actions</a> <ol>
<li><a href="#complete-cicd-pipeline" id="markdown-toc-complete-cicd-pipeline">Complete CI/CD Pipeline</a></li>
</ol>
</li>
<li><a href="#gitlab-cicd" id="markdown-toc-gitlab-cicd">GitLab CI/CD</a></li>
</ol>
</li>
<li><a href="#monitoring-and-maintenance" id="markdown-toc-monitoring-and-maintenance">Monitoring and Maintenance</a> <ol>
<li><a href="#health-checks" id="markdown-toc-health-checks">Health Checks</a> <ol>
<li><a href="#basic-health-check-endpoint" id="markdown-toc-basic-health-check-endpoint">Basic Health Check Endpoint</a></li>
<li><a href="#service-worker-health-check" id="markdown-toc-service-worker-health-check">Service Worker Health Check</a></li>
</ol>
</li>
<li><a href="#error-tracking" id="markdown-toc-error-tracking">Error Tracking</a> <ol>
<li><a href="#sentry-integration" id="markdown-toc-sentry-integration">Sentry Integration</a></li>
</ol>
</li>
<li><a href="#performance-monitoring" id="markdown-toc-performance-monitoring">Performance Monitoring</a></li>
</ol>
</li>
<li><a href="#security-considerations" id="markdown-toc-security-considerations">Security Considerations</a> <ol>
<li><a href="#content-security-policy" id="markdown-toc-content-security-policy">Content Security Policy</a></li>
<li><a href="#environment-secrets" id="markdown-toc-environment-secrets">Environment Secrets</a></li>
<li><a href="#https-enforcement" id="markdown-toc-https-enforcement">HTTPS Enforcement</a></li>
</ol>
</li>
<li><a href="#troubleshooting" id="markdown-toc-troubleshooting">Troubleshooting</a> <ol>
<li><a href="#common-deployment-issues" id="markdown-toc-common-deployment-issues">Common Deployment Issues</a> <ol>
<li><a href="#1-build-failures" id="markdown-toc-1-build-failures">1. Build Failures</a></li>
<li><a href="#2-asset-loading-issues" id="markdown-toc-2-asset-loading-issues">2. Asset Loading Issues</a></li>
<li><a href="#3-api-connection-issues" id="markdown-toc-3-api-connection-issues">3. API Connection Issues</a></li>
</ol>
</li>
</ol>
</li>
<li><a href="#next-steps" id="markdown-toc-next-steps">Next Steps</a></li>
</ol><hr />
<h2 id="pre-deployment-checklist">
<a href="#pre-deployment-checklist" class="anchor-heading" aria-labelledby="pre-deployment-checklist"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Pre-Deployment Checklist
</h2>
<h3 id="build-optimization">
<a href="#build-optimization" class="anchor-heading" aria-labelledby="build-optimization"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Build Optimization
</h3>
<p>Before deploying, ensure your build is optimized:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Run production build</span>
npm run build
<span class="c"># Analyze bundle sizes</span>
npm run build:analyze
<span class="c"># Run performance optimizations</span>
npm run optimize
<span class="c"># Test production build locally</span>
npm run preview
</code></pre></div></div>
<h3 id="environment-configuration">
<a href="#environment-configuration" class="anchor-heading" aria-labelledby="environment-configuration"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Environment Configuration
</h3>
<h4 id="production-environment-variables">
<a href="#production-environment-variables" class="anchor-heading" aria-labelledby="production-environment-variables"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Production Environment Variables
</h4>
<p>Create <code class="language-plaintext highlighter-rouge">.env.production</code>:</p>
<pre><code class="language-env"># API Configuration
VITE_API_URL=https://api.yoursite.com
VITE_APP_NAME=Gentelella Admin
VITE_DEBUG_MODE=false
# CDN Configuration
VITE_CDN_URL=https://cdn.yoursite.com
VITE_ASSETS_URL=https://assets.yoursite.com
# Performance Settings
VITE_PRELOAD_MODULES=charts,forms
VITE_ENABLE_SERVICE_WORKER=true
# Analytics
VITE_GA_TRACKING_ID=UA-XXXXXXXX-X
VITE_HOTJAR_ID=XXXXXXX
</code></pre>
<h4 id="build-configuration">
<a href="#build-configuration" class="anchor-heading" aria-labelledby="build-configuration"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Build Configuration
</h4>
<p>Ensure <code class="language-plaintext highlighter-rouge">vite.config.js</code> has production optimizations:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="k">default</span> <span class="nx">defineConfig</span><span class="p">({</span>
<span class="na">base</span><span class="p">:</span> <span class="dl">'</span><span class="s1">/your-app-path/</span><span class="dl">'</span><span class="p">,</span> <span class="c1">// Set if not deploying to root</span>
<span class="na">build</span><span class="p">:</span> <span class="p">{</span>
<span class="c1">// Output directory</span>
<span class="na">outDir</span><span class="p">:</span> <span class="dl">'</span><span class="s1">dist</span><span class="dl">'</span><span class="p">,</span>
<span class="c1">// Asset directory</span>
<span class="na">assetsDir</span><span class="p">:</span> <span class="dl">'</span><span class="s1">assets</span><span class="dl">'</span><span class="p">,</span>
<span class="c1">// Source maps for production debugging</span>
<span class="na">sourcemap</span><span class="p">:</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">NODE_ENV</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">development</span><span class="dl">'</span><span class="p">,</span>
<span class="c1">// Minification</span>
<span class="na">minify</span><span class="p">:</span> <span class="dl">'</span><span class="s1">terser</span><span class="dl">'</span><span class="p">,</span>
<span class="na">terserOptions</span><span class="p">:</span> <span class="p">{</span>
<span class="na">compress</span><span class="p">:</span> <span class="p">{</span>
<span class="na">drop_console</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
<span class="na">drop_debugger</span><span class="p">:</span> <span class="kc">true</span>
<span class="p">}</span>
<span class="p">},</span>
<span class="c1">// Chunk size warning limit</span>
<span class="na">chunkSizeWarningLimit</span><span class="p">:</span> <span class="mi">1000</span><span class="p">,</span>
<span class="na">rollupOptions</span><span class="p">:</span> <span class="p">{</span>
<span class="na">output</span><span class="p">:</span> <span class="p">{</span>
<span class="c1">// Manual chunk splitting for optimal loading</span>
<span class="na">manualChunks</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">'</span><span class="s1">vendor-core</span><span class="dl">'</span><span class="p">:</span> <span class="p">[</span><span class="dl">'</span><span class="s1">bootstrap</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">@popperjs/core</span><span class="dl">'</span><span class="p">],</span>
<span class="dl">'</span><span class="s1">vendor-charts</span><span class="dl">'</span><span class="p">:</span> <span class="p">[</span><span class="dl">'</span><span class="s1">chart.js</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">morris.js</span><span class="dl">'</span><span class="p">],</span>
<span class="dl">'</span><span class="s1">vendor-forms</span><span class="dl">'</span><span class="p">:</span> <span class="p">[</span><span class="dl">'</span><span class="s1">select2</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">tempus-dominus</span><span class="dl">'</span><span class="p">],</span>
<span class="dl">'</span><span class="s1">vendor-tables</span><span class="dl">'</span><span class="p">:</span> <span class="p">[</span><span class="dl">'</span><span class="s1">datatables.net</span><span class="dl">'</span><span class="p">],</span>
<span class="dl">'</span><span class="s1">vendor-utils</span><span class="dl">'</span><span class="p">:</span> <span class="p">[</span><span class="dl">'</span><span class="s1">dayjs</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">nprogress</span><span class="dl">'</span><span class="p">]</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">});</span>
</code></pre></div></div><hr />
<h2 id="static-hosting-platforms">
<a href="#static-hosting-platforms" class="anchor-heading" aria-labelledby="static-hosting-platforms"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Static Hosting Platforms
</h2>
<h3 id="netlify-deployment">
<a href="#netlify-deployment" class="anchor-heading" aria-labelledby="netlify-deployment"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Netlify Deployment
</h3>
<h4 id="method-1-git-integration-recommended">
<a href="#method-1-git-integration-recommended" class="anchor-heading" aria-labelledby="method-1-git-integration-recommended"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Method 1: Git Integration (Recommended)
</h4>
<ol>
<li><strong>Connect Repository</strong>
<ul>
<li>Push your code to GitHub/GitLab/Bitbucket</li>
<li>Connect repository in Netlify dashboard</li>
</ul>
</li>
<li><strong>Configure Build Settings</strong>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Build command: npm run build
Publish directory: dist
</code></pre></div> </div>
</li>
<li><strong>Environment Variables</strong>
Set in Netlify dashboard under Site Settings → Environment Variables:
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>VITE_API_URL=https://api.yoursite.com
VITE_APP_NAME=Gentelella Admin
NODE_VERSION=18
</code></pre></div> </div>
</li>
<li><strong>Custom Domain</strong>
<ul>
<li>Add custom domain in Site Settings → Domain Management</li>
<li>Configure DNS records</li>
</ul>
</li>
</ol>
<h4 id="method-2-manual-deploy">
<a href="#method-2-manual-deploy" class="anchor-heading" aria-labelledby="method-2-manual-deploy"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Method 2: Manual Deploy
</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Build the project</span>
npm run build
<span class="c"># Install Netlify CLI</span>
npm <span class="nb">install</span> <span class="nt">-g</span> netlify-cli
<span class="c"># Deploy to Netlify</span>
netlify deploy <span class="nt">--prod</span> <span class="nt">--dir</span><span class="o">=</span>dist
</code></pre></div></div>
<h4 id="netlify-configuration">
<a href="#netlify-configuration" class="anchor-heading" aria-labelledby="netlify-configuration"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Netlify Configuration
</h4>
<p>Create <code class="language-plaintext highlighter-rouge">netlify.toml</code>:</p>
<div class="language-toml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">[build]</span>
<span class="py">command</span> <span class="p">=</span> <span class="s">"npm run build"</span>
<span class="py">publish</span> <span class="p">=</span> <span class="s">"dist"</span>
<span class="nn">[build.environment]</span>
<span class="py">NODE_VERSION</span> <span class="p">=</span> <span class="s">"18"</span>
<span class="nn">[[redirects]]</span>
<span class="py">from</span> <span class="p">=</span> <span class="s">"/*"</span>
<span class="py">to</span> <span class="p">=</span> <span class="s">"/index.html"</span>
<span class="py">status</span> <span class="p">=</span> <span class="mi">200</span>
<span class="nn">[[headers]]</span>
<span class="py">for</span> <span class="p">=</span> <span class="s">"/assets/*"</span>
<span class="nn">[headers.values]</span>
<span class="py">Cache-Control</span> <span class="p">=</span> <span class="s">"public, max-age=31536000, immutable"</span>
<span class="nn">[[headers]]</span>
<span class="py">for</span> <span class="p">=</span> <span class="s">"/*.html"</span>
<span class="nn">[headers.values]</span>
<span class="py">Cache-Control</span> <span class="p">=</span> <span class="s">"public, max-age=3600"</span>
</code></pre></div></div>
<h3 id="vercel-deployment">
<a href="#vercel-deployment" class="anchor-heading" aria-labelledby="vercel-deployment"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Vercel Deployment
</h3>
<h4 id="git-integration">
<a href="#git-integration" class="anchor-heading" aria-labelledby="git-integration"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Git Integration
</h4>
<ol>
<li><strong>Connect Repository</strong>
<ul>
<li>Import project from GitHub/GitLab</li>
<li>Vercel auto-detects Vite configuration</li>
</ul>
</li>
<li><strong>Build Configuration</strong>
Vercel automatically detects these settings:
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"buildCommand"</span><span class="p">:</span><span class="w"> </span><span class="s2">"npm run build"</span><span class="p">,</span><span class="w">
</span><span class="nl">"outputDirectory"</span><span class="p">:</span><span class="w"> </span><span class="s2">"dist"</span><span class="p">,</span><span class="w">
</span><span class="nl">"installCommand"</span><span class="p">:</span><span class="w"> </span><span class="s2">"npm install"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div> </div>
</li>
<li><strong>Environment Variables</strong>
Set in Vercel dashboard:
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>VITE_API_URL=https://api.yoursite.com
VITE_APP_NAME=Gentelella Admin
</code></pre></div> </div>
</li>
</ol>
<h4 id="manual-deployment">
<a href="#manual-deployment" class="anchor-heading" aria-labelledby="manual-deployment"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Manual Deployment
</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Install Vercel CLI</span>
npm <span class="nb">install</span> <span class="nt">-g</span> vercel
<span class="c"># Deploy</span>
vercel <span class="nt">--prod</span>
</code></pre></div></div>
<h4 id="vercel-configuration">
<a href="#vercel-configuration" class="anchor-heading" aria-labelledby="vercel-configuration"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Vercel Configuration
</h4>
<p>Create <code class="language-plaintext highlighter-rouge">vercel.json</code>:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"builds"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"src"</span><span class="p">:</span><span class="w"> </span><span class="s2">"package.json"</span><span class="p">,</span><span class="w">
</span><span class="nl">"use"</span><span class="p">:</span><span class="w"> </span><span class="s2">"@vercel/static-build"</span><span class="p">,</span><span class="w">
</span><span class="nl">"config"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"distDir"</span><span class="p">:</span><span class="w"> </span><span class="s2">"dist"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">],</span><span class="w">
</span><span class="nl">"routes"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"handle"</span><span class="p">:</span><span class="w"> </span><span class="s2">"filesystem"</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"src"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/(.*)"</span><span class="p">,</span><span class="w">
</span><span class="nl">"dest"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/index.html"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">],</span><span class="w">
</span><span class="nl">"headers"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"source"</span><span class="p">:</span><span class="w"> </span><span class="s2">"/assets/(.*)"</span><span class="p">,</span><span class="w">
</span><span class="nl">"headers"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"key"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Cache-Control"</span><span class="p">,</span><span class="w">
</span><span class="nl">"value"</span><span class="p">:</span><span class="w"> </span><span class="s2">"public, max-age=31536000, immutable"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<h3 id="github-pages">
<a href="#github-pages" class="anchor-heading" aria-labelledby="github-pages"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> GitHub Pages
</h3>
<h4 id="github-actions-deployment">
<a href="#github-actions-deployment" class="anchor-heading" aria-labelledby="github-actions-deployment"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> GitHub Actions Deployment
</h4>
<p>Create <code class="language-plaintext highlighter-rouge">.github/workflows/deploy.yml</code>:</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">name</span><span class="pi">:</span> <span class="s">Deploy to GitHub Pages</span>
<span class="na">on</span><span class="pi">:</span>
<span class="na">push</span><span class="pi">:</span>
<span class="na">branches</span><span class="pi">:</span> <span class="pi">[</span> <span class="nv">main</span> <span class="pi">]</span>
<span class="na">jobs</span><span class="pi">:</span>
<span class="na">deploy</span><span class="pi">:</span>
<span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
<span class="na">permissions</span><span class="pi">:</span>
<span class="na">contents</span><span class="pi">:</span> <span class="s">read</span>
<span class="na">pages</span><span class="pi">:</span> <span class="s">write</span>
<span class="na">id-token</span><span class="pi">:</span> <span class="s">write</span>
<span class="na">steps</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Checkout</span>
<span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v3</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Setup Node.js</span>
<span class="na">uses</span><span class="pi">:</span> <span class="s">actions/setup-node@v3</span>
<span class="na">with</span><span class="pi">:</span>
<span class="na">node-version</span><span class="pi">:</span> <span class="s1">'</span><span class="s">18'</span>
<span class="na">cache</span><span class="pi">:</span> <span class="s1">'</span><span class="s">npm'</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Install dependencies</span>
<span class="na">run</span><span class="pi">:</span> <span class="s">npm ci</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Build</span>
<span class="na">run</span><span class="pi">:</span> <span class="s">npm run build</span>
<span class="na">env</span><span class="pi">:</span>
<span class="na">VITE_BASE_URL</span><span class="pi">:</span> <span class="s">/your-repo-name/</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Setup Pages</span>
<span class="na">uses</span><span class="pi">:</span> <span class="s">actions/configure-pages@v3</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Upload artifact</span>
<span class="na">uses</span><span class="pi">:</span> <span class="s">actions/upload-pages-artifact@v2</span>
<span class="na">with</span><span class="pi">:</span>
<span class="na">path</span><span class="pi">:</span> <span class="s">./dist</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Deploy to GitHub Pages</span>
<span class="na">id</span><span class="pi">:</span> <span class="s">deployment</span>
<span class="na">uses</span><span class="pi">:</span> <span class="s">actions/deploy-pages@v2</span>
</code></pre></div></div>
<h4 id="update-vite-configuration-for-github-pages">
<a href="#update-vite-configuration-for-github-pages" class="anchor-heading" aria-labelledby="update-vite-configuration-for-github-pages"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Update Vite Configuration for GitHub Pages
</h4>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// vite.config.js</span>
<span class="k">export</span> <span class="k">default</span> <span class="nx">defineConfig</span><span class="p">({</span>
<span class="na">base</span><span class="p">:</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">NODE_ENV</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">production</span><span class="dl">'</span>
<span class="p">?</span> <span class="dl">'</span><span class="s1">/your-repo-name/</span><span class="dl">'</span>
<span class="p">:</span> <span class="dl">'</span><span class="s1">/</span><span class="dl">'</span><span class="p">,</span>
<span class="c1">// ... rest of configuration</span>
<span class="p">});</span>
</code></pre></div></div><hr />
<h2 id="server-hosting">
<a href="#server-hosting" class="anchor-heading" aria-labelledby="server-hosting"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Server Hosting
</h2>
<h3 id="nginx-configuration">
<a href="#nginx-configuration" class="anchor-heading" aria-labelledby="nginx-configuration"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Nginx Configuration
</h3>
<h4 id="basic-setup">
<a href="#basic-setup" class="anchor-heading" aria-labelledby="basic-setup"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Basic Setup
</h4>
<div class="language-nginx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># /etc/nginx/sites-available/gentelella</span>
<span class="k">server</span> <span class="p">{</span>
<span class="kn">listen</span> <span class="mi">80</span><span class="p">;</span>
<span class="kn">server_name</span> <span class="s">yoursite.com</span> <span class="s">www.yoursite.com</span><span class="p">;</span>
<span class="kn">root</span> <span class="n">/var/www/gentelella/dist</span><span class="p">;</span>
<span class="kn">index</span> <span class="s">index.html</span><span class="p">;</span>
<span class="c1"># Gzip compression</span>
<span class="kn">gzip</span> <span class="no">on</span><span class="p">;</span>
<span class="kn">gzip_vary</span> <span class="no">on</span><span class="p">;</span>
<span class="kn">gzip_min_length</span> <span class="mi">1024</span><span class="p">;</span>
<span class="kn">gzip_types</span>
<span class="nc">text/plain</span>
<span class="nc">text/css</span>
<span class="nc">text/xml</span>
<span class="nc">text/javascript</span>
<span class="nc">application/javascript</span>
<span class="nc">application/xml</span><span class="s">+rss</span>
<span class="nc">application/json</span><span class="p">;</span>
<span class="c1"># Security headers</span>
<span class="kn">add_header</span> <span class="s">X-Frame-Options</span> <span class="s">"SAMEORIGIN"</span> <span class="s">always</span><span class="p">;</span>
<span class="kn">add_header</span> <span class="s">X-XSS-Protection</span> <span class="s">"1</span><span class="p">;</span> <span class="kn">mode=block"</span> <span class="s">always</span><span class="p">;</span>
<span class="kn">add_header</span> <span class="s">X-Content-Type-Options</span> <span class="s">"nosniff"</span> <span class="s">always</span><span class="p">;</span>
<span class="kn">add_header</span> <span class="s">Referrer-Policy</span> <span class="s">"no-referrer-when-downgrade"</span> <span class="s">always</span><span class="p">;</span>
<span class="kn">add_header</span> <span class="s">Content-Security-Policy</span> <span class="s">"default-src</span> <span class="s">'self'</span> <span class="s">http:</span> <span class="s">https:</span> <span class="s">data:</span> <span class="s">blob:</span> <span class="s">'unsafe-inline'"</span> <span class="s">always</span><span class="p">;</span>
<span class="c1"># Cache static assets</span>
<span class="kn">location</span> <span class="p">~</span><span class="sr">*</span> <span class="err">\</span><span class="s">.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)</span>$ <span class="p">{</span>
<span class="kn">expires</span> <span class="s">1y</span><span class="p">;</span>
<span class="kn">add_header</span> <span class="s">Cache-Control</span> <span class="s">"public,</span> <span class="s">immutable"</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1"># Handle SPA routing</span>
<span class="kn">location</span> <span class="n">/</span> <span class="p">{</span>
<span class="kn">try_files</span> <span class="nv">$uri</span> <span class="nv">$uri</span><span class="n">/</span> <span class="n">/index.html</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1"># API proxy (if needed)</span>
<span class="kn">location</span> <span class="n">/api/</span> <span class="p">{</span>
<span class="kn">proxy_pass</span> <span class="s">http://localhost:8080/</span><span class="p">;</span>
<span class="kn">proxy_set_header</span> <span class="s">Host</span> <span class="nv">$host</span><span class="p">;</span>
<span class="kn">proxy_set_header</span> <span class="s">X-Real-IP</span> <span class="nv">$remote_addr</span><span class="p">;</span>
<span class="kn">proxy_set_header</span> <span class="s">X-Forwarded-For</span> <span class="nv">$proxy_add_x_forwarded_for</span><span class="p">;</span>
<span class="kn">proxy_set_header</span> <span class="s">X-Forwarded-Proto</span> <span class="nv">$scheme</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<h4 id="ssl-with-lets-encrypt">
<a href="#ssl-with-lets-encrypt" class="anchor-heading" aria-labelledby="ssl-with-lets-encrypt"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> SSL with Lets Encrypt
</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Install Certbot</span>
<span class="nb">sudo </span>apt <span class="nb">install </span>certbot python3-certbot-nginx
<span class="c"># Get SSL certificate</span>
<span class="nb">sudo </span>certbot <span class="nt">--nginx</span> <span class="nt">-d</span> yoursite.com <span class="nt">-d</span> www.yoursite.com
<span class="c"># Auto-renewal (add to crontab)</span>
0 12 <span class="k">*</span> <span class="k">*</span> <span class="k">*</span> /usr/bin/certbot renew <span class="nt">--quiet</span>
</code></pre></div></div>
<h3 id="apache-configuration">
<a href="#apache-configuration" class="anchor-heading" aria-labelledby="apache-configuration"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Apache Configuration
</h3>
<h4 id="virtual-host-setup">
<a href="#virtual-host-setup" class="anchor-heading" aria-labelledby="virtual-host-setup"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Virtual Host Setup
</h4>
<div class="language-apache highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># /etc/apache2/sites-available/gentelella.conf</span>
<span class="p">&lt;</span><span class="nl">VirtualHost</span><span class="sr"> *:80</span><span class="p">&gt;
</span> <span class="nc">ServerName</span> yoursite.com
<span class="nc">ServerAlias</span> www.yoursite.com
<span class="nc">DocumentRoot</span> /var/www/gentelella/dist
<span class="c"># Enable compression</span>
<span class="nc">LoadModule</span> deflate_module modules/mod_deflate.so
<span class="p">&lt;</span><span class="nl">Location</span><span class="sr"> /</span><span class="p">&gt;
</span> <span class="nc">SetOutputFilter</span> DEFLATE
<span class="nc">SetEnvIfNoCase</span> <span class="ss">Request_URI</span> \
<span class="err">\.(?:</span>gif|jpe?g|png)$ no-gzip dont-vary
<span class="nc">SetEnvIfNoCase</span> <span class="ss">Request_URI</span> \
<span class="err">\.(?:</span>exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary
<span class="p">&lt;/</span><span class="nl">Location</span><span class="p">&gt;
</span>
<span class="c"># Cache static assets</span>
<span class="p">&lt;</span><span class="nl">LocationMatch</span><span class="sr"> "\.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2)$"</span><span class="p">&gt;
</span> <span class="nc">ExpiresActive</span> <span class="ss">On</span>
<span class="nc">ExpiresDefault</span> "access plus 1 year"
<span class="nc">Header</span> <span class="ss">append</span> Cache-Control "public, immutable"
<span class="p">&lt;/</span><span class="nl">LocationMatch</span><span class="p">&gt;
</span>
<span class="c"># Handle SPA routing</span>
<span class="p">&lt;</span><span class="nl">Directory</span><span class="sr"> /var/www/gentelella/dist</span><span class="p">&gt;
</span> <span class="nc">RewriteEngine</span> <span class="ss">On</span>
<span class="nc">RewriteBase</span> /
<span class="nc">RewriteRule</span> ^index\.html$ - [L]
<span class="nc">RewriteCond</span> %{REQUEST_FILENAME} !-f
<span class="nc">RewriteCond</span> %{REQUEST_FILENAME} !-d
<span class="nc">RewriteRule</span> . /index.html [L]
<span class="p">&lt;/</span><span class="nl">Directory</span><span class="p">&gt;
</span>
<span class="nc">ErrorLog</span> ${APACHE_LOG_DIR}/gentelella_error.log
<span class="nc">CustomLog</span> ${APACHE_LOG_DIR}/gentelella_access.log combined
<span class="p">&lt;/</span><span class="nl">VirtualHost</span><span class="p">&gt;
</span></code></pre></div></div><hr />
<h2 id="container-deployment">
<a href="#container-deployment" class="anchor-heading" aria-labelledby="container-deployment"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Container Deployment
</h2>
<h3 id="docker-setup">
<a href="#docker-setup" class="anchor-heading" aria-labelledby="docker-setup"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Docker Setup
</h3>
<h4 id="dockerfile">
<a href="#dockerfile" class="anchor-heading" aria-labelledby="dockerfile"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Dockerfile
</h4>
<div class="language-dockerfile highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Build stage</span>
<span class="k">FROM</span><span class="w"> </span><span class="s">node:18-alpine</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="s">build-stage</span>
<span class="k">WORKDIR</span><span class="s"> /app</span>
<span class="k">COPY</span><span class="s"> package*.json ./</span>
<span class="k">RUN </span>npm ci <span class="nt">--only</span><span class="o">=</span>production
<span class="k">COPY</span><span class="s"> . .</span>
<span class="k">RUN </span>npm run build
<span class="c"># Production stage</span>
<span class="k">FROM</span><span class="w"> </span><span class="s">nginx:alpine</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="s">production-stage</span>
<span class="k">COPY</span><span class="s"> --from=build-stage /app/dist /usr/share/nginx/html</span>
<span class="c"># Copy nginx configuration</span>
<span class="k">COPY</span><span class="s"> nginx.conf /etc/nginx/nginx.conf</span>
<span class="k">EXPOSE</span><span class="s"> 80</span>
<span class="k">CMD</span><span class="s"> ["nginx", "-g", "daemon off;"]</span>
</code></pre></div></div>
<h4 id="docker-nginx-configuration">
<a href="#docker-nginx-configuration" class="anchor-heading" aria-labelledby="docker-nginx-configuration"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Docker Nginx Configuration
</h4>
<div class="language-nginx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># nginx.conf</span>
<span class="k">events</span> <span class="p">{</span>
<span class="kn">worker_connections</span> <span class="mi">1024</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">http</span> <span class="p">{</span>
<span class="kn">include</span> <span class="n">/etc/nginx/mime.types</span><span class="p">;</span>
<span class="kn">default_type</span> <span class="nc">application/octet-stream</span><span class="p">;</span>
<span class="kn">sendfile</span> <span class="no">on</span><span class="p">;</span>
<span class="kn">keepalive_timeout</span> <span class="mi">65</span><span class="p">;</span>
<span class="kn">gzip</span> <span class="no">on</span><span class="p">;</span>
<span class="kn">gzip_vary</span> <span class="no">on</span><span class="p">;</span>
<span class="kn">gzip_min_length</span> <span class="mi">1024</span><span class="p">;</span>
<span class="kn">gzip_types</span>
<span class="nc">text/plain</span>
<span class="nc">text/css</span>
<span class="nc">text/xml</span>
<span class="nc">text/javascript</span>
<span class="nc">application/javascript</span>
<span class="nc">application/xml</span><span class="s">+rss</span>
<span class="nc">application/json</span><span class="p">;</span>
<span class="kn">server</span> <span class="p">{</span>
<span class="kn">listen</span> <span class="mi">80</span><span class="p">;</span>
<span class="kn">server_name</span> <span class="s">localhost</span><span class="p">;</span>
<span class="kn">root</span> <span class="n">/usr/share/nginx/html</span><span class="p">;</span>
<span class="kn">index</span> <span class="s">index.html</span> <span class="s">index.htm</span><span class="p">;</span>
<span class="kn">location</span> <span class="p">~</span><span class="sr">*</span> <span class="err">\</span><span class="s">.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)</span>$ <span class="p">{</span>
<span class="kn">expires</span> <span class="s">1y</span><span class="p">;</span>
<span class="kn">add_header</span> <span class="s">Cache-Control</span> <span class="s">"public,</span> <span class="s">immutable"</span><span class="p">;</span>
<span class="p">}</span>
<span class="kn">location</span> <span class="n">/</span> <span class="p">{</span>
<span class="kn">try_files</span> <span class="nv">$uri</span> <span class="nv">$uri</span><span class="n">/</span> <span class="n">/index.html</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<h4 id="docker-compose">
<a href="#docker-compose" class="anchor-heading" aria-labelledby="docker-compose"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Docker Compose
</h4>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># docker-compose.yml</span>
<span class="na">version</span><span class="pi">:</span> <span class="s1">'</span><span class="s">3.8'</span>
<span class="na">services</span><span class="pi">:</span>
<span class="na">gentelella</span><span class="pi">:</span>
<span class="na">build</span><span class="pi">:</span> <span class="s">.</span>
<span class="na">ports</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s2">"</span><span class="s">80:80"</span>
<span class="na">environment</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">NODE_ENV=production</span>
<span class="na">restart</span><span class="pi">:</span> <span class="s">unless-stopped</span>
<span class="c1"># Optional: Add database, Redis, etc.</span>
<span class="na">database</span><span class="pi">:</span>
<span class="na">image</span><span class="pi">:</span> <span class="s">postgres:14-alpine</span>
<span class="na">environment</span><span class="pi">:</span>
<span class="na">POSTGRES_DB</span><span class="pi">:</span> <span class="s">gentelella</span>
<span class="na">POSTGRES_USER</span><span class="pi">:</span> <span class="s">admin</span>
<span class="na">POSTGRES_PASSWORD</span><span class="pi">:</span> <span class="s">password</span>
<span class="na">volumes</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">postgres_data:/var/lib/postgresql/data</span>
<span class="na">volumes</span><span class="pi">:</span>
<span class="na">postgres_data</span><span class="pi">:</span>
</code></pre></div></div>
<h3 id="kubernetes-deployment">
<a href="#kubernetes-deployment" class="anchor-heading" aria-labelledby="kubernetes-deployment"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Kubernetes Deployment
</h3>
<h4 id="deployment-configuration">
<a href="#deployment-configuration" class="anchor-heading" aria-labelledby="deployment-configuration"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Deployment Configuration
</h4>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># k8s/deployment.yaml</span>
<span class="na">apiVersion</span><span class="pi">:</span> <span class="s">apps/v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Deployment</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">gentelella</span>
<span class="na">labels</span><span class="pi">:</span>
<span class="na">app</span><span class="pi">:</span> <span class="s">gentelella</span>
<span class="na">spec</span><span class="pi">:</span>
<span class="na">replicas</span><span class="pi">:</span> <span class="m">3</span>
<span class="na">selector</span><span class="pi">:</span>
<span class="na">matchLabels</span><span class="pi">:</span>
<span class="na">app</span><span class="pi">:</span> <span class="s">gentelella</span>
<span class="na">template</span><span class="pi">:</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">labels</span><span class="pi">:</span>
<span class="na">app</span><span class="pi">:</span> <span class="s">gentelella</span>
<span class="na">spec</span><span class="pi">:</span>
<span class="na">containers</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">gentelella</span>
<span class="na">image</span><span class="pi">:</span> <span class="s">your-registry/gentelella:latest</span>
<span class="na">ports</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">containerPort</span><span class="pi">:</span> <span class="m">80</span>
<span class="na">env</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">NODE_ENV</span>
<span class="na">value</span><span class="pi">:</span> <span class="s2">"</span><span class="s">production"</span>
<span class="na">resources</span><span class="pi">:</span>
<span class="na">requests</span><span class="pi">:</span>
<span class="na">memory</span><span class="pi">:</span> <span class="s2">"</span><span class="s">64Mi"</span>
<span class="na">cpu</span><span class="pi">:</span> <span class="s2">"</span><span class="s">250m"</span>
<span class="na">limits</span><span class="pi">:</span>
<span class="na">memory</span><span class="pi">:</span> <span class="s2">"</span><span class="s">128Mi"</span>
<span class="na">cpu</span><span class="pi">:</span> <span class="s2">"</span><span class="s">500m"</span>
</code></pre></div></div>
<h4 id="service-configuration">
<a href="#service-configuration" class="anchor-heading" aria-labelledby="service-configuration"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Service Configuration
</h4>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># k8s/service.yaml</span>
<span class="na">apiVersion</span><span class="pi">:</span> <span class="s">v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Service</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">gentelella-service</span>
<span class="na">spec</span><span class="pi">:</span>
<span class="na">selector</span><span class="pi">:</span>
<span class="na">app</span><span class="pi">:</span> <span class="s">gentelella</span>
<span class="na">ports</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">protocol</span><span class="pi">:</span> <span class="s">TCP</span>
<span class="na">port</span><span class="pi">:</span> <span class="m">80</span>
<span class="na">targetPort</span><span class="pi">:</span> <span class="m">80</span>
<span class="na">type</span><span class="pi">:</span> <span class="s">LoadBalancer</span>
</code></pre></div></div>
<h4 id="ingress-configuration">
<a href="#ingress-configuration" class="anchor-heading" aria-labelledby="ingress-configuration"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Ingress Configuration
</h4>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># k8s/ingress.yaml</span>
<span class="na">apiVersion</span><span class="pi">:</span> <span class="s">networking.k8s.io/v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Ingress</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">gentelella-ingress</span>
<span class="na">annotations</span><span class="pi">:</span>
<span class="na">kubernetes.io/ingress.class</span><span class="pi">:</span> <span class="s">nginx</span>
<span class="na">cert-manager.io/cluster-issuer</span><span class="pi">:</span> <span class="s">letsencrypt-prod</span>
<span class="na">spec</span><span class="pi">:</span>
<span class="na">tls</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">hosts</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">yoursite.com</span>
<span class="na">secretName</span><span class="pi">:</span> <span class="s">gentelella-tls</span>
<span class="na">rules</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">host</span><span class="pi">:</span> <span class="s">yoursite.com</span>
<span class="na">http</span><span class="pi">:</span>
<span class="na">paths</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">path</span><span class="pi">:</span> <span class="s">/</span>
<span class="na">pathType</span><span class="pi">:</span> <span class="s">Prefix</span>
<span class="na">backend</span><span class="pi">:</span>
<span class="na">service</span><span class="pi">:</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">gentelella-service</span>
<span class="na">port</span><span class="pi">:</span>
<span class="na">number</span><span class="pi">:</span> <span class="m">80</span>
</code></pre></div></div><hr />
<h2 id="cicd-pipelines">
<a href="#cicd-pipelines" class="anchor-heading" aria-labelledby="cicd-pipelines"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> CI/CD Pipelines
</h2>
<h3 id="github-actions">
<a href="#github-actions" class="anchor-heading" aria-labelledby="github-actions"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> GitHub Actions
</h3>
<h4 id="complete-cicd-pipeline">
<a href="#complete-cicd-pipeline" class="anchor-heading" aria-labelledby="complete-cicd-pipeline"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Complete CI/CD Pipeline
</h4>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># .github/workflows/ci-cd.yml</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">CI/CD Pipeline</span>
<span class="na">on</span><span class="pi">:</span>
<span class="na">push</span><span class="pi">:</span>
<span class="na">branches</span><span class="pi">:</span> <span class="pi">[</span> <span class="nv">main</span><span class="pi">,</span> <span class="nv">develop</span> <span class="pi">]</span>
<span class="na">pull_request</span><span class="pi">:</span>
<span class="na">branches</span><span class="pi">:</span> <span class="pi">[</span> <span class="nv">main</span> <span class="pi">]</span>
<span class="na">env</span><span class="pi">:</span>
<span class="na">NODE_VERSION</span><span class="pi">:</span> <span class="s1">'</span><span class="s">18'</span>
<span class="na">jobs</span><span class="pi">:</span>
<span class="na">test</span><span class="pi">:</span>
<span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
<span class="na">steps</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Checkout code</span>
<span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v3</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Setup Node.js</span>
<span class="na">uses</span><span class="pi">:</span> <span class="s">actions/setup-node@v3</span>
<span class="na">with</span><span class="pi">:</span>
<span class="na">node-version</span><span class="pi">:</span> <span class="s">$</span>
<span class="na">cache</span><span class="pi">:</span> <span class="s1">'</span><span class="s">npm'</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Install dependencies</span>
<span class="na">run</span><span class="pi">:</span> <span class="s">npm ci</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Run linting</span>
<span class="na">run</span><span class="pi">:</span> <span class="s">npm run lint</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Run tests</span>
<span class="na">run</span><span class="pi">:</span> <span class="s">npm run test</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Build project</span>
<span class="na">run</span><span class="pi">:</span> <span class="s">npm run build</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Run performance audit</span>
<span class="na">run</span><span class="pi">:</span> <span class="s">npm run optimize</span>
<span class="na">deploy-staging</span><span class="pi">:</span>
<span class="na">needs</span><span class="pi">:</span> <span class="s">test</span>
<span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
<span class="na">if</span><span class="pi">:</span> <span class="s">github.ref == 'refs/heads/develop'</span>
<span class="na">steps</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Checkout code</span>
<span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v3</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Setup Node.js</span>
<span class="na">uses</span><span class="pi">:</span> <span class="s">actions/setup-node@v3</span>
<span class="na">with</span><span class="pi">:</span>
<span class="na">node-version</span><span class="pi">:</span> <span class="s">$</span>
<span class="na">cache</span><span class="pi">:</span> <span class="s1">'</span><span class="s">npm'</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Install dependencies</span>
<span class="na">run</span><span class="pi">:</span> <span class="s">npm ci</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Build for staging</span>
<span class="na">run</span><span class="pi">:</span> <span class="s">npm run build</span>
<span class="na">env</span><span class="pi">:</span>
<span class="na">VITE_API_URL</span><span class="pi">:</span> <span class="s">$</span>
<span class="na">VITE_APP_NAME</span><span class="pi">:</span> <span class="s">Gentelella Admin (Staging)</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Deploy to staging</span>
<span class="na">uses</span><span class="pi">:</span> <span class="s">peaceiris/actions-gh-pages@v3</span>
<span class="na">with</span><span class="pi">:</span>
<span class="na">github_token</span><span class="pi">:</span> <span class="s">$</span>
<span class="na">publish_dir</span><span class="pi">:</span> <span class="s">./dist</span>
<span class="na">destination_dir</span><span class="pi">:</span> <span class="s">staging</span>
<span class="na">deploy-production</span><span class="pi">:</span>
<span class="na">needs</span><span class="pi">:</span> <span class="s">test</span>
<span class="na">runs-on</span><span class="pi">:</span> <span class="s">ubuntu-latest</span>
<span class="na">if</span><span class="pi">:</span> <span class="s">github.ref == 'refs/heads/main'</span>
<span class="na">steps</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Checkout code</span>
<span class="na">uses</span><span class="pi">:</span> <span class="s">actions/checkout@v3</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Setup Node.js</span>
<span class="na">uses</span><span class="pi">:</span> <span class="s">actions/setup-node@v3</span>
<span class="na">with</span><span class="pi">:</span>
<span class="na">node-version</span><span class="pi">:</span> <span class="s">$</span>
<span class="na">cache</span><span class="pi">:</span> <span class="s1">'</span><span class="s">npm'</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Install dependencies</span>
<span class="na">run</span><span class="pi">:</span> <span class="s">npm ci</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Build for production</span>
<span class="na">run</span><span class="pi">:</span> <span class="s">npm run build</span>
<span class="na">env</span><span class="pi">:</span>
<span class="na">VITE_API_URL</span><span class="pi">:</span> <span class="s">$</span>
<span class="na">VITE_APP_NAME</span><span class="pi">:</span> <span class="s">Gentelella Admin</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Deploy to Netlify</span>
<span class="na">uses</span><span class="pi">:</span> <span class="s">nwtgck/actions-netlify@v2.0</span>
<span class="na">with</span><span class="pi">:</span>
<span class="na">publish-dir</span><span class="pi">:</span> <span class="s1">'</span><span class="s">./dist'</span>
<span class="na">production-branch</span><span class="pi">:</span> <span class="s">main</span>
<span class="na">github-token</span><span class="pi">:</span> <span class="s">$</span>
<span class="na">deploy-message</span><span class="pi">:</span> <span class="s2">"</span><span class="s">Deploy</span><span class="nv"> </span><span class="s">from</span><span class="nv"> </span><span class="s">GitHub</span><span class="nv"> </span><span class="s">Actions"</span>
<span class="na">env</span><span class="pi">:</span>
<span class="na">NETLIFY_AUTH_TOKEN</span><span class="pi">:</span> <span class="s">$</span>
<span class="na">NETLIFY_SITE_ID</span><span class="pi">:</span> <span class="s">$</span>
</code></pre></div></div>
<h3 id="gitlab-cicd">
<a href="#gitlab-cicd" class="anchor-heading" aria-labelledby="gitlab-cicd"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> GitLab CI/CD
</h3>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># .gitlab-ci.yml</span>
<span class="na">stages</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">test</span>
<span class="pi">-</span> <span class="s">build</span>
<span class="pi">-</span> <span class="s">deploy</span>
<span class="na">variables</span><span class="pi">:</span>
<span class="na">NODE_VERSION</span><span class="pi">:</span> <span class="s2">"</span><span class="s">18"</span>
<span class="na">cache</span><span class="pi">:</span>
<span class="na">paths</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">node_modules/</span>
<span class="na">test</span><span class="pi">:</span>
<span class="na">stage</span><span class="pi">:</span> <span class="s">test</span>
<span class="na">image</span><span class="pi">:</span> <span class="s">node:$NODE_VERSION</span>
<span class="na">script</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">npm ci</span>
<span class="pi">-</span> <span class="s">npm run lint</span>
<span class="pi">-</span> <span class="s">npm run test</span>
<span class="pi">-</span> <span class="s">npm run build</span>
<span class="na">build-staging</span><span class="pi">:</span>
<span class="na">stage</span><span class="pi">:</span> <span class="s">build</span>
<span class="na">image</span><span class="pi">:</span> <span class="s">node:$NODE_VERSION</span>
<span class="na">script</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">npm ci</span>
<span class="pi">-</span> <span class="s">npm run build</span>
<span class="na">artifacts</span><span class="pi">:</span>
<span class="na">paths</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">dist/</span>
<span class="na">expire_in</span><span class="pi">:</span> <span class="s">1 hour</span>
<span class="na">only</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">develop</span>
<span class="na">build-production</span><span class="pi">:</span>
<span class="na">stage</span><span class="pi">:</span> <span class="s">build</span>
<span class="na">image</span><span class="pi">:</span> <span class="s">node:$NODE_VERSION</span>
<span class="na">script</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">npm ci</span>
<span class="pi">-</span> <span class="s">npm run build</span>
<span class="na">artifacts</span><span class="pi">:</span>
<span class="na">paths</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">dist/</span>
<span class="na">expire_in</span><span class="pi">:</span> <span class="s">1 hour</span>
<span class="na">only</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">main</span>
<span class="na">deploy-staging</span><span class="pi">:</span>
<span class="na">stage</span><span class="pi">:</span> <span class="s">deploy</span>
<span class="na">image</span><span class="pi">:</span> <span class="s">alpine:latest</span>
<span class="na">script</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">apk add --no-cache curl</span>
<span class="pi">-</span> <span class="s">curl -X POST "$STAGING_WEBHOOK_URL"</span>
<span class="na">dependencies</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">build-staging</span>
<span class="na">only</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">develop</span>
<span class="na">deploy-production</span><span class="pi">:</span>
<span class="na">stage</span><span class="pi">:</span> <span class="s">deploy</span>
<span class="na">image</span><span class="pi">:</span> <span class="s">alpine:latest</span>
<span class="na">script</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">apk add --no-cache curl</span>
<span class="pi">-</span> <span class="s">curl -X POST "$PRODUCTION_WEBHOOK_URL"</span>
<span class="na">dependencies</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">build-production</span>
<span class="na">only</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">main</span>
</code></pre></div></div><hr />
<h2 id="monitoring-and-maintenance">
<a href="#monitoring-and-maintenance" class="anchor-heading" aria-labelledby="monitoring-and-maintenance"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Monitoring and Maintenance
</h2>
<h3 id="health-checks">
<a href="#health-checks" class="anchor-heading" aria-labelledby="health-checks"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Health Checks
</h3>
<h4 id="basic-health-check-endpoint">
<a href="#basic-health-check-endpoint" class="anchor-heading" aria-labelledby="basic-health-check-endpoint"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Basic Health Check Endpoint
</h4>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// health.js</span>
<span class="k">export</span> <span class="kd">function</span> <span class="nx">setupHealthCheck</span><span class="p">()</span> <span class="p">{</span>
<span class="c1">// Simple health check</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">window</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">pathname</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">/health</span><span class="dl">'</span><span class="p">)</span> <span class="p">{</span>
<span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">innerHTML</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span>
<span class="na">status</span><span class="p">:</span> <span class="dl">'</span><span class="s1">healthy</span><span class="dl">'</span><span class="p">,</span>
<span class="na">timestamp</span><span class="p">:</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">().</span><span class="nx">toISOString</span><span class="p">(),</span>
<span class="na">version</span><span class="p">:</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">npm_package_version</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<h4 id="service-worker-health-check">
<a href="#service-worker-health-check" class="anchor-heading" aria-labelledby="service-worker-health-check"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Service Worker Health Check
</h4>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// sw.js</span>
<span class="nb">self</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="dl">'</span><span class="s1">message</span><span class="dl">'</span><span class="p">,</span> <span class="nx">event</span> <span class="o">=&gt;</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">data</span> <span class="o">&amp;&amp;</span> <span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">HEALTH_CHECK</span><span class="dl">'</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">event</span><span class="p">.</span><span class="nx">ports</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">postMessage</span><span class="p">({</span>
<span class="na">status</span><span class="p">:</span> <span class="dl">'</span><span class="s1">healthy</span><span class="dl">'</span><span class="p">,</span>
<span class="na">timestamp</span><span class="p">:</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">().</span><span class="nx">toISOString</span><span class="p">()</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="p">});</span>
</code></pre></div></div>
<h3 id="error-tracking">
<a href="#error-tracking" class="anchor-heading" aria-labelledby="error-tracking"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Error Tracking
</h3>
<h4 id="sentry-integration">
<a href="#sentry-integration" class="anchor-heading" aria-labelledby="sentry-integration"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Sentry Integration
</h4>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="o">*</span> <span class="k">as</span> <span class="nx">Sentry</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@sentry/browser</span><span class="dl">"</span><span class="p">;</span>
<span class="nx">Sentry</span><span class="p">.</span><span class="nx">init</span><span class="p">({</span>
<span class="na">dsn</span><span class="p">:</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">VITE_SENTRY_DSN</span><span class="p">,</span>
<span class="na">environment</span><span class="p">:</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">NODE_ENV</span><span class="p">,</span>
<span class="na">tracesSampleRate</span><span class="p">:</span> <span class="mf">1.0</span><span class="p">,</span>
<span class="p">});</span>
<span class="c1">// Custom error boundary</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="dl">'</span><span class="s1">error</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
<span class="nx">Sentry</span><span class="p">.</span><span class="nx">captureException</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">error</span><span class="p">);</span>
<span class="p">});</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="dl">'</span><span class="s1">unhandledrejection</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
<span class="nx">Sentry</span><span class="p">.</span><span class="nx">captureException</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">reason</span><span class="p">);</span>
<span class="p">});</span>
</code></pre></div></div>
<h3 id="performance-monitoring">
<a href="#performance-monitoring" class="anchor-heading" aria-labelledby="performance-monitoring"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Performance Monitoring
</h3>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">&lt;!-- Real User Monitoring --&gt;</span>
<span class="nt">&lt;script&gt;</span>
<span class="c1">// Monitor Core Web Vitals</span>
<span class="k">import</span> <span class="p">{</span><span class="nx">getCLS</span><span class="p">,</span> <span class="nx">getFID</span><span class="p">,</span> <span class="nx">getFCP</span><span class="p">,</span> <span class="nx">getLCP</span><span class="p">,</span> <span class="nx">getTTFB</span><span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">web-vitals</span><span class="dl">'</span><span class="p">;</span>
<span class="kd">function</span> <span class="nx">sendToAnalytics</span><span class="p">(</span><span class="nx">metric</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">fetch</span><span class="p">(</span><span class="dl">'</span><span class="s1">/analytics</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span>
<span class="na">method</span><span class="p">:</span> <span class="dl">'</span><span class="s1">POST</span><span class="dl">'</span><span class="p">,</span>
<span class="na">body</span><span class="p">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">metric</span><span class="p">),</span>
<span class="na">headers</span><span class="p">:</span> <span class="p">{</span><span class="dl">'</span><span class="s1">Content-Type</span><span class="dl">'</span><span class="p">:</span> <span class="dl">'</span><span class="s1">application/json</span><span class="dl">'</span><span class="p">}</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="nx">getCLS</span><span class="p">(</span><span class="nx">sendToAnalytics</span><span class="p">);</span>
<span class="nx">getFID</span><span class="p">(</span><span class="nx">sendToAnalytics</span><span class="p">);</span>
<span class="nx">getFCP</span><span class="p">(</span><span class="nx">sendToAnalytics</span><span class="p">);</span>
<span class="nx">getLCP</span><span class="p">(</span><span class="nx">sendToAnalytics</span><span class="p">);</span>
<span class="nx">getTTFB</span><span class="p">(</span><span class="nx">sendToAnalytics</span><span class="p">);</span>
<span class="nt">&lt;/script&gt;</span>
</code></pre></div></div><hr />
<h2 id="security-considerations">
<a href="#security-considerations" class="anchor-heading" aria-labelledby="security-considerations"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Security Considerations
</h2>
<h3 id="content-security-policy">
<a href="#content-security-policy" class="anchor-heading" aria-labelledby="content-security-policy"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Content Security Policy
</h3>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">&lt;!-- Add to index.html --&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">http-equiv=</span><span class="s">"Content-Security-Policy"</span>
<span class="na">content=</span><span class="s">"default-src 'self';
script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net;
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
font-src 'self' https://fonts.gstatic.com;
img-src 'self' data: https:;"</span><span class="nt">&gt;</span>
</code></pre></div></div>
<h3 id="environment-secrets">
<a href="#environment-secrets" class="anchor-heading" aria-labelledby="environment-secrets"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Environment Secrets
</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Use environment variables for sensitive data</span>
<span class="nb">export </span><span class="nv">VITE_API_KEY</span><span class="o">=</span><span class="s2">"your-api-key"</span>
<span class="nb">export </span><span class="nv">DATABASE_URL</span><span class="o">=</span><span class="s2">"postgresql://user:pass@host:port/db"</span>
<span class="c"># Never commit .env files with secrets</span>
<span class="nb">echo</span> <span class="s2">".env.local"</span> <span class="o">&gt;&gt;</span> .gitignore
<span class="nb">echo</span> <span class="s2">".env.production"</span> <span class="o">&gt;&gt;</span> .gitignore
</code></pre></div></div>
<h3 id="https-enforcement">
<a href="#https-enforcement" class="anchor-heading" aria-labelledby="https-enforcement"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> HTTPS Enforcement
</h3>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Redirect HTTP to HTTPS in production</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">location</span><span class="p">.</span><span class="nx">protocol</span> <span class="o">!==</span> <span class="dl">'</span><span class="s1">https:</span><span class="dl">'</span> <span class="o">&amp;&amp;</span> <span class="nx">location</span><span class="p">.</span><span class="nx">hostname</span> <span class="o">!==</span> <span class="dl">'</span><span class="s1">localhost</span><span class="dl">'</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">location</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="s2">`https:</span><span class="p">${</span><span class="nx">location</span><span class="p">.</span><span class="nx">href</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="nx">location</span><span class="p">.</span><span class="nx">protocol</span><span class="p">.</span><span class="nx">length</span><span class="p">)}</span><span class="s2">`</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div><hr />
<h2 id="troubleshooting">
<a href="#troubleshooting" class="anchor-heading" aria-labelledby="troubleshooting"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Troubleshooting
</h2>
<h3 id="common-deployment-issues">
<a href="#common-deployment-issues" class="anchor-heading" aria-labelledby="common-deployment-issues"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Common Deployment Issues
</h3>
<h4 id="1-build-failures">
<a href="#1-build-failures" class="anchor-heading" aria-labelledby="1-build-failures"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> 1. Build Failures
</h4>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Clear cache and reinstall</span>
<span class="nb">rm</span> <span class="nt">-rf</span> node_modules package-lock.json
npm <span class="nb">install</span>
<span class="c"># Check Node.js version</span>
node <span class="nt">--version</span>
npm <span class="nt">--version</span>
</code></pre></div></div>
<h4 id="2-asset-loading-issues">
<a href="#2-asset-loading-issues" class="anchor-heading" aria-labelledby="2-asset-loading-issues"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> 2. Asset Loading Issues
</h4>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Check base URL configuration</span>
<span class="c1">// vite.config.js</span>
<span class="k">export</span> <span class="k">default</span> <span class="nx">defineConfig</span><span class="p">({</span>
<span class="na">base</span><span class="p">:</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">NODE_ENV</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">production</span><span class="dl">'</span>
<span class="p">?</span> <span class="dl">'</span><span class="s1">/your-app-path/</span><span class="dl">'</span>
<span class="p">:</span> <span class="dl">'</span><span class="s1">/</span><span class="dl">'</span><span class="p">,</span>
<span class="p">});</span>
</code></pre></div></div>
<h4 id="3-api-connection-issues">
<a href="#3-api-connection-issues" class="anchor-heading" aria-labelledby="3-api-connection-issues"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> 3. API Connection Issues
</h4>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Check CORS configuration</span>
<span class="c1">// vite.config.js</span>
<span class="k">export</span> <span class="k">default</span> <span class="nx">defineConfig</span><span class="p">({</span>
<span class="na">server</span><span class="p">:</span> <span class="p">{</span>
<span class="na">proxy</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">'</span><span class="s1">/api</span><span class="dl">'</span><span class="p">:</span> <span class="p">{</span>
<span class="na">target</span><span class="p">:</span> <span class="dl">'</span><span class="s1">http://localhost:8080</span><span class="dl">'</span><span class="p">,</span>
<span class="na">changeOrigin</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
<span class="na">secure</span><span class="p">:</span> <span class="kc">false</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">});</span>
</code></pre></div></div><hr />
<h2 id="next-steps">
<a href="#next-steps" class="anchor-heading" aria-labelledby="next-steps"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Next Steps
</h2>
<ul>
<li><strong><a href="/gentelella/docs/monitoring/">Monitoring Setup</a></strong> - Set up comprehensive monitoring</li>
<li><strong><a href="/gentelella/docs/security/">Security Guide</a></strong> - Implement security best practices</li>
<li><strong><a href="/gentelella/docs/api-integration/">API Integration</a></strong> - Connect with backend APIs</li>
</ul><hr />
<p class="highlight">💡 <strong>Pro Tip</strong>: Always test your deployment in a staging environment that mirrors production before deploying to production. Use feature flags to safely roll out new features.</p>
</main>
<hr>
<footer>
<p><a href="#top" id="back-to-top">Back to top</a></p>
<p class="text-small text-grey-dk-100 mb-0">Copyright &copy; {{ 'now' | date: '%Y' }} Colorlib. Distributed under the <a href="https://github.com/puikinsh/gentelella/blob/master/LICENSE.txt">MIT license</a>.</p>
</footer>
</div>
</div>
<div class="search-overlay"></div>
</div>
</body>
</html>