mirror of https://github.com/ColorlibHQ/gentelella
1618 lines
94 KiB
HTML
1618 lines
94 KiB
HTML
|
||
|
||
<!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 Let’s 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 Let’s 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"><</span><span class="nl">VirtualHost</span><span class="sr"> *:80</span><span class="p">>
|
||
</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"><</span><span class="nl">Location</span><span class="sr"> /</span><span class="p">>
|
||
</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"></</span><span class="nl">Location</span><span class="p">>
|
||
</span>
|
||
<span class="c"># Cache static assets</span>
|
||
<span class="p"><</span><span class="nl">LocationMatch</span><span class="sr"> "\.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2)$"</span><span class="p">>
|
||
</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"></</span><span class="nl">LocationMatch</span><span class="p">>
|
||
</span>
|
||
<span class="c"># Handle SPA routing</span>
|
||
<span class="p"><</span><span class="nl">Directory</span><span class="sr"> /var/www/gentelella/dist</span><span class="p">>
|
||
</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"></</span><span class="nl">Directory</span><span class="p">>
|
||
</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"></</span><span class="nl">VirtualHost</span><span class="p">>
|
||
</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">=></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">&&</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">=></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">=></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"><!-- Real User Monitoring --></span>
|
||
<span class="nt"><script></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"></script></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"><!-- Add to index.html --></span>
|
||
<span class="nt"><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">></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">>></span> .gitignore
|
||
<span class="nb">echo</span> <span class="s2">".env.production"</span> <span class="o">>></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">&&</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 © {{ '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>
|
||
|