Core Web Stack

Unlike applications that live only on the Web, WWT has an installed base of Windows clients some of which are more than a decade old. Some of those Windows clients are installed at planetariums or museums that are using WWT in public-facing exhibits but, generally speaking, very reluctant to experiment with their technology infrastructure. Therefore, it is extremely important to preserve the detailed behavior of the WWT web API endpoints used by the historical clients.

What makes this requirement a bit tricky is that the historical WWT web API endpoints are served off of the domain, the same domain that is used to host the webclient (at, the Communities service, and user-facing web pages. In principle, we might like to use different web server frameworks for each of these components of the WWT web presence. However, web requests to the same domain name must all be handled by the same server(s) as seen by the public internet.

Azure Application GatewayπŸ”—

Until April of 2020, traffic to was all handled by a pair of virtual machines running a customized ASP.NET setup on IIS 8.5 that dealt with all forms of traffic to the domain. Deployment was manual, seriously bottlenecking development due to the aforementioned importance of keeping the core WWT data services highly reliable.

As of April 2020, traffic to the flagship domain is handled by an Azure Application Gateway frontend, a "layer 7" load balancer and reverse proxy that can redirect traffic to different web server backends based on the URL path requested. This is the core capability that allows us to begin sharding out requests to the domain to different servers depending on the service being requested.

Furthermore, the app gateway acts as a TLS termination proxy, such that it can handle HTTPS traffic while the communication to the data backends can use plain HTTP, which is valuable since the data requests take the form of many small HTTP requests. Before April 2020, the flagship domain did not support HTTPS due to the configuration challenge and worries about the load that TLS processing would add to the core data VMs.

Web Backends on the Flagship DomainπŸ”—

Since the transition to the App Gateway deployment model, requests to may be served by one of five backends.

Note that the classic website treated paths case-insensitively; that is, /wwtweb/ and /WWTWeb/ were routed identically. The App Gateway routing infrastructure is also case-insensitive, but the Linux-based backends and the Azure Storage static files website are case sensitive.

CORS/TLS proxy backendπŸ”—

Requests to /webserviceproxy.aspx and /wwtweb/webserviceproxy.aspx are used by the web client to proxy requests that would otherwise be forbidden by the user’s web browser because of either CORS or mixed content restrictions.

These requests are handled by a small server running Squid inside a Docker container. The assets to create the container are in the repository wwt-squid-proxy. Merges to the master branch of that repository trigger a continuous deployment pipeline that updates the Docker image published as aasworldwidetelescope/proxy. Finally, the WWT Azure infrastructure includes an App Service named wwtproxy that runs that Docker image, including hot-reloads when the image is updated. The App Gateway routes proxy requests to the wwtproxy App Service.

nginx utility serverπŸ”—

Requests to the /docs prefix and the path /webclient β€” but not /webclient/ or any paths below it β€” are handled by a utility nginx server, since it can easily be configured to issue both server-side redirects and simple static content.

The infrastructure for this utility server mirrors that of the CORS/TLS proxy. The container assets are tracked in the repository wwt-nginx-core. Merges to master trigger a CD pipeline that publishes a built Docker image as aasworldwidetelescope/nginx-core. In the WWT Azure infrastructure, an App Service named wwtnginxcore-prod runs a server based on that Docker image with automatic reload when the image is updated.

The nginx utility server also services requests and redirects for miscellaneous WWT domains of mainly historical interest. See the README and configuration file in wwt-nginx-core for details.

IIS/ASP.NET "user" website serverπŸ”—

When we refer to the core or flagship β€œuser” website, we mean the mostly-static user-facing content accessible through the portal at

At the moment, this website is an ASP.NET application whose source is tracked in, and continuously deployed from, the repository wwt-user-website. Work is underway to refresh this content and switch to a static site generator backend. As such, the documentation of this framework will stop here.

Static content backendπŸ”—

Much of the content served by consists of static file content. Since the infrastructure rebuild of April 2020, that includes the web client AngularJS application (URL paths /webclient/*) as well as miscellaneous data files in paths such as /data/* and /images/*.

Requests for this content are routed by the App Gateway to an Azure storage account with the static website hosting feature enabled. In the WWT Azure services, this storage account is named wwtwebstatic. Updates to this content are deployed by uploading new files to the Azure storage account, which can be (and is) automated in continuous deployment pipelines for version-controlled assets.

Legacy virtual machinesπŸ”—

All web requests not handled by any of the other backends are routed to the legacy Windows Server 2012R2 virtual machines. This includes important elements of the WWT web services such as:

  • Data and other services at URL paths /wwtweb/*
  • The entire Communities web service
  • Requests to the root path /, required by the way that App Gateway works

The sources to these web backends are nominally tracked in the repository wwt-website. However, due to the manual deployment process required by these VMs, the actual assets running in production and the source repository have diverged somewhat. Work is underway to understand and minimize this divergence, as well as to migrate the infrastructure to a system whose deployment can be fully automated.

Further note that the production deployment includes configuration files containing various keys and connection strings that must be kept secret.

Web Client applicationπŸ”—

The WWT β€œweb client”, hosted at, is an AngularJS web application whose sources live in the repository wwt-web-client.

Since the April 2020 infrastructure upgrade, a more careful distinction has been made between the web client application and the WebGL engine library powering it. The two are certainly closely connected, but they are now tracked in separate repositories and released independently.

Merges to the master branch of the wwt-web-client repository are continuously deployed to a testing prefix,, by uploading built artifacts to the appropriate location in the wwtwebstatic Azure Storage account. Version-tagged releases are deployed to production through an analogous process. For more information, see the README in the source repository.

TLS CertificatesπŸ”—

As of the April 2020 infrastructure rebuild, the domain supports HTTPS via TLS termination at the App Gateway.

TLS certificates are supplied through Let’s Encrypt. Certificate requests and deployment are automated using an instance of the keyvault-acmebot application that runs on the WWT Azure services.

CDN FrontendπŸ”—

The core content served by the domain is also made available through a Content Distribution Network (CDN) associated with the domains and A request for the URL will yield identical results as a request for the URL, except that the response may hopefully arrive faster if the user is near one of the CDN point-of-presence nodes and it has already cached the relevant content.

Because this CDN frontend is expected to serve content for arbitrary URL paths at exposed by the origin, CDN requests must be routed through the Azure App Gateway load-balancer, imposing a minor efficiency cost (as well as a financial cost in App Gateway bandwidth charges). The vision is to start transitioning CDN-friendly WWT content to route through subdomains of the domain, which can be set up to avoid the overhead of routing through the App Gateway. A secondary advantage is that requests to a separate second-level-domain will not include the HTTP cookies set by the core domain, which can potentially increase the efficiency of the HTTP traffic. (We are told that this is why most major websites use a separate domain for their CDN traffic.)