Reverse Proxy Setup
To deploy BugPin in production, place it behind a reverse proxy that handles HTTPS and SSL certificate management. This guide covers complete configurations for Nginx, Traefik, Caddy, and Apache, including CORS header requirements for the embeddable widget, upload size limits, and SSL certificate setup with Let's Encrypt.
- HTTPS/SSL: Encrypt traffic and enable secure connections
- Domain Names: Access BugPin via a custom domain (e.g.,
bugpin.example.com) - Load Balancing: Distribute traffic across multiple instances
- Centralized SSL: Manage certificates in one place
- Security: Hide internal ports and add additional security layers
Important Considerations
CORS Headers
BugPin automatically sets the required CORS headers for the widget to work:
Access-Control-Allow-Origin: *Cross-Origin-Resource-Policy: cross-origin
Do not override or strip these headers in your reverse proxy configuration. The widget will fail to load if these headers are missing.
Upload Size Limits
Set appropriate upload size limits for screenshot and file attachments. Recommended: 10MB minimum.
WebSocket Support
BugPin does not use WebSockets. Standard HTTP/HTTPS proxying is sufficient.
Traefik
Traefik is the recommended reverse proxy for Docker deployments. It integrates seamlessly with Docker Compose and provides automatic SSL certificate management.
Prerequisites
- Traefik installed and running
- Let's Encrypt certificate resolver configured
- Traefik network created (
docker network create traefik)
Docker Compose Configuration
Update your docker-compose.yml:
services:
bugpin:
image: registry.arantic.cloud/bugpin/bugpin:latest
container_name: bugpin
restart: unless-stopped
volumes:
- ./data:/data
networks:
- traefik
labels:
# Enable Traefik
- "traefik.enable=true"
# Router configuration
- "traefik.http.routers.bugpin.rule=Host(`bugpin.example.com`)"
- "traefik.http.routers.bugpin.entrypoints=websecure"
- "traefik.http.routers.bugpin.tls=true"
- "traefik.http.routers.bugpin.tls.certresolver=letsencrypt"
# Service configuration
- "traefik.http.services.bugpin.loadbalancer.server.port=7300"
# Optional: HTTP to HTTPS redirect
- "traefik.http.routers.bugpin-http.rule=Host(`bugpin.example.com`)"
- "traefik.http.routers.bugpin-http.entrypoints=web"
- "traefik.http.routers.bugpin-http.middlewares=bugpin-redirect"
- "traefik.http.middlewares.bugpin-redirect.redirectscheme.scheme=https"
- "traefik.http.middlewares.bugpin-redirect.redirectscheme.permanent=true"
networks:
traefik:
external: true
Configuration Notes
Replace bugpin.example.com with your actual domain.
Key points:
- Don't expose port 7300 directly (no
ports:section needed) - Traefik handles routing from external network to container
certresolver=letsencryptmust match your Traefik configuration- HTTP to HTTPS redirect is optional but recommended
Don't add middleware that:
- Modifies CORS headers
- Strips response headers
- Changes content types
Verification
Check that Traefik is routing correctly:
# Check CORS headers
curl -I https://bugpin.example.com/widget.js
# Expected output includes:
# access-control-allow-origin: *
# cross-origin-resource-policy: cross-origin
Nginx
Nginx is a traditional, widely-used reverse proxy with excellent performance and flexibility.
Configuration File
Create /etc/nginx/sites-available/bugpin:
server {
listen 80;
server_name bugpin.example.com;
# Redirect HTTP to HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name bugpin.example.com;
# SSL Certificate (Let's Encrypt)
ssl_certificate /etc/letsencrypt/live/bugpin.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/bugpin.example.com/privkey.pem;
# SSL Configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Proxy to BugPin
location / {
proxy_pass http://localhost:7300;
proxy_http_version 1.1;
# Proxy Headers
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Upload size limit (screenshots and attachments)
client_max_body_size 10M;
}
}
Enable the Site
# Create symlink to enable site
sudo ln -s /etc/nginx/sites-available/bugpin /etc/nginx/sites-enabled/
# Test configuration
sudo nginx -t
# Reload Nginx
sudo systemctl reload nginx
SSL Certificate with Certbot
# Install Certbot
sudo apt install certbot python3-certbot-nginx
# Obtain certificate
sudo certbot --nginx -d bugpin.example.com
# Certbot will automatically configure SSL in your Nginx config
Configuration Notes
Replace bugpin.example.com with your domain.
Key points:
- Don't add
proxy_hide_headerdirectives that strip CORS headers client_max_body_size 10Mallows 10MB uploads (adjust if needed)- Certbot automatically renews certificates
Caddy
Caddy is the simplest reverse proxy with automatic HTTPS. Perfect for quick deployments.
Caddyfile Configuration
Create a Caddyfile:
bugpin.example.com {
reverse_proxy localhost:7300
}
That's it! Caddy automatically:
- Obtains SSL certificates from Let's Encrypt
- Redirects HTTP to HTTPS
- Renews certificates automatically
- Passes headers through correctly
With Docker Compose
If running Caddy with Docker Compose alongside BugPin:
services:
caddy:
image: caddy:latest
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
networks:
- bugpin
bugpin:
image: registry.arantic.cloud/bugpin/bugpin:latest
container_name: bugpin
restart: unless-stopped
volumes:
- ./data:/data
networks:
- bugpin
networks:
bugpin:
volumes:
caddy_data:
caddy_config:
Update Caddyfile to use the Docker service name:
bugpin.example.com {
reverse_proxy bugpin:7300
}
Configuration Notes
Replace bugpin.example.com with your domain.
Key points:
- Simplest configuration - just one line
- Automatic HTTPS - no manual certificate setup
- Headers pass through automatically - no configuration needed
Apache
Apache with mod_proxy can also be used as a reverse proxy.
Configuration
Create /etc/apache2/sites-available/bugpin.conf:
<VirtualHost *:80>
ServerName bugpin.example.com
# Redirect HTTP to HTTPS
Redirect permanent / https://bugpin.example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName bugpin.example.com
# SSL Configuration
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/bugpin.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/bugpin.example.com/privkey.pem
# Reverse Proxy
ProxyPreserveHost On
ProxyPass / http://localhost:7300/
ProxyPassReverse / http://localhost:7300/
# Upload size limit
LimitRequestBody 10485760
</VirtualHost>
Enable Required Modules
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod ssl
sudo a2enmod headers
Enable the Site
# Enable site
sudo a2ensite bugpin
# Test configuration
sudo apache2ctl configtest
# Reload Apache
sudo systemctl reload apache2
SSL Certificate with Certbot
sudo certbot --apache -d bugpin.example.com
Verification & Testing
After setting up your reverse proxy, verify everything works correctly:
1. Check HTTPS
curl -I https://bugpin.example.com
Expected: Status 200 OK
2. Verify CORS Headers
curl -I https://bugpin.example.com/widget.js | grep -i "access-control\|cross-origin"
Expected output:
access-control-allow-origin: *
cross-origin-resource-policy: cross-origin
3. Test Admin Access
Open https://bugpin.example.com in a browser and verify:
- Login page loads
- No SSL certificate warnings
- No mixed content errors in browser console
4. Test Widget Loading
Add the widget to a test page:
<script
src="https://bugpin.example.com/widget.js"
data-api-key="your-api-key"
async
></script>
Check browser console for:
- Widget script loads without errors
- No CORS errors
- Widget button appears on page
Troubleshooting
CORS Errors
Symptom: Widget fails to load with CORS error in console
Causes:
- Reverse proxy stripping or overriding CORS headers
- Missing CORS headers in response
Solution:
- Remove any
proxy_hide_header(Nginx) or header modification directives - Verify headers with
curl -I https://bugpin.example.com/widget.js - Ensure BugPin response headers pass through unchanged
SSL Certificate Issues
Symptom: Browser shows SSL warning
Causes:
- Certificate not trusted
- Certificate expired
- Wrong domain in certificate
Solution:
- Use Let's Encrypt for free, trusted certificates
- Verify certificate with:
openssl s_client -connect bugpin.example.com:443 -servername bugpin.example.com - Check certificate expiration:
echo | openssl s_client -connect bugpin.example.com:443 2>/dev/null | openssl x509 -noout -dates
Upload Failures
Symptom: Screenshot upload fails
Causes:
- Upload size limit too small
- Timeout too short
Solution:
- Increase client/request body size limits:
- Nginx:
client_max_body_size 10M; - Apache:
LimitRequestBody 10485760 - Caddy: Automatic (no limit)
- Traefik: No configuration needed
- Nginx:
Connection Refused
Symptom: 502 Bad Gateway or connection refused
Causes:
- BugPin container not running
- Wrong internal port
- Network misconfiguration
Solution:
# Check if BugPin is running
docker ps | grep bugpin
# Check logs
docker logs bugpin
# Verify port 7300 is listening
curl http://localhost:7300/health
Security Best Practices
Rate Limiting
Consider adding rate limiting at the reverse proxy level:
Nginx:
limit_req_zone $binary_remote_addr zone=bugpin:10m rate=10r/s;
server {
# ... other config ...
location / {
limit_req zone=bugpin burst=20 nodelay;
proxy_pass http://localhost:7300;
# ... other proxy settings ...
}
}
Traefik:
labels:
- "traefik.http.middlewares.bugpin-ratelimit.ratelimit.average=10"
- "traefik.http.middlewares.bugpin-ratelimit.ratelimit.burst=20"
- "traefik.http.routers.bugpin.middlewares=bugpin-ratelimit"
Firewall Rules
Block direct access to port 7300:
# Allow only localhost to access port 7300
sudo ufw deny 7300
sudo ufw allow from 127.0.0.1 to any port 7300
IP Whitelisting
If BugPin is for internal use only, whitelist your IP ranges:
Nginx:
location / {
allow 192.168.1.0/24;
allow 10.0.0.0/8;
deny all;
proxy_pass http://localhost:7300;
}