Agora

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
  1. Before you start
  2. Steps
  3. You know it worked when…
  4. If it does not work
  5. Going further
  6. Who may announce a visitor's IP (AGORA_TRUSTED_PROXIES)
  7. Live streams

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 #

  1. Pick your method according to what you have:

    Your situationThe simplest method
    Docker with the manual compose file, domain pointed at your machine, ports 80 and 443 freeThe compose file's Caddy profile
    Docker, or another machine, and you already have Nginx, Traefik or CaddyYour current reverse proxy
    Panel (Pterodactyl, Pelican) or Node.js server, domain managed by CloudflareA Cloudflare tunnel
    Panel or Node.js server, and your host offers an HTTPS sub-domain pointing to your portThe host's sub-domain
  2. Set up HTTPS with the chosen method:

    • Caddy profile (manual compose): set SITE_ADDRESS to your domain in the .env, then run docker 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:3000 with 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 is http://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é -->

  3. Tell Agora its new address. In Administration → Configuration → Agora resource, Public Hub address field, enter https://forum.myserver.com. (If the SITE_URL variable is set, the field is read-only and the variable is used.)

    <!-- CAPTURE C-066 -->

  4. Update Discord. Add the callback URL https://forum.myserver.com/api/auth/callback/discord to the Redirects of your Discord application: see Connect Discord to Agora.

  5. Redeploy the FiveM resource, which embeds the address: see Install the agora FiveM resource.

  6. Set AGORA_TRUSTED_PROXIES: see "Who may announce a visitor's IP" below.

You know it worked when… #

  • https://your-domain/api/health answers "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 seeLikely causeWhat to do
"Reconnecting…" flickers on the live map, dispatch or consoleThe proxy buffers or cuts long connectionsSee "Live streams" below
Discord refuses the sign-in (redirect_uri)The callback URL was not updatedSee Discord sign-in fails
A Cloudflare error page (502, 523…)The tunnel or proxy cannot reach your serverCheck the target's IP and port, and that the server is running
The FiveM resource no longer connectsIt embeds the old addressRedeploy it: see Troubleshoot the FiveM resource
Visitors are rate-limited wrongly, or everyone shares the same limitAGORA_TRUSTED_PROXIES does not fit your setupSee 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.

ValueWho is trustedFor which setup
emptyPrivate networks and loopbackReverse proxy on the same machine or Docker network, Cloudflare tunnel, Caddy profile
noneNobodyPort exposed directly to the Internet, nothing in front. This is the value of a fresh install.sh install
a listExactly these IPs or rangesA 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 #

  1. Open /opt/agora/.env.
  2. Replace AGORA_TRUSTED_PROXIES=none with AGORA_TRUSTED_PROXIES= (empty).
  3. 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?