Skip to main content

Deployxa Best Practices

Comprehensive best practices for deploying, managing, and scaling applications on Deployxa.

Repository Structure

my-app/
├── src/ # Source code
├── public/ # Static assets
├── tests/ # Test files
├── .env.example # Environment template
├── .gitignore # Git ignore rules
├── .dockerignore # Docker ignore rules
├── README.md # Project documentation
├── package.json # Dependencies (Node.js)
├── requirements.txt # Dependencies (Python)
├── composer.json # Dependencies (PHP)
└── Dockerfile # Custom Docker config (optional)

Best Practices

Keep it clean:

  • Remove unnecessary files
  • Exclude build artifacts
  • Don't commit dependencies
  • Use .gitignore properly

Document everything:

  • Clear README with setup instructions
  • API documentation
  • Environment variable documentation
  • Deployment instructions

Use environment files:

  • .env.example for template
  • Never commit .env files
  • Document all required variables
  • Use different values per environment

Organize code:

  • Follow framework conventions
  • Separate concerns
  • Use consistent naming
  • Keep related files together

Docker Optimization

Multi-Stage Builds

Use multi-stage builds to reduce image size:

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

# Production stage
FROM node:18-alpine AS runner
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
USER node
EXPOSE 3000
CMD ["node", "dist/index.js"]

Benefits:

  • 60-80% smaller images
  • Faster deployments
  • Better security
  • Reduced bandwidth

Optimize Layers

Order Dockerfile commands for better caching:

# ✅ Good: Dependencies first (cached)
COPY package*.json ./
RUN npm ci
COPY . .

# ❌ Bad: Code first (invalidates cache)
COPY . .
COPY package*.json ./
RUN npm ci

Use Alpine Base Images

Alpine images are smaller and more secure:

# ✅ Good: Alpine (5-10MB)
FROM node:18-alpine

# ❌ Bad: Full image (300MB+)
FROM node:18

Minimize Dependencies

Install only what you need:

# ✅ Good: Production only
RUN npm ci --only=production

# ❌ Bad: All dependencies
RUN npm install

Use .dockerignore

Exclude unnecessary files:

node_modules
.git
.env
*.log
tests
docs

Secrets Management

Use Environment Variables

Never hardcode secrets:

// ❌ Bad: Hardcoded
const apiKey = 'sk_test_1234567890';

// ✅ Good: Environment variable
const apiKey = process.env.API_KEY;

Encrypt Sensitive Data

Enable encryption for secrets:

# Deployxa dashboard
Project → Environment → Add Variable → Enable Encryption

Rotate Secrets Regularly

Rotation schedule:

  • API keys: Every 90 days
  • Database passwords: Every 180 days
  • JWT secrets: Every 365 days
  • OAuth secrets: Every 180 days

Rotation process:

  1. Generate new secret
  2. Add new environment variable
  3. Deploy application
  4. Verify application works
  5. Remove old variable
  6. Deploy again

Use Different Secrets Per Environment

# Production
DATABASE_URL=postgresql://prod-host:5432/db
API_KEY=prod_key_123

# Preview
DATABASE_URL=postgresql://preview-host:5432/db
API_KEY=preview_key_123

# Development
DATABASE_URL=postgresql://localhost:5432/db
API_KEY=dev_key_123

Never Commit Secrets

Add to .gitignore:

.env
.env.local
.env.production
*.key
*.pem

Scaling Strategies

Right-Size Resources

Monitor and adjust based on usage:

Small apps (< 100 req/min):

  • 0.5 CPU, 512MB RAM

Medium apps (100-1000 req/min):

  • 1.0 CPU, 1024MB RAM

Large apps (> 1000 req/min):

  • 2.0+ CPU, 2048MB+ RAM

Enable Auto-Scaling

Configure auto-scaling for variable traffic:

{
"minContainers": 2,
"maxContainers": 10,
"triggers": [
{
"metric": "cpu_usage",
"threshold": 70,
"action": "scale_up"
}
]
}

Use Scale-to-Zero

For low-traffic applications:

  • Saves costs when idle
  • Automatic wake-up on traffic
  • 15-minute idle timeout

Monitor Resource Usage

Track usage patterns:

  • CPU usage trends
  • Memory usage patterns
  • Bandwidth consumption
  • Request rates

