A custom domain for a playground project
A project published on the playground (https://jumphp.net) can have its own address, e.g. monapp.example.org, served like
bin/jumphp deploy does: the project's site (site/) at the root ({{DOMAIN}} = the domain), the game or application in
/play/. The HTTPS certificate comes by itself at the first visit.
For the project's owner
- Studio → the project → Custom domain → the domain → Add the domain.
- At the domain's DNS host, two records (the studio shows them, ready to copy):
monapp.example.org. CNAME apps.jumphp.net. _jumphp.monapp.example.org. TXT "jumphp-verify=<the studio's token>"- the CNAME points to the server, without proxy (Cloudflare: grey cloud, "DNS only"): the server must see the TLS connection to get the certificate;
- the TXT proves the domain is yours;
- a root domain (no subdomain) cannot have a CNAME: give it the same IP addresses (A / AAAA) as
apps.jumphp.net.
- Check the DNS (propagation can take minutes; the studio says what is missing: the TXT, or the CNAME).
- Depending on the playground's settings, the administrator approves the domain ("Waiting for the administrator"), or it is online as soon as it is verified.
- Open
https://monapp.example.org/: the first visit makes the certificate (a few seconds).
Disabling the domain cuts it at once; Enable brings it back. A later failed check (CNAME removed) takes it offline. The domain always
serves the published version, and nothing of the portal (no studio, no sign-in, no cookie). The game asks its TCP tickets from its
own origin and opens wss://<the domain>/tcp: nothing to set.
For the playground's administrator
Administration → Partner sites and domains: every domain, its state, Check the DNS, Approve / remove the approval, Block (the owner cannot restore it), Delete.
How it is served: Traefik passes only the served domains through to the playground's Caddy (its HTTP provider reads
http://jumphp-playground-internal:9180/api/domains/traefik: a TCP HostSNI(...) passthrough router to jumphp-playground-tls@docker
and a port-80 router to jumphp-playground-http@docker). No low-priority HostSNI(*) catch-all: Traefik applies TCP routers
before the HTTP routers of the same entry point, so a catch-all would take the TLS of every other site of that Traefik. Caddy
(docker/Caddyfile) has an https:// site (CUSTOM_DOMAINS_SITE) with tls { on_demand } and
on_demand_tls { ask http://127.0.0.1:9180/api/domains/ask }; /api/domains/ask?domain=x answers 200 only for a served domain
(verified, on, not blocked, approved when approval is required, project published).
Settings (deploy/.env): CUSTOM_DOMAINS_SITE (https:// turns it on; default serves nothing), CUSTOM_DOMAINS_TARGET
(apps.jumphp.net), CUSTOM_DOMAINS_APPROVAL (1: the administrator approves each domain; 0: the DNS check is enough),
TRAEFIK_ENTRYPOINT, TRAEFIK_HTTP_ENTRYPOINT.
Once: apps.jumphp.net A <server IP> (DNS only), Traefik's static configuration
providers.http.endpoint: "http://jumphp-playground-internal:9180/api/domains/traefik" (pollInterval: "15s"), then
CUSTOM_DOMAINS_SITE=https:// in deploy/.env and a redeploy of the playground.