Skip to content

Asset serving

Warning

This section is unfinished. The Rapid section is complete; the other diagrams are up to date, but do not yet have textual explanations.

Legend

GitHubCloudflareGoogle CloudVirtual MachineOther
GitHubCloudflareGoogle CloudVirtual MachineOther

Overview

userRapidMaps Metadatahttps://maps-metadata.beyondallreason.dev/ Cloudflare worker serving data from R2 bucket https://github.com/beyond-all-reason/maps-metadata/tree/main/cloud/servingError Logshttps://log.beyondallreason.dev/ Source: https://github.com/beyond-all-reason/logs-uploadLauncher Confighttps://launcher-config.beyondallreason.dev/config.json Source: https://github.com/p2004a/spring-launcher-config-srvFileshttps://files-cdn.beyondallreason.dev/ Source: https://github.com/beyond-all-reason/maps-hostingPoolHosts only https://pool-init.beyondallreason.dev/data.7zRowyhttps://rowy.beyondallreason.dev/ Our own deployment of Rowy with custom patches as Firebase app on GCP. There is also a bunch of small services there to support syncing, inside https://github.com/beyond-all-reason/maps-metadata/tree/main/cloudMaps MetadataPool package buildChobbySPADS ConfigGoogle Drive MapsMain WebsiteWhat is hosted on https://www.beyondallreason.info/maps Build using WebflowworkerworkerworkerR2R2 MetadataR2 ImagesKVR2 readreadImage transformread/writeread/writesync single mapsave imagesreadwritePush commitPush commitPush metadataSync mapsPullPush dist_cfg/config.jsonhttps://maps-metadata.beyondallreason.dev/ Cloudflare worker serving data from R2 bucket https://github.com/beyond-all-reason/maps-metadata/tree/main/cloud/serving https://log.beyondallreason.dev/ Source: https://github.com/beyond-all-reason/logs-upload https://launcher-config.beyondallreason.dev/config.json Source: https://github.com/p2004a/spring-launcher-config-srv https://files-cdn.beyondallreason.dev/ Source: https://github.com/beyond-all-reason/maps-hosting Hosts only https://pool-init.beyondallreason.dev/data.7z https://rowy.beyondallreason.dev/ Our own deployment of Rowy with custom patches as Firebase app on GCP. There is also a bunch of small services there to support syncing, inside https://github.com/beyond-all-reason/maps-metadata/tree/main/cloud What is hosted on https://www.beyondallreason.info/maps Build using Webflow
userRapidMaps Metadatahttps://maps-metadata.beyondallreason.dev/ Cloudflare worker serving data from R2 bucket https://github.com/beyond-all-reason/maps-metadata/tree/main/cloud/servingError Logshttps://log.beyondallreason.dev/ Source: https://github.com/beyond-all-reason/logs-uploadLauncher Confighttps://launcher-config.beyondallreason.dev/config.json Source: https://github.com/p2004a/spring-launcher-config-srvFileshttps://files-cdn.beyondallreason.dev/ Source: https://github.com/beyond-all-reason/maps-hostingPoolHosts only https://pool-init.beyondallreason.dev/data.7zRowyhttps://rowy.beyondallreason.dev/ Our own deployment of Rowy with custom patches as Firebase app on GCP. There is also a bunch of small services there to support syncing, inside https://github.com/beyond-all-reason/maps-metadata/tree/main/cloudMaps MetadataPool package buildChobbySPADS ConfigGoogle Drive MapsMain WebsiteWhat is hosted on https://www.beyondallreason.info/maps Build using WebflowworkerworkerworkerR2R2 MetadataR2 ImagesKVR2 readreadImage transformread/writeread/writesync single mapsave imagesreadwritePush commitPush commitPush metadataSync mapsPullPush dist_cfg/config.jsonhttps://maps-metadata.beyondallreason.dev/ Cloudflare worker serving data from R2 bucket https://github.com/beyond-all-reason/maps-metadata/tree/main/cloud/serving https://log.beyondallreason.dev/ Source: https://github.com/beyond-all-reason/logs-upload https://launcher-config.beyondallreason.dev/config.json Source: https://github.com/p2004a/spring-launcher-config-srv https://files-cdn.beyondallreason.dev/ Source: https://github.com/beyond-all-reason/maps-hosting Hosts only https://pool-init.beyondallreason.dev/data.7z https://rowy.beyondallreason.dev/ Our own deployment of Rowy with custom patches as Firebase app on GCP. There is also a bunch of small services there to support syncing, inside https://github.com/beyond-all-reason/maps-metadata/tree/main/cloud What is hosted on https://www.beyondallreason.info/maps Build using Webflow

