Deploying to Google Cloud Platform
Relevant source files
The following files were used as context for generating this wiki page:Rendertron is designed for deployment on various platforms, including Google Cloud Platform (GCP). This integration primarily revolves around using Google Cloud Datastore as a persistent caching layer for rendered pages and adhering to standard Google App Engine conventions for service health monitoring.
Enabling the Datastore cache can significantly improve performance and reduce rendering costs by serving previously rendered pages directly from the cache, bypassing the resource-intensive headless Chrome rendering process for repeated requests. The application includes all necessary dependencies and configuration hooks to enable this functionality.
Google App Engine Integration
The service is structured to be compatible with Google App Engine environments.
Health Checks
A standard health check endpoint required by App Engine is included. This endpoint allows the GCP environment to verify that the Rendertron instance is running correctly.
- Endpoint:
GET /_ah/health - Response: A
200 OKstatus with the text bodyOK.
This is implemented as a simple Koa route that responds with a success message.
// src/rendertron.ts:44-45
this.app.use(
route.get('/_ah/health', (ctx: Koa.Context) => ctx.body = 'OK'));
Sources: src/rendertron.ts:44-45, src/test/app-test.ts:33-36
Caching with Google Cloud Datastore
Rendertron can use Google Cloud Datastore to cache successful render results. This feature is optional and must be explicitly enabled in the configuration.
Enabling Datastore Cache
To enable Datastore caching, the datastoreCache property must be set to true in the config.json file. When enabled, the Rendertron server initializes the DatastoreCache middleware.
Sources: README.md:111, src/rendertron.ts:48-51
| Configuration Option | Type | Default | Description |
|---|---|---|---|
datastoreCache | boolean | false | Set to true to enable caching with Google Datastore. |
Sources: README.md:111
The application includes the necessary Google Cloud client library as a dependency.
// package.json:28
"dependencies": {
"@google-cloud/datastore": "^1.4.2",
...
}
Sources: package.json:29
Caching Middleware Logic
The caching logic is implemented as Koa middleware. For each incoming render request, the middleware first checks Datastore for a cached entry corresponding to the request URL.
The following diagram illustrates the request flow when Datastore caching is enabled.
This diagram shows the sequence of operations for a request, from checking the cache to falling back to live rendering and updating the cache.
Sources: src/datastore-cache.ts:85-121
Key behaviors of the middleware:
- A cache key is generated from the full request URL.
- If a valid, non-expired entry exists, it is served immediately. The response includes an
x-rendertron-cachedheader with the timestamp of when the content was cached. - If no entry is found or the entry is expired, the request is passed to the next middleware (the renderer).
- Only successful responses (
status 200) from the renderer are cached. Other statuses are passed through without being cached.
Sources: src/datastore-cache.ts:85-121, src/test/datastore-cache-test.ts:114-121
Datastore Entity Schema
Cached pages are stored in Datastore as entities of the kind Page. The key for each entity is the full URL of the rendered request.
The structure of a cached item is defined by the CacheContent type.
// src/datastore-cache.ts:28-33
type CacheContent = {
saved: Date,
expires: Date,
headers: string,
payload: string,
};
Sources: src/datastore-cache.ts:28-33
The following diagram shows the Page entity structure.
This diagram outlines the fields stored for each cached page in Google Cloud Datastore.
Sources: src/datastore-cache.ts:60-77
| Field | Type | Description | Indexed |
|---|---|---|---|
saved | Date | The date and time when the entry was saved. | Yes |
expires | Date | The date and time when the cache entry expires (24 hours after saving). | Yes |
headers | string | A JSON string representing the HTTP headers of the original response. | No |
payload | string | A JSON string representing the response body, which may be a Buffer. | No |
Sources: src/datastore-cache.ts:60-77
Local Development with Datastore Emulator
To facilitate development and testing without connecting to a live GCP project, the repository provides scripts to use the local Google Cloud Datastore emulator.
The package.json file contains scripts to start the emulator and run tests against it.
| Script | Description |
|---|---|
start-emulator | Starts the Datastore emulator on the local machine. |
test-cache | Runs the start-emulator script, sets the GCLOUD_PROJECT environment variable, and executes the cache tests. |
Sources: package.json:20-21
The test-cache script demonstrates the required setup for using the emulator:
# package.json:21
"test-cache": "npm run start-emulator && $(gcloud beta emulators datastore env-init) && export GCLOUD_PROJECT='emulator-project' && ava build/test/datastore-cache-test.js"
This workflow is crucial for verifying the caching logic in a controlled, local environment before deployment.
Sources: package.json:21, src/test/datastore-cache-test.ts