Skip to main content

Overview

This guide covers deploying Solarecliente to various hosting platforms, including Vercel, Netlify, AWS, and custom servers. We’ll also cover CI/CD setup, environment management, and production best practices.

Pre-Deployment Checklist

1

Review Configuration

Verify all environment variables are set correctly for production:
# Check production configuration
npm run config:validate
2

Run Tests

Ensure all tests pass before deployment:
npm run test
npm run test:e2e
npm run lint
3

Build Production Bundle

Create an optimized production build:
npm run build
4

Security Audit

Check for vulnerabilities:
npm audit
npm audit fix
Never commit .env files containing production secrets to version control. Use your hosting platform’s environment variable management.

Deployment Platforms

Vercel

Optimized for frontend frameworks with automatic deployments

Netlify

Continuous deployment with built-in CDN and serverless functions

AWS

Scalable cloud infrastructure with full control

Docker

Containerized deployment for any platform

Static Hosting

Traditional web servers (Nginx, Apache)

Cloud Run

Google Cloud’s containerized serverless platform

Vercel Deployment

Quick Deploy

1

Install Vercel CLI

npm install -g vercel
2

Login to Vercel

vercel login
3

Deploy

vercel --prod

Git Integration

For automatic deployments:
1

Connect Repository

  1. Go to vercel.com
  2. Click “New Project”
  3. Import your Git repository
2

Configure Project

{
  "buildCommand": "npm run build",
  "outputDirectory": "dist",
  "installCommand": "npm install",
  "framework": "vite"
}
3

Set Environment Variables

Add your production environment variables in the Vercel dashboard:
  • VITE_API_URL
  • VITE_API_KEY
  • VITE_AUTH_CLIENT_ID
4

Deploy

Push to your main branch to trigger automatic deployment

vercel.json Configuration

{
  "version": 2,
  "buildCommand": "npm run build",
  "outputDirectory": "dist",
  "framework": "vite",
  "rewrites": [
    {
      "source": "/(.*)",
      "destination": "/index.html"
    }
  ],
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        {
          "key": "X-Content-Type-Options",
          "value": "nosniff"
        },
        {
          "key": "X-Frame-Options",
          "value": "DENY"
        },
        {
          "key": "X-XSS-Protection",
          "value": "1; mode=block"
        }
      ]
    },
    {
      "source": "/static/(.*)",
      "headers": [
        {
          "key": "Cache-Control",
          "value": "public, max-age=31536000, immutable"
        }
      ]
    }
  ]
}
Vercel automatically optimizes your deployment with edge caching and serverless functions.

Netlify Deployment

netlify.toml Configuration

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

[build.environment]
  NODE_VERSION = "20"

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

[[headers]]
  for = "/*"
  [headers.values]
    X-Frame-Options = "DENY"
    X-XSS-Protection = "1; mode=block"
    X-Content-Type-Options = "nosniff"
    Referrer-Policy = "strict-origin-when-cross-origin"

[[headers]]
  for = "/static/*"
  [headers.values]
    Cache-Control = "public, max-age=31536000, immutable"

[[headers]]
  for = "*.js"
  [headers.values]
    Cache-Control = "public, max-age=31536000, immutable"

[[headers]]
  for = "*.css"
  [headers.values]
    Cache-Control = "public, max-age=31536000, immutable"

Netlify CLI Deployment

# Install Netlify CLI
npm install -g netlify-cli

# Login
netlify login

# Initialize project
netlify init

# Deploy
netlify deploy --prod

AWS Deployment

AWS S3 + CloudFront

1

Create S3 Bucket

aws s3 mb s3://solarecliente-prod
aws s3 website s3://solarecliente-prod --index-document index.html --error-document index.html
2

Build and Upload

npm run build
aws s3 sync dist/ s3://solarecliente-prod --delete
3

Create CloudFront Distribution

aws cloudfront create-distribution \
  --origin-domain-name solarecliente-prod.s3.amazonaws.com \
  --default-root-object index.html
4

Configure Custom Domain

Update DNS records to point to your CloudFront distribution

AWS Amplify

# amplify.yml
version: 1
frontend:
  phases:
    preBuild:
      commands:
        - npm ci
    build:
      commands:
        - npm run build
  artifacts:
    baseDirectory: dist
    files:
      - '**/*'
  cache:
    paths:
      - node_modules/**/*

Docker Deployment

Dockerfile

# Build stage
FROM node:20-alpine AS builder

WORKDIR /app

COPY package*.json ./
RUN npm ci

COPY . .
RUN npm run build

# Production stage
FROM nginx:alpine

COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

nginx.conf

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

    # Gzip compression
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;

    # Security headers
    add_header X-Frame-Options "DENY" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    # Cache static assets
    location /assets/ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

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

Build and Run

# Build Docker image
docker build -t solarecliente:latest .

# Run container
docker run -d -p 80:80 \
  --name solarecliente \
  --env-file .env.production \
  solarecliente:latest

# Push to registry
docker tag solarecliente:latest registry.example.com/solarecliente:latest
docker push registry.example.com/solarecliente:latest

docker-compose.yml

version: '3.8'

services:
  web:
    build: .
    ports:
      - "80:80"
      - "443:443"
    environment:
      - NODE_ENV=production
    volumes:
      - ./ssl:/etc/nginx/ssl:ro
    restart: unless-stopped
    networks:
      - app-network

networks:
  app-network:
    driver: bridge
