Lately I just use docker compose with caddy, and have each sub-app running in .watch mode against the source directory.
This does work too though, and if you're in control of the full codebase and don't have other local dependencies (database, redis, etc), then this may be better.
Source is linked from the article towards the bottom.