Plan for Traffic Spikes

Strategies:

  • Pre-scale before known events
  • Use CDN for static assets
  • Enable caching
  • Use queue for background jobs

Performance Optimization

Enable Caching

Application caching:

// Redis cache
const cache = require('redis').createClient();

app.get('/data', async (req, res) => {
const cached = await cache.get('data');
if (cached) return res.json(JSON.parse(cached));

const data = await fetchData();
await cache.setEx('data', 3600, JSON.stringify(data));
res.json(data);
});

CDN caching:

// Cache headers
app.get('/static/*', (req, res) => {
res.setHeader('Cache-Control', 'public, max-age=31536000');
res.sendFile(req.path);
});

Optimize Database Queries

Use indexes:

CREATE INDEX idx_users_email ON users(email);

Avoid N+1 queries:

// ❌ Bad: N+1 queries
const users = await User.findAll();
for (const user of users) {
const posts = await Post.findByUserId(user.id);
}

// ✅ Good: Eager loading
const users = await User.findAll({
include: ['posts']
});

Use connection pooling:

const pool = new Pool({
max: 20,
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 2000,
});

Enable Compression

Gzip compression:

const compression = require('compression');
app.use(compression());

Brotli compression:

const express = require('express');
const app = express();

app.use((req, res, next) => {
if (req.headers['accept-encoding']?.includes('br')) {
res.setHeader('Content-Encoding', 'br');
}
next();
});

Optimize Images

Use modern formats:

  • WebP instead of JPEG/PNG
  • AVIF for better compression
  • SVG for icons and logos

Resize images:

const sharp = require('sharp');

await sharp(input)
.resize(800, 600)
.webp({ quality: 80 })
.toFile(output);

Use CDN

Serve static assets via CDN:

// Configure CDN
app.use('/static', express.static('public', {
maxAge: '1y',
etag: false
}));

Production Deployments

Pre-Deployment Checklist

Code quality:

  • All tests passing
  • No linting errors
  • Code reviewed
  • Documentation updated

Configuration:

  • Environment variables set
  • Database configured
  • Domains verified
  • SSL certificates active

Monitoring:

  • Health checks configured
  • Alerts set up
  • Logging enabled
  • Metrics tracking

Security:

  • Secrets encrypted
  • HTTPS enforced
  • Security headers enabled
  • Dependencies updated

Deployment Strategy

Rolling updates:

  • Zero downtime
  • Gradual rollout
  • Instant rollback
  • Health checks

Blue/Green deployments:

  • Full environment switch
  • Instant rollback
  • Complete testing
  • Higher resource usage

Rollback Plan

When to rollback:

  • Error rate > 5%
  • Response time > 3s
  • Critical errors
  • Security vulnerabilities

Rollback process:

  1. Identify issue
  2. Trigger rollback
  3. Verify health
  4. Investigate root cause
  5. Fix and redeploy

Monitoring Setup

Health checks:

app.get('/health', (req, res) => {
res.status(200).json({
status: 'healthy',
timestamp: new Date().toISOString()
});
});

Metrics to track:

  • Request rate
  • Error rate
  • Response time
  • CPU usage
  • Memory usage
  • Bandwidth

Alerts:

  • CPU > 80%
  • Memory > 85%
  • Error rate > 1%
  • Response time > 2s

Security Best Practices

Input Validation

Server-side validation:

const Joi = require('joi');

const schema = Joi.object({
email: Joi.string().email().required(),
password: Joi.string().min(8).required()
});

app.post('/register', (req, res) => {
const { error } = schema.validate(req.body);
if (error) return res.status(400).json({ error });
// Process registration
});

Client-side validation:

// React with Formik
import * as Yup from 'yup';

const validationSchema = Yup.object({
email: Yup.string().email().required(),
password: Yup.string().min(8).required()
});

Use Parameterized Queries

Prevent SQL injection:

// ✅ Good: Parameterized
const result = await pool.query(
'SELECT * FROM users WHERE email = $1',
[email]
);

// ❌ Bad: String concatenation
const result = await pool.query(
`SELECT * FROM users WHERE email = '${email}'`
);

Enable Security Headers

Recommended headers:

const helmet = require('helmet');