Files

userFileshttps://files-cdn.beyondallreason.dev/ Source: https://github.com/beyond-all-reason/maps-hostingSpringFilesFilesRecoil EngineworkerR2 Assets3 buckets geographically distributes across North America, Europe, and Asia.KVCache PubSubCacherMaps Upload BucketMappers have permission to directly put new map files there via web interface to upload them to CDN. https://console.cloud.google.com/storage/browser/bar-springfiles-syncer_assets-upload readreadsyncfallback lookupPubSub Upload triggertriggerwritewritereaddownload releasereadNew releasehttps://files-cdn.beyondallreason.dev/ Source: https://github.com/beyond-all-reason/maps-hosting 3 buckets geographically distributes across North America, Europe, and Asia. Mappers have permission to directly put new map files there via web interface to upload them to CDN. https://console.cloud.google.com/storage/browser/bar-springfiles-syncer_assets-upload
userFileshttps://files-cdn.beyondallreason.dev/ Source: https://github.com/beyond-all-reason/maps-hostingSpringFilesFilesRecoil EngineworkerR2 Assets3 buckets geographically distributes across North America, Europe, and Asia.KVCache PubSubCacherMaps Upload BucketMappers have permission to directly put new map files there via web interface to upload them to CDN. https://console.cloud.google.com/storage/browser/bar-springfiles-syncer_assets-upload readreadsyncfallback lookupPubSub Upload triggertriggerwritewritereaddownload releasereadNew releasehttps://files-cdn.beyondallreason.dev/ Source: https://github.com/beyond-all-reason/maps-hosting 3 buckets geographically distributes across North America, Europe, and Asia. Mappers have permission to directly put new map files there via web interface to upload them to CDN. https://console.cloud.google.com/storage/browser/bar-springfiles-syncer_assets-upload

Rapid

Rapid is the format and protocol that the client uses to download game versions. A repo contains content-addressed files, packages that list the files in each version, and a versions.gz file that maps tags such as byar:test to those packages. Clients (pr-downloader) start with the repos.gz master list of repos and then fetch only the files they do not already have.

