Skip to content

Latest commit

 

History

History
580 lines (435 loc) · 10.2 KB

File metadata and controls

580 lines (435 loc) · 10.2 KB

Deployment Guide

This guide covers how to deploy the Metis Admin Template to various hosting platforms.

Table of Contents


Building for Production

Standard Build

# Install dependencies (if not already done)
npm install

# Create production build
npm run build

This generates optimized files in the dist-modern/ directory:

dist-modern/
├── assets/
│   ├── main-[hash].js          # Main application bundle
│   ├── main-[hash].css         # Compiled CSS
│   ├── vendor-bootstrap-[hash].js
│   ├── vendor-charts-[hash].js
│   ├── vendor-ui-[hash].js
│   └── [page]-[hash].js        # Page-specific bundles
├── index.html
├── analytics.html
├── users.html
└── ... (other HTML pages)

Build Output Analysis

# Preview the production build locally
npm run preview

# The preview server runs at http://localhost:4173

Environment-Specific Builds

Create environment files for different deployments:

# .env.production
VITE_API_URL=https://api.yourdomain.com
VITE_ENABLE_DEMO_DATA=false

# .env.staging
VITE_API_URL=https://staging-api.yourdomain.com
VITE_ENABLE_DEMO_DATA=true

Build with specific environment:

# Uses .env.production
npm run build

# Uses .env.staging
npm run build -- --mode staging

Static Hosting

Netlify

Option 1: Git Integration

  1. Connect your repository to Netlify
  2. Configure build settings:
    • Build command: npm run build
    • Publish directory: dist-modern

Option 2: Manual Deploy

# Install Netlify CLI
npm install -g netlify-cli

# Build and deploy
npm run build
netlify deploy --prod --dir=dist-modern

netlify.toml configuration:

[build]
  command = "npm run build"
  publish = "dist-modern"

