You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .github/copilot-instructions.md
+8-5Lines changed: 8 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,11 +22,14 @@ This is the Interledger Developers Portal, a documentation site built with [Astr
22
22
-**Important**: Build output is copied to `_netlify/builders/developers/` to serve at `/developers/` path
23
23
- Redirect rules route `/developers/*` to `/developers/index.html` for client-side routing
24
24
25
-
### Production (Google Cloud)
26
-
- Deployed to `https://interledger.org/developers/` via Google Cloud Storage
27
-
- Triggered automatically on merge to `main` by `.github/workflows/deploy_gcs.yml`
28
-
- Process: Build β Deploy to GCS β Rebuild nginx-rewrite Cloud Run service β Invalidate CDN
29
-
-**Legacy**: `deploy.yml` exists but is deprecated - use `deploy_gcs.yml`
25
+
### Production (Netlify, fronted by GCP)
26
+
- Built and hosted by Netlify at `https://interledger-org-developers.netlify.app/developers/`
27
+
- Users reach it at `https://interledger.org/developers/` via the GCP load balancer, which proxies `/developers/*` through a Cloud Run nginx service (`nginx-rewrite`) to Netlify
28
+
- The address bar stays on `interledger.org` β it is **not** a redirect
29
+
- GCP Cloud CDN sits in front of the proxy (default TTL 1 hour)
30
+
-**After a content deploy**, if you need changes live immediately, manually run the **Invalidate CDN** workflow in the Actions tab
31
+
- The `Deploy nginx proxy to Cloud Run` workflow (`.github/workflows/deploy_gcs.yml`) only rebuilds the proxy container and triggers on changes under `ci/nginx-rewrite/**`
32
+
- The nginx config itself lives in `ci/nginx-rewrite/` (Dockerfile + nginx.conf)
Simple nginx-based static file server for the developers portal under the `/developers` path.
3
+
Reverse-proxy running on Cloud Run that forwards `/developers/*` requests from the Interledger load balancer to the Netlify-hosted developers portal, while keeping the user's browser URL on `interledger.org` / `staging.interledger.org`.
4
4
5
5
## Background
6
6
7
-
Previously, this content was served from an AWS S3 bucket through AWS CloudFront CDN. After migrating to GCS, we encountered a significant limitation: the GCS CDN lacks CloudFront's intelligent URL rewriting capabilities, and automatic `index.html` serving doesn't come out of the box. The simplest solution was to host the content through nginx and handle all rewrite rules at the server level.
7
+
Historical progression:
8
+
9
+
1.**AWS S3 + CloudFront** β original setup.
10
+
2.**GCS + Cloud CDN** β after migrating to GCP. The GCS CDN lacked CloudFront-style URL rewriting and automatic `index.html` serving, so we introduced an nginx layer on Cloud Run to handle rewrite rules and serve baked-in static files.
11
+
3.**Netlify + Cloud Run nginx proxy (current)** β for project-management reasons the site is now built and hosted on Netlify. The same nginx service was repurposed as a thin reverse proxy so users still see `interledger.org/developers/...` in their address bar instead of a `netlify.app` URL.
8
12
9
13
## What it does
10
14
11
-
-Serves static files from the GCS bucket `gs://interledger-org-developers-portal/developers`
12
-
-Content is baked into the container image at build time (multi-stage Docker build)
13
-
-Handles index.html fallback for pretty URLs using `try_files`
14
-
-Redirects paths without trailing slash to the slash version for clean URLs
15
-
-Serves all content under `/developers/` path
15
+
-Receives `/developers/*` traffic from the GCP HTTPS load balancer (`nginx-rewrite-backend`).
16
+
-Proxies those requests to `https://interledger-org-developers.netlify.app`.
17
+
-Rewrites any absolute `Location` headers Netlify sends so redirects stay relative.
18
+
-Uses `absolute_redirect off` so nginx-issued redirects (e.g. `/developers` β `/developers/`) don't leak the internal `:8080` scheme/port.
19
+
-Exposes a `/health` endpoint for Cloud Run health checks.
16
20
17
-
## Building and deploying
21
+
The container contains **no site content** β everything is proxied live from Netlify.
18
22
19
-
Deployment happens automatically via GitHub Actions when changes are merged to `main`:
23
+
## Building and deploying
20
24
21
-
1. Site is built with Astro
22
-
2. Files are synced to `gs://interledger-org-developers-portal/developers`
23
-
3. Container is built (fetches content from GCS at build time)
24
-
4. New revision is deployed to Cloud Run
25
+
Deployment happens automatically via GitHub Actions when files under `ci/nginx-rewrite/**` change on `main`. It can also be triggered manually from the Actions tab (`Deploy nginx proxy to Cloud Run` workflow).
25
26
26
-
Manual deployment:
27
+
Manual deployment from a workstation:
27
28
28
29
```bash
29
30
cd ci/nginx-rewrite
30
31
31
-
# Build the container (fetches from GCS during build)
@@ -44,39 +45,38 @@ gcloud run deploy nginx-rewrite \
44
45
--max-instances 10
45
46
```
46
47
48
+
## CDN cache invalidation
49
+
50
+
The GCP load balancer in front of this service has Cloud CDN enabled on `nginx-rewrite-backend` (default TTL 1 hour). After a Netlify deploy, cached HTML may take up to an hour to refresh. To flush it immediately, run the `Invalidate CDN` workflow in the developers repo (or run `gcloud compute url-maps invalidate-cdn-cache interledger-org --path "/developers/*" --async`).
51
+
47
52
## How it works
48
53
49
-
### Multi-stage Docker build
54
+
### Dockerfile
50
55
51
-
1.**Stage 1 (fetcher)**: Uses `google/cloud-sdk:alpine` to fetch content from GCS
52
-
- Runs `gsutil rsync` to download `gs://interledger-org-developers-portal/developers/` to `/content/developers/`
53
-
2.**Stage 2 (nginx)**: Uses `nginx:alpine` to serve the content
54
-
- Copies content from stage 1
55
-
- Copies custom `nginx.conf`
56
-
- Runs as non-root user (Cloud Run requirement)
56
+
Single-stage `nginx:alpine` image with a custom `nginx.conf`. Runs as the non-root `nginx` user (Cloud Run requirement).
57
57
58
58
### Nginx configuration
59
59
60
-
Simple configuration in `nginx.conf`:
61
-
62
-
-**Root**: `/usr/share/nginx/html` (contains the `developers/` folder)
63
-
-**Location `/developers/`**: Uses `try_files $uri $uri/ $uri/index.html =404` for index fallback
64
-
-**Location `= /developers`**: 301 redirect to `/developers/` for consistency
65
-
-**absolute_redirect off**: Ensures redirects use relative paths (important for load balancer)
60
+
-**`location /developers/`**: `proxy_pass` to Netlify with `Host` header override and `proxy_ssl_server_name on` for correct SNI.
61
+
-**`location = /developers`**: 301 redirect to `/developers/`.
62
+
-**`absolute_redirect off`**: makes redirects relative so the public hostname/scheme from the load balancer is preserved.
63
+
-**`proxy_redirect`**: rewrites any absolute Netlify URLs in response `Location` headers back to relative paths.
0 commit comments