A modern, dual-environment SSR frontend for FreshmenFest 2025 built with Astro, deployed on Google Cloud Platform with automatic CI/CD.
URL: https://freshmenfest2025.com
freshmenfest2025.com β Load Balancer
βββ /api/* β Cloud Run (Backend) - strips /api prefix
βββ /_astro/* β Cloud Storage Bucket (CDN)
βββ /images/* β Cloud Storage Bucket (CDN)
βββ /* β Cloud Run (Astro SSR Frontend)
URL: https://dev.freshmenfest2025.com
dev.freshmenfest2025.com β Load Balancer
βββ /api/* β Cloud Run (Backend) - strips /api prefix
βββ /_astro/* β Cloud Storage Bucket (CDN)
βββ /images/* β Cloud Storage Bucket (CDN)
βββ /* β Cloud Run (Astro SSR Frontend)
- Framework: Astro with SSR
- Styling: Tailwind CSS
- Runtime: Node.js 20
- Package Manager: pnpm
- Deployment: Google Cloud Run + Cloud Storage
- CI/CD: GitHub Actions (Dual Environment)
feature/new-feature β dev (PR + review) β Auto-deploy to dev.freshmenfest2025.com
β
dev β main (PR + approval) β Auto-deploy to freshmenfest2025.com
main
β Production (requires manual approval)dev
β Development (team can merge)feature/*
β Feature branches
- Node.js 20 or later
- pnpm
- Git
# Clone and setup
git clone <repository-url>
cd fdrpkm68-frontend
pnpm install
# Copy environment template
cp .env.example .env.local
# Start development (with backend proxy)
pnpm dev
Local URLs:
- Frontend: http://localhost:4321
- API Proxy: http://localhost:4321/api/_ β http://localhost:8080/_
Command | Action |
---|---|
pnpm dev |
Start dev server with API proxy |
pnpm build |
Build for production |
pnpm preview |
Preview production build |
pnpm astro ... |
Run Astro CLI commands |
# Frontend runs on :4321, API proxy forwards to :8080
PUBLIC_API_URL=http://localhost:4321/api
PUBLIC_SITE_URL=http://localhost:4321
NODE_ENV=development
# Production secrets
PROD_API_URL=https://freshmenfest2025.com/api
PROD_SITE_URL=https://freshmenfest2025.com
# Shared secrets
GCP_PROJECT_ID=your-project-id
GCP_SA_KEY={service account JSON}
src/
βββ components/
β βββ common/ # Shared components (Header, Footer)
β βββ firstdate/ # First Date specific components
β βββ rpkm/ # RPKM specific components
βββ layouts/
β βββ MainLayout.astro # Main page layout
βββ lib/
β βββ api.ts # API utilities (USE THIS!)
βββ pages/
β βββ api/ # Internal API routes only
β βββ *.astro # Page components
βββ styles/
βββ global.css # Global styles only
// β
CORRECT - Always use /api prefix
await fetch("/api/register");
await fetch("/api/events");
// β WRONG - Never omit /api prefix
await fetch("/register");
// β
CORRECT - No /api prefix in backend
app.post("/register", handler);
app.get("/events", handler);
// β WRONG - Don't include /api in backend
app.post("/api/register", handler);
# β
CORRECT - Images location
public/images/logo.png
public/images/events/event1.jpg
# β
CORRECT - Image references
<img src="/images/logo.png" alt="Logo" />
import { api } from '@/lib/api';
// GET request
const { data, error } = await api.get('/users');
// POST request
const result = await api.post('/register', userData);
// Error handling
if (error) {
console.error('API Error:', error);
return;
}
- Push to
dev
β Auto-deploy todev.freshmenfest2025.com
- Push to
main
β Auto-deploy tofreshmenfest2025.com
# 1. Develop on feature branch
git checkout -b feature/new-feature
# 2. Create PR to dev branch
gh pr create --base dev --head feature/new-feature
# 3. After review, merge to dev
# β Auto-deploys to dev.freshmenfest2025.com
# 4. When ready for production
gh pr create --base main --head dev --title "Deploy to Production"
# 5. After approval, merge to main
# β Auto-deploys to freshmenfest2025.com
- Development: https://dev.freshmenfest2025.com
- Production: https://freshmenfest2025.com
- Local: http://localhost:4321
- Health Endpoint:
/api/health
- Development Logs: GitHub Actions β dev deployment
- Production Logs: GitHub Actions β main deployment
- GCP Monitoring: Cloud Run console
- Environment Separation: Complete isolation between dev/prod
- Secret Management: GitHub Secrets for production
- Service Account: Minimal GCP permissions
- HTTPS Only: All environments enforce HTTPS
- Container Security: Non-root user, minimal attack surface
- β Dual Environment: Automatic dev/prod deployment
- β API Prefix Stripping: Load balancer handles routing
- β Static Asset CDN: Global content delivery
- β SSR Capabilities: Dynamic content with SEO benefits
- β Vite Proxy: Seamless local development
- β TypeScript: Full type safety
- β Tailwind CSS: Utility-first styling
- DEVELOPER_GUIDELINES.md - MANDATORY coding standards
- DEPLOYMENT.md - Detailed deployment setup
- GCP Setup Guide - Infrastructure configuration
Before creating any PR, ensure:
- Read DEVELOPER_GUIDELINES.md
- Code follows naming conventions
- Frontend uses
/api
prefix for API calls - Backend routes have NO
/api
prefix - Images are in
/public/images/
-
pnpm build
passes successfully - TypeScript types are properly defined
- Targeting correct branch (
dev
for features)
- Read DEVELOPER_GUIDELINES.md (mandatory)
- Create feature branch from
dev
- Follow all coding conventions
- Test locally with
pnpm build
- Create PR targeting
dev
branch - Address review feedback
- Merge triggers auto-deployment
This project is licensed under the MIT License.
- Check DEVELOPER_GUIDELINES.md first
- Review error messages carefully
- Test with
pnpm build
locally - Ask in team chat if stuck
Remember: Frontend uses /api
, Backend doesn't! π