Publishing ServBay Sites to the Public Internet (Reverse Proxy, Tunnels & Port Forwarding)
Beyond local development, many users deploy ServBay on a dedicated server (such as a colocated Mac mini, an office workstation, a Windows server, etc.) as a backend origin server, then expose the site to the public internet for external access. This is fully production-ready—many users are already running ServBay stably in this way.
However, if you’re not familiar with ServBay’s default networking behavior, it’s easy to run into issues with protocol, certificates, Host headers, or networking—leading to the classic “everything works locally, but public access fails.” This article is for anyone who wants to use ServBay as an origin server: we’ll clarify these defaults, then provide end-to-end solutions in the order of built-in tunnels → reverse proxy (recommended) → port forwarding, concluding with a universal troubleshooting checklist for public access.
Supported Platforms
This guide applies to ServBay for macOS and ServBay for Windows. The site protocol modes, listening behavior, and certificate directory structure are identical across both platforms—only the install paths differ (macOS: /Applications/ServBay, Windows: generally C:\ServBay, depending on your install). The default web server also varies: macOS uses Caddy by default, Windows uses Nginx—you can switch either to Nginx / Apache / Caddy.
Understanding ServBay’s Default Networking Behavior
Most issues with public access stem from misunderstanding these defaults:
- Sites use
HTTP & HTTPSby default. In this mode, HTTP (80) requests are unconditionally 301-redirected to HTTPS (443). This is an intentional, modern default—stick to HTTPS, don’t fall back to plain HTTP 80. - HTTPS sites are selected by SNI. On a single ServBay, multiple sites are matched via the SNI field (equals the site’s domain) in the TLS handshake. Reverse proxies must send the correct SNI when making HTTPS upstream requests, otherwise you’ll get the default site/certificate.
- By default, all network interfaces are listened on (
0.0.0.0), and the default ports are HTTP 80 / HTTPS 443—so outside access is naturally allowed in most cases. No need to change the bind address. - Local HTTPS certificates are issued by the ServBay CA. ServBay has a built-in local CA (displayed in your Keychain as
ServBay User CA - ECC Root) and issues your site certificates. Public visitors’ browsers will not trust this by default—but just have your frontend reverse proxy trust this CA (or skip validation). There’s no need to get a separate public cert for upstream links.
Common Pitfall: HTTP & HTTPS + Only Forwarding Port 80
If you keep the default HTTP & HTTPS mode but only forward port 80, not 443: client requests http://yourdomain → ServBay sends 301 https://yourdomain → client tries 443 → no response → access fails. Browsers and HSTS may also cache this 301, making the problem sticky and hard to debug.
Don’t fall back to HTTP 80—instead, make HTTPS work end-to-end (see the recommended reverse proxy solution below).
Choosing a Publishing Method
| Method | Description | Recommended Scenarios |
|---|---|---|
| Built-in Tunnel (frpc / cloudflared) | Provided by ServBay; actively opens outbound tunnel—no public IP/ports required | No public IP, home/NAT networks, fastest publish |
| Frontend Reverse Proxy (Recommended) | Nginx/HAProxy/Caddy/Traefik handles public traffic and certs, then proxies HTTPS upstream to ServBay | Public entry point, needs unified backend, centralized certificates |
| Port Forwarding (NAT) | Gateway directly forwards public ports to ServBay host | Only one backend, and you know what you’re doing |
Method 1: Built-In Tunnels (Simplest, No Public IP Needed)
If you lack a public IP, or don’t want to fuss with reverse proxies and certs, ServBay’s built-in tunnel services are the easiest choice. They establish outbound connections from ServBay, automatically bypassing NAT, IPv6, port forwarding, and certificate trust headaches:
- Cloudflare Tunnel (cloudflared) — Exposes local sites via Cloudflare’s global network, granting auto-issued trusted HTTPS, no ports needed. Ideal when you want a stable public domain + CDN/WAF.
- frp (frpc) — Connects to your self-hosted frps server for full self-management.
- ngrok / Pinggy — Instantly creates a temporary public URL, handy for demos or Webhook testing.
For most users, a “one-click” cloudflared tunnel solves “publish local site to internet” in minutes—no need to read on unless you require a reverse proxy or port forwarding.
Method 2: Frontend Reverse Proxy + HTTPS Upstream (Recommended)
This is the recommended production approach: frontend proxy provides public trusted HTTPS, and upstreams to ServBay over HTTPS (keep sites in HTTP & HTTPS mode)—ensuring end-to-end encryption.
Why Prefer HTTPS Upstream Over Plain HTTP 80
Most outdated tutorials still suggest “run HTTP on the backend, use plaintext to proxy.” We discourage this unless you have very specific reasons and accept the risks:
- End-to-End Encryption: Even if proxy and ServBay are on the same LAN, traffic is always encrypted, eliminating the risk of internal packet sniffing or tampering.
- Modern Protocol Support: Only via HTTPS can the frontend enable HTTP/2 (h2)—providing multiplexing, header compression, connection reuse, and more. Plain HTTP 80 locks you into old paradigms.
- Avoid Downgrade Pitfalls: Backsliding to HTTP means headaches from
HTTP & HTTPS’s 301, HSTS cache, app-levelhttpslinks, and more. - Trusting the ServBay CA is Easy: ServBay’s self-signed CA is fine—just have your proxy trust this CA or skip validation. One-time setup, long-term stable.
If you truly need plain HTTP 80, see Method 3. For users who know exactly what they’re doing.
General Key Points
The following apply to all four reverse proxy types. Example: public domain example.com, ServBay backend host 192.168.1.115, backend HTTPS port 443, and the ServBay site remains in HTTP & HTTPS mode.
- Upstream via HTTPS: Set
proxy_pass(or upstream) tohttps://192.168.1.115:443. - Send the Correct SNI: SNI must equal the ServBay site domain (
example.com), or ServBay can’t select the right site/cert. - Trust the ServBay CA (recommended) or skip verification: See below for how to get the CA file.
- Preserve the Host header: Use
Host: example.comfor ServBay’sserver_namematching. - Send
X-Forwarded-Proto: https: So backend apps know the original request was HTTPS, avoiding redirect loops or HTTP link generation. - Ensure IPv4 / IPv6 Consistency: See IPv4/IPv6 Consistency.
Getting the ServBay CA (for Upstream Certificate Validation)
The ServBay local root CA certificate file is located in your ServBay install directory:
- macOS:
/Applications/ServBay/ssl/private/ServBay-Private-CA-ECC-Root.crt - Windows:
C:\ServBay\ssl\private\ServBay-Private-CA-ECC-Root.crt(path may vary)
Copy this .crt file to your reverse proxy server (e.g. /etc/nginx/servbay-ca/) and configure your proxy to trust it for upstream validation.
About the Certificate Chain
ServBay uses a “Root CA + Intermediate CA” two-tier architecture, with site certs issued by the intermediate. If proxying fails because only the root is trusted, combine the root and intermediate cert (e.g. ServBay-Private-CA-ECC-Intermediate.crt in the same folder) into a single CA bundle for validation. You can also first test the chain by temporarily disabling validation, then later enforce strict validation.
Example: Nginx Reverse Proxy (HTTPS Upstream)
nginx
server {
listen 443 ssl;
listen [::]:443 ssl; # To support IPv6
server_name example.com;
# Public-facing trusted certificate (e.g., Let's Encrypt)
ssl_certificate /etc/nginx/certs/example.com/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/example.com/privkey.pem;
location / {
proxy_pass https://192.168.1.115:443; # HTTPS upstream
# —— Key: SNI & Upstream Validation ——
proxy_ssl_server_name on; # Send SNI
proxy_ssl_name example.com; # SNI = ServBay site domain
proxy_ssl_trusted_certificate /etc/nginx/servbay-ca/servbay-ca-bundle.crt;
proxy_ssl_verify on; # Enable validation after trusting ServBay CA
proxy_ssl_verify_depth 2; # Two tiers: root + intermediate
# Simpler (no CA): proxy_ssl_verify off;
# —— Key: Preserve Host & Protocol ——
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;
}
}
# HTTP to HTTPS redirect (handled at the proxy)
server {
listen 80;
listen [::]:80;
server_name example.com;
return 301 https://$host$request_uri;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Example: HAProxy Reverse Proxy (HTTPS Upstream)
haproxy
frontend fe_web
bind :80
bind :443 ssl crt /etc/haproxy/certs/example.com.pem
http-request redirect scheme https unless { ssl_fc }
http-request set-header X-Forwarded-Proto https if { ssl_fc }
default_backend be_servbay
backend be_servbay
option forwardfor
http-request set-header Host example.com
# HTTPS upstream: ssl + send SNI + validate ServBay CA
server servbay1 192.168.1.115:443 ssl sni str(example.com) \
verify required ca-file /etc/haproxy/servbay-ca/servbay-ca-bundle.crt
# Simpler: server servbay1 192.168.1.115:443 ssl sni str(example.com) verify none1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
Example: Caddy Reverse Proxy (HTTPS Upstream)
Caddy handles certificate issuance/renewal for example.com automatically, and reverse_proxy passes Host and X-Forwarded-* by default:
caddy
example.com {
reverse_proxy https://192.168.1.115:443 {
header_up Host {host}
transport http {
tls_server_name example.com # SNI
tls_trusted_ca_certs /etc/caddy/servbay-ca/servbay-ca-bundle.crt
# Simpler: tls_insecure_skip_verify
}
}
}1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
Example: Traefik Reverse Proxy (HTTPS Upstream)
File provider dynamic configuration example:
yaml
# traefik-dynamic.yml
http:
routers:
servbay:
rule: "Host(`example.com`)"
entryPoints:
- websecure
service: servbay
tls:
certResolver: letsencrypt
services:
servbay:
loadBalancer:
passHostHeader: true # Pass Host header
servers:
- url: "https://192.168.1.115:443" # HTTPS upstream
serversTransport: servbay-tls
serversTransports:
servbay-tls:
serverName: example.com # SNI
rootCAs:
- /etc/traefik/servbay-ca/servbay-ca-bundle.crt
# Simpler: insecureSkipVerify: true1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Method 3: Port Forwarding (NAT)
If you only have one backend, you can configure your gateway/router to forward public ports directly to the ServBay host (assume LAN IP 192.168.1.115).
Recommended: Forward Port 443, Keep HTTPS
- Set up gateway port forwarding:
Public 443 → 192.168.1.115:443(andPublic 80 → 192.168.1.115:80so ServBay can internally redirect 80 to 443). - Set DNS
Arecord to your public IPv4. - Keep the site in
HTTP & HTTPSmode. Since visitors connect directly to ServBay, you must configure a publicly trusted certificate for that domain (see below), or users will encounter browser cert warnings. - Ensure IPv4/IPv6 are consistent (see next section).
Plain HTTP 80 Forwarding (For Special Cases Only)
Only forwarding port 80 and switching a site to HTTP mode sacrifices all HTTPS/HTTP2 benefits and often leads to browser HSTS/cache issues. Recommended only for users who absolutely need it and fully understand the risks. If you must: explicitly set site protocol to HTTP (to avoid 301s to unavailable 443) and only forward port 80.
IPv4/IPv6 Consistency
One common cause of unstable public access: if a domain has both A (IPv4) and AAAA (IPv6) records, clients (due to Happy Eyeballs) will sometimes prefer IPv6. If you only port forward or proxy IPv4, IPv6 requests will fail. Two options:
- Use IPv4 Only: Ensure
dig AAAA yourdomain +shortreturns nothing; only keep theArecord. - Support IPv6 Too: Set up port forwarding/proxy listeners for IPv6 (
[::]), and ensure the backend is reachable over IPv6.
Public Access Troubleshooting Checklist
Got issues with public access (unreachable, timeouts, cert errors, wrong site, etc.)? Systematically check (domain example.com, backend 192.168.1.115):
Are you being 301-redirected to port 443, which isn’t open?
bashcurl -I http://example.com1If it returns
301andLocation: https://..., but you haven’t set up 443 → there's your answer. Enable HTTPS access (recommended) or switch this site toHTTPmode.Is IPv6 causing trouble?
bashcurl -4 -I https://example.com # IPv4 only curl -6 -I https://example.com # IPv6 only dig A example.com +short dig AAAA example.com +short # Has AAAA, but IPv6 isn’t reachable? Remove or fix it.1
2
3
4Is SNI/cert validation failing upstream? (HTTPS proxy scenarios) Test with the right SNI:
bashcurl -I --resolve example.com:443:192.168.1.115 https://example.com \ --cacert /path/servbay-ca-bundle.crt1
2If cert/site mismatch, SNI is likely wrong or CA not trusted.
Is the request reaching ServBay? On the ServBay host, check the web server access log for that site. If timeouts don’t show in the log, it’s likely a networking/gateway/proxy issue.
Is the Host header correct? (L7 proxy scenarios)
bashcurl -k -I -H "Host: example.com" https://192.168.1.115/1Works when connecting direct, but fails through proxy → Proxy isn’t preserving the Host header.
Certificates and Security
- Upstream connections: When proxying reverse → ServBay over HTTPS, have the proxy trust the ServBay CA (
ServBay-Private-CA-ECC-Root.crt, merge the intermediate cert if needed). This is internal trust—a one-time setup. - Public certificates: Certificates for public visitors must be from a public trusted CA. Reverse proxy mode puts this on the proxy (Caddy/Traefik can auto-issue/renew). Port-forwarding direct means you need a public cert on ServBay—see Issuing SSL Certificates via ACME. The ServBay self-signed
ServBay User CAis for local/LAN use only and isn’t trusted by public users. - Don’t expose databases: When exposing the web to the internet, do NOT also open MySQL, Redis, Memcached, or similar ports. For hardening, see LAN Access.
- Firewalls: Only open required ports; block everything else.
FAQ
- Q: Local works, but public access fails. Is this a DNS issue?
- A: Usually not “can’t resolve”—it’s because of
HTTP & HTTPS301s to unopened 443, SNI/cert misconfiguration, missing Host header, or IPv4/IPv6 mismatches. Debug using the checklist.
- A: Usually not “can’t resolve”—it’s because of
- Q: Do I have to downgrade to HTTP 80 for reverse proxying?
- A: No, and it’s not recommended. Stay on
HTTP & HTTPS; proxy upstreams via HTTPS and trusts (or skips) the ServBay CA. This gives you end-to-end encryption and HTTP/2 support.
- A: No, and it’s not recommended. Stay on
- Q: Reverse proxy fails with cert/site errors?
- A: Ensure correct SNI (site domain) and trust the ServBay CA (include intermediate cert if needed). For quick testing, skip validation first, then enforce strict validation.
- Q: Is running ServBay as an origin on a server stable in production?
- A: Yes. Many users run ServBay on Mac mini/Windows servers in datacenters with stable external service. Align protocol mode, SNI, Host header, cert trust, and IPv4/IPv6 for success.
- Q: What if I don’t have a public IP?
- A: Use Method 1: Built-In Tunnels (cloudflared/frpc). No public IP or port forwarding required.
Summary
Publishing ServBay as a backend origin server on the public internet is technically straightforward. The recommended approach is: keep sites in HTTP & HTTPS mode, use a frontend reverse proxy for HTTPS upstream, send the correct SNI and trust the ServBay CA for end-to-end encryption and HTTP/2. If without a public IP, the built-in cloudflared/frpc tunnels are the easiest. Port forwarding is suitable for those who know precisely what they’re doing. If you run into access issues, follow the troubleshooting checklist—problems almost always boil down to protocol mode, SNI/cert config, Host header, or IPv4/IPv6.