userBunnyRapid repos are served to players from https://repos-cdn.beyondallreason.dev/. The CDN is provided by https://bunny.net/.Rapid Hosting ServerDebian host managed with the Ansible playbook at https://github.com/beyond-all-reason/rapid-hosting. The host is shared with the SPADS setup. All services run as Podman quadlets.GitHub ActionsA workflow in the game repo calls the composite action to request a build and stream its log. The action retries transient failures. Source: https://github.com/beyond-all-reason/rapid-hosting/tree/main/actionGitHub OIDC Providerhttps://token.actions.githubusercontent.com The workflow's token is the only credential. GitHub and the builder do not share any secrets.BYAR-ChobbyBeyond-All-ReasonPull Zonehttps://repos-cdn.beyondallreason.dev/ The repos.gz master list is maintained directly in the storage zone. The builder does not write it.Storage ZoneHolds the pool, packages, versions.gz, and fresh copies for every repo. It is the origin for the pull zone.CaddyTerminates TLS for https://repos.beyondallreason.dev/, serves the store as the origin for the repos, and reverse-proxies /build to the builder without buffering the response.rapid-builderHTTP service that builds Rapid packages on request and publishes them to Bunny. It verifies the OIDC token, evaluates the repo's CEL policy, and serializes builds for each repo. Source: https://github.com/beyond-all-reason/rapid-hosting/tree/main/rapid-builderrapid-buildgitTool that converts a Git checkout to Rapid format and incrementally updates the local store. Part of https://github.com/beyond-all-reason/RapidToolsRapid StoreGit CheckoutsEdge RuleRedirects a repo's versions.gz to the unique fresh copy uploaded by the last build. This works around Bunny storage replication lag. Edge rule changes propagate globally within a minute, but newly uploaded files do not. Download packagesoriginPOST /buildreadfetch commitinvokereadreadwriteUpload pool, packages,and versions.gz (rclone)Upload a fresh copy andupdate the ruleTrigger workflowTrigger workflowMint tokenPOST /build (OIDC token)Verify tokenFetch commitFetch commitRapid repos are served to players from https://repos-cdn.beyondallreason.dev/. The CDN is provided by https://bunny.net/. Debian host managed with the Ansible playbook at https://github.com/beyond-all-reason/rapid-hosting. The host is shared with the SPADS setup. All services run as Podman quadlets. A workflow in the game repo calls the composite action to request a build and stream its log. The action retries transient failures. Source: https://github.com/beyond-all-reason/rapid-hosting/tree/main/action https://token.actions.githubusercontent.com The workflow's token is the only credential. GitHub and the builder do not share any secrets. https://repos-cdn.beyondallreason.dev/ The repos.gz master list is maintained directly in the storage zone. The builder does not write it. Holds the pool, packages, versions.gz, and fresh copies for every repo. It is the origin for the pull zone. Terminates TLS for https://repos.beyondallreason.dev/, serves the store as the origin for the repos, and reverse-proxies /build to the builder without buffering the response. HTTP service that builds Rapid packages on request and publishes them to Bunny. It verifies the OIDC token, evaluates the repo's CEL policy, and serializes builds for each repo. Source: https://github.com/beyond-all-reason/rapid-hosting/tree/main/rapid-builder Tool that converts a Git checkout to Rapid format and incrementally updates the local store. Part of https://github.com/beyond-all-reason/RapidTools Redirects a repo's versions.gz to the unique fresh copy uploaded by the last build. This works around Bunny storage replication lag. Edge rule changes propagate globally within a minute, but newly uploaded files do not.
userBunnyRapid repos are served to players from https://repos-cdn.beyondallreason.dev/. The CDN is provided by https://bunny.net/.Rapid Hosting ServerDebian host managed with the Ansible playbook at https://github.com/beyond-all-reason/rapid-hosting. The host is shared with the SPADS setup. All services run as Podman quadlets.GitHub ActionsA workflow in the game repo calls the composite action to request a build and stream its log. The action retries transient failures. Source: https://github.com/beyond-all-reason/rapid-hosting/tree/main/actionGitHub OIDC Providerhttps://token.actions.githubusercontent.com The workflow's token is the only credential. GitHub and the builder do not share any secrets.BYAR-ChobbyBeyond-All-ReasonPull Zonehttps://repos-cdn.beyondallreason.dev/ The repos.gz master list is maintained directly in the storage zone. The builder does not write it.Storage ZoneHolds the pool, packages, versions.gz, and fresh copies for every repo. It is the origin for the pull zone.CaddyTerminates TLS for https://repos.beyondallreason.dev/, serves the store as the origin for the repos, and reverse-proxies /build to the builder without buffering the response.rapid-builderHTTP service that builds Rapid packages on request and publishes them to Bunny. It verifies the OIDC token, evaluates the repo's CEL policy, and serializes builds for each repo. Source: https://github.com/beyond-all-reason/rapid-hosting/tree/main/rapid-builderrapid-buildgitTool that converts a Git checkout to Rapid format and incrementally updates the local store. Part of https://github.com/beyond-all-reason/RapidToolsRapid StoreGit CheckoutsEdge RuleRedirects a repo's versions.gz to the unique fresh copy uploaded by the last build. This works around Bunny storage replication lag. Edge rule changes propagate globally within a minute, but newly uploaded files do not. Download packagesoriginPOST /buildreadfetch commitinvokereadreadwriteUpload pool, packages,and versions.gz (rclone)Upload a fresh copy andupdate the ruleTrigger workflowTrigger workflowMint tokenPOST /build (OIDC token)Verify tokenFetch commitFetch commitRapid repos are served to players from https://repos-cdn.beyondallreason.dev/. The CDN is provided by https://bunny.net/. Debian host managed with the Ansible playbook at https://github.com/beyond-all-reason/rapid-hosting. The host is shared with the SPADS setup. All services run as Podman quadlets. A workflow in the game repo calls the composite action to request a build and stream its log. The action retries transient failures. Source: https://github.com/beyond-all-reason/rapid-hosting/tree/main/action https://token.actions.githubusercontent.com The workflow's token is the only credential. GitHub and the builder do not share any secrets. https://repos-cdn.beyondallreason.dev/ The repos.gz master list is maintained directly in the storage zone. The builder does not write it. Holds the pool, packages, versions.gz, and fresh copies for every repo. It is the origin for the pull zone. Terminates TLS for https://repos.beyondallreason.dev/, serves the store as the origin for the repos, and reverse-proxies /build to the builder without buffering the response. HTTP service that builds Rapid packages on request and publishes them to Bunny. It verifies the OIDC token, evaluates the repo's CEL policy, and serializes builds for each repo. Source: https://github.com/beyond-all-reason/rapid-hosting/tree/main/rapid-builder Tool that converts a Git checkout to Rapid format and incrementally updates the local store. Part of https://github.com/beyond-all-reason/RapidTools Redirects a repo's versions.gz to the unique fresh copy uploaded by the last build. This works around Bunny storage replication lag. Edge rule changes propagate globally within a minute, but newly uploaded files do not.

