{"id":31585044,"url":"https://github.com/nathanfox/nginx-dev-gateway","last_synced_at":"2026-05-06T00:39:55.929Z","repository":{"id":317586220,"uuid":"1063288321","full_name":"nathanfox/nginx-dev-gateway","owner":"nathanfox","description":"Lightweight NGINX-based API gateway for Kubernetes development - simplifies access to multiple services through a single kubectl port-forward","archived":false,"fork":false,"pushed_at":"2025-10-01T19:27:48.000Z","size":131,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"develop","last_synced_at":"2025-10-01T21:24:04.228Z","etag":null,"topics":["api-gateway","developer-tools","kubectl","kubernetes","microservices","nginx","port-forward","websocket"],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nathanfox.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"docs/roadmap.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"nathanfox"}},"created_at":"2025-09-24T12:24:50.000Z","updated_at":"2025-10-01T19:27:51.000Z","dependencies_parsed_at":"2025-10-01T21:24:07.514Z","dependency_job_id":"28611d48-fd51-47da-be8e-5482553390e4","html_url":"https://github.com/nathanfox/nginx-dev-gateway","commit_stats":null,"previous_names":["nathanfox/nginx-dev-gateway"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/nathanfox/nginx-dev-gateway","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nathanfox%2Fnginx-dev-gateway","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nathanfox%2Fnginx-dev-gateway/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nathanfox%2Fnginx-dev-gateway/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nathanfox%2Fnginx-dev-gateway/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nathanfox","download_url":"https://codeload.github.com/nathanfox/nginx-dev-gateway/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nathanfox%2Fnginx-dev-gateway/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278547778,"owners_count":26004772,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-05T02:00:06.059Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-gateway","developer-tools","kubectl","kubernetes","microservices","nginx","port-forward","websocket"],"created_at":"2025-10-06T01:26:44.043Z","updated_at":"2025-10-06T01:26:45.541Z","avatar_url":"https://github.com/nathanfox.png","language":"Shell","funding_links":["https://github.com/sponsors/nathanfox"],"categories":[],"sub_categories":[],"readme":"# NGINX Dev Gateway for Kubernetes\n\nA lightweight, namespace-aware NGINX-based API gateway for Kubernetes that enables developers to access multiple microservices through a single `kubectl port-forward` command.\n\n## What's New in v0.3.0\n\n🎉 **Major improvements for developer experience:**\n\n- **⚡ Hot Reload Without Restart**: Update routes without restarting pods - your port-forward stays alive!\n- **🔧 Configurable Port**: Default port changed to 8000 (configurable via `NGINX_PORT` env var) to avoid conflicts with common dev tools\n- **🎨 Path Stripping Control**: New `--strip-prefix` / `--no-strip-prefix` flags for `discover-routes` with clear documentation in generated files\n- **🐛 Bug Fixes**:\n  - Route template processing now works correctly with `${CURRENT_NAMESPACE}` substitution\n  - NGINX access logs now show proper values (envsubst no longer breaks NGINX variables)\n  - ConfigMap changes sync instantly via annotation-based forcing\n\n**Breaking Changes:**\n- Default port changed from 8080 → 8000 (update your port-forward commands)\n- Route ConfigMap key changed to `.template` extension (re-run `update-routes` to migrate)\n\n## Features\n\n- 🚀 **Single Entry Point**: One `kubectl port-forward` to access all services\n- 🎯 **Path-Based Routing**: Route requests based on URL paths (`/api/service` → `service`)\n- 🔍 **Namespace-Aware**: Automatically routes to services in the same namespace, with support for cross-namespace routing\n- 🔄 **WebSocket Support**: Full WebSocket protocol support for real-time applications\n- 📝 **ConfigMap-Based Configuration**: Easy route management through Kubernetes ConfigMaps\n- 🏃 **Lightweight**: Alpine-based image (~15MB) with minimal resource usage\n- 🛠️ **Developer-Friendly**: Simple management script for all operations\n\n## Quick Start\n\n### Prerequisites\n\n- Kubernetes cluster (local or remote)\n- `kubectl` configured and connected to your cluster\n- Docker (for building the image)\n\n### 1. Build the Docker Image\n\n```bash\n./manage.sh build\n```\n\n### 2. Push to Registry (Required for Kubernetes)\n\nKubernetes needs to pull images from a registry. The deployment will automatically use the registry specified in the `REGISTRY` environment variable.\n\n#### Option A: Azure Container Registry (ACR) for AKS\n```bash\n# Setup ACR (one time only)\naz acr create --resource-group \u003cyour-rg\u003e --name \u003cyour-acr\u003e --sku Basic\naz aks update -n \u003cyour-aks\u003e -g \u003cyour-rg\u003e --attach-acr \u003cyour-acr\u003e\n\n# Build, push, and deploy with registry\nexport REGISTRY=\u003cyour-acr\u003e.azurecr.io\nexport NAMESPACE=developer-john\n\naz acr login --name \u003cyour-acr\u003e\n./manage.sh build\n./manage.sh push\n./manage.sh deploy  # Automatically uses $REGISTRY image\n```\n\n#### Option B: Docker Hub\n```bash\n# Build, push, and deploy with Docker Hub\nexport REGISTRY=docker.io/\u003cyour-username\u003e\nexport NAMESPACE=developer-john\n\ndocker login\n./manage.sh build\n./manage.sh push\n./manage.sh deploy  # Automatically uses $REGISTRY image\n```\n\n#### Option C: Build directly with ACR (No local Docker needed)\n```bash\n# Build directly in Azure (no local Docker required)\naz acr build --registry \u003cyour-acr\u003e --image nginx-dev-gateway:latest .\n\n# Deploy using the ACR image\nexport REGISTRY=\u003cyour-acr\u003e.azurecr.io\nexport NAMESPACE=developer-john\n./manage.sh deploy\n```\n\n### 3. Deploy to Your Namespace\n\nIf you've already set `REGISTRY` and `NAMESPACE` environment variables above:\n```bash\n./manage.sh deploy  # Uses $REGISTRY for image and $NAMESPACE for deployment\n```\n\nOr specify namespace explicitly:\n```bash\n./manage.sh deploy -n developer-john\n```\n\n### 3. Start Port-Forward\n\n```bash\n# With environment variable set\n./manage.sh port-forward 8000\n\n# Or with explicit namespace\n./manage.sh port-forward -n developer-john 8000\n```\n\n### 4. Access Your Services\n\n```bash\n# Access services through the gateway\ncurl http://localhost:8000/api/echo/hello\ncurl http://localhost:8000/api/users/list\nwscat -c ws://localhost:8000/ws/notifications\n```\n\n## Typical Development Setup\n\nIn most development scenarios, you're debugging 1-3 services in your namespace while using stable versions of other services from a shared namespace:\n\n```\nYour Namespace (dev-john):\n  - payment-service (debugging)\n  - nginx-gateway\n\nDefault/Staging Namespace:\n  - user-service (stable)\n  - order-service (stable)\n  - inventory-service (stable)\n  - 20+ other services (stable)\n```\n\nSee [Development Workflow Guide](docs/development-workflow.md) for detailed setup instructions.\n\n### Quick Setup for Your Services\n\n#### Option 1: Automatic Service Discovery (Recommended)\n\n```bash\n# Discover services and generate routes automatically\n./manage.sh -n $NAMESPACE discover-routes my-routes.conf \\\n  --stable-namespace default \\\n  --debug-services payment-service,order-service\n\n# Apply the generated routes\n./manage.sh -n $NAMESPACE update-routes my-routes.conf\n\n# Dynamically switch services between debug and stable\n./manage.sh -n $NAMESPACE switch-service payment-service debug   # Use debug version\n./manage.sh -n $NAMESPACE switch-service payment-service stable  # Use stable version\n./manage.sh -n $NAMESPACE switch-service payment-service toggle  # Toggle between versions\n```\n\n#### Option 2: Manual Configuration\n\n1. **Discover your services**:\n```bash\n# See what's in your namespace (services you're debugging)\nkubectl get svc -n $NAMESPACE --no-headers | awk '{print $1}'\n\n# See what's in the stable namespace\nkubectl get svc -n default --no-headers | awk '{print $1}'\n```\n\n2. **Create your routes** (`my-routes.conf`):\n```nginx\n# Service I'm debugging (in my namespace)\nlocation /api/payment/ {\n    set $payment_upstream payment-service.${CURRENT_NAMESPACE}.svc.cluster.local:8080;\n    proxy_pass http://$payment_upstream/;\n    include /etc/nginx/includes/proxy.conf;\n}\n\n# Stable services (in default namespace)\nlocation /api/users/ {\n    set $users_upstream user-service.default.svc.cluster.local:8080;\n    proxy_pass http://$users_upstream/;\n    include /etc/nginx/includes/proxy.conf;\n}\n```\n\n3. **Apply and test**:\n```bash\n./manage.sh -n $NAMESPACE update-routes my-routes.conf\ncurl http://localhost:8000/api/payment/   # Your debug version\ncurl http://localhost:8000/api/users/     # Stable version\n```\n\n## Route Configuration\n\nRoutes are defined in the ConfigMap `nginx-gateway-routes`. Edit the default routes:\n\n```bash\n# With environment variable\nexport NAMESPACE=developer-john\n./manage.sh update-routes\n\n# Or with flag\n./manage.sh -n developer-john update-routes\n```\n\n### Example Route Configuration\n\n\u003e **Important**: Always use variables in `proxy_pass` for Kubernetes services to ensure proper DNS resolution. See [Routing Guide](docs/routing-guide.md) for details.\n\n```nginx\n# Route to service in same namespace (with runtime DNS resolution)\nlocation /api/myapp/ {\n    set $myapp_upstream myapp-service.${CURRENT_NAMESPACE}.svc.cluster.local:8080;\n    proxy_pass http://$myapp_upstream/;\n    include /etc/nginx/includes/proxy.conf;\n}\n\n# Route to service in different namespace\nlocation /api/billing/ {\n    set $billing_upstream billing-service.dev.svc.cluster.local:3000;\n    proxy_pass http://$billing_upstream/;\n    include /etc/nginx/includes/proxy.conf;\n}\n\n# WebSocket route (requires special configuration)\nlocation /ws/notifications {\n    set $ws_upstream notification-service.${CURRENT_NAMESPACE}.svc.cluster.local:8080;\n    proxy_pass http://$ws_upstream/;\n\n    # Required WebSocket headers\n    proxy_http_version 1.1;\n    proxy_set_header Upgrade $http_upgrade;\n    proxy_set_header Connection \"upgrade\";\n    proxy_buffering off;\n\n    # Long timeouts for persistent connections\n    proxy_connect_timeout 7d;\n    proxy_send_timeout 7d;\n    proxy_read_timeout 7d;\n}\n\n# Route with path rewriting\nlocation ~ ^/svc/([a-z]+)/(.*)$ {\n    set $service_upstream $1-service.${CURRENT_NAMESPACE}.svc.cluster.local:8080;\n    proxy_pass http://$service_upstream/$2;\n    include /etc/nginx/includes/proxy.conf;\n}\n```\n\n## Management Commands\n\nAll commands support both environment variable and command-line flag for namespace:\n\n```bash\n# Set namespace once for all commands\nexport NAMESPACE=developer-john\n\n# Build Docker image\n./manage.sh build\n\n# Deploy to namespace\n./manage.sh deploy                      # uses $NAMESPACE\n./manage.sh deploy -n other-namespace   # overrides with flag\n\n# Update routes configuration\n./manage.sh update-routes [routes-file]\n\n# Auto-discover services and generate routes\n./manage.sh discover-routes [output-file] [options]\n# Options:\n#   --stable-namespace NS    Namespace for stable services (default: default)\n#   --debug-services LIST    Comma-separated services to debug\n\n# Switch service between debug and stable versions\n./manage.sh switch-service \u003cservice-name\u003e [mode]\n# Modes: debug, stable, toggle (default: toggle)\n\n# View gateway logs\n./manage.sh logs\n\n# Check deployment status\n./manage.sh status\n\n# Reload NGINX configuration\n./manage.sh reload\n\n# Port-forward to local machine\n./manage.sh port-forward [port]\n\n# Run tests\n./manage.sh test\n\n# Uninstall from namespace\n./manage.sh uninstall\n```\n\n### Environment Variables\n\n```bash\nexport NAMESPACE=developer-john      # Default namespace for operations\nexport REGISTRY=myregistry.io        # Docker registry URL\nexport IMAGE_NAME=nginx-dev-gateway  # Docker image name\nexport IMAGE_TAG=v1.0.0              # Docker image tag\n```\n\n## Architecture\n\nThe gateway consists of:\n\n1. **NGINX Proxy**: Routes incoming requests to Kubernetes services\n2. **ConfigMap**: Stores routing configuration\n3. **Namespace Context**: Automatically detects and uses deployment namespace\n4. **Service Discovery**: Uses Kubernetes DNS for service resolution\n\n## Use Cases\n\n### Developer Debugging\nEach developer gets their own gateway instance in their namespace:\n\n```bash\n# John's gateway\n./manage.sh deploy -n developer-john\n./manage.sh port-forward -n developer-john 8000\n\n# Jane's gateway\n./manage.sh deploy -n developer-jane\n./manage.sh port-forward -n developer-jane 8001\n```\n\n### Microservices Access\nAccess multiple services through a single port:\n\n```bash\n# Instead of multiple port-forwards:\nkubectl port-forward svc/user-service 8081:80\nkubectl port-forward svc/order-service 8082:80\nkubectl port-forward svc/payment-service 8083:80\n\n# Use one gateway:\nkubectl port-forward svc/nginx-gateway 8000:8000\n# Access all services via paths:\n# http://localhost:8000/api/users\n# http://localhost:8000/api/orders\n# http://localhost:8000/api/payments\n```\n\n## Advanced Configuration\n\n### Environment Variables\n\nConfigure the gateway behavior through environment variables:\n\n```yaml\nenv:\n- name: NGINX_WORKER_PROCESSES\n  value: \"auto\"              # Number of nginx worker processes\n- name: NGINX_WORKER_CONNECTIONS\n  value: \"1024\"              # Max connections per worker\n- name: LOG_LEVEL\n  value: \"info\"              # Nginx log level (debug, info, notice, warn, error, crit)\n- name: PROXY_CONNECT_TIMEOUT\n  value: \"60s\"               # Timeout for connecting to upstream\n- name: PROXY_SEND_TIMEOUT\n  value: \"60s\"               # Timeout for sending to upstream\n- name: PROXY_READ_TIMEOUT\n  value: \"60s\"               # Timeout for reading from upstream\n- name: PROXY_BUFFER_SIZE\n  value: \"4k\"                # Buffer size for proxy responses\n- name: PROXY_BUFFERS\n  value: \"8 4k\"              # Number and size of buffers\n```\n\nYou can also update these values on a running deployment:\n\n```bash\n# Update timeout values\nkubectl set env deployment/nginx-gateway \\\n  PROXY_CONNECT_TIMEOUT=30s \\\n  PROXY_READ_TIMEOUT=120s \\\n  -n developer-john\n\n# View current environment variables\nkubectl get deployment nginx-gateway -n developer-john -o jsonpath='{.spec.template.spec.containers[0].env[*]}' | jq\n```\n\n### Custom Routes File\n\nCreate a custom routes file and apply it:\n\n```nginx\n# my-routes.conf\nlocation /api/custom/ {\n    set $custom_upstream custom-service.${CURRENT_NAMESPACE}.svc.cluster.local:9000;\n    proxy_pass http://$custom_upstream/;\n    include /etc/nginx/includes/proxy.conf;\n}\n```\n\n```bash\n./manage.sh -n developer-john update-routes my-routes.conf\n```\n\n## Troubleshooting\n\n### Check Gateway Status\n```bash\n./manage.sh status -n developer-john\n```\n\n### View Logs\n```bash\n./manage.sh logs -n developer-john\n```\n\n### Test Connectivity\n```bash\n./manage.sh test -n developer-john\n```\n\n### Common Issues\n\n1. **502 Bad Gateway**\n   - Service doesn't exist or has no endpoints\n   - Check service name and namespace\n   - Verify service is running: `kubectl get svc -n \u003cnamespace\u003e`\n\n2. **Connection Refused**\n   - Port-forward not active\n   - Run: `./manage.sh port-forward -n \u003cnamespace\u003e 8000`\n\n3. **404 Not Found**\n   - Route not configured\n   - Update routes: `./manage.sh update-routes -n \u003cnamespace\u003e`\n\n4. **WebSocket Connection Issues**\n   - Ensure using variables in proxy_pass for runtime DNS resolution\n   - Check WebSocket headers are properly configured\n   - See [Routing Guide](docs/routing-guide.md#websocket-routing) for details\n\n## Project Structure\n\n```\nnginx-dev-gateway/\n├── Dockerfile                 # Alpine NGINX image\n├── manage.sh                  # Management script\n├── nginx/\n│   ├── nginx.conf.template   # Main NGINX config\n│   ├── conf.d/               # Server configurations\n│   ├── includes/             # Reusable config snippets\n│   └── scripts/              # Container scripts\n├── k8s/\n│   └── base/                 # Kubernetes manifests\n│       ├── configmap.yaml    # Routes configuration\n│       ├── deployment.yaml   # Gateway deployment\n│       └── service.yaml      # ClusterIP service\n├── docs/                     # Documentation\n│   ├── api-gateway-plan.md  # Architecture design\n│   ├── routing-guide.md      # Routing configuration guide\n│   ├── kubectl-setup.md      # kubectl setup guide\n│   └── service-discovery.md  # Service discovery patterns\n├── tests/                    # Test suites\n└── test-services/           # Test service deployments\n```\n\n## Documentation\n\n- [Routing Guide](docs/routing-guide.md) - **Essential reading** for configuring routes, especially WebSocket support\n- [Architecture Design](docs/api-gateway-plan.md) - Detailed implementation plan\n- [Roadmap \u0026 Future Enhancements](docs/roadmap.md) - Planned features and improvements\n- [kubectl Setup Guide](docs/kubectl-setup.md) - Setting up kubectl aliases and helpers\n- [Service Discovery Patterns](docs/service-discovery.md) - Kubernetes service discovery patterns\n\n## Contributing\n\nContributions are welcome! Please read the documentation above to understand the architecture and routing patterns.\n\n## License\n\nMIT License - See LICENSE file for details","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnathanfox%2Fnginx-dev-gateway","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnathanfox%2Fnginx-dev-gateway","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnathanfox%2Fnginx-dev-gateway/lists"}