97 lines
3.2 KiB
Markdown
97 lines
3.2 KiB
Markdown
# Raspberry Pi deployment
|
|
|
|
This profile runs the single-container QSfera server on a 64-bit Raspberry Pi
|
|
OS and persists configuration and user data outside the container. It expects a
|
|
separate reverse proxy for a browser-trusted TLS certificate; by default port
|
|
9200 is therefore published only on `127.0.0.1`.
|
|
|
|
## Requirements
|
|
|
|
- `uname -m` must report `aarch64` or `arm64`.
|
|
- Docker Engine with the Compose plugin must be installed.
|
|
- The selected QSfera image tag or digest must contain `linux/arm64`.
|
|
- The configuration and data directories must be on persistent storage and
|
|
writable by UID/GID `1000:1000`, which is the non-root user in the image.
|
|
|
|
For an external disk mounted at `/mnt/qsfera`, create the directories with:
|
|
|
|
```sh
|
|
sudo install -d -o 1000 -g 1000 -m 0750 /mnt/qsfera/config /mnt/qsfera/data
|
|
findmnt /mnt/qsfera
|
|
```
|
|
|
|
`findmnt` must show the expected external filesystem before the service starts.
|
|
This prevents an unavailable disk from silently placing data on the Pi's root
|
|
filesystem.
|
|
|
|
## Configuration
|
|
|
|
```sh
|
|
cd Server/deployments/raspberry-pi
|
|
cp .env.example .env
|
|
chmod 600 .env
|
|
```
|
|
|
|
Fill every empty value in `.env`. The Compose file deliberately has no default
|
|
for the image, public URL, admin password, persistent paths or memory limit.
|
|
`docker compose config` fails when any of these values is empty.
|
|
|
|
Choose `QSFERA_MEMORY_LIMIT` from measurements on the target Pi:
|
|
|
|
```text
|
|
QSFERA_MEMORY_LIMIT = total RAM - OS reserve - other services reserve
|
|
```
|
|
|
|
Use `free -h` for total/current host memory and `docker stats` for the other
|
|
containers. Leave enough headroom for the kernel, filesystem cache and reverse
|
|
proxy. QSfera's Go runtime then derives its own default `GOMEMLIMIT` from the
|
|
container limit with a 0.9 ratio.
|
|
|
|
Keep `QSFERA_BIND_IP=127.0.0.1` when the reverse proxy runs on the same Pi. Set
|
|
it to a reachable interface only when access to port 9200 is protected by an
|
|
equivalent network and TLS design.
|
|
|
|
## Start and verify
|
|
|
|
```sh
|
|
sh ./smoke-test.sh
|
|
docker compose ps
|
|
```
|
|
|
|
The smoke test validates the Compose file, starts the service and waits for the
|
|
container health check. Its default 180-second startup budget can be changed
|
|
with `SMOKE_TIMEOUT_SECONDS`.
|
|
|
|
## Backup
|
|
|
|
The backup script stops QSfera, archives both persistent directories, writes a
|
|
SHA-256 checksum and starts the service again:
|
|
|
|
```sh
|
|
sh ./backup.sh /mnt/backups/qsfera
|
|
```
|
|
|
|
Copy the resulting `.tar.gz` and `.sha256` files to storage that is independent
|
|
of the Pi and its data disk.
|
|
|
|
## Restore
|
|
|
|
Restore replaces the current configuration and data. Check the selected archive
|
|
and its checksum first, then run:
|
|
|
|
```sh
|
|
RESTORE_CONFIRM=restore sh ./restore.sh /mnt/backups/qsfera/qsfera-TIMESTAMP.tar.gz
|
|
sh ./smoke-test.sh
|
|
```
|
|
|
|
The restore script verifies the checksum when the matching `.sha256` file is
|
|
present and stops the service during replacement. It starts QSfera only after a
|
|
successful extraction; after an error the service remains stopped so a partial
|
|
data set is never served automatically.
|
|
|
|
## References
|
|
|
|
- [Raspberry Pi external storage documentation](https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#external-storage)
|
|
- [Docker Compose service configuration](https://docs.docker.com/reference/compose-file/services/)
|
|
- [Go garbage collector guide](https://go.dev/doc/gc-guide)
|