Por qué EC2 y no simplemente Railway o Render
Para MVPs y proyectos chicos, Railway, Render o Fly.io son perfectos: setup en minutos, escalan solos, sin gestión de servidor. Pero para proyectos de producción con requerimientos de control, costo predecible o necesidad de personalización, EC2 tiene sentido.
El tradeoff es claro: más control implica más responsabilidad. Esta guía es para cuando ese tradeoff vale la pena.
Instancia EC2 y configuración inicial
Para la mayoría de mis backends, uso una instancia t3.small (2 vCPU, 2GB RAM) en Ubuntu 22.04. Suficiente para aplicaciones con tráfico moderado.
# Conectar via SSH
ssh -i tu-key.pem ubuntu@ip-publica
# Actualizar e instalar Node.js via nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
source ~/.bashrc
nvm install 20
nvm use 20
# Verificar
node -v && npm -v
Clonar el proyecto y configurar variables de entorno
git clone https://github.com/tuusuario/tu-proyecto.git
cd tu-proyecto
npm install --production
# Crear archivo .env
nano .env
# Pegar todas las variables de entorno
# Test manual
node index.js
PM2: gestión de procesos en producción
npm install -g pm2
# Iniciar aplicación
pm2 start index.js --name mi-app
# Configurar auto-restart al reiniciar el servidor
pm2 startup
pm2 save
# Comandos útiles
pm2 status
pm2 logs mi-app
pm2 restart mi-app
pm2 monit # monitor en tiempo real
Nginx como reverse proxy
sudo apt install nginx -y
sudo nano /etc/nginx/sites-available/mi-app
server {
listen 80;
server_name tudominio.com www.tudominio.com;
location / {
proxy_pass http://localhost:4002;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_cache_bypass $http_upgrade;
}
}
sudo ln -s /etc/nginx/sites-available/mi-app /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
SSL con Certbot (gratis)
sudo snap install certbot --classic
sudo certbot --nginx -d tudominio.com -d www.tudominio.com
Certbot modifica automáticamente la config de Nginx para HTTPS y configura la renovación automática del certificado.
Actualizaciones sin downtime
# Script de deploy
git pull origin main
npm install --production
pm2 restart mi-app