Back to articles
Technology Insight

How to Host Multiple Websites on a Single VPS Using Docker and Nginx Proxy Manager

May 17, 2026

Introduction: The Modern Web Hosting Challenge

In today's digital landscape, businesses and developers often need to manage multiple websites, applications, and services. Traditional hosting approaches—using separate virtual private servers (VPS) for each site or manually configuring complex web servers—quickly become expensive, inefficient, and difficult to maintain. The solution lies in containerization and intelligent reverse proxy management. By combining Docker with Nginx Proxy Manager, you can create a powerful, scalable, and cost-effective hosting environment on a single VPS. This approach not only reduces infrastructure costs but also simplifies deployment, enhances security through isolation, and provides a user-friendly interface for managing SSL certificates and routing rules.

Understanding the Core Technologies

Docker: The Foundation of Containerization

Docker is a platform that enables you to package applications and their dependencies into lightweight, portable containers. Unlike traditional virtual machines that require a full operating system for each instance, Docker containers share the host system's kernel, making them incredibly efficient. For multi-website hosting, Docker provides several key advantages:

  • Isolation: Each website runs in its own container, preventing conflicts between different applications, libraries, or runtime environments.
  • Portability: Containers can be easily moved between different VPS providers or local development environments.
  • Resource Efficiency: Multiple containers consume significantly fewer resources than multiple virtual machines.
  • Version Control: Docker images can be versioned, ensuring consistent deployments across different environments.

Nginx Proxy Manager: Simplified Reverse Proxy Management

Nginx Proxy Manager (NPM) is an open-source tool that provides a clean, web-based interface for managing Nginx proxy hosts. While Nginx itself is a powerful web server and reverse proxy, its configuration files can be complex and error-prone. NPM abstracts this complexity, allowing you to:

  • Easily create reverse proxy rules to route traffic to different containers
  • Obtain and renew free SSL certificates from Let's Encrypt with a few clicks
  • Manage access controls, redirects, and custom configurations through a GUI
  • Monitor traffic and connection statistics

Together, these technologies create a complete hosting solution where Docker handles application deployment and NPM manages external access and security.

Architectural Overview: How Everything Connects

Before diving into implementation, it's crucial to understand the architectural flow. When a visitor accesses one of your websites, the request follows this path:

  1. The visitor's browser sends a request to your VPS's public IP address or domain name.
  2. Nginx Proxy Manager, running on ports 80 and 443, receives the request.
  3. NPM examines the request's host header (the domain name) and matches it against configured proxy hosts.
  4. Based on the matching rule, NPM forwards the request to the appropriate Docker container's internal IP address and port.
  5. The containerized application (like WordPress, Node.js, or a static site) processes the request and sends the response back through the same path.

This architecture creates a clean separation of concerns: Docker manages the applications, while NPM handles network routing and SSL termination. Each component can be updated, scaled, or replaced independently without affecting the others.

Step-by-Step Implementation Guide

Prerequisites and Initial Setup

Before beginning, ensure you have:

  • A VPS with at least 2GB RAM and 20GB storage (Ubuntu 20.04/22.04 LTS recommended)
  • Root or sudo access to the server
  • A registered domain name with DNS access
  • Basic familiarity with command-line interfaces

Start by updating your system and installing Docker:

Note: Always use the official Docker installation script or repository for security and stability. Avoid third-party packages that might contain outdated or modified versions.

Installing Docker and Docker Compose

First, install Docker using the official convenience script:

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER

After installation, verify Docker is running with sudo docker ps. Next, install Docker Compose, which allows you to define multi-container applications in YAML files:

sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

Deploying Nginx Proxy Manager with Docker Compose

Create a dedicated directory for your NPM configuration:

mkdir ~/nginx-proxy-manager
cd ~/nginx-proxy-manager

Create a docker-compose.yml file with the following configuration:

version: '3.8'
services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: unless-stopped
    ports:
      - '80:80'
      - '81:81'
      - '443:443'
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt

This configuration maps the essential ports (80 for HTTP, 443 for HTTPS, 81 for the admin interface) and creates persistent volumes for configuration data and SSL certificates. Start NPM with:

docker-compose up -d

Access the admin interface at http://your-server-ip:81 using the default credentials ([email protected] / changeme) and immediately change the password.

Configuring DNS and Your First Proxy Host

For NPM to route traffic correctly, you need to configure DNS records pointing to your VPS. Create an A record for each domain/subdomain that points to your server's public IP address. In NPM's admin interface:

  1. Click "Proxy Hosts" then "Add Proxy Host"
  2. Enter your domain name (e.g., blog.yourdomain.com)
  3. Set the forward hostname to the internal Docker service name (or IP) and port
  4. Enable SSL and request a Let's Encrypt certificate
  5. Force SSL and HTTP/2 support for better security and performance

