Hosting and Server for Jeydoo
Reference: Asana Ticket
We will manage two server environments: Staging and Production, following the structure used in ark-management and ark-management-staging.
🧪 Staging Environment
Used for QA testing and internal review. Connects to a staging database.
-
Global Admin Panel:
management-staging.jeydoo.de
-
Client Management Panel:
app-staging.jeydoo.de
-
Employee Booking Panel:
time-staging.jeydoo.de
🚀 Production Environment
Live environment for client use. Connects to the production database.
-
Global Admin Panel:
management.jeydoo.de
-
Client Management Panel:
app.jeydoo.de
-
Employee Booking Panel:
time.jeydoo.de
Multi-Tenant SaaS Setup
🔧 Approach: Private Database per Tenant
Each tenant will use a separate private database for improved data isolation and flexibility.
🌐 Subdomain & Domain Routing via Nginx
Jeydoo.com will support multiple tenants by configuring subdomains or custom domains that all share the same server IP. These will be managed using domain-based routing (e.g., via Nginx, Traefik, or HAProxy).
Examples of supported domains/subdomains:
-
tenant-123.jeydoo.com
-
fitplus.jeydoo.de
-
time.fitplus.com
-
time.fit-club.com
🧭 How it works:
-
All tenant subdomains and domains point to a single shared IP using DNS A or CNAME records.
-
The reverse proxy (e.g., Nginx) routes traffic to the correct tenant instance based on the incoming domain.
tenant1.jeydoo.com -> 192.0.2.10
tenant2.jeydoo.com -> 192.0.2.10
This setup provides us with:
-
Scalability – easily add more tenants without changing infrastructure.
-
Flexibility – tenants can use either subdomains or their own custom domains.
-
Security – private database ensures better data isolation per tenant.
Architecture Recommendation:
Use 1 Shared IP Address with Domain-Based Routing
We recommend sticking with a single shared IP address and leveraging domain-based routing. This approach is:
-
Reliable – Proven to work across many production environments
-
Cost-efficient – No need for multiple IP addresses
-
Scalable & automated – Easily managed using tools like Docker, Traefik, and Let’s Encrypt for automatic HTTPS
Handling Private Databases Per Tenant
Each tenant can have their own private database. The key is to detect the tenant based on the incoming domain/subdomain and connect to the corresponding database dynamically.
✅ Example Flow:
-
Client sends request to
tenant123.jeydoo.com
-
Backend extracts the hostname/domain
-
Use the domain as a key to fetch tenant-specific DB credentials (from a map, config, or service)
-
Establish DB connection for that request
Example in Golang:
domain := r.Host // e.g., tenant1.jeydoo.com
db := ConnectToTenantDatabase(domain)
2. Private PostgreSQL Per Tenant (Docker)
-
Each tenant has its own PostgreSQL container with internal Docker networking (no public IP). e.g postgres://tenant1:pass@tenant1-db:5432/dbname
-
a
docker-compose.yml
file for a multi-tenant SaaS app setup where each tenant has a separate PostgreSQL database.