tenant1.site.com → internal port 8960
tenant2.site.com → internal port 8961
tenant3.site.com → internal port 8962
tenant1.site.com → internal port 8960
tenant2.site.com → internal port 8961
tenant3.site.com → internal port 8962
tenant1.site.com → internal port 8960
tenant2.site.com → internal port 8961
tenant3.site.com → internal port 8962 - A full OS kernel sitting in memory doing nothing most of the time
- A Windows Server license (per guest, not per host)
- Its own IIS instance, its own patch cycle, its own failure surface
- Manual intervention every time something needs to change across all clients - Docker containers — one per client, lightweight, isolated, disposable
- A per-client docker-compose — each tenant gets their own database and cache, no sharing
- Nginx as the single entry point — all traffic hits port 443, nginx decides where it goes
- A provisioning panel — so spinning up a new client isn't a half-day manual process - The application container
- A dedicated database instance
- A dedicated cache instance - Pulls the next available port from a ports table in the database
- Generates a docker-compose from the base template with the assigned port and client config
- Spins the container stack with docker compose up -d
- Writes the nginx config fragment for the subdomain mapping
- Reloads nginx - Containerize your application with Docker
- Define a docker-compose template that includes app, database, and cache per tenant
- Set up nginx as your reverse proxy with per-client config fragments in conf.d/
- Build a simple ports registry to manage internal port assignments
- Wire up a basic provisioning script that generates configs and spins containers