Configuraciones reales que usamos en producción. No teoría — código que corre en servidores reales atendiendo clientes reales hoy.
Configuración completa de Nginx para un servidor de producción que sirve múltiples sitios con SSL, HTTP/2, compresión pre-calculada y todos los security headers necesarios para un score A en securityheaders.com.
# /etc/nginx/snippets/security-headers.conf
add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload' always;
add_header X-Frame-Options 'SAMEORIGIN' always;
add_header X-Content-Type-Options 'nosniff' always;
add_header Referrer-Policy 'strict-origin-when-cross-origin' always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://www.googletagmanager.com;" always;
add_header Permissions-Policy 'camera=(), microphone=(), geolocation=()' always;
# Server block con HTTP/2 y gzip estático
server {
listen 443 ssl;
http2 on;
gzip_static on; # sirve .gz pre-comprimidos
gzip on;
gzip_comp_level 6;
gzip_types text/html text/css application/javascript image/svg+xml;
location ~* \.html$ {
include snippets/security-headers.conf;
add_header Cache-Control 'public, max-age=3600, must-revalidate';
}
location ~* \.(css|js|svg)$ {
include snippets/security-headers.conf;
add_header Cache-Control 'public, max-age=31536000, immutable';
}
}
Arquitectura de API para captura de leads con persistencia en MySQL y notificación automática por email usando Nodemailer. Rate limiting y validación incluidos.
// Patrón: guardar lead + notificar en una sola transacción
app.post('/api/contact', async (req, res) => {
const { name, email, service, message } = req.body;
if (!name || !email || !service || !message)
return res.status(400).json({ error: 'Campos requeridos' });
// 1. Persistir en DB
await pool.execute(
'INSERT INTO leads (name, email, service, message) VALUES (?, ?, ?, ?)',
[name, email, service, message]
);
// 2. Notificar por correo (no bloquea la respuesta)
transporter.sendMail({
from: '"DevSolutions" <contacto@developersolutions.org>',
to: 'contacto@developersolutions.org',
subject: `Nuevo lead: ${name}`,
html: buildEmailTemplate(name, email, service, message)
}).catch(console.error); // No bloquear si el correo falla
res.json({ ok: true }); // Responder inmediatamente
});
Integración completa de Mercado Pago para una plataforma de reservas deportivas. Incluye creación de preferencias, webhook seguro con validación de firma HMAC y manejo de estados de pago.
// Crear preferencia de pago
const preference = await mercadopago.preferences.create({
items: [{
title: `Reserva cancha - ${booking.court} - ${booking.date}`,
quantity: 1,
unit_price: booking.price
}],
back_urls: {
success: `${BASE_URL}/booking/success`,
failure: `${BASE_URL}/booking/failure`
},
notification_url: `${BASE_URL}/api/webhooks/mercadopago`,
external_reference: booking.id.toString()
});
// Validar webhook con firma HMAC
app.post('/api/webhooks/mercadopago', (req, res) => {
const signature = req.headers['x-signature'];
const expectedSig = crypto
.createHmac('sha256', process.env.MP_WEBHOOK_SECRET)
.update(JSON.stringify(req.body))
.digest('hex');
if (signature !== expectedSig)
return res.status(401).json({ error: 'Firma inválida' });
// Procesar el pago confirmado
handlePaymentConfirmed(req.body);
res.sendStatus(200);
});
Arquitectura para correr múltiples aplicaciones Node.js en un solo servidor Ubuntu con PM2 para gestión de procesos y Nginx como reverse proxy. Cada app en su propio puerto, un solo punto de entrada.
# ecosystem.config.js — gestión de múltiples apps
module.exports = {
apps: [
{ name: 'app-vinos', script: 'server.js', cwd: '/var/www/vinos/api', env: { PORT: 3000 } },
{ name: 'app-arenas', script: 'server.js', cwd: '/var/www/arenas/api', env: { PORT: 3001 } },
{ name: 'app-devsol', script: 'server.js', cwd: '/var/www/steban-api', env: { PORT: 3002 } },
]
};
# Nginx — cada dominio apunta a su puerto
# /etc/nginx/sites-available/vinos
server {
server_name vinosadelina.com;
location /api/ { proxy_pass http://localhost:3000; }
}
# /etc/nginx/sites-available/developersolutions
server {
server_name developersolutions.org;
location /api/ { proxy_pass http://localhost:3002; }
}
Llevamos estas soluciones a producción para nuestros clientes. Cuéntanos tu proyecto.
Hablar con un desarrollador →