One hostname a charger can be told about and actually reach
Charger control needs TLS, and the stack speaks plain HTTP, so the README said "terminate TLS in a reverse proxy" and left the operator to work out which four settings have to agree. This adds the proxy: a Caddy overlay that fronts the Web App BFF — which already carries /api/ and /ocpp/ — so browsers and chargers arrive at the same name and the certificate is issued on first boot. The four settings are derived from DV_DOMAIN, since one value getting typed right is better odds than four: OCPP_PUBLIC_URL, OCPP_REQUIRE_TLS back on, CORS, and TRUST_FORWARDED_PROTO on the Web App. That last one is the non-obvious one — without it the BFF overwrites Caddy's X-Forwarded-Proto with its own plaintext hop and the API Server rejects the charger it just told to connect over wss. The README's OCPP section was stale besides: it still sent chargers to the API Server port alone, from before the BFF carried that path. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
9f5c8dc49a
commit
e9a82a1cca
+40
-9
@@ -80,16 +80,47 @@ instead. PocketBase runs as root, so a root-owned host directory is fine.
|
||||
|
||||
## Charger control (OCPP)
|
||||
|
||||
Chargers in own/proxy mode dial in to `/ocpp/{serial}` **on the API Server
|
||||
port**, authenticating with a per-charger control token in an OCPP Basic-auth
|
||||
header. A plaintext `ws://` would put that token on the wire in the clear, so
|
||||
`OCPP_REQUIRE_TLS` defaults to `true` and non-TLS connections are rejected.
|
||||
Chargers in own/proxy mode dial in to `/ocpp/{serial}`, authenticating with a
|
||||
per-charger control token in an OCPP Basic-auth header. Two ports answer that
|
||||
path: the API Server's own, and the Web App's, whose BFF proxies `/ocpp/`
|
||||
through. The second one matters because it is the address the panel hands out —
|
||||
the endpoint is derived from the host the panel itself was reached on, which is
|
||||
the Web App, unless `OCPP_PUBLIC_URL` says otherwise.
|
||||
|
||||
This stack serves plain HTTP, so to actually use charger control you need to
|
||||
terminate TLS in a reverse proxy in front of it and set `OCPP_PUBLIC_URL` to the
|
||||
public `wss://` base (behind a proxy, deriving it from request headers is
|
||||
unreliable). `OCPP_REQUIRE_TLS=false` is for trusted networks only. You will
|
||||
also need `API_BIND` set so the proxy can reach the port.
|
||||
A plaintext `ws://` puts the control token on the wire in the clear, so
|
||||
`OCPP_REQUIRE_TLS` defaults to `true` and non-TLS connections are rejected.
|
||||
`OCPP_REQUIRE_TLS=false` is for a trusted network you own end to end.
|
||||
|
||||
### With a public hostname and TLS
|
||||
|
||||
`docker-compose.tls.yml` adds Caddy in front of the stack: one hostname, a
|
||||
certificate issued on first boot, and everything behind it spoken to over the
|
||||
compose network. Browsers and chargers arrive at the same name.
|
||||
|
||||
```sh
|
||||
# in .env
|
||||
DV_DOMAIN=drivervault.example.com
|
||||
DV_ACME_EMAIL=you@example.com
|
||||
|
||||
docker compose -f docker-compose.prod.yml -f docker-compose.tls.yml up -d
|
||||
```
|
||||
|
||||
The overlay sets the rest for you: `OCPP_PUBLIC_URL=wss://$DV_DOMAIN`,
|
||||
`OCPP_REQUIRE_TLS=true`, `CORS_ALLOW_ORIGINS=https://$DV_DOMAIN`, and
|
||||
`TRUST_FORWARDED_PROTO=true` on the Web App so the BFF passes Caddy's
|
||||
`X-Forwarded-Proto` to the API Server instead of overwriting it with its own
|
||||
plaintext hop. Point the charger's OCPP backend at the endpoint the panel then
|
||||
shows, with the control token as its authorization key.
|
||||
|
||||
Two things the overlay cannot arrange: `DV_DOMAIN` must resolve to the host from
|
||||
the internet with ports 80 and 443 reaching it (Caddy needs `:80` for the ACME
|
||||
challenge), and the charger must be able to resolve that name too — behind NAT
|
||||
that usually means hairpin NAT or a split-DNS entry pointing it at the LAN
|
||||
address.
|
||||
|
||||
Using a proxy you already run instead? Terminate TLS there, forward to the Web
|
||||
App port, and set the same four variables by hand — the `X-Forwarded-Proto` one
|
||||
included, or chargers will be rejected as insecure.
|
||||
|
||||
## Notes
|
||||
|
||||
|
||||
Reference in New Issue
Block a user