Deploying Multiple Website Containers

Example 1: WordPress Website

Create a separate directory for your WordPress site and a docker-compose.yml file:

version: '3.8'
services:
  wordpress:
    image: wordpress:latest
    restart: unless-stopped
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: secure_password
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - ./wp-content:/var/www/html/wp-content
  db:
    image: mysql:8.0
    restart: unless-stopped
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: secure_password
      MYSQL_RANDOM_ROOT_PASSWORD: '1'
    volumes:
      - ./mysql-data:/var/lib/mysql

Start the WordPress stack, then in NPM, create a proxy host pointing to wordpress:80 (using the service name as hostname since both compose files are on the same Docker network).

Example 2: Node.js Application

For a Node.js application, create a Dockerfile:

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

Build and run the container, then configure NPM to forward traffic to the container's port 3000.

Example 3: Static Website

For static sites, use the Nginx Alpine image:

version: '3.8'
services:
  static-site:
    image: nginx:alpine
    restart: unless-stopped
    volumes:
      - ./html:/usr/share/nginx/html:ro

Advanced Configuration and Best Practices

Network Configuration and Isolation

For better security and organization, create a custom Docker network:

docker network create web-network

Add networks: web-network to all your Docker Compose files and ensure NPM is connected to the same network. This isolates your application traffic from the default Docker bridge network.

SSL Certificate Management

NPM makes SSL management straightforward, but consider these best practices:

  • Use wildcard certificates (*.yourdomain.com) for multiple subdomains
  • Enable "Force SSL" to automatically redirect HTTP to HTTPS
  • Monitor certificate expiration dates in the NPM interface
  • Use DNS challenge for Let's Encrypt when hosting services without public HTTP access

Performance Optimization

To ensure optimal performance across multiple sites:

  • Configure NPM caching for static assets
  • Use HTTP/2 for all SSL-enabled sites
  • Implement gzip/brotli compression in NPM settings
  • Set appropriate client_max_body_size for file uploads
  • Monitor resource usage with docker stats

Security Considerations

Security is paramount when hosting multiple sites:

  • Regularly update Docker images with docker-compose pull and docker-compose up -d
  • Use non-root users inside containers when possible
  • Implement fail2ban or similar protection against brute-force attacks
  • Regularly backup NPM's data directory and Let's Encrypt certificates
  • Use strong, unique passwords for all admin interfaces

Monitoring, Maintenance, and Troubleshooting

Essential Monitoring Commands

Regular monitoring helps prevent issues before they affect your sites:

# View running containers and resource usage
docker ps
docker stats

# Check NPM logs
docker-compose logs -f app

# Verify SSL certificate status
certbot certificates

Common Issues and Solutions

Issue: 502 Bad Gateway errors
Solution: Check if the target container is running and accessible on the expected port. Verify network connectivity with docker network inspect web-network.

Issue: SSL certificate renewal failures
Solution: Ensure ports 80 and 443 are open in your firewall. For DNS challenge failures, verify API credentials for your DNS provider.

Issue: High memory usage
Solution: Set memory limits in Docker Compose files and monitor with docker stats. Consider upgrading your VPS if consistently near capacity.

Backup Strategy

Implement a comprehensive backup strategy:

  1. Backup NPM data: tar -czf npm-backup.tar.gz ~/nginx-proxy-manager/data
  2. Backup Let's Encrypt certificates: tar -czf letsencrypt-backup.tar.gz ~/nginx-proxy-manager/letsencrypt
  3. Backup individual website data volumes
  4. Store backups in a secure, off-server location
  5. Test restoration procedures regularly

Scaling and Future Considerations

As your hosting needs grow, consider these advanced approaches:

  • Load Balancing: Deploy multiple instances of high-traffic sites behind NPM
  • Database Externalization: Move databases to managed services for better performance and reliability
  • CI/CD Integration: Automate deployment with GitHub Actions, GitLab CI, or similar tools
  • Monitoring Stack: Implement Prometheus, Grafana, and cAdvisor for detailed metrics
  • High Availability: Deploy multiple VPS instances with shared storage and floating IPs

Conclusion: The Future of Web Hosting

Hosting multiple websites on a single VPS with Docker and Nginx Proxy Manager represents a modern, efficient approach to web infrastructure. This combination provides the flexibility to host diverse applications, the security of container isolation, and the simplicity of a graphical management interface. By implementing this architecture, you significantly reduce hosting costs while gaining greater control over your web presence. The skills learned—Docker containerization, reverse proxy configuration, SSL management, and multi-service orchestration—are highly transferable and increasingly essential in today's cloud-native world. Start with a simple setup, follow best practices for security and maintenance, and gradually expand as your needs grow. The future of web hosting is containerized, automated, and efficient, and with these tools, you're well-positioned to embrace it.