Replace nginx with Caddy for TLS termination and reverse proxying.
- Replace nginx with Caddy as the web server for both Docker and native
(RPi/Debian) deployments. Caddy handles HTTPS termination, reverse
proxying to all services (API, React app, Controller, Kiwix, Help, Map),
and serves the media/download file browsers.
- Generate a Root CA and signed leaf certificates for HTTPS. The Root CA
uses Name Constraints to restrict signing to local addresses only
(.local, localhost, and RFC 1918 private IP ranges), mitigating MITM
risk if the CA key is compromised.
- Add an HTTP landing page that guides users through one-time CA
certificate installation on iOS, Android, macOS, Windows, Linux, and
Firefox, with auto-redirect when the cert is already trusted.
- Add trailing-slash redirects for /controller, /docs, /media, and
/download so bare paths don't fall through to the React catch-all.
- Add a Root CA download link on the Settings page under Configs.
- Update help.sh diagnostics for IPv6 listener detection and HTTP/2
status codes.
- Remove all nginx config files and the https_proxy Docker container.
- Bump wrolpi-help submodule with certificate documentation.
2026-03-07 12:08:27 -07:00
|
|
|
# WROLPi Docker
|
|
|
|
|
|
|
|
|
|
Development and testing environment using Docker containers.
|
|
|
|
|
|
|
|
|
|
## Quick Start
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git clone https://github.com/lrnselfreliance/wrolpi.git
|
|
|
|
|
cd wrolpi
|
|
|
|
|
git submodule update --init
|
|
|
|
|
docker-compose build --parallel
|
|
|
|
|
docker volume create --name=openstreetmap-data
|
|
|
|
|
docker volume create --name=openstreetmap-rendered-tiles
|
|
|
|
|
docker-compose run --rm api db upgrade
|
|
|
|
|
docker-compose up
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Browse to https://localhost:8443
|
|
|
|
|
|
|
|
|
|
## Services
|
|
|
|
|
|
2026-04-07 20:01:49 -06:00
|
|
|
| Service | Port(s) | Description |
|
|
|
|
|
|----------------|--------------------------|-----------------------------|
|
|
|
|
|
| **web** | 8443 (HTTPS), 8084-8086 | Caddy reverse proxy |
|
|
|
|
|
| **api** | 8081 | Sanic API server |
|
|
|
|
|
| **app** | (via web) | React frontend |
|
|
|
|
|
| **controller** | 8080 | System management (FastAPI) |
|
|
|
|
|
| **archive** | 8083 | SingleFile/Readability |
|
|
|
|
|
| **zim** | (via web:8085) | Kiwix |
|
|
|
|
|
| **help** | (via web:8086) | MkDocs documentation |
|
|
|
|
|
| **map** | (via web:8084) | OpenStreetMap tile server |
|
Replace nginx with Caddy for TLS termination and reverse proxying.
- Replace nginx with Caddy as the web server for both Docker and native
(RPi/Debian) deployments. Caddy handles HTTPS termination, reverse
proxying to all services (API, React app, Controller, Kiwix, Help, Map),
and serves the media/download file browsers.
- Generate a Root CA and signed leaf certificates for HTTPS. The Root CA
uses Name Constraints to restrict signing to local addresses only
(.local, localhost, and RFC 1918 private IP ranges), mitigating MITM
risk if the CA key is compromised.
- Add an HTTP landing page that guides users through one-time CA
certificate installation on iOS, Android, macOS, Windows, Linux, and
Firefox, with auto-redirect when the cert is already trusted.
- Add trailing-slash redirects for /controller, /docs, /media, and
/download so bare paths don't fall through to the React catch-all.
- Add a Root CA download link on the Settings page under Configs.
- Update help.sh diagnostics for IPv6 listener detection and HTTP/2
status codes.
- Remove all nginx config files and the https_proxy Docker container.
- Bump wrolpi-help submodule with certificate documentation.
2026-03-07 12:08:27 -07:00
|
|
|
|
|
|
|
|
## TLS Certificates
|
|
|
|
|
|
|
|
|
|
WROLPi uses a two-tier PKI for HTTPS. A **root CA** is generated once and persists
|
|
|
|
|
in the media directory. A **leaf certificate** is regenerated on every container start
|
|
|
|
|
to pick up hostname and IP changes.
|
|
|
|
|
|
|
|
|
|
### How it works
|
|
|
|
|
|
|
|
|
|
1. On first start, the `web` container generates a root CA at `/opt/media/config/ssl/`.
|
|
|
|
|
2. A leaf cert signed by the root CA is created at `/etc/ssl/caddy/` inside the container.
|
|
|
|
|
3. Caddy serves HTTPS on ports 443, 8084, 8085, and 8086 using the leaf cert.
|
2026-04-07 20:01:49 -06:00
|
|
|
4. The Controller serves on port 80 with a certificate trust banner when needed.
|
Replace nginx with Caddy for TLS termination and reverse proxying.
- Replace nginx with Caddy as the web server for both Docker and native
(RPi/Debian) deployments. Caddy handles HTTPS termination, reverse
proxying to all services (API, React app, Controller, Kiwix, Help, Map),
and serves the media/download file browsers.
- Generate a Root CA and signed leaf certificates for HTTPS. The Root CA
uses Name Constraints to restrict signing to local addresses only
(.local, localhost, and RFC 1918 private IP ranges), mitigating MITM
risk if the CA key is compromised.
- Add an HTTP landing page that guides users through one-time CA
certificate installation on iOS, Android, macOS, Windows, Linux, and
Firefox, with auto-redirect when the cert is already trusted.
- Add trailing-slash redirects for /controller, /docs, /media, and
/download so bare paths don't fall through to the React catch-all.
- Add a Root CA download link on the Settings page under Configs.
- Update help.sh diagnostics for IPv6 listener detection and HTTP/2
status codes.
- Remove all nginx config files and the https_proxy Docker container.
- Bump wrolpi-help submodule with certificate documentation.
2026-03-07 12:08:27 -07:00
|
|
|
|
|
|
|
|
### Trusting the certificate
|
|
|
|
|
|
2026-04-07 20:01:49 -06:00
|
|
|
1. Browse to `http://<host-ip>` to see the Controller. If the HTTPS certificate is not
|
|
|
|
|
yet trusted, a banner will appear with the download link and platform-specific
|
|
|
|
|
trust instructions.
|
Replace nginx with Caddy for TLS termination and reverse proxying.
- Replace nginx with Caddy as the web server for both Docker and native
(RPi/Debian) deployments. Caddy handles HTTPS termination, reverse
proxying to all services (API, React app, Controller, Kiwix, Help, Map),
and serves the media/download file browsers.
- Generate a Root CA and signed leaf certificates for HTTPS. The Root CA
uses Name Constraints to restrict signing to local addresses only
(.local, localhost, and RFC 1918 private IP ranges), mitigating MITM
risk if the CA key is compromised.
- Add an HTTP landing page that guides users through one-time CA
certificate installation on iOS, Android, macOS, Windows, Linux, and
Firefox, with auto-redirect when the cert is already trusted.
- Add trailing-slash redirects for /controller, /docs, /media, and
/download so bare paths don't fall through to the React catch-all.
- Add a Root CA download link on the Settings page under Configs.
- Update help.sh diagnostics for IPv6 listener detection and HTTP/2
status codes.
- Remove all nginx config files and the https_proxy Docker container.
- Bump wrolpi-help submodule with certificate documentation.
2026-03-07 12:08:27 -07:00
|
|
|
2. Download and install the root CA on your device.
|
|
|
|
|
3. All HTTPS ports will work without browser warnings.
|
|
|
|
|
|
|
|
|
|
The root CA only needs to be trusted once. Leaf certs can be regenerated (hostname
|
|
|
|
|
change, container rebuild) without needing to re-trust.
|
|
|
|
|
|
|
|
|
|
### Name Constraints
|
|
|
|
|
|
|
|
|
|
The root CA is restricted to local/private networks only via X.509 Name Constraints.
|
|
|
|
|
Even if the CA key were compromised, it cannot sign certificates for public domains.
|
|
|
|
|
|
|
|
|
|
Permitted:
|
|
|
|
|
|
|
|
|
|
- DNS: `*.local`, `localhost`
|
|
|
|
|
- IPv4: `127.0.0.0/8`, `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`
|
|
|
|
|
- IPv6: `::1`, `fc00::/7` (unique local), `fe80::/10` (link-local)
|
|
|
|
|
|
|
|
|
|
### EXTRA_SANS
|
|
|
|
|
|
|
|
|
|
The Docker container cannot discover the host's real LAN IP. Set `EXTRA_SANS` in a
|
|
|
|
|
`.env` file so the leaf certificate includes your host's IP and hostname:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
# .env
|
|
|
|
|
EXTRA_SANS=IP:10.0.0.5,DNS:myhost.local
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Each entry must have a type prefix (`IP:` or `DNS:`). Multiple entries are
|
|
|
|
|
comma-separated. After changing `EXTRA_SANS`, restart the web container:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
docker compose up -d --build web
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Regenerating the root CA
|
|
|
|
|
|
|
|
|
|
If you need to regenerate the root CA (e.g. after updating the certificate
|
|
|
|
|
generation script), delete the old CA files and rebuild:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
rm test/config/ssl/ca.crt test/config/ssl/ca.key
|
|
|
|
|
docker compose up -d --build web
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
All devices will need to re-download and re-trust the new CA from
|
2026-04-07 20:01:49 -06:00
|
|
|
`http://<host-ip>/ca.crt`.
|
Replace nginx with Caddy for TLS termination and reverse proxying.
- Replace nginx with Caddy as the web server for both Docker and native
(RPi/Debian) deployments. Caddy handles HTTPS termination, reverse
proxying to all services (API, React app, Controller, Kiwix, Help, Map),
and serves the media/download file browsers.
- Generate a Root CA and signed leaf certificates for HTTPS. The Root CA
uses Name Constraints to restrict signing to local addresses only
(.local, localhost, and RFC 1918 private IP ranges), mitigating MITM
risk if the CA key is compromised.
- Add an HTTP landing page that guides users through one-time CA
certificate installation on iOS, Android, macOS, Windows, Linux, and
Firefox, with auto-redirect when the cert is already trusted.
- Add trailing-slash redirects for /controller, /docs, /media, and
/download so bare paths don't fall through to the React catch-all.
- Add a Root CA download link on the Settings page under Configs.
- Update help.sh diagnostics for IPv6 listener detection and HTTP/2
status codes.
- Remove all nginx config files and the https_proxy Docker container.
- Bump wrolpi-help submodule with certificate documentation.
2026-03-07 12:08:27 -07:00
|
|
|
|
|
|
|
|
## Volumes
|
|
|
|
|
|
|
|
|
|
The `test/` directory is mounted to `/opt/media` inside containers, serving as the
|
|
|
|
|
media directory for development. Certificate files, configs, and downloaded content
|
|
|
|
|
are stored here.
|
|
|
|
|
|
|
|
|
|
Two external volumes are required for the map service:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
docker volume create --name=openstreetmap-data
|
|
|
|
|
docker volume create --name=openstreetmap-rendered-tiles
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Environment Variables
|
|
|
|
|
|
|
|
|
|
| Variable | Default | Description |
|
|
|
|
|
|-------------------|----------------|----------------------------------------------|
|
|
|
|
|
| `MEDIA_DIRECTORY` | `/opt/media` | Media directory inside containers |
|
|
|
|
|
| `EXTRA_SANS` | (empty) | Additional SANs for the TLS leaf certificate |
|
|
|
|
|
| `WEB_HOST` | `0.0.0.0` | Host bind address for the web service |
|
|
|
|
|
| `WEB_HTTPS_PORT` | `8443` | HTTPS port |
|
|
|
|
|
| `REACT_APP_API` | `0.0.0.0:8081` | API bind address |
|
|
|
|
|
| `UID` | `1000` | User ID for api/app containers |
|
|
|
|
|
| `GID` | `1000` | Group ID for api/app containers |
|
|
|
|
|
|
|
|
|
|
## Upgrading
|
|
|
|
|
|
|
|
|
|
See [UPGRADE.md](../UPGRADE.md) for upgrade instructions.
|