(core) make Grist easier to run with a single server

Summary:
This makes many small changes so that Grist is less fussy to run as a single instance behind a reverse proxy. Some users had difficulty with the self-connections Grist would make, due to internal network setup, and since these are unnecessary in any case in this scenario, they are now optimized away. Likewise some users had difficulties related to doc worker urls, which are now also optimized away. With these changes, users should be able to get a lot further on first try, at least far enough to open and edit documents.

The `GRIST_SINGLE_ORG` setting was proving a bit confusing, since it appeared to only work when set to `docs`. This diff
adds a check for whether the specified org exists, and if not, it creates it. This still depends on having a user email to make as the owner of the team, so there could be remaining difficulties there.

Test Plan: tested manually with nginx

Reviewers: jarek

Reviewed By: jarek

Differential Revision: https://phab.getgrist.com/D3299
This commit is contained in:
Paul Fitzpatrick
2022-03-02 14:07:26 -05:00
parent 0da397ab90
commit 2563fb745a
13 changed files with 228 additions and 68 deletions

View File

@@ -672,7 +672,7 @@ export class UserAPIImpl extends BaseAPI implements UserAPI {
method: 'GET',
credentials: 'include'
});
return json.docWorkerUrl;
return getDocWorkerUrl(this._homeUrl, json);
}
public async getWorkerAPI(key: string): Promise<DocWorkerAPI> {
@@ -968,3 +968,28 @@ export class DocAPIImpl extends BaseAPI implements DocAPI {
return this.requestJson(url.href);
}
}
/**
* Get a docWorkerUrl from information returned from backend. When the backend
* is fully configured, and there is a pool of workers, this is straightforward,
* just return the docWorkerUrl reported by the backend. For single-instance
* installs, the backend returns a null docWorkerUrl, and a client can simply
* use the homeUrl of the backend, with extra path prefix information
* given by selfPrefix. At the time of writing, the selfPrefix contains a
* doc-worker id, and a tag for the codebase (used in consistency checks).
*/
export function getDocWorkerUrl(homeUrl: string, docWorkerInfo: {
docWorkerUrl: string|null,
selfPrefix?: string,
}): string {
if (!docWorkerInfo.docWorkerUrl) {
if (!docWorkerInfo.selfPrefix) {
// This should never happen.
throw new Error('missing selfPrefix for docWorkerUrl');
}
const url = new URL(homeUrl);
url.pathname = docWorkerInfo.selfPrefix + url.pathname;
return url.href;
}
return docWorkerInfo.docWorkerUrl;
}

View File

@@ -472,7 +472,7 @@ export interface GristLoadConfig {
getDoc?: {[id: string]: Document};
// Pre-fetched call to getWorker for the doc being loaded.
getWorker?: {[id: string]: string};
getWorker?: {[id: string]: string|null};
// The timestamp when this gristConfig was generated.
timestampMs: number;
@@ -528,6 +528,21 @@ export function getKnownOrg(): string|null {
}
}
/**
* Like getKnownOrg, but respects singleOrg/GRIST_SINGLE_ORG strictly.
* The main difference in behavior would be for orgs with custom domains
* served from a shared pool of servers, for which gristConfig.org would
* be set, but not gristConfig.singleOrg.
*/
export function getSingleOrg(): string|null {
if (isClient()) {
const gristConfig: GristLoadConfig = (window as any).gristConfig;
return (gristConfig && gristConfig.singleOrg) || null;
} else {
return process.env.GRIST_SINGLE_ORG || null;
}
}
/**
* Returns true if org must be encoded in path, not in domain. Determined from
* gristConfig on the client. On on the server returns true if the host is