Skip to main content

Hosting the Care frontend on GCS

This guide covers hosting the Care static frontend (a built care_fe) on Google Cloud Storage (GCS), fronted by Cloud CDN and a global external load balancer with managed SSL/TLS, Cloud DNS, and Cloud Monitoring.

info

GCS hosts only the static frontend — the compiled output of care_fe. The Care backend/API is a separate service and must be deployed elsewhere (for example on GKE or another provider). Point the frontend's API configuration at wherever that backend is reachable.

Architecture components

  • Google Cloud Storage — static file hosting for the built frontend
  • Cloud CDN — global content delivery and edge caching
  • Global load balancer — external traffic management
  • Managed SSL/TLS — secure HTTPS termination
  • Cloud DNS — domain management

Prerequisites

  1. A GCP project with billing enabled
  2. A domain name managed in Cloud DNS
  3. The Google Cloud SDK (gcloud, gsutil) installed and authenticated
  4. The required IAM permissions to create buckets, load balancers, certificates, and DNS records

Infrastructure

GCS bucket configuration

# Create bucket in specified region
gsutil mb -l asia-south1 gs://[BUCKET_NAME]

# Set public access permissions
gsutil iam ch allUsers:objectViewer gs://[BUCKET_NAME]

# Enable bucket versioning
gsutil versioning set on gs://[BUCKET_NAME]

CDN and load balancer setup

# Create backend bucket with CDN
gcloud compute backend-buckets create [BACKEND_BUCKET_NAME] \
--gcs-bucket-name=[BUCKET_NAME] \
--enable-cdn

# Configure URL map
gcloud compute url-maps create [URL_MAP_NAME] \
--default-backend-bucket=[BACKEND_BUCKET_NAME]

# Create HTTP proxy
gcloud compute target-http-proxies create [HTTP_PROXY_NAME] \
--url-map=[URL_MAP_NAME]

# Reserve global IP
gcloud compute addresses create [IP_ADDRESS_NAME] --global

SSL/TLS and forwarding rules

# Create SSL certificate
gcloud compute ssl-certificates create [SSL_CERT_NAME] \
--domains=[DOMAIN_NAME]

# Create HTTPS proxy
gcloud compute target-https-proxies create [HTTPS_PROXY_NAME] \
--url-map=[URL_MAP_NAME] \
--ssl-certificates=[SSL_CERT_NAME]

# Create forwarding rules
gcloud compute forwarding-rules create [HTTP_FORWARDING_RULE] \
--load-balancing-scheme=EXTERNAL \
--global \
--address=[IP_ADDRESS_NAME] \
--target-http-proxy=[HTTP_PROXY_NAME] \
--ports=80

gcloud compute forwarding-rules create [HTTPS_FORWARDING_RULE] \
--load-balancing-scheme=EXTERNAL \
--global \
--address=[IP_ADDRESS_NAME] \
--target-https-proxy=[HTTPS_PROXY_NAME] \
--ports=443

CORS setup

gsutil cors set '[
{
"origin": ["https://[DOMAIN_NAME]"],
"method": ["GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"],
"responseHeader": ["Content-Type", "Access-Control-Allow-Origin", "Access-Control-Allow-Methods", "Access-Control-Allow-Headers"],
"maxAgeSeconds": 3600
}
]' gs://[BUCKET_NAME]

Bucket security

# Set uniform bucket-level access
gsutil bucketiam set bucketpolicyonly:on gs://[BUCKET_NAME]

# Configure bucket encryption
gsutil bucketencryption set on gs://[BUCKET_NAME]

DNS configuration

  1. Get the load balancer IP:
gcloud compute addresses describe [IP_ADDRESS_NAME] --global --format="get(address)"
  1. Configure DNS records:
  • A record — point to the load balancer IP
  • AAAA record — for IPv6 support

Verification

# Verify bucket setup
gsutil ls -L gs://[BUCKET_NAME]

# Check SSL certificate
gcloud compute ssl-certificates describe [SSL_CERT_NAME]

# Test load balancer
curl -I https://[DOMAIN_NAME]

Deployment

Build the frontend

# Clone the repository
git clone https://github.com/ohcnetwork/care_fe.git
cd care_fe

# Install dependencies (a postinstall script runs automatically to
# install platform deps and generate headers)
npm install

# Build the application for production
npm run build
note

The care_fe package.json has no setup script. Running npm install automatically triggers the postinstall script, so no separate setup step is required. The production build is written to the dist/ directory — that is the directory you upload in the next step.

Upload build files

