|
| 1 | +# Nginx Rewrite Service |
| 2 | + |
| 3 | +Simple nginx-based static file server for the developers portal under the `/developers` path. |
| 4 | + |
| 5 | +## Background |
| 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. |
| 8 | + |
| 9 | +## What it does |
| 10 | + |
| 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 |
| 16 | + |
| 17 | +## Building and deploying |
| 18 | + |
| 19 | +Deployment happens automatically via GitHub Actions when changes are merged to `main`: |
| 20 | + |
| 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 | + |
| 26 | +Manual deployment: |
| 27 | + |
| 28 | +```bash |
| 29 | +cd ci/nginx-rewrite |
| 30 | + |
| 31 | +# Build the container (fetches from GCS during build) |
| 32 | +gcloud builds submit --tag gcr.io/interledger-websites/nginx-rewrite:latest . |
| 33 | + |
| 34 | +# Deploy to Cloud Run |
| 35 | +gcloud run deploy nginx-rewrite \ |
| 36 | + --image gcr.io/interledger-websites/nginx-rewrite:latest \ |
| 37 | + --platform managed \ |
| 38 | + --region us-central1 \ |
| 39 | + --allow-unauthenticated \ |
| 40 | + --port 8080 \ |
| 41 | + --memory 512Mi \ |
| 42 | + --cpu 1 \ |
| 43 | + --min-instances 0 \ |
| 44 | + --max-instances 10 |
| 45 | +``` |
| 46 | + |
| 47 | +## How it works |
| 48 | + |
| 49 | +### Multi-stage Docker build |
| 50 | + |
| 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) |
| 57 | + |
| 58 | +### Nginx configuration |
| 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) |
| 66 | + |
| 67 | +## Architecture |
| 68 | + |
| 69 | +``` |
| 70 | +GitHub Actions (on push to main) |
| 71 | + ↓ |
| 72 | + 1. Build Astro site |
| 73 | + 2. Sync to GCS bucket |
| 74 | + 3. Build container (fetches from GCS) |
| 75 | + 4. Deploy to Cloud Run |
| 76 | + ↓ |
| 77 | +Load Balancer (staging.interledger.org) |
| 78 | + ↓ |
| 79 | + /developers → nginx-rewrite Cloud Run service |
| 80 | + ↓ |
| 81 | + Serves baked-in static files |
| 82 | +``` |
0 commit comments