configure-reverse-proxy

Configure reverse proxy patterns across multiple tools including Nginx, Traefik, and ShinyProxy. Covers WebSocket proxying, path-based and host-based routing, SSL termination, and Docker label auto-discovery. Use when routing multiple services behind a single entry point, proxying WebSocket connections (Shiny, Socket.IO), auto-discovering Docker services with Traefik labels, or adding SSL termination to services that don't handle TLS natively.

9 stars

Best use case

configure-reverse-proxy is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Configure reverse proxy patterns across multiple tools including Nginx, Traefik, and ShinyProxy. Covers WebSocket proxying, path-based and host-based routing, SSL termination, and Docker label auto-discovery. Use when routing multiple services behind a single entry point, proxying WebSocket connections (Shiny, Socket.IO), auto-discovering Docker services with Traefik labels, or adding SSL termination to services that don't handle TLS natively.

Teams using configure-reverse-proxy should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/configure-reverse-proxy/SKILL.md --create-dirs "https://raw.githubusercontent.com/pjt222/agent-almanac/main/i18n/caveman-lite/skills/configure-reverse-proxy/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/configure-reverse-proxy/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How configure-reverse-proxy Compares

Feature / Agentconfigure-reverse-proxyStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Configure reverse proxy patterns across multiple tools including Nginx, Traefik, and ShinyProxy. Covers WebSocket proxying, path-based and host-based routing, SSL termination, and Docker label auto-discovery. Use when routing multiple services behind a single entry point, proxying WebSocket connections (Shiny, Socket.IO), auto-discovering Docker services with Traefik labels, or adding SSL termination to services that don't handle TLS natively.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Configure Reverse Proxy

Set up reverse proxy patterns for routing traffic to backend services using Nginx, Traefik, or ShinyProxy.

## When to Use

- Routing multiple services behind a single entry point
- Proxying WebSocket connections (Shiny, Socket.IO, live reload)
- Auto-discovering Docker services with Traefik labels
- Path-based or host-based routing to different backends
- Adding SSL termination to services that don't handle TLS

## Inputs

- **Required**: Backend services to proxy (host:port)
- **Required**: Routing strategy (path-based, host-based, or both)
- **Optional**: Proxy tool preference (Nginx, Traefik)
- **Optional**: Domain name(s) for host-based routing
- **Optional**: WebSocket endpoints to proxy

## Procedure

### Step 1: Choose Proxy Tool

| Feature | Nginx | Traefik |
|---------|-------|---------|
| Configuration | Static files | Docker labels / dynamic |
| Auto-discovery | No (manual) | Yes (Docker provider) |
| Let's Encrypt | Via certbot | Built-in ACME |
| Dashboard | No (3rd party) | Built-in |
| WebSocket | Manual config | Automatic |
| Best for | Static config, high traffic | Dynamic Docker environments |

### Step 2: Nginx — Path-Based Routing

```nginx
server {
    listen 80;

    location /api/ {
        proxy_pass http://api:8000/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location /app/ {
        proxy_pass http://webapp:3000/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location / {
        root /usr/share/nginx/html;
        try_files $uri $uri/ /index.html;
    }
}
```

**Note:** Trailing `/` on `proxy_pass` strips the location prefix. `proxy_pass http://api:8000/;` with `location /api/` forwards `/api/users` as `/users`.

### Step 3: Nginx — Host-Based Routing

```nginx
server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://api:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://webapp:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
```

### Step 4: Nginx — WebSocket Proxying

WebSockets require upgrade headers. Essential for Shiny, Socket.IO, and live reload:

```nginx
location /ws/ {
    proxy_pass http://app:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_read_timeout 86400;
}
```

For Shiny apps specifically:

```nginx
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server {
    location / {
        proxy_pass http://shiny:3838;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $host;
        proxy_read_timeout 86400;
        proxy_buffering off;
    }
}
```

**Got:** WebSocket connections establish and persist.

**If fail:** Check `proxy_http_version 1.1` is set. Verify `Upgrade` and `Connection` headers.

### Step 5: Traefik — Docker Label Auto-Discovery

`docker-compose.yml`:

