Behind a proxy: HTTPS, Cloudflare and visitor IP addresses
Get HTTPS for your Hub (Caddy, Cloudflare, your host's proxy, Nginx), then set AGORA_TRUSTED_PROXIES and let live streams through.
Updated on Oct 4, 2026, 5:45 p.m.
On this page
In short. Agora listens in clear text (HTTP) on its port: 3000 with Docker, the panel's allocation on a panel. To switch to HTTPS (the encrypted version, with the browser's padlock), you put a reverse proxy in front of it: a program or service that receives your visitors over HTTPS on your domain and hands them to Agora. Then you tell Agora who is allowed to announce your visitors' IP address.
HTTPS becomes essential as soon as your server leaves the testing phase: the FiveM resource refuses to talk to a Hub over http:// at a public address (an address on your local network is not subject to this).
Before you start #
- Agora installed and reachable at
http://IP:PORT, through one of the routes in Choose between Docker, the panel egg and a Node.js server. - A domain name (for example
forum.myserver.com), bought from a domain registrar. The words reverse proxy, HTTPS, port and domain name are in the glossary. - Agora administrator access, to change the public address in the admin area.
Steps #
Pick your method according to what you have:
Your situation The simplest method Docker with the manual compose file, domain pointed at your machine, ports 80 and 443 free The compose file's Caddy profile Docker, or another machine, and you already have Nginx, Traefik or Caddy Your current reverse proxy Panel (Pterodactyl, Pelican) or Node.js server, domain managed by Cloudflare A Cloudflare tunnel Panel or Node.js server, and your host offers an HTTPS sub-domain pointing to your port The host's sub-domain Set up HTTPS with the chosen method:
Caddy profile (manual compose): set
SITE_ADDRESSto your domain in the.env, then rundocker compose --profile caddy up -d. Caddy obtains and renews the certificate on its own. Ports 80 and 443 must be free.Existing reverse proxy: point it at Agora's port (
http://IP:3000with Docker).Cloudflare tunnel: a tunnel is an outgoing link that Cloudflare opens towards your server, without opening anything in your firewall. In your Cloudflare Zero Trust dashboard, create a tunnel, install the command it gives you on a machine that can reach your server, then add a public hostname (
forum.myserver.com) whose service ishttp://IP:PORT, with your server's IP and port. <!-- À CONFIRMER : libellés actuels de Cloudflare Zero Trust (Networks → Tunnels, nom d'hôte public), à vérifier sur un compte Cloudflare --><!-- CAPTURE C-068 -->
Host's sub-domain: in your host's panel, look for an option along the lines of "sub-domain" or "proxy" that links a name to your port, then use that name. <!-- À CONFIRMER : cette option varie d'un hébergeur à l'autre ; aucun hébergeur testé -->
Tell Agora its new address. In Administration → Configuration → Agora resource, Public Hub address field, enter
https://forum.myserver.com. (If theSITE_URLvariable is set, the field is read-only and the variable is used.)<!-- CAPTURE C-066 -->
Update Discord. Add the callback URL
https://forum.myserver.com/api/auth/callback/discordto the Redirects of your Discord application: see Connect Discord to Agora.Redeploy the FiveM resource, which embeds the address: see Install the agora FiveM resource.
Set
AGORA_TRUSTED_PROXIES: see "Who may announce a visitor's IP" below.
You know it worked when… #
https://your-domain/api/healthanswers"ok":true, with the padlock in the browser.<!-- CAPTURE C-067 -->
Discord sign-in works from the new address.
Server → Players still receives the resource's signal.
If it does not work #
| What you see | Likely cause | What to do |
|---|---|---|
| "Reconnecting…" flickers on the live map, dispatch or console | The proxy buffers or cuts long connections | See "Live streams" below |
Discord refuses the sign-in (redirect_uri) | The callback URL was not updated | See Discord sign-in fails |
| A Cloudflare error page (502, 523…) | The tunnel or proxy cannot reach your server | Check the target's IP and port, and that the server is running |
| The FiveM resource no longer connects | It embeds the old address | Redeploy it: see Troubleshoot the FiveM resource |
| Visitors are rate-limited wrongly, or everyone shares the same limit | AGORA_TRUSTED_PROXIES does not fit your setup | See below |
Going further #
Who may announce a visitor's IP (AGORA_TRUSTED_PROXIES) #
Agora rate-limits some actions per IP address (getting started, tablet, 911, search…). So it reads the connection's IP, and only trusts the X-Forwarded-For header when it comes from a trusted proxy.
| Value | Who is trusted | For which setup |
|---|---|---|
| empty | Private networks and loopback | Reverse proxy on the same machine or Docker network, Cloudflare tunnel, Caddy profile |
none | Nobody | Port exposed directly to the Internet, nothing in front. This is the value of a fresh install.sh install |
| a list | Exactly these IPs or ranges | A proxy at a public address, or Cloudflare "orange cloud" directly in front of the port |
A Cloudflare tunnel whose program runs on a machine with a public address falls under "a proxy at a public address": list that address. <!-- À CONFIRMER : cas d'un tunnel Cloudflare lancé sur une machine à adresse publique -->
You add a reverse proxy in front of an install.sh install #
- Open
/opt/agora/.env. - Replace
AGORA_TRUSTED_PROXIES=nonewithAGORA_TRUSTED_PROXIES=(empty). - Run
cd /opt/agora && docker compose up -d.
On a panel #
The variable is not in the distributed egg. Without it, private networks are trusted: another container on the node could announce the IP of its choice to the rate limits. If your players reach the port directly (nothing in front), the panel administrator can add the variable to the egg with the value none; if a reverse proxy or a Cloudflare tunnel runs on the node, leave it empty.
Cloudflare as a proxy, without a tunnel #
Declare the ranges published at cloudflare.com/ips, comma-separated. A list replaces private networks: if your reverse proxy is also on a Docker network, include both.
Live streams #
The live map, dispatch and console use streamed responses (Server-Sent Events). A proxy that buffers or cuts long connections makes "Reconnecting…" flicker.
On Nginx, turn buffering off and lengthen the read timeout:
proxy_buffering off;
proxy_read_timeout 3600s;Was this article helpful?
Related articles
- Install with Docker (install.sh)A single command installs Agora and its PostgreSQL database on a Linux machine with Docker: you have no database to prepare.
- Install on PelicanImport the Pelican egg (not the Pterodactyl one), create a server with it, then start it: the Hub's database is built in, you have nothing to provide.
- Install on a host's Node.js server (agora.mjs)Only have an ordinary host's customer panel? Order a Node.js server, drop a single file (agora.mjs) and your key: Agora installs its database and everything else.
- Environment variablesWhere and how to change Agora's startup settings depending on your installation route (Docker, panel, Node.js server), and the list of the ones that matter.
- The live map: permissions, on duty, multi-job, OneSyncLive player positions for staff, and for on-duty colleagues of the same job if you open it; almost no cost for the game server.
- Site settings and the home pageAdministration → Configuration applies everything live: name, logo, language, public address, theme, Discord, payments, security, map, portal, dealership and tablet.