Use multi-stage Docker builds to minimize image size and improve security.

CI/CD Pipeline

GitHub Actions

# .github/workflows/deploy.yml
name: Deploy to Production

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '20'
          cache: 'npm'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Run tests
        run: npm run test
      
      - name: Run linter
        run: npm run lint
      
      - name: Build application
        run: npm run build
        env:
          VITE_API_URL: ${{ secrets.VITE_API_URL }}
          VITE_API_KEY: ${{ secrets.VITE_API_KEY }}
      
      - name: Deploy to Vercel
        uses: amondnet/vercel-action@v20
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
          vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
          vercel-args: '--prod'

GitLab CI/CD

# .gitlab-ci.yml
stages:
  - test
  - build
  - deploy

variables:
  NODE_VERSION: "20"

cache:
  paths:
    - node_modules/

test:
  stage: test
  image: node:${NODE_VERSION}
  script:
    - npm ci
    - npm run test
    - npm run lint

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

deploy:production:
  stage: deploy
  image: node:${NODE_VERSION}
  only:
    - main
  script:
    - npm install -g vercel
    - vercel --token $VERCEL_TOKEN --prod --yes
  environment:
    name: production
    url: https://solarecliente.example.com

Environment Management

Multiple Environments

# .env.development
VITE_API_URL=http://localhost:8000
VITE_LOG_LEVEL=debug
VITE_SOURCE_MAPS=true
# .env.staging
VITE_API_URL=https://staging-api.example.com
VITE_LOG_LEVEL=info
VITE_SOURCE_MAPS=true
VITE_SENTRY_DSN=your_staging_sentry_dsn
# .env.production
VITE_API_URL=https://api.example.com
VITE_LOG_LEVEL=error
VITE_SOURCE_MAPS=false
VITE_SENTRY_DSN=your_production_sentry_dsn
VITE_ANALYTICS_ID=your_analytics_id

Production Optimization

Build Optimization

// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { visualizer } from 'rollup-plugin-visualizer';

export default defineConfig({
  plugins: [
    react(),
    visualizer({ open: true })
  ],
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          'react-vendor': ['react', 'react-dom', 'react-router-dom'],
          'ui-vendor': ['@radix-ui/react-dialog', '@radix-ui/react-dropdown-menu'],
          'utils': ['date-fns', 'zod', 'clsx']
        }
      }
    },
    chunkSizeWarningLimit: 1000,
    minify: 'terser',
    terserOptions: {
      compress: {
        drop_console: true,
        drop_debugger: true
      }
    }
  }
});

Performance Monitoring

// src/monitoring/performance.ts
import * as Sentry from '@sentry/react';
import { BrowserTracing } from '@sentry/tracing';

Sentry.init({
  dsn: import.meta.env.VITE_SENTRY_DSN,
  integrations: [
    new BrowserTracing(),
    new Sentry.Replay()
  ],
  tracesSampleRate: 1.0,
  replaysSessionSampleRate: 0.1,
  replaysOnErrorSampleRate: 1.0,
  environment: import.meta.env.VITE_APP_ENV
});

SSL/TLS Configuration

Let’s Encrypt with Certbot

# Install Certbot
sudo apt-get update
sudo apt-get install certbot python3-certbot-nginx

# Obtain certificate
sudo certbot --nginx -d solarecliente.example.com

# Auto-renewal
sudo certbot renew --dry-run

Nginx SSL Configuration

server {
    listen 443 ssl http2;
    server_name solarecliente.example.com;

    ssl_certificate /etc/letsencrypt/live/solarecliente.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/solarecliente.example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    # HSTS
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    root /usr/share/nginx/html;
    index index.html;

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

# Redirect HTTP to HTTPS
server {
    listen 80;
    server_name solarecliente.example.com;
    return 301 https://$server_name$request_uri;
}

Monitoring and Logging

Error Tracking

Use Sentry or similar for error monitoring

Analytics

Implement Google Analytics or custom analytics

Uptime Monitoring

Set up uptime checks with Pingdom or UptimeRobot

Performance

Monitor Core Web Vitals and performance metrics

Rollback Strategy

1

Version Tagging

git tag -a v1.0.0 -m "Production release v1.0.0"
git push origin v1.0.0
2

Keep Previous Builds

Maintain the last 3-5 production builds for quick rollback
3

Rollback Command

# Vercel
vercel rollback

# Custom deployment
./scripts/rollback.sh v1.0.0
Always test rollback procedures in staging before deploying to production.

Post-Deployment

1

Verify Deployment

  • Check application loads correctly
  • Test critical user flows
  • Verify API connections
  • Check error tracking is working
2

Monitor Performance

  • Review performance metrics
  • Check server response times
  • Monitor error rates
  • Verify CDN caching
3

Update Documentation

  • Document deployment date and version
  • Update changelog
  • Notify team of deployment

Troubleshooting

  • Check Node.js version compatibility
  • Verify all environment variables are set
  • Clear node_modules and reinstall dependencies
  • Review build logs for specific errors
  • Check browser console for errors
  • Verify API endpoints are accessible
  • Review CORS configuration
  • Check authentication token validity
  • Analyze bundle size with visualizer
  • Check for unnecessary re-renders
  • Verify CDN caching is working
  • Review database query performance

Next Steps

Configuration

Review configuration options for your deployment

Dashboard

Monitor your deployment with the built-in dashboard

Build docs developers (and LLMs) love