diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c6ecaf5..b12bc30 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,11 +17,15 @@ jobs: with: node-version: 24 cache: npm + cache-dependency-path: | + package-lock.json + tracker/package-lock.json - run: npm ci + - run: npm ci --prefix tracker - name: Check JavaScript syntax - run: find src tests -name '*.js' -print0 | xargs -0 -n1 node --check + run: find src tests tracker/src tracker/public tracker/tests -name '*.js' -print0 | xargs -0 -n1 node --check - name: Parse YAML - run: ruby -e 'require "yaml"; Dir[".github/**/*.yml", "compose*.yml"].flatten.each { |file| YAML.load_file(file) }' + run: ruby -e 'require "yaml"; Dir[".github/**/*.yml", "compose*.yml", "tracker/compose.yml"].flatten.each { |file| YAML.load_file(file) }' - run: git diff --check test: @@ -34,21 +38,47 @@ jobs: with: node-version: 24 cache: npm + cache-dependency-path: | + package-lock.json + tracker/package-lock.json - run: npm ci + - run: npm ci --prefix tracker - run: npm test + - run: npm test --prefix tracker integration-test: needs: test runs-on: ubuntu-latest timeout-minutes: 10 + services: + postgres: + image: postgres:16-alpine + env: + POSTGRES_DB: container_pilot + POSTGRES_USER: tracker + POSTGRES_PASSWORD: tracker-integration-password + ports: + - 5432:5432 + options: >- + --health-cmd "pg_isready -U tracker -d container_pilot" + --health-interval 5s + --health-timeout 5s + --health-retries 10 steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v7 with: node-version: 24 cache: npm + cache-dependency-path: | + package-lock.json + tracker/package-lock.json - run: npm ci + - run: npm ci --prefix tracker - run: npm run test:integration + - run: npm run test:integration --prefix tracker + env: + DATABASE_URL: postgresql://tracker:tracker-integration-password@127.0.0.1:5432/container_pilot security-check: needs: lint @@ -60,8 +90,13 @@ jobs: with: node-version: 24 cache: npm + cache-dependency-path: | + package-lock.json + tracker/package-lock.json - run: npm ci + - run: npm ci --prefix tracker - run: npm audit --omit=dev --audit-level=high + - run: npm audit --prefix tracker --omit=dev --audit-level=high docker-build: needs: [integration-test, security-check] @@ -78,3 +113,10 @@ jobs: platforms: linux/amd64,linux/arm64 cache-from: type=gha cache-to: type=gha,mode=max + - uses: docker/build-push-action@v6 + with: + context: ./tracker + push: false + platforms: linux/amd64,linux/arm64 + cache-from: type=gha,scope=tracker + cache-to: type=gha,mode=max,scope=tracker diff --git a/CHANGELOG.md b/CHANGELOG.md index 47543a7..a21c05c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +## 0.9.0-rc.11 + +- Added explicit opt-in anonymous telemetry with a live payload preview, daily jittered reporting, fail-open delivery, local reset/server deletion controls, and persistent update and rollback counters. +- Added a separately deployable PostgreSQL telemetry tracker with a write-only public listener, authenticated internal dashboard, strict schema/rate/body limits, retention, migrations, and hardened Compose/reverse-proxy examples. + ## 0.9.0-rc.10 - Restored an anonymized product dashboard preview to the English and German README files. diff --git a/README.de.md b/README.de.md index 8c40151..59d4a3e 100644 --- a/README.de.md +++ b/README.de.md @@ -5,7 +5,7 @@
Moderne deutsche Weboberfläche zur kontrollierten Prüfung und Installation von Docker-Image-Updates.
-
+
@@ -18,7 +18,7 @@
Der Schwerpunkt liegt auf einem nachvollziehbaren Update-Workflow mit **konfigurierbaren Prüfintervallen, Freigabe pro Container, optionaler Sofortinstallation und automatischem Rollback**. Bei Images mit einem festen Tag prüft Container Pilot zusätzlich, ob ein `latest`-Tag vorhanden ist. In der Weboberfläche kann bewusst zwischen einem Update des bestehenden Tags und einem Wechsel auf `latest` entschieden werden. Die Automatik wechselt niemals selbstständig den Tag.
-> **Projektstatus:** Version 0.9.0-rc.10 ist ein Release Candidate. Die Update-Engine besitzt Healthcheck-Validierung, Aktionssperren, Self-Updates und Docker-Integrationstests. Vor dem Stable-Release ist ein kontrollierter Praxistest mit den eigenen Stacks vorgesehen.
+> **Projektstatus:** Version 0.9.0-rc.11 ist ein Release Candidate. Die Update-Engine besitzt Healthcheck-Validierung, Aktionssperren, Self-Updates und Docker-Integrationstests. Vor dem Stable-Release ist ein kontrollierter Praxistest mit den eigenen Stacks vorgesehen.
## Einblick
@@ -51,6 +51,15 @@ Der Schwerpunkt liegt auf einem nachvollziehbaren Update-Workflow mit **konfigur
| **Benutzer** | Administrator- und Viewer-Konten über die Weboberfläche verwalten |
| **Ereignisse** | Prüf-, Update-, Fehler-, Benutzer- und Anmeldeereignisse in einem eigenen Menüpunkt nachvollziehen |
| **Systemupdate** | GitHub Releases prüfen und Container Pilot über einen getrennten Helfer mit Healthcheck und automatischer Wiederherstellung aktualisieren |
+| **Anonyme Nutzungsstatistiken** | Freiwillig und standardmäßig deaktiviert; exakte Daten vor dem Versand anzeigen, sofort senden, deaktivieren, Identität zurücksetzen oder Serverdaten löschen |
+
+## Freiwillige anonyme Nutzungsstatistiken
+
+Container Pilot enthält eine freiwillige und besonders datensparsame Nutzungsstatistik. Sie soll uns helfen zu verstehen, wie sich das Projekt in realen Installationen und unterschiedlichen Einsatzszenarien verhält. **Die Funktion ist standardmäßig ausgeschaltet und überträgt nichts, bis ein Administrator sie ausdrücklich aktiviert.**
+
+Nach der Aktivierung wird nur das kleinste sinnvoll nutzbare Maß an zusammengefassten technischen Daten übertragen, beispielsweise Container-Pilot- und Docker-Version, Architektur, allgemeines Betriebssystem, aggregierte Containerzahlen, verwendete Funktionskategorien und kumulierte Update-Ergebnisse. Container- oder Image-Namen, IP-Adressen, Hostnamen, Registry-Domains, Zugangsdaten, Umgebungsvariablen, Mount-Pfade und Anwendungsdaten werden niemals übertragen. Die Weboberfläche zeigt vor dem Versand exakt den aktuellen Payload; die Funktion kann jederzeit deaktiviert und die zugehörigen Daten können gelöscht werden.
+
+Wir freuen uns über jeden Administrator, der diese Funktion freiwillig aktiviert. Die anonymen Erkenntnisse aus dem praktischen Einsatz helfen uns, Kompatibilität, Zuverlässigkeit und Zugänglichkeit gezielt zu verbessern, damit Container Pilot in möglichst vielen Umgebungen und für möglichst viele Menschen gut funktioniert. Alle Einzelheiten stehen unter [Telemetrie und Datenschutz](docs/telemetry.md).
## Architektur: Weboberfläche, Docker API und Registry
@@ -131,6 +140,8 @@ Sitzungen bleiben zwölf Stunden gültig und werden beim Ändern des eigenen Ken
## Sicherheit im Docker-Betrieb
+Anonyme Nutzungsstatistiken sind freiwillig, standardmäßig deaktiviert und transparent unter [Telemetrie und Datenschutz](docs/telemetry.md) dokumentiert.
+
Der eingebundene Docker-Socket ermöglicht weitreichende Kontrolle über den Docker-Host. Container Pilot gehört deshalb ausschließlich in eine vertrauenswürdige Verwaltungsumgebung.
- Weboberfläche nicht ungeschützt im öffentlichen Internet bereitstellen
diff --git a/README.md b/README.md
index 0f3e532..d3d9079 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@
A Docker update manager with a Web UI, per-container policies, health checks, and automatic rollback.
A safer Watchtower alternative focused on control and recovery.
-
+
@@ -72,6 +72,15 @@ Detect → Decide → Update → Verify → Recover
- Container configuration reconstruction, including mounts, networks, ports, environment, and restart policy
- Safe self-update flow through a separate helper container
- Opt-in Watchtower policy import with a read-only preview and per-rule confirmation
+- Optional anonymous usage statistics with an exact payload preview and full administrator control
+
+## Optional anonymous usage statistics
+
+Container Pilot includes voluntary, privacy-minimizing usage statistics to help us understand how the project behaves across real installations and different deployment scenarios. **The feature is disabled by default and sends nothing until an administrator explicitly enables it.**
+
+When enabled, only the smallest useful set of aggregated technical data is reported, such as the Container Pilot and Docker versions, architecture, general operating system, aggregate container counts, enabled feature categories, and cumulative update results. Container Pilot never reports container or image names, IP addresses, hostnames, registry domains, credentials, environment variables, mount paths, or application data. The Web UI shows the exact payload before it is sent, and reporting can be disabled or deleted at any time.
+
+We appreciate every administrator who voluntarily enables this feature. These anonymous field insights help us prioritize compatibility, reliability, and accessibility work so Container Pilot can serve as many environments and users as possible. Full details are available in [Telemetry and privacy](docs/telemetry.md).
## Important safety boundary
@@ -97,6 +106,7 @@ Read [Security](docs/security.md), [Updates](docs/updates.md), and [Rollback](do
- [Release-candidate testing](docs/testing.md)
- [Webhook notifications](docs/notifications.md)
- [Private registries](docs/private-registries.md)
+- [Telemetry and privacy](docs/telemetry.md)
- [Project website](https://deepzone.github.io/container-pilot/)
- [Roadmap](ROADMAP.md)
- [Changelog](CHANGELOG.md)
@@ -109,7 +119,7 @@ Published multi-architecture images are available from:
ghcr.io/deepzone/container-pilot
```
-- Complete version tags such as `0.9.0-rc.10` are fixed release references and must never be reused.
+- Complete version tags such as `0.9.0-rc.11` are fixed release references and must never be reused.
- Release candidates use the `rc` channel once published by the release workflow.
- `latest`, major, and minor aliases are reserved for stable releases.
- Successful builds from `main` use the moving `edge` tag and a commit-specific `sha-*` tag. They are development builds, not releases.
@@ -140,6 +150,8 @@ npm run test:integration
## Contributing and security
+Anonymous usage statistics are optional, disabled by default, and documented transparently in [Telemetry and privacy](docs/telemetry.md).
+
Contributions are welcome. Read [CONTRIBUTING.md](CONTRIBUTING.md) before opening a pull request.
Do not publish credentials, tokens, private image names, internal addresses, or complete state files in issues. Report vulnerabilities according to [SECURITY.md](SECURITY.md).
diff --git a/compose.yml b/compose.yml
index 0b7a1e9..bb2efd2 100644
--- a/compose.yml
+++ b/compose.yml
@@ -1,6 +1,6 @@
services:
container-pilot:
- image: ${CP_IMAGE:-ghcr.io/deepzone/container-pilot:0.9.0-rc.10}
+ image: ${CP_IMAGE:-ghcr.io/deepzone/container-pilot:0.9.0-rc.11}
container_name: container-pilot
restart: unless-stopped
init: true
diff --git a/docs/installation.md b/docs/installation.md
index e5b96ce..caa5e48 100644
--- a/docs/installation.md
+++ b/docs/installation.md
@@ -33,7 +33,7 @@ Then open `https://YOUR-DOCKER-HOST:3080`. See [HTTPS and reverse proxy](reverse
The Compose file defaults to the current release candidate until the first stable release exists. To select an explicit published image without editing the file:
```bash
-CP_IMAGE=ghcr.io/deepzone/container-pilot:0.9.0-rc.10 docker compose up -d
+CP_IMAGE=ghcr.io/deepzone/container-pilot:0.9.0-rc.11 docker compose up -d
```
After a stable release is published, select the stable channel with `CP_IMAGE=ghcr.io/deepzone/container-pilot:latest` and `CP_SELF_UPDATE_CHANNEL=stable`. The `latest` tag is never published for a release candidate.
diff --git a/docs/releases.md b/docs/releases.md
index 3285ec4..23a049e 100644
--- a/docs/releases.md
+++ b/docs/releases.md
@@ -2,13 +2,13 @@
[Documentation index](../README.md) · [Installation](installation.md)
-Container Pilot uses [Semantic Versioning](https://semver.org/). Release candidates use tags such as `v0.9.0-rc.10`; stable releases use tags such as `v1.0.0`.
+Container Pilot uses [Semantic Versioning](https://semver.org/). Release candidates use tags such as `v0.9.0-rc.11`; stable releases use tags such as `v1.0.0`.
## Channels
| Git tag | Published image tags | Intended use |
| --- | --- | --- |
-| `v0.9.0-rc.10` | `0.9.0-rc.10`, `rc` | controlled release-candidate testing |
+| `v0.9.0-rc.11` | `0.9.0-rc.11`, `rc` | controlled release-candidate testing |
| `v1.2.3` | `1.2.3`, `1.2`, `1`, `latest`, `stable` | stable installations |
| push to `main` | `edge`, `sha-