app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", "data:", "https:"],
}
},
hsts: {
maxAge: 31536000,
includeSubDomains: true,
preload: true
}
}));

Use HTTPS Only

Enforce HTTPS:

// Express.js
app.use((req, res, next) => {
if (req.header('x-forwarded-proto') !== 'https') {
return res.redirect(`https://${req.header('host')}${req.url}`);
}
next();
});

Implement Rate Limiting

Prevent abuse:

const rateLimit = require('express-rate-limit');

const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // limit each IP to 100 requests per windowMs
message: 'Too many requests from this IP'
});

app.use('/api/', limiter);

Keep Dependencies Updated

Regular updates:

# Check for vulnerabilities
npm audit

# Fix vulnerabilities
npm audit fix

# Update dependencies
npm update

Monitoring Best Practices

Set Up Health Checks

Application health:

app.get('/health', (req, res) => {
// Check database
db.query('SELECT 1', (err) => {
if (err) return res.status(500).json({ status: 'unhealthy' });
res.status(200).json({ status: 'healthy' });
});
});

Configure Alerts

Alert thresholds:

  • CPU > 80% for 5 minutes
  • Memory > 85% for 5 minutes
  • Error rate > 1% for 5 minutes
  • Response time > 2s for 5 minutes

Notification channels:

  • Email for all alerts
  • Slack for critical alerts
  • SMS for emergency alerts

Monitor Key Metrics

Application metrics:

  • Request rate
  • Error rate
  • Response time (P50, P95, P99)
  • Throughput

Infrastructure metrics:

  • CPU usage
  • Memory usage
  • Disk I/O
  • Network I/O

Business metrics:

  • Active users
  • Conversion rate
  • Revenue
  • Customer satisfaction

Use Structured Logging

JSON logging:

const winston = require('winston');

const logger = winston.createLogger({
format: winston.format.json(),
transports: [
new winston.transports.Console()
]
});

logger.info('User logged in', {
userId: 123,
ip: req.ip,
timestamp: new Date()
});

Review Logs Regularly

Daily review:

  • Error patterns
  • Performance trends
  • Security events
  • User activity

Weekly review:

  • Usage trends
  • Resource optimization
  • Cost analysis
  • Security posture

Cost Optimization

Right-Size Resources

Monitor usage:

  • Track CPU/RAM usage
  • Identify underutilized resources
  • Adjust limits accordingly

Avoid over-provisioning:

  • Start with minimum resources
  • Scale up as needed
  • Use auto-scaling

Enable Scale-to-Zero

For low-traffic apps:

  • Saves costs when idle
  • Automatic wake-up
  • 15-minute timeout

Use Build Cache

Faster builds:

  • Enable build cache
  • Cache dependencies
  • Reuse build artifacts

Optimize Bandwidth

Reduce bandwidth:

  • Enable compression
  • Use CDN
  • Optimize images
  • Minify assets

Monitor Costs

Track spending:

  • Review invoices monthly
  • Set budget alerts
  • Identify cost drivers
  • Optimize regularly

Troubleshooting Best Practices

Systematic Approach

  1. Identify the problem:

    • Check logs
    • Review metrics
    • Reproduce issue
  2. Isolate the cause:

    • Check recent changes
    • Review dependencies
    • Test components
  3. Implement fix:

    • Apply solution
    • Test thoroughly
    • Deploy carefully
  4. Verify resolution:

    • Monitor metrics
    • Check logs
    • Confirm fix

Use Logs Effectively

Search logs:

# Search for errors
grep "error" logs/app.log

# Filter by time
grep "2024-01-15" logs/app.log

# Count errors
grep -c "error" logs/app.log

Monitor During Troubleshooting

Watch metrics:

  • CPU usage
  • Memory usage
  • Error rate
  • Response time

Check logs in real-time:

tail -f logs/app.log

Document Solutions

Create runbooks:

  • Common issues
  • Step-by-step fixes
  • Prevention measures
  • Contact information

Learn from Incidents

Post-mortem process:

  1. Timeline reconstruction
  2. Root cause analysis
  3. Impact assessment
  4. Lessons learned
  5. Action items
  6. Documentation update

Resources


Need Help? Contact support@deployxa.com or join our community Discord.