Deployment Issues
Troubleshooting deployment problems, build failures, and production environment issues.
Deployment Issues
Comprehensive guide to resolving deployment problems and production environment issues.
Build Failures
Next.js Build Errors
Common Build Issues:
# Type checking errors
npm run build
# Error: Type error: Property 'id' does not exist on type 'never'
# Solution: Fix TypeScript errors
# Check tsconfig.json configuration
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"skipLibCheck": false,
"incremental": true
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}
# Disable type checking during build (not recommended)
# next.config.js
const nextConfig = {
typescript: {
ignoreBuildErrors: true, // Only for emergency deployments
},
eslint: {
ignoreDuringBuilds: true, // Only for emergency deployments
},
}
Dependency Resolution Issues
# Clear package-lock.json and node_modules
rm -rf node_modules package-lock.json
npm install
# Check for dependency conflicts
npm ls
# Update dependencies
npm update
# Install specific versions
npm install package-name@version
# Use npm audit to fix vulnerabilities
npm audit fix
Environment Variable Issues
// next.config.js - Expose environment variables to client
const nextConfig = {
env: {
CUSTOM_KEY: process.env.CUSTOM_KEY,
API_URL: process.env.API_URL,
},
// Or use public runtime config
publicRuntimeConfig: {
API_URL: process.env.API_URL,
},
// Server-only variables
serverRuntimeConfig: {
SECRET_KEY: process.env.SECRET_KEY,
},
}
// Use NEXT_PUBLIC_ prefix for client-side variables
// .env.local
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
// Environment variable validation
const requiredEnvVars = [
'NEXT_PUBLIC_SUPABASE_URL',
'NEXT_PUBLIC_SUPABASE_ANON_KEY',
]
requiredEnvVars.forEach((envVar) => {
if (!process.env[envVar]) {
throw new Error(`Missing required environment variable: ${envVar}`)
}
})
Deployment Platform Issues
Vercel Deployment Problems
# Vercel CLI debugging
npx vercel --debug
# Check deployment logs
npx vercel logs <deployment-url>
# Environment variables in Vercel
# Set via dashboard or CLI
npx vercel env add VARIABLE_NAME
# Build settings for Vercel
# vercel.json
{
"buildCommand": "npm run build",
"outputDirectory": ".next",
"installCommand": "npm install",
"framework": "nextjs",
"functions": {
"app/api/**/*.ts": {
"maxDuration": 30
}
},
"headers": [
{
"source": "/(.*)",
"headers": [
{
"key": "X-Frame-Options",
"value": "DENY"
}
]
}
]
}
Netlify Deployment Issues
# netlify.toml
[build]
publish = "out"
command = "npm run build && npm run export"
[build.environment]
NODE_VERSION = "18"
NPM_VERSION = "8"
# Redirects for SPA
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
# Function timeout
[functions]
node_bundler = "esbuild"
external_node_modules = ["sharp"]
# Environment variables (set in Netlify dashboard)
# NEXT_PUBLIC_SUPABASE_URL
# NEXT_PUBLIC_SUPABASE_ANON_KEY
Docker Deployment
# Dockerfile
FROM node:18-alpine AS base
# Install dependencies only when needed
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm ci --only=production
# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY /app/node_modules ./node_modules
COPY . .
# Environment variables for build
ARG NEXT_PUBLIC_SUPABASE_URL
ARG NEXT_PUBLIC_SUPABASE_ANON_KEY
ENV NEXT_PUBLIC_SUPABASE_URL=$NEXT_PUBLIC_SUPABASE_URL
ENV NEXT_PUBLIC_SUPABASE_ANON_KEY=$NEXT_PUBLIC_SUPABASE_ANON_KEY
RUN npm run build
# Production image
FROM base AS runner
WORKDIR /app
ENV NODE_ENV production
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY /app/public ./public
COPY /app/.next/standalone ./
COPY /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT 3000
CMD ["node", "server.js"]
Production Environment Issues
Performance in Production
// next.config.js - Production optimizations
const nextConfig = {
// Enable compression
compress: true,
// Optimize images
images: {
formats: ['image/avif', 'image/webp'],
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
},
// Bundle analyzer for production debugging
webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
if (!dev && !isServer) {
// Analyze bundle in production
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
config.plugins.push(
new BundleAnalyzerPlugin({
analyzerMode: 'static',
reportFilename: './analyze/client.html',
openAnalyzer: false,
})
)
}
return config
},
// Enable SWC minification
swcMinify: true,
// Experimental features
experimental: {
optimizePackageImports: ['lucide-react'],
},
}
Database Connection Issues
// Production database configuration
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
auth: {
autoRefreshToken: true,
persistSession: true,
detectSessionInUrl: true,
},
db: {
schema: 'public',
},
global: {
headers: {
'X-Client-Info': 'smart-shelf-v1.0.0',
},
},
// Production-specific settings
realtime: {
params: {
eventsPerSecond: 5, // Limit events in production
},
},
}
)
// Connection pooling for API routes
let supabaseAdmin: SupabaseClient | null = null
export function getSupabaseAdmin() {
if (!supabaseAdmin) {
supabaseAdmin = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.SUPABASE_SERVICE_ROLE_KEY!,
{
auth: {
autoRefreshToken: false,
persistSession: false,
},
}
)
}
return supabaseAdmin
}
SSL/HTTPS Issues
// Force HTTPS in production
// next.config.js
const nextConfig = {
async headers() {
return [
{
source: '/(.*)',
headers: [
{
key: 'Strict-Transport-Security',
value: 'max-age=31536000; includeSubDomains; preload',
},
{
key: 'X-Content-Type-Options',
value: 'nosniff',
},
{
key: 'X-Frame-Options',
value: 'DENY',
},
{
key: 'Referrer-Policy',
value: 'origin-when-cross-origin',
},
],
},
]
},
async redirects() {
return [
{
source: '/:path*',
has: [
{
type: 'header',
key: 'x-forwarded-proto',
value: 'http',
},
],
destination: 'https://yourdomain.com/:path*',
permanent: true,
},
]
},
}
CI/CD Pipeline Issues
GitHub Actions Configuration
# .github/workflows/deploy.yml
name: Deploy to Production
on:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
env:
NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL }}
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }}
- name: Build application
run: npm run build
env:
NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL }}
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }}
deploy:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Deploy to Vercel
uses: amondnet/vercel-action@v25
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.ORG_ID }}
vercel-project-id: ${{ secrets.PROJECT_ID }}
vercel-args: '--prod'
Monitoring and Logging
// Production error tracking
export function setupErrorTracking() {
// Sentry configuration
if (process.env.NODE_ENV === 'production') {
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
environment: process.env.NODE_ENV,
tracesSampleRate: 0.1,
})
}
// Custom error logging
window.addEventListener('error', (event) => {
console.error('Global error:', event.error)
// Send to logging service
fetch('/api/log-error', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
error: event.error.message,
stack: event.error.stack,
url: window.location.href,
timestamp: new Date().toISOString(),
}),
})
})
}
// Health check endpoint
// pages/api/health.ts
export default function handler(req: NextApiRequest, res: NextApiResponse) {
try {
// Check database connection
// Check external services
// Check environment variables
res.status(200).json({
status: 'healthy',
timestamp: new Date().toISOString(),
version: process.env.npm_package_version,
})
} catch (error) {
res.status(500).json({
status: 'unhealthy',
error: error.message,
timestamp: new Date().toISOString(),
})
}
}
Troubleshooting Commands
Debug Deployment
# Check build locally
npm run build
npm start
# Test production build
NODE_ENV=production npm run build
NODE_ENV=production npm start
# Check bundle size
npx @next/bundle-analyzer
# Analyze dependencies
npm ls --depth=0
npm outdated
# Check for security vulnerabilities
npm audit
npm audit fix
# Clear Next.js cache
rm -rf .next
npm run build
# Check environment variables
printenv | grep NEXT_PUBLIC
# Test with production environment variables
cp .env.production .env.local
npm run dev
Database Migration in Production
# Backup production database
pg_dump -h hostname -U username database_name > backup.sql
# Run migrations safely
supabase migration up --dry-run
supabase migration up
# Rollback if needed
supabase migration down
# Check migration status
supabase migration list
Common Deployment Errors
"Module not found"
- Cause: Missing dependencies or wrong import paths
- Solution: Check package.json and import statements
"Environment variable undefined"
- Cause: Missing environment variables in deployment
- Solution: Set variables in deployment platform
"Build timeout"
- Cause: Build taking too long
- Solution: Optimize build process, increase timeout limits
"Memory limit exceeded"
- Cause: Not enough memory allocated
- Solution: Increase memory limits or optimize code
"Database connection failed"
- Cause: Network issues or wrong credentials
- Solution: Check connection strings and firewall settings
For platform-specific deployment guides, refer to the documentation for Vercel, Netlify, or your chosen deployment platform.