# Mountebank Studio — production serving. # # Two jobs: serve the static build, and forward each environment to its instance. # # THE FORWARDING IS THE POINT. A browser will not let this page read a response # from another host unless that host allows this origin, which would mean adding # `--origin` to every Mountebank you want to use — including the ones your DevOps # team installed and that you should not have to restart. Forwarding here removes # that requirement entirely: the panel calls THIS host, this host calls the # instance, and nothing is cross-origin. The instance is never touched. # # One `location` per environment, and in the panel you enter the PATH as the admin # API — `/mb/stage`, not the instance's own URL. # # The direct model still works for an instance you start yourself: enter its full # URL in the panel and start it with `--origin "https://this-host"`. The two can be # mixed, one environment each way. # # Deploy: yarn build → copy dist/ to /var/www/mountebank-studio # server { listen 443 ssl http2; server_name mountebank-studio.example.com; # ssl_certificate /etc/nginx/certs/example.crt; # ssl_certificate_key /etc/nginx/certs/example.key; root /var/www/mountebank-studio; index index.html; # ── the app ──────────────────────────────────────────────────────────── # Routing is client-side, so any path that is not a real file is index.html. location / { try_files $uri $uri/ /index.html; } # Hashed build assets never change under the same name. location /assets/ { expires 1y; add_header Cache-Control "public, immutable"; } # ── which paths forward where ────────────────────────────────────────── # The panel offers to repoint an environment at a forwarded path ONLY when it # can prove the path leads to that same instance, and this is the proof: the # map, stated by the layer that owns it. Keep it in step with the blocks below. # # Without it nothing breaks — the panel simply never offers the switch, and you # enter the path by hand. Never let it name an instance a viewer may not reach. # # location = /mb/targets.json { # default_type application/json; # add_header Cache-Control "no-store"; # return 200 '{"stage":"https://mountebank.stg.example.com","dev":"https://mountebank.dev.example.com"}'; # } # ── the environments ─────────────────────────────────────────────────── # One block per instance. The trailing slash on both the location and the # proxy_pass is what strips the prefix: /mb/stage/imposters → /imposters. # # In the panel, add an environment whose admin API is `/mb/stage`. # # location /mb/stage/ { # proxy_pass https://mountebank.stg.example.com/; # proxy_set_header Host mountebank.stg.example.com; # proxy_http_version 1.1; # # # An imposter's recorded traffic can be large; do not buffer it to disk. # proxy_buffering off; # # # These mocks decide what the services under test see. Anyone who can # # open this path can rewrite them, so protect it as you would the panel. # # auth_basic "Mountebank Studio"; # # auth_basic_user_file /etc/nginx/.htpasswd; # } # # location /mb/dev/ { # proxy_pass https://mountebank.dev.example.com/; # proxy_set_header Host mountebank.dev.example.com; # proxy_http_version 1.1; # proxy_buffering off; # } # ── who may open the panel ───────────────────────────────────────────── # These mocks decide what the services under test see, so the panel is worth # protecting even when the instances behind it are unauthenticated. # # auth_basic "Mountebank Studio"; # auth_basic_user_file /etc/nginx/.htpasswd; # # …or put it behind the same SSO as your other internal tools. access_log /var/log/nginx/mountebank-studio.access.log; error_log /var/log/nginx/mountebank-studio.error.log; }