Troubleshooting Common Issues
This guide helps you diagnose and fix common issues when deploying and running applications on the Strongly platform.
Build Failures
Build Timeout (10 minutes)
Problem: Build exceeds 10-minute timeout limit
Symptoms:
- Build logs show timeout error
- Large dependencies downloading
- Complex build steps
Solutions:
- Optimize Docker build:
# Use .dockerignore to exclude unnecessary files
node_modules
.git
*.log
# Use multi-stage builds
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
FROM node:18-alpine
COPY /app/dist ./dist
- Leverage layer caching:
# Copy package files first (changes less often)
COPY package*.json ./
RUN npm ci
# Copy code last (changes more often)
COPY . .
- Reduce dependencies:
// Remove unnecessary devDependencies
{
"dependencies": {
"express": "^4.18.2"
},
"devDependencies": {}
}
Dockerfile Syntax Errors
Problem: Invalid Dockerfile syntax
Symptoms:
- Build fails immediately
- Error: "Dockerfile parse error"
Common Issues:
# Bad: Missing WORKDIR
COPY . .
# Good: Set WORKDIR first
WORKDIR /app
COPY . .
# Bad: Wrong order (FROM must be first)
RUN apt-get update
FROM node:18
# Good: FROM first
FROM node:18
RUN apt-get update
# Bad: Missing quotes for paths with spaces
COPY my folder /app
# Good: Quote paths
COPY "my folder" /app
Solution: Validate Dockerfile locally before deploying:
docker build -t test .
Missing Files in Build Context
Problem: Files not found during build
Symptoms:
COPYcommand fails- Module not found errors
Solutions:
- Check archive structure:
# Dockerfile and manifest must be in root
app.tar.gz
├── Dockerfile
├── strongly.manifest.yaml
├── package.json
└── src/
- Verify .dockerignore isn't excluding needed files:
# Don't ignore required files
!package.json
!src/
- Use correct COPY paths:
# Relative to build context root
COPY package.json ./
COPY src/ ./src/
Dependency Installation Failures
Problem: npm/pip/apt fails to install dependencies
Symptoms:
- "Package not found"
- "Network timeout"
- "Permission denied"
Solutions:
- Network issues:
# Add retry logic for apt
RUN apt-get update && \
apt-get install -y --no-install-recommends \
package || \
(apt-get update && apt-get install -y package)
- Use specific versions:
{
"dependencies": {
"express": "4.18.2" // Exact version, not "^4.18.2"
}
}
- Clear package manager cache:
# npm
RUN npm ci --only=production && \
npm cache clean --force
# pip
RUN pip install --no-cache-dir -r requirements.txt
# apt
RUN apt-get clean && \
rm -rf /var/lib/apt/lists/*
Application Startup Issues
Health Check Failures
Problem: App deployed but health checks fail
Symptoms:
- Status shows "Unhealthy"
- Pods continuously restart
- "CrashLoopBackOff" status
Solutions:
- Implement health check endpoint:
// Express.js
app.get('/health', (req, res) => {
res.status(200).json({ status: 'ok' });
});
- Verify health check path in manifest:
health_check:
path: /health # Must match your endpoint
port: 3000
initial_delay: 15 # Give app time to start
- Check application logs:
Navigate to app details → Logs tab
Look for startup errors
- Test locally:
docker run -p 3000:3000 my-app
curl http://localhost:3000/health
Port Binding Errors
Problem: Application fails to start due to port conflicts
Symptoms:
- "Port already in use"
- "EADDRINUSE" error
- App crashes on startup
Solutions:
- Match port in code and manifest:
// server.js
const PORT = process.env.PORT || 3000;
app.listen(PORT);
# manifest
ports:
- port: 3000
expose: true
- Use PORT environment variable:
// Always use environment variable
const PORT = process.env.PORT;
if (!PORT) {
throw new Error('PORT environment variable not set');
}
Missing Environment Variables
Problem: App crashes due to missing configuration
Symptoms:
- "Environment variable not defined"
- "Cannot read property of undefined"
- Database connection errors
Solutions:
- Check STRONGLY_SERVICES is parsed:
const services = JSON.parse(process.env.STRONGLY_SERVICES || '{}');
if (!services.addons) {
throw new Error('No addons configured');
}
- Provide default values:
const LOG_LEVEL = process.env.LOG_LEVEL || 'info';
const TIMEOUT = parseInt(process.env.TIMEOUT || '30000');
- Validate required variables on startup:
const required = ['DATABASE_URL', 'JWT_SECRET'];
const missing = required.filter(v => !process.env[v]);
if (missing.length > 0) {
throw new Error(`Missing required env vars: ${missing.join(', ')}`);
}
- Check manifest configuration:
env:
- name: DATABASE_URL
value: ""
required: true # Platform will enforce this
secret: true
Out of Memory (OOM) Errors
Problem: Application killed due to memory limit
Symptoms:
- Status: "OOMKilled"
- Pods restart frequently
- "JavaScript heap out of memory"
Solutions:
- Increase memory limit:
# manifest
resources:
memory_request: "1Gi"
memory_limit: "2Gi" # Increase from 1Gi
- Optimize application code:
// Bad: Loading entire dataset
const data = await db.collection.find().toArray();
// Good: Use streaming or pagination
const cursor = db.collection.find();
for await (const doc of cursor) {
process(doc);
}
- Increase Node.js heap size:
CMD ["node", "--max-old-space-size=1536", "server.js"]
- Enable autoscaling with memory threshold:
# Autoscaling config
memory_threshold: 70% # Scale before hitting limit
Service Connection Issues
Database Connection Failures
Problem: Cannot connect to database
Symptoms:
- "ECONNREFUSED"
- "Connection timeout"
- "Authentication failed"
Solutions:
- Verify service is connected:
const services = JSON.parse(process.env.STRONGLY_SERVICES || '{}');
console.log('Available addons:', Object.keys(services.addons || {}));
- Check environment match:
Development apps → Development databases only
Production apps → Production databases only
- Verify connection string format:
// MongoDB
const mongoUrl = services.addons['addon-id'].connectionString;
// Format: mongodb://user:pass@host:27017/dbname
// PostgreSQL
const pgUrl = services.datasources['ds-id'].credentials;
// Format: postgresql://user:pass@host:5432/dbname
- Test connection separately:
const { MongoClient } = require('mongodb');
async function testConnection() {
try {
const client = await MongoClient.connect(connectionString);
console.log('✓ Connected to database');
await client.close();
} catch (err) {
console.error('✗ Connection failed:', err.message);
}
}
- Check service health:
Navigate to Add-ons → Click addon name → Check status
Ensure addon is "Running"
AI Model API Errors
Problem: Cannot call AI model
Symptoms:
- "Unauthorized"
- "Invalid API key"
- "Model not found"
Solutions:
- Verify model configuration:
const services = JSON.parse(process.env.STRONGLY_SERVICES || '{}');
const model = services.aiModels['model-id'];
console.log('Model:', model.name);
console.log('Endpoint:', model.endpoint);
console.log('Has API key:', !!model.apiKey);
- Check API request format:
// OpenAI format
const response = await fetch(`${model.endpoint}/chat/completions`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${model.apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: model.model,
messages: [{ role: 'user', content: 'Hello' }]
})
});
if (!response.ok) {
const error = await response.text();
console.error('API error:', error);
}
- Verify model is running (for self-hosted):
Navigate to AI Gateway → Models → Check status
Ensure model is "Running"
Workflow Trigger Failures
Problem: Cannot invoke workflow
Symptoms:
- "Webhook not found"
- "Workflow execution failed"
- No response from workflow
Solutions:
- Verify workflow configuration:
const services = JSON.parse(process.env.STRONGLY_SERVICES || '{}');
const workflow = services.workflows['workflow-id'];
console.log('Workflow URL:', workflow.url);
console.log('Method:', workflow.method);
- Check request format:
const response = await fetch(workflow.url, {
method: 'POST', // Usually POST
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
// Your workflow input
input: 'data'
})
});
const result = await response.json();
console.log('Workflow result:', result);
- Verify workflow is active:
Navigate to Workflows → Check workflow status
Ensure workflow is "Active"
Performance Issues
High CPU Usage
Problem: CPU usage consistently high
Symptoms:
- Slow response times
- Autoscaling constantly triggering
- CPU at or near limit
Solutions:
- Profile your application:
// Node.js CPU profiling
node --prof server.js
node --prof-process isolate-*.log > profile.txt
- Optimize hot code paths:
// Bad: Synchronous operation in request handler
app.get('/users', (req, res) => {
const data = fs.readFileSync('users.json'); // Blocks event loop
res.json(JSON.parse(data));
});
// Good: Asynchronous operation
app.get('/users', async (req, res) => {
const data = await fs.promises.readFile('users.json');
res.json(JSON.parse(data));
});
- Add caching:
const cache = new Map();
app.get('/users', async (req, res) => {
if (cache.has('users')) {
return res.json(cache.get('users'));
}
const users = await db.users.find().toArray();
cache.set('users', users);
setTimeout(() => cache.delete('users'), 60000); // 1 min TTL
res.json(users);
});
- Scale horizontally:
# Enable autoscaling
cpu_threshold: 60% # Lower threshold
max_replicas: 10
Slow Response Times
Problem: API responses are slow
Symptoms:
- P95 > 1 second
- Timeout errors
- User complaints
Solutions:
- Add database indexes:
-- Check slow queries
EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'test@example.com';
-- Add index
CREATE INDEX idx_users_email ON users(email);
- Implement connection pooling:
// Bad: New connection per request
app.get('/users', async (req, res) => {
const client = new MongoClient(url);
await client.connect();
const users = await client.db().collection('users').find().toArray();
await client.close();
res.json(users);
});
// Good: Connection pool
const pool = new MongoClient(url, { maxPoolSize: 10 });
await pool.connect();
app.get('/users', async (req, res) => {
const users = await pool.db().collection('users').find().toArray();
res.json(users);
});
- Add pagination:
app.get('/users', async (req, res) => {
const page = parseInt(req.query.page) || 1;
const limit = 20;
const skip = (page - 1) * limit;
const users = await db.users
.find()
.skip(skip)
.limit(limit)
.toArray();
res.json({ users, page, hasMore: users.length === limit });
});
- Monitor with metrics:
const startTime = Date.now();
app.use((req, res, next) => {
res.on('finish', () => {
const duration = Date.now() - startTime;
if (duration > 1000) {
console.warn(`Slow request: ${req.path} (${duration}ms)`);
}
});
next();
});
Deployment Issues
Cannot Redeploy
Problem: Redeploy button doesn't work
Solutions:
- Check app status is not "Deploying"
- Wait for current operation to complete
- Try stopping and starting app first
- Contact support if stuck
Promotion to Production Fails
Problem: Cannot promote from Development to Production
Solutions:
- Ensure production add-ons exist and are mapped
- Verify all required environment variables are set
- Check resource availability in production
- Review error message for specific issue
Getting Help
Diagnostic Information
When contacting support, provide:
- App ID and Name
- Error logs from app details page
- Build logs if build failed
- Steps to reproduce the issue
- Screenshots of errors
- Manifest file content
Enable Debug Logging
# manifest
env:
- name: LOG_LEVEL
value: "debug" # Or "DEBUG" for Python
// Node.js
const logger = winston.createLogger({
level: process.env.LOG_LEVEL || 'info'
});
Common Log Patterns
Connection Refused:
Error: connect ECONNREFUSED 10.0.2.15:5432
→ Database not running or wrong host/port
Out of Memory:
<--- Last few GCs --->
FATAL ERROR: Reached heap limit
→ Increase memory limit or optimize code
Module Not Found:
Error: Cannot find module 'express'
→ Dependency not installed, check package.json
Port in Use:
Error: listen EADDRINUSE: address already in use :::3000
→ Port conflict, check manifest configuration