Servidor de Desarrollo con Múltiples Proyectos: Guía Completa de Configuración

Introducción

El desarrollo de software moderno a menudo involucra manejar múltiples proyectos simultáneamente - cada uno con diferentes stacks tecnológicos, dependencias, bases de datos y requisitos de entorno. Configurar un servidor de desarrollo dedicado que pueda alojar múltiples proyectos de forma limpia y eficiente es esencial para desarrolladores individuales, equipos de desarrollo y organizaciones que buscan centralizar su infraestructura de desarrollo.

Un servidor multi-proyecto bien configurado elimina problemas de "funciona en mi máquina", proporciona entornos de desarrollo consistentes, habilita colaboración fácil, simplifica pruebas de despliegue y sirve como área de preparación antes de lanzamientos de producción. Al aislar proyectos mientras se comparte infraestructura subyacente, maximiza la utilización de recursos mientras mantiene separación de responsabilidades.

Esta guía completa le guía a través de la construcción de un servidor de desarrollo listo para producción capaz de alojar múltiples proyectos con diferentes requisitos tecnológicos. Aprenderá cómo configurar servidores web con hosts virtuales, configurar múltiples instancias de bases de datos, gestionar versiones de lenguajes de programación, implementar contenedorización para aislamiento, configurar proxies inversos, asegurar entornos de desarrollo e implementar flujos de trabajo de despliegue eficientes.

Ya sea que sea un desarrollador freelance gestionando proyectos de clientes, una startup ejecutando múltiples servicios, un equipo de desarrollo necesitando infraestructura compartida, o una organización consolidando entornos de desarrollo, esta guía proporciona la base para despliegue profesional de servidor de desarrollo multi-proyecto.

Resumen de Caso de Uso

¿Por Qué Desplegar un Servidor de Desarrollo?

Un servidor de desarrollo centralizado ofrece ventajas significativas sobre el desarrollo solo local:

Entornos Consistentes: Eliminar discrepancias de entorno entre desarrolladores. Todos trabajan en configuraciones idénticas, reduciendo problemas de "funciona en mi máquina".

Colaboración en Equipo: Múltiples desarrolladores acceden al mismo servidor, ven el trabajo del otro y colaboran en características sin procedimientos complejos de configuración local.

Desarrollo Remoto: Acceder al entorno de desarrollo desde cualquier lugar - laptop, tablet u otra estación de trabajo, habilitando arreglos de trabajo flexibles.

Compartir Recursos: Compartir servidores de bases de datos, capas de caché y herramientas de desarrollo entre proyectos en lugar de duplicar en la máquina de cada desarrollador.

Demostraciones a Clientes: Demostrar fácilmente características en progreso a clientes o partes interesadas mediante URLs simples sin desplegar a producción.

Pruebas y Staging: Probar despliegues, migraciones de bases de datos y cambios de infraestructura en entornos similares a producción antes de lanzar.

Aprendizaje y Experimentación: Experimentar de forma segura con nuevas tecnologías, frameworks y herramientas sin afectar su estación de trabajo principal.

Eficiencia de Costos: Un solo servidor aloja múltiples proyectos en lugar de servidores separados para cada uno, reduciendo costos de infraestructura.

Escenarios Comunes de Despliegue

Portafolio de Desarrollador Freelance: Alojar múltiples proyectos de clientes para desarrollo y revisión del cliente, cada uno con su propio dominio (client1.dev.example.com, client2.dev.example.com).

Arquitectura Multi-Servicio de Startup: Desarrollar y probar microservicios localmente antes de desplegar a producción, con servicios como API, panel de administración, backend móvil y frontend todos ejecutándose simultáneamente.

Servidor de Desarrollo de Agencia: Agencia de desarrollo web ejecutando docenas de proyectos de clientes en varias etapas de desarrollo, accesibles a diseñadores, desarrolladores y clientes.

Desarrollo de Software como Servicio (SaaS): Desarrollo de aplicación multi-inquilino donde diferentes características o instancias de clientes se ejecutan en entornos aislados.

Desarrollo de Proyecto de Código Abierto: Colaboradores trabajando en diferentes características o versiones de proyectos de código abierto en entornos aislados.

