Repository navigation
Reverse Proxy
Start the backend using Deployment, then choose one proxy below. An ordinary installation needs one hostname and one proxy; leave MirrorProxy ACME off.
| Software | Certificates | Example |
|---|---|---|
| Caddy | Automatic issuance and renewal | Configuration |
| Nginx / OpenResty | Existing certificates or Certbot | Configuration |
| Traefik v3 | Built-in ACME | Configuration |
| Apache HTTP Server 2.4 | Existing certificates or Certbot | Configuration |
| HAProxy | PEM loaded from an external certificate tool | Configuration |
| Nginx Proxy Manager | Certificate management in its UI | Form example |
- Replace every
mirror.example.com, point DNS at the gateway, and make its public ports 80/443 reachable. - File examples below assume the proxy runs on the host, with backend
http://127.0.0.1:3000. Proxy the whole site without a/mirrorproxy/prefix; preserve paths and query strings. - The binary trusts loopback; the deployment page's Docker backend trusts its fixed bridge gateway
172.30.40.1. Trust only actual proxies, never0.0.0.0/0. - For a container proxy, use the shared-network service name and a fixed trusted proxy address instead. See the complete quick start.
- Merge into existing configurations, retain a copy, check syntax, and then reload. Do not overwrite other sites.
Install using Caddy's instructions. With its official systemd service, edit /etc/caddy/Caddyfile:
mirror.example.com {
reverse_proxy 127.0.0.1:3000
}sudo caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile
sudo systemctl reload caddyCaddy obtains and renews certificates and redirects HTTP to HTTPS. Certbot is unnecessary.
If its service has not been started yet, use sudo systemctl enable --now caddy.
Automatic HTTPS
The proxy directives also work with OpenResty. A common Debian/Ubuntu Nginx site file is /etc/nginx/conf.d/mirrorproxy.conf.
With Nginx-based panels such as aaPanel or 1Panel, edit the matching site's reverse-proxy settings rather than creating duplicate sites.
No certificate yet? Start an HTTP site, then let Certbot enable HTTPS. Initial site:
server {
listen 80;
server_name mirror.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Connection "";
proxy_buffering off;
proxy_read_timeout 300s;
}
}Check and load it, install Certbot using its official instructions, then run:
sudo nginx -t
sudo systemctl reload nginx
sudo certbot --nginx --redirect -d mirror.example.com
sudo certbot renew --dry-runCertbot adds the TLS listener, certificate paths, and HTTP redirect. OpenResty and panel-managed installations may use different executables and service names;
use their certificate tools or a matching certificate installation, rather than blindly running the system nginx command.
Already have certificates? Complete 80/443 site
The certificate files must already exist. Adjust the paths:
server {
listen 80;
server_name mirror.example.com;
return 301 https://mirror.example.com$request_uri;
}
server {
listen 443 ssl;
server_name mirror.example.com;
ssl_certificate /etc/letsencrypt/live/mirror.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mirror.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Connection "";
proxy_buffering off;
proxy_read_timeout 300s;
}
}Run sudo nginx -t and only then sudo systemctl reload nginx.
The example overwrites client-supplied scheme/address headers, preserves the original Host and port, and does not append a URI to proxy_pass.
Reload Nginx after certificate renewal. Proxy directives
For Traefik v3 running on the host, using a file provider without a Docker socket.
Merge this static configuration into /etc/traefik/traefik.yml and replace the email:
entryPoints:
web:
address: ':80'
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ':443'
providers:
file:
filename: /etc/traefik/mirrorproxy.yml
watch: true
certificatesResolvers:
letsencrypt:
acme:
email: admin@example.com
storage: /var/lib/traefik/acme.json
httpChallenge:
entryPoint: webCreate /etc/traefik/mirrorproxy.yml for the dynamic route:
http:
routers:
mirrorproxy:
rule: 'Host(`mirror.example.com`)'
entryPoints: [websecure]
service: mirrorproxy
tls:
certResolver: letsencrypt
services:
mirrorproxy:
loadBalancer:
passHostHeader: true
servers:
- url: 'http://127.0.0.1:3000'The Traefik account must be able to write /var/lib/traefik. Keep acme.json persistent and readable/writable only by that account (0600).
Restart after static configuration changes; an existing systemd service can use sudo systemctl restart traefik.
For foreground operation, use traefik --configFile=/etc/traefik/traefik.yml; binding 80/443 needs permission.
Traefik issues certificates, preserves Host, and supplies scheme/client-address headers. Do not enable forwardedHeaders.insecure.
ACME reference
For Apache HTTP Server 2.4 with ssl, headers, proxy, proxy_http, and alias enabled.
Debian/Ubuntu can use sudo a2enmod ssl headers proxy proxy_http alias.
Prepare a valid certificate first. If needed, use the Certbot Apache guide
with an existing HTTP site before applying the complete configuration below.
Save /etc/apache2/sites-available/mirrorproxy.conf, using your certificate paths:
<VirtualHost *:80>
ServerName mirror.example.com
Redirect permanent / https://mirror.example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName mirror.example.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/mirror.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/mirror.example.com/privkey.pem
SSLProtocol -all +TLSv1.2 +TLSv1.3
ProxyRequests Off
ProxyPreserveHost On
ProxyAddHeaders Off
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-For "expr=%{REMOTE_ADDR}"
RequestHeader unset X-Forwarded-Host
RequestHeader unset X-Real-IP
AllowEncodedSlashes NoDecode
ProxyPass / http://127.0.0.1:3000/ nocanon
ProxyPassReverse / http://127.0.0.1:3000/
ProxyTimeout 300
</VirtualHost>sudo a2ensite mirrorproxy
sudo apachectl configtest
sudo systemctl reload apache2Other distributions may use httpd for paths and services. Reload Apache after certificate renewal.
The example disables forward proxying, proxies the whole site, and overwrites client-supplied address headers.
Apache proxy reference
Prepare a certificate first. HAProxy's PEM file contains both the chain and private key; fullchain.pem alone is insufficient:
sudo install -d -m 0700 /etc/haproxy/certs
sudo sh -c 'umask 077; cat /etc/letsencrypt/live/mirror.example.com/fullchain.pem /etc/letsencrypt/live/mirror.example.com/privkey.pem > /etc/haproxy/certs/mirror.pem'For a dedicated /etc/haproxy/haproxy.cfg; merge only the relevant frontend/backend sections into a shared installation:
global
log stdout format raw local0
ssl-default-bind-options ssl-min-ver TLSv1.2
defaults
mode http
timeout connect 10s
timeout client 300s
timeout server 300s
frontend mirror_http
bind :80
http-request redirect scheme https code 301
frontend mirror_https
bind :443 ssl crt /etc/haproxy/certs/mirror.pem
http-request set-header X-Forwarded-Proto https
http-request set-header X-Forwarded-For %[src]
http-request del-header X-Forwarded-Host
http-request del-header X-Real-IP
default_backend mirrorproxy
backend mirrorproxy
server app 127.0.0.1:3000 checksudo haproxy -c -f /etc/haproxy/haproxy.cfg
sudo systemctl reload haproxyAfter external certificate renewal, regenerate mirror.pem, validate, and reload HAProxy. Updating only the original certificate files is insufficient.
HAProxy TLS example
In Nginx Proxy Manager, open Proxy Hosts → Add Proxy Host:
| Field | Example |
|---|---|
| Domain Names | mirror.example.com |
| Scheme | http |
| Forward Hostname / IP |
127.0.0.1 for a host proxy; mirrorproxy on a shared container network |
| Forward Port | 3000 |
| SSL Certificate | Request a new SSL Certificate, or select an existing valid certificate |
| Force SSL | Enabled |
NPM usually runs in a container: mirrorproxy:3000 on the same network is the common backend.
Do not copy 127.0.0.1 into that setup. MirrorProxy should trust NPM's actual fixed container address.
NPM cannot share the same ports 80/443 with Caddy/Nginx. Save and open the HTTPS hostname.
NPM guide
curl -f https://mirror.example.com/healthz
curl -f https://mirror.example.com/npm/is-numberAlso sign in at /admin and reload. For 502, certificate, or login failures, follow Troubleshooting.
开始使用 · Start here
- 首页 · Home
- Docker + HTTPS 快速开始 · Quick start
- 二进制与已有入口部署 · Deployment
- 常见反向代理配置 · Reverse proxies
- 常见问题 · Troubleshooting
日常使用 · Everyday use
- 客户端改源 · Client
- Linux 系统与版本支持 · Linux system sources
- 其他客户端安装方式 · Client installation
- 支持的软件源 · Sources
- 容器镜像总览 · Container images
- 后台管理 · Administration
进阶配置 · Advanced
开发与维护 · Development