Development Server with Multiple Projects: Complete Setup Guide

Introduction

Modern software development often involves juggling multiple projects simultaneously - each with different technology stacks, dependencies, databases, and environment requirements. Setting up a dedicated development server that can host multiple projects cleanly and efficiently is essential for individual developers, development teams, and organizations seeking to centralize their development infrastructure.

A well-configured multi-project development server eliminates "works on my machine" problems, provides consistent development environments, enables easy collaboration, simplifies deployment testing, and serves as a staging ground before production releases. By isolating projects while sharing underlying infrastructure, you maximize resource utilization while maintaining separation of concerns.

This comprehensive guide walks you through building a production-ready development server capable of hosting multiple projects with different technology requirements. You'll learn how to set up web servers with virtual hosts, configure multiple database instances, manage programming language versions, implement containerization for isolation, configure reverse proxies, secure development environments, and implement efficient deployment workflows.

Whether you're a freelance developer managing client projects, a startup running multiple services, a development team needing shared infrastructure, or an organization consolidating development environments, this guide provides the foundation for professional multi-project development server deployment.

Use Case Overview

Why Deploy a Development Server?

A centralized development server offers significant advantages over local-only development:

Consistent Environments: Eliminate environment discrepancies between developers. Everyone works in identical setups, reducing "it works on my machine" issues.

Team Collaboration: Multiple developers access the same server, view each other's work, and collaborate on features without complex local setup procedures.

Remote Development: Access development environment from anywhere - laptop, tablet, or another workstation, enabling flexible work arrangements.

Resource Sharing: Share database servers, caching layers, and development tools across projects rather than duplicating on each developer's machine.

Client Demonstrations: Easily demonstrate work-in-progress features to clients or stakeholders via simple URLs without deploying to production.

Testing and Staging: Test deployments, database migrations, and infrastructure changes in production-like environments before releasing.

Learning and Experimentation: Safely experiment with new technologies, frameworks, and tools without affecting your primary workstation.

Cost Efficiency: Single server hosts multiple projects rather than separate servers for each, reducing infrastructure costs.

Common Deployment Scenarios

Freelance Developer Portfolio: Host multiple client projects for development and client review, each with its own domain (client1.dev.example.com, client2.dev.example.com).

Startup Multi-Service Architecture: Develop and test microservices locally before deploying to production, with services like API, admin panel, mobile backend, and frontend all running simultaneously.

Agency Development Server: Web development agency running dozens of client projects in various stages of development, accessible to designers, developers, and clients.

Software as a Service (SaaS) Development: Multi-tenant application development where different features or customer instances run in isolated environments.

Open Source Project Development: Contributors working on different features or versions of open-source projects in isolated environments.

Educational Environment: Schools or bootcamps providing students with individual development environments for coursework and projects.

DevOps Testing Lab: Testing infrastructure as code, deployment scripts, and CI/CD pipelines before applying to production systems.

Technology Stack Challenges

Modern development servers must support diverse technology stacks:

Web Frameworks:

  • 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

Databases:

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

Frontend Build Tools:

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

Requirements

System Requirements

Minimum Requirements (1-3 Small Projects):

  • CPU: 2 cores at 2.0+ GHz
  • RAM: 4GB
  • Storage: 50GB SSD
  • Network: 10 Mbps
  • OS: Ubuntu 20.04/22.04 or Debian 11/12

Recommended Requirements (5-10 Medium Projects):

  • CPU: 4 cores at 2.5+ GHz
  • RAM: 16GB
  • Storage: 200GB SSD
  • Network: 100 Mbps
  • OS: Ubuntu 22.04 LTS

High-Performance Requirements (20+ Projects or Complex Stacks):

  • CPU: 8+ cores at 3.0+ GHz
  • RAM: 32GB+
  • Storage: 500GB NVMe SSD
  • Network: 1 Gbps
  • OS: Ubuntu 22.04 LTS

Software Requirements

