😎

Status: Sette opp monorepo for første gruppe med multi-tenants. Det blir Payload CMS med multi-tenant setup i backend som kjører i Payload Cloud, og parallelle Next-apper som deployes fra en server hos kanskje Dreamhost, hvis ikke Vercel. Denne første gruppa skal ha tenants med bare 1-2 admins og enkle collections i backend og enkel Vipps-handlekurv i frontend.

Yarn Workspaces

Man har en package.json på rot som erklærer at det ligger workspaces i /packages. I packages har jeg 1 prosjekt for backend som er en multitenant Payload CMS, og x antall Next-prosjekter, som er mine tenants i gruppa.

  • Kjør yarn install på rot for å installere alle prosjektene og “hoiste” (konsolidere) dependenciene deres (unngå node_modules bloat). Dette er native funksjonalitet i Yarn Workspaces.
  • Kjør yarn workspace <project-name> run <script> for å kjøre et script på et prosjekt.
  • NB! Yarn vil ikke kjøre flere script på en gang. Du må gå på rot og installere Concurrently med yarn add concurrently --dev -W og så legge til et script i package.json på rot som angir scriptene det gjelder:
  "scripts": {
    "dev-concurrently": "concurrently \"yarn workspace backend run dev\" \"yarn workspace hjertets-tempel run dev\" \"yarn workspace oscar-floor run dev\""
  }

Nyttig å sette opp for å kjøre backend samtidig med prosjektet som jobbes med.

--dev flagget adder Concurrently som en dev-dependency.

-W flagget er for å forsikre Yarn om at du virkelig vil installere Concurrently på rot.

Nginx

ChatGPT foreslår nginx for å løse følgende:

  • Routing av innkommende HTTP-requests til riktig prosess: Jeg trenger at en requests til www.tenant-1.com blir servet av kun Next-appen til tenant 1.

Lokalt prøver jeg å mocke noen tenant-domener ved å legge til typ dette i hosts-fila:

127.0.0.1 tenant-1.localhost
127.0.0.1 tenant-2.localhost

Da skal de URLene rute til 127.0.0.1.

Så har jeg nginx-kjørende med følgende config, som skal revers-proxye disse requestene slik at URLene routes til riktig prosess:

# Configuration for the first tenant
server {
    listen 80;
    server_name tenant-1.localhost;

    # Specific path routing to the CMS app
    location /admin {
        proxy_pass http://localhost:3000; # Your CMS app port
        proxy_set_header Host $host;
        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;
    }

    # Default routing to the tenant's Next.js app
    location / {
        proxy_pass http://localhost:3001; # Tenant 1's Next.js app port
        proxy_set_header Host $host;
        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;
    }
}
  • Maskering av URL når request kommer fra en tenant-frontend til admin-grensesnittet som serves av backend: Jeg vil at admin-login skal finnes på URLen www.tenant-1.com/login, ikke tenant-1.firstbird.is/login

Dette oppnås med nginx-configen over, der requests til /admin routes til backend-prosessen. I følge chatGPT skal alle subroutes også maskeres da, typ /admin/login og så videre.

Next-apper og port

I produksjon vil Next-appene kjøre på samme server, så de må gis spesifikke porter som nginx kan route trafikken deres til.