Entorno Educativo: Escuelas o bootcamps proporcionando a estudiantes entornos de desarrollo individuales para trabajo de curso y proyectos.

Laboratorio de Pruebas DevOps: Probar infraestructura como código, scripts de despliegue y pipelines CI/CD antes de aplicar a sistemas de producción.

Desafíos de Stack Tecnológico

Los servidores de desarrollo modernos deben soportar diversos stacks tecnológicos:

Frameworks Web:

  • PHP (Laravel, Symfony, WordPress)
  • Python (Django, Flask, FastAPI)
  • Node.js (Express, NestJS, Next.js)
  • Ruby (Rails, Sinatra)
  • Java (Spring Boot, Jakarta EE)
  • Go, Rust, .NET Core

Bases de Datos:

  • MySQL/MariaDB
  • PostgreSQL
  • MongoDB
  • Redis
  • SQLite

Herramientas de Construcción Frontend:

  • Webpack, Vite, Parcel
  • npm, yarn, pnpm
  • Sass, PostCSS, Tailwind CSS

Requisitos

Requisitos del Sistema

Requisitos Mínimos (1-3 Proyectos Pequeños):

  • CPU: 2 núcleos a 2.0+ GHz
  • RAM: 4GB
  • Almacenamiento: 50GB SSD
  • Red: 10 Mbps
  • SO: Ubuntu 20.04/22.04 o Debian 11/12

Requisitos Recomendados (5-10 Proyectos Medianos):

  • CPU: 4 núcleos a 2.5+ GHz
  • RAM: 16GB
  • Almacenamiento: 200GB SSD
  • Red: 100 Mbps
  • SO: Ubuntu 22.04 LTS

Requisitos de Alto Rendimiento (20+ Proyectos o Stacks Complejos):

  • CPU: 8+ núcleos a 3.0+ GHz
  • RAM: 32GB+
  • Almacenamiento: 500GB NVMe SSD
  • Red: 1 Gbps
  • SO: Ubuntu 22.04 LTS

Requisitos de Software

