Pin Pi server stable image
This commit is contained in:
@@ -33,18 +33,21 @@ Date: 2026-06-08.
|
|||||||
- Server `qsfera_full/env.production.example` provides a tracked production-safe starting point with TLS validation enabled and demo users disabled.
|
- Server `qsfera_full/env.production.example` provides a tracked production-safe starting point with TLS validation enabled and demo users disabled.
|
||||||
- Server `qsfera_full/validate-production-env.sh` checks production `.env` invariants before compose validation: TLS validation enabled, demo users disabled, pinned production image, required domains, required secrets, and no public-production MinIO.
|
- Server `qsfera_full/validate-production-env.sh` checks production `.env` invariants before compose validation: TLS validation enabled, demo users disabled, pinned production image, required domains, required secrets, and no public-production MinIO.
|
||||||
- Server now has a Raspberry Pi 5 Docker path matching the Ikar/Argus deployment style: `Server/docker-compose.rpi5.yml`, `Server/.env.example`, and `Server/docs/raspberry-pi-5-docker.md`.
|
- Server now has a Raspberry Pi 5 Docker path matching the Ikar/Argus deployment style: `Server/docker-compose.rpi5.yml`, `Server/.env.example`, and `Server/docs/raspberry-pi-5-docker.md`.
|
||||||
|
- Server Docker builds now accept explicit production metadata for `QSFERA_VERSION`, `QSFERA_EDITION`, and `QSFERA_BUILD_DATE`, and the Raspberry Pi 5 compose path defaults to pinned image `qsfera-cloud-server:7.0.0-rpi5-stable`.
|
||||||
- Windows/Desktop update channel defaults now match the build channel: stable builds default to `stable`, beta builds default to `beta`.
|
- Windows/Desktop update channel defaults now match the build channel: stable builds default to `stable`, beta builds default to `beta`.
|
||||||
- Windows/Desktop CI now validates production release invariants before Windows packaging and requires signing variables for stable tag releases.
|
- Windows/Desktop CI now validates production release invariants before Windows packaging and requires signing variables for stable tag releases.
|
||||||
|
|
||||||
## Raspberry Pi 5 Check
|
## Raspberry Pi 5 Check
|
||||||
|
|
||||||
- Pi target checked on 2026-06-08: `192.168.0.185` reports `aarch64`, 64-bit Debian 13, Docker `29.4.3`, Docker Compose `v5.1.3`, and Docker server architecture `aarch64`.
|
- Pi target checked on 2026-06-08: `192.168.0.185` reports `aarch64`, 64-bit Debian 13, Docker `29.4.3`, Docker Compose `v5.1.3`, and Docker server architecture `aarch64`.
|
||||||
- Current QSfera server is already running on that Pi as `qsfera-cloud-server:rpi5-local`, with `Arch=arm64`, bind-mounted config/data under `/mnt/data/qsfera/cloud-server`, and loopback port `127.0.0.1:9200`.
|
- Before stable-image deployment, the old Pi server was running as local/dev image `qsfera-cloud-server:rpi5-local`; public `/status.php` reported `edition: dev` and `productversion: 7.0.0`.
|
||||||
- `https://qsfera.kusoft.xyz/status.php` returned HTTP `200` during the check.
|
- The Pi server now runs through `/mnt/data/qsfera/cloud-server/src/docker-compose.rpi5.yml` with pinned image `qsfera-cloud-server:7.0.0-rpi5-stable`, bind-mounted config/data under `/mnt/data/qsfera/cloud-server`, and loopback port `127.0.0.1:9200`.
|
||||||
- The Pi root filesystem is nearly full: `/dev/mmcblk0p2` reported `57G` size, `52G` used, `2.4G` available, `96%` use. `/mnt/data` reported `916G` size, `18G` used, `853G` available, `2%` use.
|
|
||||||
- Before switching the Pi server to compose, config/data were backed up to `/mnt/data/qsfera/backups/cloud-server-before-compose-20260608-200921.tar.gz`. The archive was created with `sudo tar`, had size `213M`, and `tar -tzf` completed successfully.
|
- Before switching the Pi server to compose, config/data were backed up to `/mnt/data/qsfera/backups/cloud-server-before-compose-20260608-200921.tar.gz`. The archive was created with `sudo tar`, had size `213M`, and `tar -tzf` completed successfully.
|
||||||
- The Pi server now runs through `/mnt/data/qsfera/cloud-server/src/docker-compose.rpi5.yml` with `docker compose`. `docker compose ps` reported `qsfera-cloud-server` as `Up` and `healthy`, still bound to `127.0.0.1:9200`.
|
- Before switching to the stable image, config/data were backed up to `/mnt/data/qsfera/backups/cloud-server-before-stable-image-20260608-201536.tar.gz`. The archive had size `213M`, and `tar -tzf` completed successfully.
|
||||||
- This is now compose-managed on the Pi, but I do not count it as fully production-ready yet because the running image is still a local/dev build (`qsfera-cloud-server:rpi5-local`, external status reports `edition: dev`) rather than a pinned production release image.
|
- `docker run --rm --entrypoint /usr/bin/qsfera qsfera-cloud-server:7.0.0-rpi5-stable version --skip-services` returned `Version: 7.0.0`, `Edition: stable`, and `Compiled: 2026-06-08 00:00:00 +0000 UTC`.
|
||||||
|
- After deployment, `docker compose ps` reported `qsfera-cloud-server` as `Up` and `healthy`; `docker inspect` reported `IMAGE=qsfera-cloud-server:7.0.0-rpi5-stable HEALTH=healthy`.
|
||||||
|
- Local `https://127.0.0.1:9200/status.php` and public `https://qsfera.kusoft.xyz/status.php` both returned `edition: stable` and `productversion: 7.0.0`; the public request returned HTTP `200`.
|
||||||
|
- After Docker builder cache cleanup and the stable deployment, `/dev/mmcblk0p2` reported `57G` size, `12G` used, `43G` available, `21%` use. `/mnt/data` reported `916G` size, `18G` used, `852G` available, `3%` use.
|
||||||
|
|
||||||
## Android Argus Publication Check
|
## Android Argus Publication Check
|
||||||
|
|
||||||
@@ -61,7 +64,6 @@ Date: 2026-06-08.
|
|||||||
- Decide the rollout policy for any devices that installed the debug-signed Argus `1.3.5` APK. The production-signed `1.3.6` APK is the correct current release, but installed debug-signed clients will not satisfy the app's own signer-digest check for an in-place update.
|
- Decide the rollout policy for any devices that installed the debug-signed Argus `1.3.5` APK. The production-signed `1.3.6` APK is the correct current release, but installed debug-signed clients will not satisfy the app's own signer-digest check for an in-place update.
|
||||||
- Fill production domains, ACME email, admin passwords, Keycloak passwords, and storage secrets from a secret manager. Do not commit real values.
|
- Fill production domains, ACME email, admin passwords, Keycloak passwords, and storage secrets from a secret manager. Do not commit real values.
|
||||||
- Run `./validate-production-env.sh .env` and then `docker compose config` for `Server/devtools/deployments/qsfera_full` with a filled production `.env`; Docker CLI is not available in this local environment, so compose rendering is not locally verified.
|
- Run `./validate-production-env.sh .env` and then `docker compose config` for `Server/devtools/deployments/qsfera_full` with a filled production `.env`; Docker CLI is not available in this local environment, so compose rendering is not locally verified.
|
||||||
- For the Pi deployment, build or pull a pinned production QSfera image instead of the current local/dev `qsfera-cloud-server:rpi5-local` image.
|
|
||||||
- Provide real Windows signing secrets in CI: `QSFERA_DESKTOP_SIGN_PACKAGE=True` and `QSFERA_DESKTOP_CODESIGN_CERTIFICATE` with the Craft-compatible signing certificate reference.
|
- Provide real Windows signing secrets in CI: `QSFERA_DESKTOP_SIGN_PACKAGE=True` and `QSFERA_DESKTOP_CODESIGN_CERTIFICATE` with the Craft-compatible signing certificate reference.
|
||||||
- Configure and verify the desktop updater endpoint via `APPLICATION_UPDATE_URL`; `Desktop/scripts/validate-production-release.ps1` confirms update notifications are enabled but cannot prove a live update feed without that URL.
|
- Configure and verify the desktop updater endpoint via `APPLICATION_UPDATE_URL`; `Desktop/scripts/validate-production-release.ps1` confirms update notifications are enabled but cannot prove a live update feed without that URL.
|
||||||
|
|
||||||
@@ -71,4 +73,5 @@ Date: 2026-06-08.
|
|||||||
- Add mobile-data controls comparable to Google Photos/Yandex Disk beyond the Wi-Fi-only default: mobile-data limit, no-video-over-mobile-data, and no-roaming options.
|
- Add mobile-data controls comparable to Google Photos/Yandex Disk beyond the Wi-Fi-only default: mobile-data limit, no-video-over-mobile-data, and no-roaming options.
|
||||||
- Store auto-upload sync cursors per source folder rather than one timestamp for all folders.
|
- Store auto-upload sync cursors per source folder rather than one timestamp for all folders.
|
||||||
- Add production monitoring runbook and compose verification for metrics, tracing, alerts, backups, and restore drills.
|
- Add production monitoring runbook and compose verification for metrics, tracing, alerts, backups, and restore drills.
|
||||||
|
- Move Docker build cache and/or Docker data-root planning for the Pi to `/mnt/data`, or add documented retention, so future server image rebuilds cannot fill the root filesystem again.
|
||||||
- Verify sharing controls against Google Drive and Yandex Disk expectations: link expiration, password, disable downloads, organization-only access, and role inheritance.
|
- Verify sharing controls against Google Drive and Yandex Disk expectations: link expiration, password, disable downloads, organization-only access, and role inheritance.
|
||||||
|
|||||||
+4
-1
@@ -1,4 +1,7 @@
|
|||||||
QSFERA_RPI_IMAGE=qsfera-cloud-server:rpi5-local
|
QSFERA_RPI_IMAGE=qsfera-cloud-server:7.0.0-rpi5-stable
|
||||||
|
QSFERA_VERSION=7.0.0
|
||||||
|
QSFERA_EDITION=stable
|
||||||
|
QSFERA_BUILD_DATE=20260608
|
||||||
QSFERA_RPI_HOST_PORT=9200
|
QSFERA_RPI_HOST_PORT=9200
|
||||||
QSFERA_RPI_CONFIG_PATH=/mnt/data/qsfera/cloud-server/config
|
QSFERA_RPI_CONFIG_PATH=/mnt/data/qsfera/cloud-server/config
|
||||||
QSFERA_RPI_DATA_PATH=/mnt/data/qsfera/cloud-server/data
|
QSFERA_RPI_DATA_PATH=/mnt/data/qsfera/cloud-server/data
|
||||||
|
|||||||
+11
-2
@@ -26,15 +26,21 @@ RUN make node-generate-prod
|
|||||||
|
|
||||||
FROM golang:1.25-alpine AS build
|
FROM golang:1.25-alpine AS build
|
||||||
ARG TARGETARCH=arm64
|
ARG TARGETARCH=arm64
|
||||||
|
ARG QSFERA_VERSION=7.0.0
|
||||||
|
ARG QSFERA_EDITION=stable
|
||||||
|
ARG QSFERA_BUILD_DATE=20260608
|
||||||
RUN apk add bash make git curl gcc musl-dev libc-dev binutils-gold inotify-tools vips-dev
|
RUN apk add bash make git curl gcc musl-dev libc-dev binutils-gold inotify-tools vips-dev
|
||||||
|
|
||||||
COPY --from=generate /qsfera /qsfera
|
COPY --from=generate /qsfera /qsfera
|
||||||
|
|
||||||
WORKDIR /qsfera/qsfera
|
WORKDIR /qsfera/qsfera
|
||||||
RUN make release-linux-docker-${TARGETARCH} ENABLE_VIPS=true DIST=/dist
|
RUN make release-linux-docker-${TARGETARCH} ENABLE_VIPS=true DIST=/dist VERSION="${QSFERA_VERSION}" EDITION="${QSFERA_EDITION}" DATE="${QSFERA_BUILD_DATE}"
|
||||||
|
|
||||||
FROM alpine:3.23
|
FROM alpine:3.23
|
||||||
ARG TARGETARCH=arm64
|
ARG TARGETARCH=arm64
|
||||||
|
ARG QSFERA_VERSION=7.0.0
|
||||||
|
ARG QSFERA_EDITION=stable
|
||||||
|
ARG QSFERA_BUILD_DATE=20260608
|
||||||
|
|
||||||
RUN apk add --no-cache attr ca-certificates curl mailcap tree vips && \
|
RUN apk add --no-cache attr ca-certificates curl mailcap tree vips && \
|
||||||
echo 'hosts: files dns' >| /etc/nsswitch.conf
|
echo 'hosts: files dns' >| /etc/nsswitch.conf
|
||||||
@@ -46,7 +52,10 @@ LABEL maintainer="QSfera" \
|
|||||||
org.opencontainers.image.description="КуСфера file-sync and share platform" \
|
org.opencontainers.image.description="КуСфера file-sync and share platform" \
|
||||||
org.opencontainers.image.licenses="Apache-2.0" \
|
org.opencontainers.image.licenses="Apache-2.0" \
|
||||||
org.opencontainers.image.documentation="" \
|
org.opencontainers.image.documentation="" \
|
||||||
org.opencontainers.image.source=""
|
org.opencontainers.image.source="" \
|
||||||
|
org.opencontainers.image.version="${QSFERA_VERSION}" \
|
||||||
|
eu.qsfera.image.edition="${QSFERA_EDITION}" \
|
||||||
|
eu.qsfera.image.build-date="${QSFERA_BUILD_DATE}"
|
||||||
|
|
||||||
ENTRYPOINT ["/usr/bin/qsfera"]
|
ENTRYPOINT ["/usr/bin/qsfera"]
|
||||||
CMD ["server"]
|
CMD ["server"]
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
services:
|
services:
|
||||||
qsfera-cloud-server:
|
qsfera-cloud-server:
|
||||||
container_name: qsfera-cloud-server
|
container_name: qsfera-cloud-server
|
||||||
image: ${QSFERA_RPI_IMAGE:-qsfera-cloud-server:rpi5-local}
|
image: ${QSFERA_RPI_IMAGE:-qsfera-cloud-server:7.0.0-rpi5-stable}
|
||||||
platform: linux/arm64
|
platform: linux/arm64
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
args:
|
args:
|
||||||
TARGETARCH: arm64
|
TARGETARCH: arm64
|
||||||
|
QSFERA_VERSION: ${QSFERA_VERSION:-7.0.0}
|
||||||
|
QSFERA_EDITION: ${QSFERA_EDITION:-stable}
|
||||||
|
QSFERA_BUILD_DATE: ${QSFERA_BUILD_DATE:-20260608}
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
entrypoint:
|
entrypoint:
|
||||||
- /bin/sh
|
- /bin/sh
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ Files used for this deployment:
|
|||||||
## What This Runs
|
## What This Runs
|
||||||
|
|
||||||
- QSfera server from this `Server` source tree.
|
- 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 config persisted under `/etc/qsfera` inside the container.
|
||||||
- QSfera data persisted under `/var/lib/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
|
- Host-side config and data paths controlled by `QSFERA_RPI_CONFIG_PATH` and
|
||||||
@@ -26,6 +29,8 @@ Files used for this deployment:
|
|||||||
3. Use a 64-bit OS. The compose file sets `platform: linux/arm64`, and the Dockerfile builds with `TARGETARCH=arm64`.
|
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.
|
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.
|
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
|
## Start
|
||||||
|
|
||||||
@@ -36,6 +41,13 @@ cp .env.example .env
|
|||||||
docker compose -f docker-compose.rpi5.yml up -d --build
|
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
|
## Stop
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -82,6 +94,7 @@ container uses:
|
|||||||
|
|
||||||
- host config: `/mnt/data/qsfera/cloud-server/config`
|
- host config: `/mnt/data/qsfera/cloud-server/config`
|
||||||
- host data: `/mnt/data/qsfera/cloud-server/data`
|
- host data: `/mnt/data/qsfera/cloud-server/data`
|
||||||
|
- image: `qsfera-cloud-server:7.0.0-rpi5-stable`
|
||||||
- public URL: `https://qsfera.kusoft.xyz`
|
- public URL: `https://qsfera.kusoft.xyz`
|
||||||
- loopback port: `127.0.0.1:9200`
|
- loopback port: `127.0.0.1:9200`
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user