# Raspberry Pi 5 Docker Run

This server repository contains a Dockerized QSfera path for Raspberry Pi 5 and other
64-bit ARM Linux hosts.

Files used for this deployment:

- `Dockerfile`
- `docker-compose.rpi5.yml`
- `.env.example`

## What This Runs

- QSfera server from this `Server` source tree.
- A pinned production image tag by default: `qsfera-cloud-server:7.0.0-rpi5-stable`.
- Build metadata injected into the binary through Docker build args:
  `QSFERA_VERSION`, `QSFERA_EDITION`, and `QSFERA_BUILD_DATE`.
- QSfera config persisted under `/etc/qsfera` inside the container.
- QSfera data persisted under `/var/lib/qsfera` inside the container.
- Host-side config and data paths controlled by `QSFERA_RPI_CONFIG_PATH` and
  `QSFERA_RPI_DATA_PATH`.
- Host-side backend port bound only to `127.0.0.1:9200`; external access should go
  through the reverse proxy and HTTPS domain.

## Prerequisites On Raspberry Pi 5

1. Install Docker Engine using the official Docker docs: `https://docs.docker.com/engine/install/debian/`.
2. Install the Docker Compose plugin using the official Docker docs: `https://docs.docker.com/compose/install/`.
3. Use a 64-bit OS. The compose file sets `platform: linux/arm64`, and the Dockerfile builds with `TARGETARCH=arm64`.
4. Put `QSFERA_RPI_CONFIG_PATH` and `QSFERA_RPI_DATA_PATH` on durable storage, not on a nearly full SD-card root filesystem.
5. Set `OC_URL` to the public HTTPS URL used by clients and the reverse proxy.
6. Keep `QSFERA_EDITION=stable` and a concrete `QSFERA_VERSION` for production
   rollouts. Leaving those unset falls back to the defaults in the compose file.

## Start

Run from the `Server` directory:

```bash
cp .env.example .env
docker compose -f docker-compose.rpi5.yml up -d --build
```

Verify the image metadata before rollout:

```bash
docker compose -f docker-compose.rpi5.yml build
docker run --rm --entrypoint /usr/bin/qsfera qsfera-cloud-server:7.0.0-rpi5-stable version --skip-services
```

## Stop

```bash
docker compose -f docker-compose.rpi5.yml down
```

## Logs

```bash
docker compose -f docker-compose.rpi5.yml logs -f qsfera-cloud-server
```

## Update After Pulling New Code

```bash
docker compose -f docker-compose.rpi5.yml up -d --build
```

## Verify

Local backend status endpoint:

```bash
curl -k https://127.0.0.1:9200/status.php
```

External reverse-proxied status endpoint:

```bash
curl https://qsfera.example.com/status.php
```

## Data Location

Docker bind mounts:

- host config: `${QSFERA_RPI_CONFIG_PATH}`
- container config: `/etc/qsfera`
- host data: `${QSFERA_RPI_DATA_PATH}`
- container data: `/var/lib/qsfera`

For the current Raspberry Pi deployment inspected on 2026-06-08, the existing
container uses:

- host config: `/mnt/data/qsfera/cloud-server/config`
- host data: `/mnt/data/qsfera/cloud-server/data`
- image: `qsfera-cloud-server:7.0.0-rpi5-stable`
- public URL: `https://qsfera.kusoft.xyz`
- loopback port: `127.0.0.1:9200`

## Reverse Proxy

The server is intentionally bound to loopback. Put Caddy, Nginx, Traefik, or another
reverse proxy in front of it for external HTTPS access.

The inspected Raspberry Pi uses Caddy with this QSfera route:

```caddyfile
qsfera.kusoft.xyz {
    encode zstd gzip
    handle {
        reverse_proxy https://127.0.0.1:9200 {
            transport http {
                tls_insecure_skip_verify
                versions 1.1
            }
        }
    }
}
```
