원클릭으로
reverse-proxy-deployment
Deploy web applications behind Apache reverse proxy on rivsprod01 with relative URLs and proper path configuration
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Deploy web applications behind Apache reverse proxy on rivsprod01 with relative URLs and proper path configuration
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Pattern for automated testing with GitHub issue creation and Claude Code auto-fixing. Creates Test → Fail → Issue → Fix → Repeat cycle until tests pass.
Managing Cyril's Workshop blog posts and devblog via API - creating, editing, publishing, and updating content programmatically
RDBMS access patterns for DuckDB, MySQL (keycloak), PostgreSQL (dw, x3rocs), SQL Server (sage1000, x3), and DBISAM (Exportmaster) using ODBC and native drivers
Using Qwen 2.5 models via Ollama for local LLM inference, text analysis, and AI-powered automation
GPU VRAM management patterns for sharing memory across services (Ollama, Whisper, ComfyUI). OOM retry logic, auto-unload on idle, and service signaling protocol.
Audio transcription using local whisper.cpp server with CUDA acceleration. HTTP API for speech-to-text conversion.
| name | Reverse Proxy Deployment |
| description | Deploy web applications behind Apache reverse proxy on rivsprod01 with relative URLs and proper path configuration |
Guide for deploying web applications behind the Apache reverse proxy on rivsprod01 (dw.ramsden-international.com). Covers frontend relative URL patterns and Apache ProxyPass configuration.
When deploying a web application that will be accessed through the reverse proxy:
/etc/apache2/proxy-conf.d/ with proper path strippingUser: I have a web app with frontend on port 9273 and API on port 8765. Deploy it behind the proxy at /myapp/
Claude: I'll set up your application for reverse proxy deployment:
1. **Update Frontend URLs**: Change API calls to use relative URLs
- Before: `fetch('http://localhost:8765/api/status')`
- After: `fetch('api/status')` // Relative to current path
2. **Create Apache Config**: SSH to rivsprod01 and create `/etc/apache2/proxy-conf.d/myapp.conf`
- API path: `/myapp/api/` → backend on port 8765
- Frontend path: `/myapp/` → frontend on port 9273
- API location must come FIRST (more specific)
3. **Reload Apache**: `sudo systemctl reload apache2`
[Provides implementation using the ProxyPass Configuration pattern below]
User: My frontend has `fetch('http://localhost:3000/api/data')` hardcoded. How do I make it work behind a proxy?
Claude: Absolute URLs won't work behind a reverse proxy. You need to update the frontend to use relative URLs:
**Options:**
1. **Best: Use relative URLs** - `fetch('api/data')` - works anywhere
2. **Alternative: Use base path** - Store base path in config, prepend to all API calls
3. **Hidden input method** - Store proxy path in HTML, read in JavaScript
For option 1 (recommended):
- Replace all `http://localhost:3000/api/` with `api/`
- The browser resolves relative to current page path
- If page is at `/myapp/`, API call goes to `/myapp/api/`
[Shows the Relative URL Pattern implementation below]
User: I have 3 services running on ports 8001, 8002, 8003. Deploy all at /service1/, /service2/, /service3/
Claude: I'll configure all three services in a single Apache config file:
1. **Create single config file**: `/etc/apache2/proxy-conf.d/services.conf`
2. **Add ProxyPass for each**: More specific paths first (doesn't matter here since no overlap)
3. **Each service gets clean URLs**: Paths are stripped before forwarding
4. **Reload once**: All services go live together
[Provides implementation using the Multi-Service Configuration pattern below]
User: My frontend loads but API calls return 404. Frontend is at /rabbit/, API should be at /rabbit/api/
Claude: The issue is likely ProxyPass configuration. Let me check:
1. **Verify services are reachable**: From rivsprod01, can you curl the backend directly?
- `curl http://10.99.0.3:8765/status` should work
2. **Check ProxyPass order**: API location must come BEFORE frontend location
- Wrong order: frontend `/rabbit/` catches `/rabbit/api/` requests
- Right order: API `/rabbit/api/` catches first, then frontend `/rabbit/`
3. **Verify trailing slashes**: Both paths need trailing slashes for stripping
- `ProxyPass /rabbit/api/ http://10.99.0.3:8765/`
- Without trailing slash, path isn't stripped properly
[Shows debugging steps from Troubleshooting section below]
The sections below contain proven working configurations from production deployments.
Reference Files in This Folder:
rabbit.conf - Example Apache config from Invoice OCR deploymentPurpose: Make frontend work behind any reverse proxy path without hardcoding URLs
<!-- Hidden input stores the API base path -->
<input type="hidden" id="serverUrl" value="api">
<script>
function getServerUrl() {
return document.getElementById('serverUrl').value.trim();
}
// Use in fetch calls
async function checkStatus() {
const res = await fetch(`${getServerUrl()}/status`);
const data = await res.json();
// ...
}
</script>
Key Points:
"api" (relative) not "http://localhost:8765" (absolute)api/status relative to current pagehttps://example.com/rabbit/, request goes to https://example.com/rabbit/api/status/rabbit/ and forwards to backend// config.js
const CONFIG = {
API_BASE: 'api', // Relative to current path
WS_BASE: 'ws' // WebSocket endpoint if needed
};
// Use throughout app
fetch(`${CONFIG.API_BASE}/endpoint`)
When to use:
Purpose: Configure Apache to forward requests from public path to internal service
File: /etc/apache2/proxy-conf.d/myservice.conf
# Single service on custom path
ProxyPass /myservice/ http://10.99.0.3:8080/
ProxyPassReverse /myservice/ http://10.99.0.3:8080/
Key Points:
<Location> blocks needed)/myservice/page becomes /page at backendProxyPassReverse rewrites response headers (redirects, etc.)File: /etc/apache2/proxy-conf.d/service-with-api.conf
# Backend API - Must come FIRST (more specific path)
ProxyPass /rabbit/api/ http://10.99.0.3:8765/
ProxyPassReverse /rabbit/api/ http://10.99.0.3:8765/
# Frontend - Comes SECOND (less specific path)
ProxyPass /rabbit/ http://10.99.0.3:9273/
ProxyPassReverse /rabbit/ http://10.99.0.3:9273/
Key Points:
GET /rabbit/api/status → matches first rule → GET /status to port 8765GET /rabbit/index.html → matches second rule → GET /index.html to port 9273# Service that handles file uploads (PDFs, images, etc.)
ProxyPass /uploads/ http://10.99.0.3:7000/
ProxyPassReverse /uploads/ http://10.99.0.3:7000/
# Important for large PDF uploads
<Location /uploads/>
ProxyPass http://10.99.0.3:7000/
ProxyPassReverse http://10.99.0.3:7000/
# Allow 50MB uploads
LimitRequestBody 52428800
</Location>
When to use:
Purpose: Deploy multiple independent services in one config file
File: /etc/apache2/proxy-conf.d/all-services.conf
# Service 1: API Gateway
ProxyPass /api/ http://10.99.0.3:8001/
ProxyPassReverse /api/ http://10.99.0.3:8001/
# Service 2: Admin Dashboard
ProxyPass /admin/ http://10.99.0.3:8002/
ProxyPassReverse /admin/ http://10.99.0.3:8002/
# Service 3: Public Website
ProxyPass /site/ http://10.99.0.3:8003/
ProxyPassReverse /site/ http://10.99.0.3:8003/
Key Points:
Standard deployment process for new service:
# From local machine where service runs
curl http://10.99.0.3:8765/status # Test your port
# From rivsprod01 (SSH in)
ssh rivsprod01 "curl -s http://10.99.0.3:8765/status"
Expected: JSON response or HTML, not connection refused
# SSH to rivsprod01
ssh rivsprod01
# Create config file (as root or with sudo)
sudo nano /etc/apache2/proxy-conf.d/myservice.conf
# Add ProxyPass configuration (see patterns above)
# Verify syntax (optional, but recommended)
# apache2ctl configtest # May not be available
# Just proceed to reload if command not found
sudo systemctl reload apache2
# Verify Apache is still running
sudo systemctl status apache2
# From any machine
curl https://dw.ramsden-international.com/myservice/
# Or open in browser
Cause: ProxyPass configuration issue
Diagnostic Steps:
Verify service is accessible from rivsprod01:
ssh rivsprod01 "curl -s http://10.99.0.3:PORT/endpoint"
Check Apache config order:
ssh rivsprod01 "cat /etc/apache2/proxy-conf.d/myservice.conf"
Check Apache error logs:
ssh rivsprod01 "sudo tail -50 /var/log/apache2/error.log | grep myservice"
Solution:
sudo systemctl reload apache2Cause: Frontend path is catching API requests
Example of Wrong Configuration:
# WRONG - Frontend catches everything
ProxyPass /app/ http://10.99.0.3:9000/
ProxyPass /app/api/ http://10.99.0.3:8000/
Solution - Put API First:
# CORRECT - API catches specific path first
ProxyPass /app/api/ http://10.99.0.3:8000/
ProxyPass /app/ http://10.99.0.3:9000/
Cause: Service not listening on accessible IP
Diagnostic:
# On machine running service
netstat -tlnp | grep PORT
# or
ss -tlnp | grep PORT
Look for:
127.0.0.1:PORT - Only listening on localhost (wrong)10.99.0.3:PORT - Listening on network IP (correct)0.0.0.0:PORT - Listening on all interfaces (also correct)Solution: Configure service to bind to 0.0.0.0 or specific IP 10.99.0.3
Cause: Configuration syntax error
Diagnostic:
ssh rivsprod01 "sudo systemctl status apache2"
Solution:
sudo tail /var/log/apache2/error.logCause: Backend not configured for CORS, or wrong origin
Solution (Backend): Enable CORS in your service
# FastAPI example
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Or specific domain
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
Note: Proxy handles forwarding; backend sees requests from proxy IP, not client
| Hostname | IP Address | Purpose |
|---|---|---|
| rivsprod01 | 10.99.0.2 | Reverse proxy server (Apache) |
| pogs (local) | 10.99.0.3 | Development machine running services |
Service Configuration:
10.99.0.3 or 0.0.0.0 to be accessible from rivsprod01http://10.99.0.3:PORT in ProxyPass target URLslocalhost or 127.0.0.1 in ProxyPass targets| Path | Purpose |
|---|---|
/etc/apache2/proxy-conf.d/*.conf | Proxy configurations (add yours here) |
/etc/apache2/sites-available/default-ssl.conf | Main SSL site config (includes proxy-conf.d) |
/var/log/apache2/error.log | Apache error log |
/var/log/apache2/access.log | Access log (if needed) |
Important: Configs in /etc/apache2/proxy-conf.d/ are automatically included by the SSL site configuration.
sudo systemctl reload apache2