Serving

Players download repos from https://repos-cdn.beyondallreason.dev/, a Bunny pull zone backed by a Bunny storage zone. The builder writes <repo>/pool, <repo>/packages, and <repo>/versions.gz to the storage zone. Players communicate only with the CDN. The repos.gz master list is maintained manually in the storage zone, not by the builder, so it can list repos that are no longer built.

Replication from the storage zone to the edge regions lags behind writes. Immediately after a build, the CDN can therefore serve a stale versions.gz, causing clients to fetch a version that is no longer current. To avoid this, each build uploads the same file under a unique name, <repo>/fresh/versions_<stamp>.gz, because new files are visible in edge locations immediately. It waits until the CDN serves that copy and then updates an edge rule to redirect <repo>/versions.gz to it. Edge rule changes propagate globally within a minute.

Building

Builds run on a single server managed by the rapid-hosting Ansible playbook. The server also hosts one of the SPADS instances, and all services run as Podman quadlets. Two services are involved:

  • Caddy terminates TLS, serves the builder's store as the origin for the repos at https://repos.beyondallreason.dev/, and reverse-proxies /build to the builder without buffering as required by the build API.
  • rapid-builder is an HTTP service that builds and publishes a commit on request: it runs rapid-buildgit from RapidTools and uploads the result to Bunny. It keeps a Git clone and a Rapid store for each repo, so a build processes only changed content. See its README for a single build step by step.

A GitHub Actions workflow in the game repository triggers a build by calling the composite action from the same repo. The action sends the workflow's OIDC token to /build, so GitHub and the server do not share a secret. What a repo may publish is decided by a CEL policy defined in the playbook's group variables, see the authorization docs. Currently, a push to stable in Beyond-All-Reason publishes byar:test; a manual run on master publishes byar:pr-<number> or byar:br-<name>; and a push to master in BYAR-Chobby publishes byar-chobby:test.

The builder sends its metrics and logs to the monitoring server.

Rowy

userMaps Metadatahttps://maps-metadata.beyondallreason.dev/ Cloudflare worker serving data from R2 bucket https://github.com/beyond-all-reason/maps-metadata/tree/main/cloud/servingRowyhttps://rowy.beyondallreason.dev/ Our own deployment of Rowy with custom patches as Firebase app on GCP. There is also a bunch of small services there to support syncing, inside https://github.com/beyond-all-reason/maps-metadata/tree/main/cloudMaps MetadataworkerR2 MetadataR2 ImagesImagorFrontendFirebase frontend, https://rowy.beyondallreason.dev/FirestoreMap ParserGithub TriggerUploaded Assets BucketParsed Maps Bucket readreadImage transformread/writereadread/writeinvokeinvokewritereadreadwritesync single mapPush metadataPullhttps://maps-metadata.beyondallreason.dev/ Cloudflare worker serving data from R2 bucket https://github.com/beyond-all-reason/maps-metadata/tree/main/cloud/serving https://rowy.beyondallreason.dev/ Our own deployment of Rowy with custom patches as Firebase app on GCP. There is also a bunch of small services there to support syncing, inside https://github.com/beyond-all-reason/maps-metadata/tree/main/cloud Firebase frontend, https://rowy.beyondallreason.dev/
userMaps Metadatahttps://maps-metadata.beyondallreason.dev/ Cloudflare worker serving data from R2 bucket https://github.com/beyond-all-reason/maps-metadata/tree/main/cloud/servingRowyhttps://rowy.beyondallreason.dev/ Our own deployment of Rowy with custom patches as Firebase app on GCP. There is also a bunch of small services there to support syncing, inside https://github.com/beyond-all-reason/maps-metadata/tree/main/cloudMaps MetadataworkerR2 MetadataR2 ImagesImagorFrontendFirebase frontend, https://rowy.beyondallreason.dev/FirestoreMap ParserGithub TriggerUploaded Assets BucketParsed Maps Bucket readreadImage transformread/writereadread/writeinvokeinvokewritereadreadwritesync single mapPush metadataPullhttps://maps-metadata.beyondallreason.dev/ Cloudflare worker serving data from R2 bucket https://github.com/beyond-all-reason/maps-metadata/tree/main/cloud/serving https://rowy.beyondallreason.dev/ Our own deployment of Rowy with custom patches as Firebase app on GCP. There is also a bunch of small services there to support syncing, inside https://github.com/beyond-all-reason/maps-metadata/tree/main/cloud Firebase frontend, https://rowy.beyondallreason.dev/