Core Components:

  • Nginx (reverse proxy and web server)
  • Docker and Docker Compose (containerization)
  • Git (version control)
  • SSL/TLS certificates (Let's Encrypt)

Programming Languages:

  • PHP (multiple versions via php-fpm)
  • Python (pyenv for version management)
  • Node.js (nvm for version management)
  • Ruby (rbenv for version management)

Databases:

  • MySQL/MariaDB
  • PostgreSQL
  • MongoDB
  • Redis

Development Tools:

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

Network Requirements

Domain Configuration: Wildcard DNS or individual subdomains for each project (*.dev.example.com).

Firewall Ports:

  • 80/TCP (HTTP)
  • 443/TCP (HTTPS)
  • 22/TCP (SSH for deployment)
  • Optional: Direct database ports (restricted to VPN/specific IPs)

Prerequisites Knowledge

  • Linux system administration
  • Web server configuration (Nginx/Apache)
  • Docker containerization basics
  • Basic networking and DNS concepts
  • Version control with Git

Step-by-Step Setup

Step 1: System Preparation

Update system:

sudo apt update && sudo apt upgrade -y

Install essential tools:

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

Step 2: Install Nginx

Install Nginx:

sudo apt install nginx -y

Enable and start:

sudo systemctl enable nginx
sudo systemctl start nginx

Step 3: Install Docker and Docker Compose

Install 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

Add user to docker group:

sudo usermod -aG docker $USER
newgrp docker

Verify installation:

docker --version
docker compose version

Step 4: Install Multiple PHP Versions

Add PHP repository:

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

Install PHP versions:

# 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}

Verify PHP-FPM services:

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

Step 5: Install Node.js with nvm

Install nvm (Node Version Manager):

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

Install multiple Node.js versions:

nvm install 16
nvm install 18
nvm install 20

# Set default
nvm alias default 18

Install global packages:

npm install -g pm2 yarn pnpm

Step 6: Install Python with pyenv

Install pyenv:

curl https://pyenv.run | bash

Add to shell configuration:

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

Install Python versions:

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

Step 7: Install Databases

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

Step 8: Configure Project Structure

Create organized directory structure:

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

Create standard project structure:

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

Configuration

Nginx Virtual Host Setup for Multiple Projects

Create Nginx configuration for first PHP project:

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

Add configuration:

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;
    }
}

Enable site:

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

Node.js Project with Reverse Proxy

Create Node.js project configuration:

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

Add:

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;
    }
}

Enable and reload:

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

Start Node.js app with PM2:

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

Docker-Based Project Isolation

Create Docker Compose setup for project:

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

Example multi-container setup:

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:

Start containers:

docker compose up -d

Nginx reverse proxy for Docker project:

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;
    }
}

Python Django Project Setup

Create virtual environment:

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

Install Django:

pip install django gunicorn
django-admin startproject myproject

Create Gunicorn systemd service:

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

Add:

[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

Start service:

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

Nginx configuration:

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;
    }
}

Database Per-Project Configuration

Create separate databases for projects:

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 with Let's Encrypt

Install Certbot:

sudo apt install certbot python3-certbot-nginx -y

Obtain wildcard certificate:

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

Follow prompts to add DNS TXT record.

Update Nginx configurations:

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-renew certificates:

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

Optimization

Resource Allocation

PHP-FPM Tuning:

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

Optimize:

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

Nginx Worker Processes:

worker_processes auto;
worker_connections 1024;

Caching Strategies

Install and configure Redis for session storage:

sudo apt install php8.1-redis -y

PHP configuration:

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

Nginx caching:

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;
}

Automated Deployment

Create deployment script:

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!"

Make executable:

chmod +x ~/deploy.sh

Use:

./deploy.sh php/laravel/project1 develop

Monitoring and Maintenance

Project Monitoring

Install monitoring tools:

sudo apt install htop iotop nethogs -y

Monitor processes:

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

Log Management

Centralize logs:

sudo nano /etc/logrotate.d/projects

Add:

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

View aggregated logs:

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

Backup Strategy

Create backup script:

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

Schedule with cron:

crontab -e

Add:

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

Security Considerations

Firewall Configuration

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

Restrict Database Access

Configure MySQL to listen only on localhost:

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

Environment Variable Management

Use .env files for sensitive configuration:

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

Never commit .env to version control:

echo ".env" >> .gitignore

User Access Control

Create separate user per project:

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

Set appropriate permissions:

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

Conclusion

You now have a comprehensive development server capable of hosting multiple projects with different technology stacks, isolated environments, and efficient resource sharing. This infrastructure provides the foundation for professional development workflows, team collaboration, and deployment testing.

Key achievements:

  • Multi-stack support for PHP, Node.js, Python, and containerized applications
  • Project isolation through virtual hosts, Docker, and version managers
  • Resource efficiency sharing infrastructure while maintaining separation
  • Professional workflows with automated deployment and monitoring
  • Scalable architecture ready for additional projects and technologies

Regular maintenance includes updating software packages, monitoring resource usage, reviewing logs, backing up projects and databases, and optimizing configurations as project requirements evolve.

Develop efficiently!