[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200

Vercel

Option 1: Git Integration

  1. Import project from GitHub/GitLab
  2. Framework preset: Vite
  3. Output directory: dist-modern

Option 2: CLI Deploy

# Install Vercel CLI
npm install -g vercel

# Deploy
vercel --prod

vercel.json configuration:

{
  "buildCommand": "npm run build",
  "outputDirectory": "dist-modern",
  "framework": "vite"
}

GitHub Pages

Using GitHub Actions:

Create .github/workflows/deploy.yml:

name: Deploy to GitHub Pages

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Build
        run: npm run build
        env:
          BASE_URL: /your-repo-name/

      - name: Deploy to GitHub Pages
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./dist-modern

Configure base URL in vite.config.js:

export default defineConfig({
  base: process.env.BASE_URL || '/',
  // ... other config
});

AWS S3 + CloudFront

1. Create S3 Bucket:

aws s3 mb s3://your-bucket-name --region us-east-1

2. Configure for static hosting:

{
  "IndexDocument": { "Suffix": "index.html" },
  "ErrorDocument": { "Key": "index.html" }
}

3. Deploy:

npm run build
aws s3 sync dist-modern/ s3://your-bucket-name --delete

4. Create CloudFront distribution for HTTPS and CDN caching.

Firebase Hosting

# Install Firebase CLI
npm install -g firebase-tools

# Initialize
firebase init hosting

# Deploy
npm run build
firebase deploy

firebase.json:

{
  "hosting": {
    "public": "dist-modern",
    "ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
    "rewrites": [
      { "source": "**", "destination": "/index.html" }
    ]
  }
}

Server Deployment

Nginx Configuration

server {
    listen 80;
    server_name yourdomain.com;
    root /var/www/metis-admin/dist-modern;
    index index.html;

    # Gzip compression
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
    gzip_min_length 1000;

    # Cache static assets
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    # HTML files - no cache
    location ~* \.html$ {
        expires -1;
        add_header Cache-Control "no-store, no-cache, must-revalidate";
    }

    # SPA fallback
    location / {
        try_files $uri $uri/ /index.html;
    }
}

With SSL (Let's Encrypt):

server {
    listen 443 ssl http2;
    server_name yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

    # ... rest of config
}

server {
    listen 80;
    server_name yourdomain.com;
    return 301 https://$server_name$request_uri;
}

Apache Configuration

.htaccess:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.html$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.html [L]
</IfModule>

# Compression
<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/css application/javascript application/json
</IfModule>

# Caching
<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType text/css "access plus 1 year"
    ExpiresByType application/javascript "access plus 1 year"
    ExpiresByType image/png "access plus 1 year"
    ExpiresByType image/svg+xml "access plus 1 year"
</IfModule>

Docker Deployment

Dockerfile

# Build stage
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Production stage
FROM nginx:alpine
COPY --from=build /app/dist-modern /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

nginx.conf (for Docker)

server {
    listen 80;
    root /usr/share/nginx/html;
    index index.html;

    gzip on;
    gzip_types text/plain text/css application/json application/javascript;

    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    location / {
        try_files $uri $uri/ /index.html;
    }
}

docker-compose.yml

version: '3.8'

services:
  metis-admin:
    build: .
    ports:
      - "80:80"
    restart: unless-stopped

Build and Run

# Build image
docker build -t metis-admin .

# Run container
docker run -d -p 80:80 metis-admin

# Or with docker-compose
docker-compose up -d

CI/CD Integration

GitHub Actions

name: CI/CD

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      - run: npm ci
      - run: npm run lint
      - run: npm run build

  deploy:
    needs: test
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      - run: npm ci
      - run: npm run build
      - name: Deploy
        run: |
          # Add your deployment commands here
          echo "Deploying to production..."

GitLab CI

stages:
  - test
  - build
  - deploy

variables:
  NODE_VERSION: "20"

test:
  stage: test
  image: node:${NODE_VERSION}
  cache:
    paths:
      - node_modules/
  script:
    - npm ci
    - npm run lint

build:
  stage: build
  image: node:${NODE_VERSION}
  cache:
    paths:
      - node_modules/
  script:
    - npm ci
    - npm run build
  artifacts:
    paths:
      - dist-modern/
    expire_in: 1 week

deploy:
  stage: deploy
  only:
    - main
  script:
    - echo "Deploying to production..."

Performance Optimization

Pre-deployment Checklist

  • Run npm run lint - no errors
  • Run npm run build - successful build
  • Run npm run preview - test locally
  • Check bundle sizes in build output
  • Verify all pages load correctly
  • Test dark/light mode
  • Test on mobile devices

Optimization Tips

1. Analyze Bundle Size:

# Install bundle analyzer
npm install --save-dev rollup-plugin-visualizer

# Add to vite.config.js
import { visualizer } from 'rollup-plugin-visualizer';

export default defineConfig({
  plugins: [
    visualizer({ open: true })
  ]
});

2. Enable Compression:

Most hosting platforms handle this automatically. For custom servers, enable gzip/brotli.

3. Use CDN for Static Assets:

Configure your hosting to serve assets from a CDN for better global performance.

4. Set Proper Cache Headers:

  • HTML files: no-cache
  • JS/CSS with hashes: max-age=31536000, immutable
  • Images: max-age=86400

5. Lazy Load Images:

<img src="image.jpg" loading="lazy" alt="Description">

Lighthouse Score Targets

  • Performance: 90+
  • Accessibility: 90+
  • Best Practices: 90+
  • SEO: 90+

Troubleshooting

Common Issues

1. 404 errors on page refresh

Solution: Configure server for SPA routing (see Nginx/Apache configs above).

2. Assets not loading

Check the base option in vite.config.js matches your deployment path.

3. CORS errors

Configure your API server to allow requests from your deployment domain.

4. Build fails

# Clear cache and rebuild
rm -rf node_modules dist-modern
npm install
npm run build

For additional help, see the GitHub Issues page.