UNPKG

gentelella

Version:

Gentelella Admin is a free to use Bootstrap admin template

909 lines (639 loc) 95.7 kB
<!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(6)) > 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(6) > a { font-weight: 600; text-decoration: none; }.site-nav > ul.nav-list:first-child > li:nth-child(6) > button svg { transform: rotate(-90deg); }.site-nav > ul.nav-list:first-child > li.nav-list-item:nth-child(6) > 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.9.5" /> <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="http://localhost:4000/gentelella/deployment/" /> <meta property="og:url" content="http://localhost:4000/gentelella/deployment/" /> <meta property="og:site_name" content="Gentelella Admin Template" /> <meta property="og:image" content="http://localhost:4000/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="http://localhost:4000/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":"http://localhost:4000/gentelella/assets/images/gentelella-preview.jpg","url":"http://localhost:4000/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/performance/" class="nav-list-link">Performance 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></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">&lt;</span><span class="nl">VirtualHost</span><span class="sr"> *:80</span><span class="p">&gt; </span> <span class="nc">ServerName</span> yoursite.com <span class="nc">ServerAlias</span> www.yoursite.com <span class="nc">DocumentRoot</span> /var/www/gentelella/dist <span class="c"># Enable compression</span> <span class="nc">LoadModule</span> deflate_module modules/mod_deflate.so <span class="p">&lt;</span><span class="nl">Location</span><span class="sr"> /</span><span class="p">&gt; </span> <span class="nc">SetOutputFilter</span> DEFLATE <span class="nc">SetEnvIfNoCase</span> <span class="ss">Request_URI</span> \ <span class="err">\.(?:</span>gif|jpe?g|png)$ no-gzip dont-vary <span class="nc">SetEnvIfNoCase</span> <span class="ss">Request_URI</span> \ <span class="err">\.(?:</span>exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary <span class="p">&lt;/</span><span class="nl">Location</span><span class="p">&gt; </span> <span class="c"># Cache static assets</span> <span class="p">&lt;</span><span class="nl">LocationMatch</span><span class="sr"> "\.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2)$"</span><span class="p">&gt; </span> <span class="nc">ExpiresActive</span> <span class="ss">On</span> <span class="nc">ExpiresDefault</span> "access plus 1 year" <span class="nc">Header</span> <span class="ss">append</span> Cache-Control "public, immutable" <span class="p">&lt;/</span><span class="nl">LocationMatch</span><span class="p">&gt; </span> <span class="c"># Handle SPA routing</span> <span class="p">&lt;</span><span class="nl">Directory</span><span class="sr"> /var/www/gentelella/dist</span><span class="p">&gt; </span> <span class="nc">RewriteEngine</span> <span class="ss">On</span> <span class="nc">RewriteBase</span> / <span class="nc">RewriteRule</span> ^index\.html$ - [L] <span class="nc">RewriteCond</span> %{REQUEST_FILENAME} !-f <span class="nc">RewriteCond</span> %{REQUEST_FILENAME} !-d <span class="nc">RewriteRule</span> . /index.html [L] <span class="p">&lt;/</span><span class="nl">Directory</span><span class="p">&gt; </span> <span class="nc">ErrorLog</span> ${APACHE_LOG_DIR}/gentelella_error.log <span class="nc">CustomLog</span> ${APACHE_LOG_DIR}/gentelella_access.log combined <span class="p">&lt;/</span><span class="nl">VirtualHost</span><span class="p">&gt; </span></code></pre></div></div><hr /> <h2 id="container-deployment"> <a href="#container-deployment" class="anchor-heading" aria-labelledby="container-deployment"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Container Deployment </h2> <h3 id="docker-setup"> <a href="#docker-setup" class="anchor-heading" aria-labelledby="docker-setup"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Docker Setup </h3> <h4 id="dockerfile"> <a href="#dockerfile" class="anchor-heading" aria-labelledby="dockerfile"><svg viewBox="0 0 16 16" aria-hidden="true"><use xlink:href="#svg-link"></use></svg></a> Dockerfile </h4> <div class="language-dockerfile highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Build stage</span> <span class="k">FROM</span><span class="w"> </span><span class="s">node:18-alpine</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="s">build-stage</span> <span class="k">WORKDIR</span><span class="s"> /app</span> <span class="k">COPY</span><span class="s"> package*.json ./</span> <span class="k">RUN </span>npm ci <span class="nt">--only</span><span class="o">=</span>production <span class="k">COPY</span><span class="s"> . .</span> <span class="k">RUN </span>npm run build <span class="c"># Production stage</span> <span class="k">FROM</span><span class="w"> </span><span class="s">nginx:alpine</span><span