DevOps para freelancers Valencia: Despliegues automatizados CI/CD, infraestructura como código 2025
DevOps para freelancers Valencia: Despliegues automatizados CI/CD, infraestructura como código 2025
Introducción: DevOps no es solo para empresas
Como freelance full stack, empecé desplegando manualmente por FTP. Era un caos: errores humanos, downtime, estrés constante.
Ahora tengo despliegues automáticos que se activan con un commit. Si algo falla, se arregla solo. Mis clientes duermen tranquilos, yo trabajo menos.
En este artículo te doy mi stack DevOps completo: herramientas, workflows y configuraciones que uso diariamente para 20+ proyectos en producción.
El problema de los freelancers sin DevOps
La realidad dolorosa
Antes (2019-2022):
- Despliegues manuales por SSH
- Configuración diferente en cada entorno
- “Funciona en mi máquina”
- Downtime por errores humanos
- Horas perdidas en debugging de producción
Ahora (2024-2025):
- Push to main → Deploy automático
- Entornos idénticos (staging = prod)
- Monitoreo 24/7
- Rollbacks automáticos
- Tiempo de deploy: 3 minutos
Resultado: Más proyectos, menos estrés, clientes felices.
Stack DevOps para freelancers: Lo que realmente uso
1. GitHub Actions: CI/CD gratuito y poderoso
Pipeline básico para web app
# .github/workflows/deploy.yml
name: Deploy to Production
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm run test
- name: Build
run: npm run build
deploy:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
steps:
- uses: actions/checkout@v4
- name: Deploy to Vercel
uses: amondnet/vercel-action@v25
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
vercel-args: '--prod'
Pipeline avanzado con staging
# .github/workflows/staging-deploy.yml
name: Deploy to Staging
on:
push:
branches: [ develop ]
jobs:
deploy-staging:
runs-on: ubuntu-latest
environment: staging
steps:
- uses: actions/checkout@v4
- name: Deploy to staging
run: |
echo "Deploying to staging environment"
# Tu lógica de deploy aquí
2. Vercel + Netlify: Hosting con superpoderes
Vercel para Next.js/React
Ventajas para freelancers:
- ✅ Deploy automático desde Git
- ✅ Preview deployments por PR
- ✅ Edge Functions (serverless)
- ✅ Analytics integrado
- ✅ Dominios gratis para staging
// vercel.json - Configuración avanzada
{
"buildCommand": "npm run build",
"outputDirectory": ".next",
"framework": "nextjs",
"functions": {
"api/**/*.js": {
"runtime": "nodejs18.x"
}
},
"rewrites": [
{
"source": "/api/(.*)",
"destination": "/api/$1"
}
],
"headers": [
{
"source": "/(.*)",
"headers": [
{
"key": "X-Frame-Options",
"value": "DENY"
},
{
"key": "X-Content-Type-Options",
"value": "nosniff"
}
]
}
]
}
Netlify para cualquier cosa
# netlify.toml
[build]
command = "npm run build"
publish = "dist"
[build.environment]
NODE_VERSION = "18"
[[redirects]]
from = "/api/*"
to = "/.netlify/functions/:splat"
status = 200
[[headers]]
for = "/static/*"
[headers.values]
Cache-Control = "public, max-age=31536000"
[functions]
directory = "netlify/functions"
3. Railway: Base de datos + backend sin servidor
Por qué Railway para freelancers
- ✅ PostgreSQL/MySQL gratis para empezar
- ✅ Deploy desde Git automático
- ✅ Backups automáticos
- ✅ Escalado automático
- ✅ Precios predecibles
# railway.toml
name: mi-proyecto
source: .
builder: nixpacks
healthcheckPath: /
healthcheckTimeout: 300
restartPolicyType: ON_FAILURE
restartPolicyMaxRetries: 10
Migraciones de base de datos
// scripts/migrate.js
const { Client } = require('pg');
async function runMigrations() {
const client = new Client({
connectionString: process.env.DATABASE_URL,
});
await client.connect();
// Crear tabla de usuarios
await client.query(`
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
name VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
`);
console.log('Migrations completed');
await client.end();
}
runMigrations();
4. Terraform: Infraestructura como código
Setup básico para freelancer
# main.tf
terraform {
required_providers {
digitalocean = {
source = "digitalocean/digitalocean"
version = "~> 2.0"
}
}
}
# Droplet para staging
resource "digitalocean_droplet" "staging" {
image = "ubuntu-22-04-x64"
name = "staging-server"
region = "fra1"
size = "s-1vcpu-1gb"
ssh_keys = [
data.digitalocean_ssh_key.my_key.id
]
}
# Domain
resource "digitalocean_domain" "default" {
name = "mi-proyecto.com"
}
# Database
resource "digitalocean_database_cluster" "postgres" {
name = "mi-proyecto-db"
engine = "pg"
version = "15"
size = "db-s-1vcpu-1gb"
region = "fra1"
node_count = 1
}
5. Docker: Entornos consistentes
Dockerfile optimizado para Node.js
# Dockerfile
FROM node:18-alpine AS base
# Install dependencies only when needed
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --only=production
# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app
ENV NODE_ENV production
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
# Set the correct permission for prerender cache
RUN mkdir .next
RUN chown nextjs:nodejs .next
# Automatically leverage output traces to reduce image size
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT 3000
CMD ["node", "server.js"]
Docker Compose para desarrollo local
# docker-compose.yml
version: '3.8'
services:
db:
image: postgres:15
environment:
POSTGRES_DB: myapp
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
redis:
image: redis:7-alpine
ports:
- "6379:6379"
app:
build: .
ports:
- "3000:3000"
environment:
DATABASE_URL: postgresql://user:password@db:5432/myapp
REDIS_URL: redis://redis:6379
depends_on:
- db
- redis
volumes:
- .:/app
- /app/node_modules
volumes:
postgres_data:
Workflow DevOps diario: Cómo trabajo
1. Desarrollo local con hot reload
# Iniciar stack completo
docker-compose up -d
# Desarrollar con hot reload
npm run dev
# Tests automáticos
npm run test:watch
# Linting automático
npm run lint:fix
2. Git flow optimizado
# Crear feature branch
git checkout -b feature/nueva-funcionalidad
# Commits pequeños y descriptivos
git commit -m "feat: add user authentication"
# Push y crear PR
git push origin feature/nueva-funcionalidad
# GitHub Actions ejecuta:
# - Tests automáticos
# - Linting
# - Build
# - Deploy a staging (preview deployment)
3. Monitoreo y alertas
Sentry para errores
// sentry.client.config.js
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: process.env.SENTRY_DSN,
tracesSampleRate: 1.0,
integrations: [
new Sentry.BrowserTracing({
routingInstrumentation: Sentry.nextRouterInstrumentation,
}),
],
environment: process.env.NODE_ENV,
});
Uptime monitoring con UptimeRobot
# uptime.yml (conceptual)
monitors:
- url: https://mi-proyecto.com
friendly_name: Main Site
monitor_type: 1 # HTTP
keyword_type: 1 # Keyword monitoring
keyword_value: "Mi Proyecto"
alert_contacts: ["email@miemail.com"]
- url: https://api.mi-proyecto.com/health
friendly_name: API Health
monitor_type: 1
alert_contacts: ["email@miemail.com"]
Casos reales: DevOps que salvó proyectos
Caso 1: E-commerce con picos de tráfico
Cliente: Tienda online de productos fitness
Problema: Ventas flash causaban crashes
Solución DevOps:
- Railway + auto-scaling
- Redis para cache de productos
- CDN para assets estáticos
- Monitoring con alertas
Resultado:
- 🚀 Tiempo de respuesta: Consistente <200ms
- 💰 Ventas flash: Sin downtime
- 📈 Revenue: +300% en eventos promocionales
- 😊 Cliente: “Nunca más preocupaciones técnicas”
Caso 2: API crítica para negocio
Cliente: Startup de delivery
Problema: API lenta causaba cancelaciones
Stack implementado:
- Railway PostgreSQL + Redis
- Vercel Edge Functions
- GitHub Actions CI/CD
- Sentry monitoring
Optimizaciones:
// API route optimizada
export default async function handler(req, res) {
// Cache con Redis
const cached = await redis.get(`restaurants:${city}`);
if (cached) {
return res.json(JSON.parse(cached));
}
// Query optimizada
const restaurants = await prisma.restaurant.findMany({
where: { city, active: true },
select: {
id: true,
name: true,
rating: true,
deliveryTime: true,
},
orderBy: { rating: 'desc' },
});
// Cache por 5 minutos
await redis.setex(`restaurants:${city}`, 300, JSON.stringify(restaurants));
res.json(restaurants);
}
Resultado:
- ⚡ API response: <100ms consistently
- 📱 App crashes: -90%
- 🚚 Deliveries completed: +150%
- ⭐ App rating: 4.8/5
Caso 3: Blog corporativo de alto tráfico
Cliente: Blog de empresa tech con 100K+ visitantes/mes
Infraestructura:
- Vercel + Next.js (SSG)
- PlanetScale (MySQL serverless)
- Cloudflare CDN
- GitHub Actions
DevOps features:
- Deploy previews por PR
- A/B testing automático
- Analytics en tiempo real
- Backups automáticos
Resultado:
- 📊 Page load: <1.5s global
- 🔍 SEO: Posición 1 en keywords principales
- 📈 Tráfico: +400% en 8 meses
- 💰 Ad revenue: +250%
Seguridad básica para freelancers
1. Secrets management
# .github/workflows/deploy.yml
jobs:
deploy:
steps:
- name: Deploy
run: |
echo "Deploying with secrets"
env:
API_KEY: ${{ secrets.API_KEY }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
2. HTTPS obligatorio
// next.config.js
module.exports = {
// Forzar HTTPS
async headers() {
return [
{
source: '/(.*)',
headers: [
{
key: 'Strict-Transport-Security',
value: 'max-age=63072000; includeSubDomains; preload'
}
]
}
];
},
};
3. Backup automático
# Script de backup
#!/bin/bash
DATE=$(date +%Y%m%d_%H%M%S)
pg_dump $DATABASE_URL > backup_$DATE.sql
aws s3 cp backup_$DATE.sql s3://my-backups/
Costos realistas para freelancers
Stack gratuito/mínimo
- GitHub Actions: 2,000 minutos gratis/mes
- Vercel/Netlify: Generoso free tier
- Railway: $5/mes para database básica
- PlanetScale: 1 database gratis
- Sentry: 5,000 events gratis/mes
Total mensual: ~$10-20
Stack profesional
- Railway: $20-50/mes
- Vercel Pro: $20/mes
- Monitoring: $20-50/mes
- Backups: $5-10/mes
Total mensual: ~$65-130
ROI: Se paga solo con 1-2 proyectos.
Conclusión: DevOps como multiplicador
DevOps no es complicado. Es liberador.
Antes perdía horas en deployments manuales. Ahora me enfoco en escribir código que importa.
Mis clientes tienen infraestructura enterprise por el precio de un café al día.
¿Quieres automatizar tus despliegues? Contáctame y configuramos tu stack DevOps completo.
Preguntas frecuentes (FAQ)
¿Qué stack CI/CD recomiendas para freelancers?
GitHub Actions + Vercel/Netlify para frontend y Railway/Render para backend/DB. Matrices para tests y deploy automático a main.
¿Cómo manejo secretos y variables?
Usa secrets cifrados en GitHub Actions y entornos separados (staging/prod). No commits .env; usa env en el proveedor.
¿Cuándo usar Terraform vs config manual?
Terraform si el proyecto es recurrente o multi-entorno; config manual rápida para MVPs pequeños, luego migras a IaC.
¿Qué monitoreo mínimo debo tener?
Uptime + errores (Sentry) + logs básicos. Para performance web, Lighthouse CI o Web Vitals en producción.
Recursos relacionados
- Herramientas de IA para desarrollo web: Stack completo 2025
- Testing y QA automatizado en desarrollo web: Guía completa 2025
- Optimización de rendimiento web: Core Web Vitals y mejores prácticas 2025
Publicado el 18 de diciembre de 2025 por Adrián Pozo Esteban - Desarrollador Full Stack Freelance especializado en DevOps, CI/CD y automatización para freelancers en Valencia, España

