Troubleshooting
This guide covers common issues you might encounter when using Easy Deploy and provides solutions to resolve them quickly.
Deployment Issues
Section titled “Deployment Issues”Build Failures
Section titled “Build Failures”Common Causes
Section titled “Common Causes”- Missing dependencies: Package.json missing required packages
- Node version mismatch: Application requires specific Node.js version
- Build script errors: Errors in build commands or scripts
- Environment variables: Missing required environment variables
Solutions
Section titled “Solutions”Check build logs
# View detailed build logseasydeploy logs APP_NAME --build
# View real-time deployment logseasydeploy deploy APP_NAME --followFix dependency issues
# Ensure all dependencies are listednpm install --save missing-package
# Update package-lock.jsonnpm install
# Check for security vulnerabilitiesnpm audit fixSpecify Node.js version
{ "engines": { "node": "18.x", "npm": "9.x" }}Deployment Timeout
Section titled “Deployment Timeout”Symptoms: Deployment takes longer than 10 minutes and times out
Solutions:
-
Optimize build process:
- Remove unnecessary files from build
- Use
.easydeploy-ignoreto exclude large directories - Enable build caching in
.easydeploy.yml
-
Break down large builds:
.easydeploy.yml build:timeout: 20m # Increase timeoutcache: true # Enable cachingparallel: true # Enable parallel builds
Failed Health Checks
Section titled “Failed Health Checks”Symptoms: Application builds successfully but fails health checks
Causes:
- Application not starting properly
- Wrong port configuration
- Health check endpoint not responding
Solutions:
-
Check port configuration:
Terminal window const PORT = process.env.PORT || 3000;app.listen(PORT, '0.0.0.0', () => {console.log(`Server running on port ${PORT}`);}); -
Implement health check endpoint:
Terminal window app.get('/health', (req, res) => {res.status(200).json({ status: 'healthy' });}); -
Configure health checks:
.easydeploy.yml health_check:path: "/health"timeout: 30sinterval: 10s
Application Runtime Issues
Section titled “Application Runtime Issues”Memory Issues
Section titled “Memory Issues”Out of Memory Errors
Section titled “Out of Memory Errors”Symptoms:
- Application crashes with “out of memory” errors
- Slow response times
- Frequent restarts
Solutions:
-
Increase memory allocation:
.easydeploy.yml resources:memory: 1GB # Increase from default 512MB -
Optimize memory usage:
Terminal window // Implement garbage collection monitoringif (process.env.NODE_ENV === 'production') {setInterval(() => {if (global.gc) {global.gc();}}, 30000);} -
Memory leak detection:
Terminal window # Monitor memory usageeasydeploy metrics APP_NAME --metric=memory --period=24h
Memory Leaks
Section titled “Memory Leaks”Detection:
- Gradually increasing memory usage
- Application slowdown over time
- Eventual crashes
Solutions:
-
Profile memory usage:
Terminal window // Add memory monitoringsetInterval(() => {const used = process.memoryUsage();console.log('Memory usage:', {rss: Math.round(used.rss / 1024 / 1024) + 'MB',heapTotal: Math.round(used.heapTotal / 1024 / 1024) + 'MB',heapUsed: Math.round(used.heapUsed / 1024 / 1024) + 'MB'});}, 60000); -
Common leak sources:
- Event listeners not removed
- Timers not cleared
- Unclosed database connections
- Large objects in global scope
Performance Issues
Section titled “Performance Issues”Slow Response Times
Section titled “Slow Response Times”Symptoms:
- High response times (>1000ms)
- Timeouts on client side
- Poor user experience
Diagnosis:
# Check response time metricseasydeploy metrics APP_NAME --metric=response_time --period=1h
# Monitor application logseasydeploy logs APP_NAME --follow --level=infoSolutions:
-
Database optimization:
Terminal window // Add database connection poolingconst pool = new Pool({connectionString: process.env.DATABASE_URL,max: 20,idleTimeoutMillis: 30000,connectionTimeoutMillis: 2000,}); -
Implement caching:
Terminal window const redis = require('redis');const client = redis.createClient(process.env.REDIS_URL);// Cache frequently accessed dataapp.get('/api/data', async (req, res) => {const cacheKey = `data:${req.params.id}`;let data = await client.get(cacheKey);if (!data) {data = await database.getData(req.params.id);await client.setex(cacheKey, 300, JSON.stringify(data));} else {data = JSON.parse(data);}res.json(data);}); -
Optimize API calls:
Terminal window // Implement request batchingconst batchRequests = (requests) => {return Promise.all(requests.map(req =>fetch(req.url, req.options)));};
Database Issues
Section titled “Database Issues”Connection Problems
Section titled “Connection Problems”Connection Timeouts
Section titled “Connection Timeouts”Symptoms:
- “Connection timeout” errors
- Intermittent database connectivity
- Application hanging on database calls
Solutions:
-
Check connection configuration:
Terminal window const dbConfig = {connectionString: process.env.DATABASE_URL,connectionTimeoutMillis: 5000,idleTimeoutMillis: 30000,max: 10 // connection pool size}; -
Implement retry logic:
Terminal window async function queryWithRetry(query, params, maxRetries = 3) {for (let attempt = 1; attempt <= maxRetries; attempt++) {try {return await db.query(query, params);} catch (error) {if (attempt === maxRetries) throw error;await new Promise(resolve => setTimeout(resolve, 1000 * attempt));}}}
Connection Pool Exhaustion
Section titled “Connection Pool Exhaustion”Symptoms:
- “Pool exhausted” errors
- New connections rejected
- Application stops responding
Solutions:
-
Increase pool size:
Terminal window const pool = new Pool({max: 20, // Increase from defaultmin: 2,acquire: 30000,idle: 10000}); -
Ensure connections are released:
Terminal window // Always use try/finallyasync function getData() {const client = await pool.connect();try {return await client.query('SELECT * FROM users');} finally {client.release();}}
Performance Issues
Section titled “Performance Issues”Slow Queries
Section titled “Slow Queries”Detection:
# Enable slow query loggingeasydeploy database DB_NAME --enable-slow-query-log
# View slow querieseasydeploy database DB_NAME --slow-queries --limit=10Solutions:
-
Add indexes:
Terminal window -- Identify missing indexes-- Add appropriate indexCREATE INDEX idx_users_email ON users(email); -
Optimize queries:
Terminal window -- Before: N+1 query problemSELECT * FROM users;-- Then for each user:SELECT * FROM orders WHERE user_id = ?;-- After: Single join querySELECT u.*, o.* FROM users uLEFT JOIN orders o ON u.id = o.user_id;
SSL/Certificate Issues
Section titled “SSL/Certificate Issues”SSL Certificate Errors
Section titled “SSL Certificate Errors”Certificate Not Valid
Section titled “Certificate Not Valid”Symptoms:
- “SSL certificate not valid” errors
- Browser security warnings
- HTTPS not working
Solutions:
-
Check certificate status:
Terminal window curl -I https://yourdomain.comeasydeploy ssl APP_NAME --status -
Force certificate renewal:
Terminal window easydeploy ssl APP_NAME --renew -
Verify domain configuration:
Terminal window # Check DNS recordsdig yourdomain.comnslookup yourdomain.com
Mixed Content Warnings
Section titled “Mixed Content Warnings”Symptoms:
- Browser console warnings about mixed content
- Some resources not loading over HTTPS
Solutions:
-
Update resource URLs:
Terminal window <!-- Before --><script src="http://example.com/script.js"></script><!-- After --><script src="https://example.com/script.js"></script> -
Use protocol-relative URLs:
Terminal window <script src="//example.com/script.js"></script> -
Configure Content Security Policy:
Terminal window app.use((req, res, next) => {res.setHeader('Content-Security-Policy',"default-src 'self' https:; img-src 'self' https: data:");next();});
Environment Variable Issues
Section titled “Environment Variable Issues”Missing Variables
Section titled “Missing Variables”Symptoms:
- Application crashes on startup
- “undefined” environment variable errors
- Features not working correctly
Solutions:
-
Check variable configuration:
Terminal window easydeploy env APP_NAME --list -
Set missing variables:
Terminal window easydeploy env APP_NAME --set KEY=value -
Use default values in code:
Terminal window const dbUrl = process.env.DATABASE_URL || 'postgresql://localhost:5432/myapp';const port = process.env.PORT || 3000;const nodeEnv = process.env.NODE_ENV || 'development';
Incorrect Variable Values
Section titled “Incorrect Variable Values”Detection:
// Add environment validationfunction validateEnvironment() { const required = ['DATABASE_URL', 'JWT_SECRET', 'API_KEY']; const missing = required.filter(key => !process.env[key]);
if (missing.length > 0) { console.error('Missing required environment variables:', missing); process.exit(1); }}
validateEnvironment();API Issues
Section titled “API Issues”Rate Limiting
Section titled “Rate Limiting”Symptoms:
- 429 “Too Many Requests” responses
- API calls being rejected
- Slow application performance
Solutions:
-
Implement client-side rate limiting:
Terminal window class RateLimiter {constructor(maxRequests, timeWindow) {this.maxRequests = maxRequests;this.timeWindow = timeWindow;this.requests = [];}async makeRequest(requestFn) {const now = Date.now();this.requests = this.requests.filter(time => now - time < this.timeWindow);if (this.requests.length >= this.maxRequests) {const waitTime = this.timeWindow - (now - this.requests[0]);await new Promise(resolve => setTimeout(resolve, waitTime));}this.requests.push(now);return requestFn();}} -
Add retry logic with exponential backoff:
Terminal window async function apiCallWithRetry(url, options, maxRetries = 3) {for (let attempt = 1; attempt <= maxRetries; attempt++) {try {const response = await fetch(url, options);if (response.status === 429) {const retryAfter = response.headers.get('Retry-After') || attempt * 2;await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));continue;}return response;} catch (error) {if (attempt === maxRetries) throw error;await new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 1000));}}}
CORS Issues
Section titled “CORS Issues”Symptoms:
- “CORS policy” errors in browser console
- API calls failing from frontend
- Cross-origin request blocked
Solutions:
-
Configure CORS properly:
Terminal window const cors = require('cors');app.use(cors({origin: process.env.FRONTEND_URL || 'http://localhost:3000',credentials: true,methods: ['GET', 'POST', 'PUT', 'DELETE'],allowedHeaders: ['Content-Type', 'Authorization']})); -
Handle preflight requests:
Terminal window app.options('*', cors()); // Enable preflight for all routes
Monitoring and Debugging
Section titled “Monitoring and Debugging”Log Analysis
Section titled “Log Analysis”Finding Errors in Logs
Section titled “Finding Errors in Logs”# Search for errorseasydeploy logs APP_NAME --level=error --since=1h
# Search for specific patternseasydeploy logs APP_NAME --grep="database connection"
# Follow logs in real-timeeasydeploy logs APP_NAME --followStructured Logging
Section titled “Structured Logging”const winston = require('winston');
const logger = winston.createLogger({ level: 'info', format: winston.format.combine( winston.format.timestamp(), winston.format.json() ), transports: [ new winston.transports.Console() ]});
// Use structured logginglogger.info('User logged in', { userId: user.id, email: user.email, ip: req.ip, userAgent: req.get('User-Agent')});
logger.error('Database error', { error: error.message, stack: error.stack, query: query, duration: queryTime});Performance Monitoring
Section titled “Performance Monitoring”Application Metrics
Section titled “Application Metrics”// Add custom metricsconst client = require('prom-client');
const httpDuration = new client.Histogram({ name: 'http_request_duration_seconds', help: 'Duration of HTTP requests in seconds', labelNames: ['method', 'route', 'status']});
app.use((req, res, next) => { const start = Date.now();
res.on('finish', () => { const duration = (Date.now() - start) / 1000; httpDuration .labels(req.method, req.route?.path || req.url, res.statusCode) .observe(duration); });
next();});Getting Help
Section titled “Getting Help”Support Channels
Section titled “Support Channels”- Documentation: Check this guide and API documentation
- Community Forum: Search existing solutions
- Support Tickets: For account-specific issues
- Status Page: Check for service outages
When to Contact Support
Section titled “When to Contact Support”- Account issues: Billing, permissions, access problems
- Platform bugs: Unexpected behavior in Easy Deploy platform
- Security concerns: Potential security vulnerabilities
- Performance issues: Platform-level performance problems
Information to Include
Section titled “Information to Include”When contacting support, provide:
- Application name and ID
- Deployment ID (if applicable)
- Error messages and stack traces
- Steps to reproduce the issue
- Expected vs actual behavior
- Browser and operating system (for frontend issues)
Self-Service Resources
Section titled “Self-Service Resources”# Check application statuseasydeploy status APP_NAME
# View recent deploymentseasydeploy deployments APP_NAME --limit=10
# Check resource usageeasydeploy metrics APP_NAME --metric=cpu,memory --period=24h
# Restart applicationeasydeploy restart APP_NAME
# View configurationeasydeploy config APP_NAMEEmergency Procedures
Section titled “Emergency Procedures”For critical issues:
- Check status page for known outages
- Enable maintenance mode if needed:
Terminal window easydeploy maintenance APP_NAME --enable - Rollback to previous version:
Terminal window easydeploy rollback APP_NAME --to=DEPLOYMENT_ID - Contact emergency support for critical production issues
Remember: Most issues can be resolved by checking logs, verifying configuration, and following the troubleshooting steps in this guide.