OpenHosting listens on plain HTTP (port 3000). In production you put a reverse
proxy in front of it to terminate TLS, and set Admin → Settings → Public
URL to your https:// address so emails and payment redirects are correct.
The one-line installer does this for you: it installs nginx, proxies it to the app, and obtains a Let's Encrypt certificate for your domain (
--domain, or answer its prompt) with automatic renewal. Adding the domain later — or moving the app to another port, which repoints nginx too — is the installer's--reconfigureaction. The sections below are for custom or manual setups; pass--no-nginx(OH_SKIP_NGINX=1) to bring your own proxy.
The simplest option — Caddy fetches and renews certificates automatically:
billing.example.com {
reverse_proxy localhost:3000
}
server {
listen 80;
server_name billing.example.com;
location / { return 301 https://$host$request_uri; }
}
server {
listen 443 ssl;
server_name billing.example.com;
ssl_certificate /etc/letsencrypt/live/billing.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/billing.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Obtain the certificate with certbot:
certbot --nginx -d billing.example.comIf you run the Docker stack behind Traefik, add labels to the app service in
docker-compose.yml:
labels:
- "traefik.enable=true"
- "traefik.http.routers.oh.rule=Host(`billing.example.com`)"
- "traefik.http.routers.oh.tls.certresolver=le"
- "traefik.http.services.oh.loadbalancer.server.port=3000"OpenHosting reads the client IP from X-Forwarded-For for the audit log and
fraud checks (velocity limits, ban lists). Make sure your
proxy sets it, as shown above. Without it, all requests appear to come from the
proxy's own IP.
On Kubernetes, TLS is handled by the Ingress + cert-manager — see Deploy on Kubernetes.