```yaml
services:
  traefik:
    image: traefik:v3.2
    command:
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.letsencrypt.acme.email=admin@example.com"
      - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
      - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - letsencrypt:/letsencrypt

  api:
    image: myapi:latest
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api.rule=Host(`api.example.com`)"
      - "traefik.http.routers.api.entrypoints=websecure"
      - "traefik.http.routers.api.tls.certresolver=letsencrypt"
      - "traefik.http.services.api.loadbalancer.server.port=8000"

  webapp:
    image: myapp:latest
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.webapp.rule=Host(`app.example.com`)"
      - "traefik.http.routers.webapp.entrypoints=websecure"
      - "traefik.http.routers.webapp.tls.certresolver=letsencrypt"
      - "traefik.http.services.webapp.loadbalancer.server.port=3000"

volumes:
  letsencrypt:
```

**Got:** Traefik auto-discovers services via labels, provisions SSL certificates.

### Step 6: Traefik — Path-Based Routing with Labels

```yaml
services:
  api:
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api.rule=Host(`example.com`) && PathPrefix(`/api`)"
      - "traefik.http.routers.api.middlewares=strip-api"
      - "traefik.http.middlewares.strip-api.stripprefix.prefixes=/api"
      - "traefik.http.services.api.loadbalancer.server.port=8000"
```

### Step 7: Traefik — Rate Limiting and Headers

```yaml
labels:
  - "traefik.http.middlewares.ratelimit.ratelimit.average=100"
  - "traefik.http.middlewares.ratelimit.ratelimit.burst=50"
  - "traefik.http.middlewares.security.headers.stsSeconds=63072000"
  - "traefik.http.middlewares.security.headers.contentTypeNosniff=true"
  - "traefik.http.middlewares.security.headers.frameDeny=true"
  - "traefik.http.routers.app.middlewares=ratelimit,security"
```

### Step 8: Verify Proxy Configuration

```bash
# Nginx: test config
docker compose exec nginx nginx -t

# Check routing
curl -H "Host: api.example.com" http://localhost/health

# Check WebSocket (needs wscat: npm install -g wscat)
wscat -c ws://localhost/ws/

# Traefik dashboard (if enabled)
# http://localhost:8080/dashboard/
```

**Got:** Requests route to correct backends. WebSocket upgrades succeed.

## Validation

- [ ] HTTP requests route to the correct backend based on path or host
- [ ] WebSocket connections establish and maintain
- [ ] SSL termination works (if configured)
- [ ] Backend services receive correct `Host`, `X-Real-IP`, `X-Forwarded-For` headers
- [ ] Traefik auto-discovers new services via labels (if using Traefik)
- [ ] Configuration survives `docker compose restart`

## Pitfalls

- **Trailing slash mismatch**: `proxy_pass http://app/` vs `http://app` behaves differently with path stripping in Nginx.
- **WebSocket timeout**: Default `proxy_read_timeout` is 60s. Long-lived WebSocket connections need `86400` (24h).
- **Docker socket security**: Mounting `/var/run/docker.sock` in Traefik gives it full Docker access. Use `ro` mount and consider socket proxy.
- **DNS resolution**: Nginx resolves upstreams at startup. Use `resolver 127.0.0.11` for Docker's internal DNS with dynamic services.
- **Missing `proxy_buffering off`**: Shiny and SSE endpoints need `proxy_buffering off` for real-time streaming.

## Related Skills

- `configure-nginx` - detailed Nginx configuration with SSL and security headers
- `deploy-shinyproxy` - ShinyProxy for containerized Shiny app hosting
- `setup-compose-stack` - compose stack that uses a reverse proxy
- `configure-api-gateway` - API gateway patterns with Kong and Traefik

Related Skills

deploy-shinyproxy

9
from pjt222/agent-almanac

Deploy ShinyProxy for hosting multiple containerized Shiny applications. Covers ShinyProxy Docker deployment, application.yml configuration, Shiny app Docker images, authentication, container backends, usage tracking, and scaling. Use when hosting multiple Shiny apps behind a single entry point, needing per-app authentication and access control, deploying Shiny apps as isolated Docker containers, or scaling beyond single-app deployment with usage analytics and audit logging.

configure-putior-mcp

9
from pjt222/agent-almanac