# Upload all build files
gsutil -m cp -r dist/* gs://[BUCKET_NAME]/

Cache-control configuration

# Dynamic content (no cache)
gsutil -m setmeta -h "Cache-Control:no-cache, no-store, must-revalidate" \
gs://[BUCKET_NAME]/service-worker.js \
gs://[BUCKET_NAME]/*.js.map

# HTML files (1 hour cache)
gsutil -m setmeta -h "Cache-Control:public, max-age=3600" \
gs://[BUCKET_NAME]/index.html \
gs://[BUCKET_NAME]/robots.txt

# Manifest files (1 day cache)
gsutil -m setmeta -h "Cache-Control:public, max-age=86400" \
gs://[BUCKET_NAME]/manifest.* \
gs://[BUCKET_NAME]/favicon.ico

# Static assets (1 year cache)
gsutil -m setmeta -h "Cache-Control:public, max-age=31536000" \
gs://[BUCKET_NAME]/static/* \
gs://[BUCKET_NAME]/assets/* \
gs://[BUCKET_NAME]/*.{js,css,png,svg,jpg}

Cache strategy

Content TypeCache DurationCache-Control Header
DynamicNo cacheno-cache, no-store, must-revalidate
HTML1 hourpublic, max-age=3600
Manifests1 daypublic, max-age=86400
Static1 yearpublic, max-age=31536000

Rollback

# 1. List available versions
gsutil ls -a gs://[BUCKET_NAME]

# 2. Restore specific version
gsutil cp -r gs://[BUCKET_NAME]@[TIMESTAMP]/* gs://[BUCKET_NAME]/

# 3. Invalidate CDN cache
gcloud compute url-maps invalidate-cdn-cache [URL_MAP_NAME] \
--path "/*"

Post-deployment verification

# Check website accessibility
curl -I https://[DOMAIN_NAME]

# Verify cache headers
curl -I https://[DOMAIN_NAME]/index.html
curl -I https://[DOMAIN_NAME]/static/js/main.js

# Check CDN status
gcloud compute backend-buckets describe [BACKEND_BUCKET_NAME]

Monitoring & operations

Cloud Monitoring configuration

# Enable monitoring service
gcloud services enable monitoring.googleapis.com

# Create monitoring workspace
gcloud monitoring workspaces create [WORKSPACE_NAME] \
--display-name="GCS Website Monitoring"

Key metrics

ComponentMetrics to Monitor
CDNCache hit ratio, Edge latency
Load BalancerRequest count, Response latency
StorageStorage usage, Egress costs

Troubleshooting

SSL/certificate issues

# Check certificate status
gcloud compute ssl-certificates describe [SSL_CERT_NAME]

# Verify domain mapping
gcloud compute target-https-proxies describe [HTTPS_PROXY_NAME]

# Update certificate
gcloud compute ssl-certificates create [SSL_CERT_NAME]-new \
--domains=[DOMAIN_NAME]

CDN/cache issues

# Check object metadata
gsutil stat gs://[BUCKET_NAME]/path/to/file

# Invalidate specific path
gcloud compute url-maps invalidate-cdn-cache [URL_MAP_NAME] \
--path "/static/*"

# Invalidate all cache
gcloud compute url-maps invalidate-cdn-cache [URL_MAP_NAME] \
--path "/*"

Access issues

# Check bucket permissions
gsutil iam get gs://[BUCKET_NAME]

# Update permissions
gsutil iam ch allUsers:objectViewer gs://[BUCKET_NAME]

# Test access
curl -I https://[DOMAIN_NAME]

Maintenance cadence

Daily

  • Monitor error rates
  • Check CDN performance
  • Review access logs

Weekly

  • Review cost metrics
  • Check SSL certificate status
  • Analyze traffic patterns

Monthly

  • Review IAM permissions
  • Update security policies
  • Optimize cache settings

Cost management

# Get current month's cost
gcloud billing accounts list

# View CDN usage
gcloud compute backend-buckets describe [BACKEND_BUCKET_NAME] \
--format="get(cdnPolicy)"

# Optimize storage class
gsutil rewrite -s STANDARD gs://[BUCKET_NAME]/**

Backup configuration

# Create backup script
cat > backup.sh <<EOF
#!/bin/bash
BACKUP_DATE=\$(date +%Y%m%d)
gsutil -m cp -r gs://[BUCKET_NAME] gs://[BACKUP_BUCKET]/\$BACKUP_DATE
gsutil lifecycle set lifecycle.json gs://[BACKUP_BUCKET]
EOF

# Configure retention policy
cat > lifecycle.json <<EOF
{
"rule": [
{
"action": {"type": "Delete"},
"condition": {"age": 30}
}
]
}
EOF