Componentes Principales:

  • Nginx (proxy inverso y servidor web)
  • Docker y Docker Compose (contenedorización)
  • Git (control de versiones)
  • Certificados SSL/TLS (Let's Encrypt)

Lenguajes de Programación:

  • PHP (múltiples versiones vía php-fpm)
  • Python (pyenv para gestión de versiones)
  • Node.js (nvm para gestión de versiones)
  • Ruby (rbenv para gestión de versiones)

Bases de Datos:

  • MySQL/MariaDB
  • PostgreSQL
  • MongoDB
  • Redis

Herramientas de Desarrollo:

  • Composer (PHP)
  • pip/pipenv (Python)
  • npm/yarn (Node.js)
  • bundler (Ruby)

Requisitos de Red

Configuración de Dominio: DNS comodín o subdominios individuales para cada proyecto (*.dev.example.com).

Puertos de Firewall:

  • 80/TCP (HTTP)
  • 443/TCP (HTTPS)
  • 22/TCP (SSH para despliegue)
  • Opcional: Puertos directos de base de datos (restringidos a VPN/IPs específicas)

Conocimientos Previos

  • Administración de sistemas Linux
  • Configuración de servidor web (Nginx/Apache)
  • Fundamentos de contenedorización Docker
  • Conceptos básicos de redes y DNS
  • Control de versiones con Git

Configuración Paso a Paso

Paso 1: Preparación del Sistema

Actualizar sistema:

sudo apt update && sudo apt upgrade -y

Instalar herramientas esenciales:

sudo apt install -y build-essential curl wget git unzip \
    software-properties-common apt-transport-https ca-certificates \
    gnupg lsb-release

Paso 2: Instalar Nginx

Instalar Nginx:

sudo apt install nginx -y

Habilitar e iniciar:

sudo systemctl enable nginx
sudo systemctl start nginx

Paso 3: Instalar Docker y Docker Compose

Instalar Docker:

# Add Docker GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# Add repository
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list

# Install Docker
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

Agregar usuario al grupo docker:

sudo usermod -aG docker $USER
newgrp docker

Verificar instalación:

docker --version
docker compose version

Paso 4: Instalar Múltiples Versiones de PHP

Agregar repositorio PHP:

sudo add-apt-repository ppa:ondrej/php -y
sudo apt update

Instalar versiones PHP:

# Install PHP 7.4, 8.0, 8.1, 8.2
sudo apt install -y php7.4-fpm php7.4-{cli,mysql,pgsql,mbstring,xml,curl,zip,gd}
sudo apt install -y php8.0-fpm php8.0-{cli,mysql,pgsql,mbstring,xml,curl,zip,gd}
sudo apt install -y php8.1-fpm php8.1-{cli,mysql,pgsql,mbstring,xml,curl,zip,gd}
sudo apt install -y php8.2-fpm php8.2-{cli,mysql,pgsql,mbstring,xml,curl,zip,gd}

Verificar servicios PHP-FPM:

sudo systemctl status php7.4-fpm
sudo systemctl status php8.1-fpm

Paso 5: Instalar Node.js con nvm

Instalar nvm (Node Version Manager):

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash
source ~/.bashrc

Instalar múltiples versiones de Node.js:

nvm install 16
nvm install 18
nvm install 20

# Set default
nvm alias default 18

Instalar paquetes globales:

npm install -g pm2 yarn pnpm

Paso 6: Instalar Python con pyenv

Instalar pyenv:

curl https://pyenv.run | bash

Agregar a configuración de shell:

echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
source ~/.bashrc

Instalar versiones de Python:

pyenv install 3.9.18
pyenv install 3.10.13
pyenv install 3.11.6
pyenv install 3.12.0

Paso 7: Instalar Bases de Datos

MySQL/MariaDB:

sudo apt install -y mysql-server
sudo mysql_secure_installation

PostgreSQL:

sudo apt install -y postgresql postgresql-contrib

MongoDB:

# Import MongoDB GPG key
curl -fsSL https://www.mongodb.org/static/pgp/server-6.0.asc | sudo gpg --dearmor -o /usr/share/keyrings/mongodb-archive-keyring.gpg

# Add repository
echo "deb [arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-archive-keyring.gpg] https://repo.mongodb.org/apt/ubuntu $(lsb_release -cs)/mongodb-org/6.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-6.0.list

# Install
sudo apt update
sudo apt install -y mongodb-org
sudo systemctl enable mongod
sudo systemctl start mongod

Redis:

sudo apt install -y redis-server

Paso 8: Configurar Estructura de Proyectos

Crear estructura de directorio organizada:

sudo mkdir -p /var/www/projects
sudo chown -R $USER:$USER /var/www/projects

Crear estructura estándar de proyectos:

cd /var/www/projects

# Create directories for different project types
mkdir -p php/{laravel,wordpress,symfony}
mkdir -p nodejs/{express,nextjs,nuxt}
mkdir -p python/{django,flask}
mkdir -p static

Configuración

Configuración de Host Virtual Nginx para Múltiples Proyectos

Crear configuración Nginx para primer proyecto PHP:

sudo nano /etc/nginx/sites-available/project1.dev

Agregar configuración:

server {
    listen 80;
    server_name project1.dev.example.com;

    root /var/www/projects/php/laravel/project1/public;
    index index.php index.html;

    access_log /var/log/nginx/project1-access.log;
    error_log /var/log/nginx/project1-error.log;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
    }

    location ~ /\.ht {
        deny all;
    }
}

Habilitar sitio:

sudo ln -s /etc/nginx/sites-available/project1.dev /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Proyecto Node.js con Proxy Inverso

Crear configuración de proyecto Node.js:

sudo nano /etc/nginx/sites-available/nodeapp.dev

Agregar:

server {
    listen 80;
    server_name nodeapp.dev.example.com;

    access_log /var/log/nginx/nodeapp-access.log;
    error_log /var/log/nginx/nodeapp-error.log;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Habilitar y recargar:

sudo ln -s /etc/nginx/sites-available/nodeapp.dev /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Iniciar aplicación Node.js con PM2:

cd /var/www/projects/nodejs/express/nodeapp
pm2 start app.js --name nodeapp
pm2 save
pm2 startup

Aislamiento de Proyecto Basado en Docker

Crear configuración Docker Compose para proyecto:

mkdir -p /var/www/projects/docker/project-alpha
cd /var/www/projects/docker/project-alpha
nano docker-compose.yml

Ejemplo de configuración multi-contenedor:

version: '3.8'

services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./src:/var/www/html
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - php
      - db

  php:
    image: php:8.1-fpm
    volumes:
      - ./src:/var/www/html

  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: rootpass
      MYSQL_DATABASE: projectdb
      MYSQL_USER: devuser
      MYSQL_PASSWORD: devpass
    volumes:
      - db_data:/var/lib/mysql

  redis:
    image: redis:alpine

volumes:
  db_data:

Iniciar contenedores:

docker compose up -d

Proxy inverso Nginx para proyecto Docker:

server {
    listen 80;
    server_name alpha.dev.example.com;

    location / {
        proxy_pass http://localhost:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Configuración de Proyecto Python Django

Crear entorno virtual:

cd /var/www/projects/python/django
pyenv local 3.11.6
python -m venv venv
source venv/bin/activate

Instalar Django:

pip install django gunicorn
django-admin startproject myproject

Crear servicio systemd Gunicorn:

sudo nano /etc/systemd/system/django-myproject.service

Agregar:

[Unit]
Description=Django Myproject
After=network.target

[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/projects/python/django/myproject
Environment="PATH=/var/www/projects/python/django/venv/bin"
ExecStart=/var/www/projects/python/django/venv/bin/gunicorn \
    --workers 3 \
    --bind 127.0.0.1:8001 \
    myproject.wsgi:application

[Install]
WantedBy=multi-user.target

Iniciar servicio:

sudo systemctl enable django-myproject
sudo systemctl start django-myproject

Configuración Nginx:

server {
    listen 80;
    server_name django.dev.example.com;

    location / {
        proxy_pass http://127.0.0.1:8001;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location /static {
        alias /var/www/projects/python/django/myproject/static;
    }
}

Configuración de Base de Datos Por Proyecto

Crear bases de datos separadas para proyectos:

MySQL:

sudo mysql -u root -p
CREATE DATABASE project1_dev;
CREATE USER 'project1_user'@'localhost' IDENTIFIED BY 'secure_password';
GRANT ALL PRIVILEGES ON project1_dev.* TO 'project1_user'@'localhost';
FLUSH PRIVILEGES;

PostgreSQL:

sudo -u postgres psql
CREATE DATABASE project2_dev;
CREATE USER project2_user WITH PASSWORD 'secure_password';
GRANT ALL PRIVILEGES ON DATABASE project2_dev TO project2_user;

SSL/TLS con Let's Encrypt

Instalar Certbot:

sudo apt install certbot python3-certbot-nginx -y

Obtener certificado comodín:

sudo certbot certonly --manual --preferred-challenges dns -d '*.dev.example.com'

Seguir instrucciones para agregar registro TXT DNS.

Actualizar configuraciones Nginx:

server {
    listen 443 ssl http2;
    server_name project1.dev.example.com;

    ssl_certificate /etc/letsencrypt/live/dev.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/dev.example.com/privkey.pem;

    # ... rest of configuration
}

server {
    listen 80;
    server_name project1.dev.example.com;
    return 301 https://$server_name$request_uri;
}

Auto-renovar certificados:

sudo systemctl enable certbot.timer
sudo systemctl start certbot.timer

Optimización

Asignación de Recursos

Ajuste PHP-FPM:

sudo nano /etc/php/8.1/fpm/pool.d/www.conf

Optimizar:

pm = dynamic
pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10
pm.max_requests = 500

Procesos Worker de Nginx:

worker_processes auto;
worker_connections 1024;

Estrategias de Caché

Instalar y configurar Redis para almacenamiento de sesiones:

sudo apt install php8.1-redis -y

Configuración PHP:

session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379"

Caché Nginx:

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m;

location / {
    proxy_cache my_cache;
    proxy_pass http://localhost:3000;
}

Despliegue Automatizado

Crear script de despliegue:

nano ~/deploy.sh
#!/bin/bash

PROJECT=$1
BRANCH=${2:-main}

cd /var/www/projects/$PROJECT

echo "Pulling latest changes..."
git pull origin $BRANCH

if [ -f "package.json" ]; then
    echo "Installing Node.js dependencies..."
    npm install
    npm run build
    pm2 restart $PROJECT
fi

if [ -f "composer.json" ]; then
    echo "Installing PHP dependencies..."
    composer install --no-dev --optimize-autoloader
    php artisan migrate --force
    php artisan config:cache
    php artisan route:cache
fi

echo "Deployment complete!"

Hacer ejecutable:

chmod +x ~/deploy.sh

Usar:

./deploy.sh php/laravel/project1 develop

Monitoreo y Mantenimiento

Monitoreo de Proyectos

Instalar herramientas de monitoreo:

sudo apt install htop iotop nethogs -y

Monitorear procesos:

pm2 monit               # Node.js apps
sudo systemctl status php8.1-fpm
docker compose ps

Gestión de Logs

Centralizar logs:

sudo nano /etc/logrotate.d/projects

Agregar:

/var/www/projects/**/*.log {
    daily
    rotate 14
    compress
    delaycompress
    notifempty
    missingok
    create 0640 www-data www-data
}

Ver logs agregados:

sudo tail -f /var/log/nginx/*.log
pm2 logs
docker compose logs -f

Estrategia de Respaldo

Crear script de respaldo:

nano ~/backup-projects.sh
#!/bin/bash

BACKUP_DIR="/backup/projects/$(date +%Y-%m-%d)"
mkdir -p $BACKUP_DIR

# Backup project files
rsync -av /var/www/projects/ $BACKUP_DIR/files/

# Backup databases
mysqldump --all-databases > $BACKUP_DIR/mysql-all.sql
sudo -u postgres pg_dumpall > $BACKUP_DIR/postgres-all.sql

# Compress
tar -czf $BACKUP_DIR.tar.gz $BACKUP_DIR/
rm -rf $BACKUP_DIR

# Keep only last 7 days
find /backup/projects/ -name "*.tar.gz" -mtime +7 -delete

Programar con cron:

crontab -e

Agregar:

0 2 * * * /home/user/backup-projects.sh

Consideraciones de Seguridad

Configuración de Firewall

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

Restringir Acceso a Base de Datos

Configurar MySQL para escuchar solo en localhost:

sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
bind-address = 127.0.0.1

Gestión de Variables de Entorno

Usar archivos .env para configuración sensible:

nano /var/www/projects/php/laravel/project1/.env
APP_ENV=development
APP_KEY=base64:...
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=project1_dev
DB_USERNAME=project1_user
DB_PASSWORD=secure_password

Nunca hacer commit de .env al control de versiones:

echo ".env" >> .gitignore

Control de Acceso de Usuarios

Crear usuario separado por proyecto:

sudo useradd -m -s /bin/bash project1
sudo usermod -aG www-data project1

Establecer permisos apropiados:

sudo chown -R project1:www-data /var/www/projects/php/laravel/project1
sudo chmod -R 755 /var/www/projects/php/laravel/project1

Conclusión

Ahora tiene un servidor de desarrollo completo capaz de alojar múltiples proyectos con diferentes stacks tecnológicos, entornos aislados y compartir recursos eficientemente. Esta infraestructura proporciona la base para flujos de trabajo de desarrollo profesionales, colaboración en equipo y pruebas de despliegue.

Logros clave:

  • Soporte multi-stack para PHP, Node.js, Python y aplicaciones contenedorizadas
  • Aislamiento de proyecto a través de hosts virtuales, Docker y gestores de versiones
  • Eficiencia de recursos compartiendo infraestructura mientras mantiene separación
  • Flujos de trabajo profesionales con despliegue automatizado y monitoreo
  • Arquitectura escalable lista para proyectos y tecnologías adicionales

El mantenimiento regular incluye actualizar paquetes de software, monitorear uso de recursos, revisar logs, respaldar proyectos y bases de datos, y optimizar configuraciones a medida que evolucionan los requisitos del proyecto.

¡Desarrolle eficientemente!