Configure the putior MCP server to expose 16 workflow visualization tools to AI assistants. Covers Claude Code and Claude Desktop setup, dependency installation (mcptools, ellmer), tool verification, and optional ACP server configuration for agent-to-agent communication. Use when enabling AI assistants to annotate and visualize workflows interactively, setting up a new development environment with putior MCP integration, or configuring agent-to-agent communication via ACP for automated pipelines.

configure-nginx

9
from pjt222/agent-almanac

Configure Nginx as a web server and reverse proxy. Covers static file serving, reverse proxy to upstream services, SSL/TLS termination with Let's Encrypt, location blocks, load balancing, rate limiting, and security headers. Use when serving static files in production, reverse proxying to backend services (Node.js, Python, R/Shiny), terminating SSL/TLS, load balancing across instances, or adding rate limiting and security headers to harden an endpoint.

configure-mcp-server

9
from pjt222/agent-almanac

Configure MCP (Model Context Protocol) servers for Claude Code and Claude Desktop. Covers mcptools setup, Hugging Face integration, WSL path handling, and multi-client configuration. Use when setting up Claude Code to connect to R via mcptools, configuring Claude Desktop with MCP servers, adding Hugging Face or other remote MCP servers, or troubleshooting MCP connectivity between clients and servers.

configure-log-aggregation

9
from pjt222/agent-almanac

Set up centralized log aggregation with Loki and Promtail (or ELK stack), including log parsing, label extraction, retention policies, and integration with metrics for correlation. Use when consolidating logs from multiple services into a searchable system, replacing local log files with centralized queryable storage, correlating logs with metrics and traces, implementing structured logging with label extraction, or troubleshooting production incidents requiring cross-service log analysis.

configure-ingress-networking

9
from pjt222/agent-almanac

Configure Kubernetes Ingress networking with NGINX Ingress Controller, cert-manager for automated TLS certificate management, path-based routing, rate limiting, and multi-domain hosting with SSL termination and load balancing. Use when exposing multiple Kubernetes services via a single load balancer, implementing path-based or host-based routing, automating TLS certificate issuance with Let's Encrypt, or setting up blue-green and canary deployments with traffic splitting.

configure-git-repository

9
from pjt222/agent-almanac

Configure a Git repository with proper .gitignore, branch strategy, commit conventions, hooks, and remote setup. Covers initial setup and common patterns for R, Node.js, and Python projects. Use when initializing version control for a new project, adding a .gitignore for a specific language or framework, setting up branch protection and conventions, or configuring commit hooks.

configure-api-gateway

9
from pjt222/agent-almanac

Deploy and configure an API gateway (Kong or Traefik) to handle API traffic management, authentication, rate limiting, request/response transformation, and routing. Covers plugin configuration, upstream services, consumer management, and integration with existing infrastructure. Use when multiple backend services need a unified API endpoint, when centralized authentication or rate limiting is required, when implementing API versioning, or when needing detailed analytics and load balancing for microservices.

configure-alerting-rules

9
from pjt222/agent-almanac

Configure Prometheus Alertmanager with routing trees, receivers (Slack, PagerDuty, email), inhibition rules, silences, and notification templates for actionable incident alerting. Use when implementing proactive monitoring with automated incident detection, routing alerts to the appropriate team by severity, reducing alert fatigue through grouping and deduplication, integrating with on-call systems like PagerDuty, or migrating from legacy alerting to Prometheus-based alerting.

skill-name-here

9
from pjt222/agent-almanac

One to three sentences describing what this skill accomplishes, followed by key activation triggers. This field is the primary mechanism agents use to decide whether to activate the skill — it is read during discovery before the full body is loaded. Start with a verb. Include the most important "when to use" conditions inline. Max 1024 characters.

write-vignette

9
from pjt222/agent-almanac

Create R package vignettes using R Markdown or Quarto. Covers vignette setup, YAML configuration, code chunk options, building and testing, and CRAN requirements for vignettes. Use when adding a Getting Started tutorial, documenting complex workflows spanning multiple functions, creating domain-specific guides, or when CRAN submission requires user-facing documentation beyond function help pages.

write-validation-documentation

9
from pjt222/agent-almanac

Write IQ/OQ/PQ validation documentation for computerized systems in regulated environments. Covers protocols, reports, test scripts, deviation handling, and approval workflows. Use when validating R or other software for regulated use, preparing for a regulatory audit, documenting qualification of computing environments, or creating and updating validation protocols and reports for new or re-qualified systems.