diff --git a/docs/e2e-testing/manual/README.md b/docs/e2e-testing/manual/README.md
index 19f77cba..c2d80a66 100644
--- a/docs/e2e-testing/manual/README.md
+++ b/docs/e2e-testing/manual/README.md
@@ -116,6 +116,77 @@ nano envs/manual-test.json
+**Using MySQL Instead of SQLite**:
+
+The default template uses SQLite (`driver: "sqlite3"`), which is suitable for testing and small deployments. To use MySQL instead, you need to provide additional database configuration fields:
+
+
+Click to expand MySQL configuration example
+
+```json
+{
+ "environment": {
+ "name": "manual-test-mysql",
+ "instance_name": null
+ },
+ "ssh_credentials": {
+ "private_key_path": "fixtures/testing_rsa",
+ "public_key_path": "fixtures/testing_rsa.pub",
+ "username": "torrust",
+ "port": 22
+ },
+ "provider": {
+ "provider": "lxd",
+ "profile_name": "torrust-profile-manual-test-mysql"
+ },
+ "tracker": {
+ "core": {
+ "database": {
+ "driver": "mysql",
+ "host": "mysql",
+ "port": 3306,
+ "database_name": "torrust_tracker",
+ "username": "tracker_user",
+ "password": "tracker_password"
+ },
+ "private": false
+ },
+ "udp_trackers": [
+ {
+ "bind_address": "0.0.0.0:6969"
+ }
+ ],
+ "http_trackers": [
+ {
+ "bind_address": "0.0.0.0:7070"
+ }
+ ],
+ "http_api": {
+ "bind_address": "0.0.0.0:1212",
+ "admin_token": "MyAccessToken"
+ }
+ }
+}
+```
+
+
+
+**Required MySQL Fields**:
+
+When `driver` is set to `"mysql"`, you must provide:
+
+- `host` - MySQL hostname (use `"mysql"` for Docker Compose service name)
+- `port` - MySQL port (typically `3306`)
+- `database_name` - Name of the database to create
+- `username` - MySQL user for tracker connection
+- `password` - Password for the MySQL user
+
+These credentials are used to:
+
+1. Configure the MySQL Docker container (via docker-compose.yml)
+2. Configure the tracker to connect to MySQL
+3. Initialize the database schema
+
> **π‘ Tip**: Always use `create template` to generate configuration files. This ensures you get the latest schema and prevents issues with outdated examples in documentation.
### Step 2: Create Environment
diff --git a/docs/e2e-testing/manual/mysql-verification.md b/docs/e2e-testing/manual/mysql-verification.md
index 3e18cf37..58c1c1cc 100644
--- a/docs/e2e-testing/manual/mysql-verification.md
+++ b/docs/e2e-testing/manual/mysql-verification.md
@@ -22,30 +22,70 @@ Complete the standard deployment workflow first (see [Manual E2E Testing Guide](
4. β
Software released
5. β
Services running
-**Your environment configuration must include MySQL**:
+**Your environment configuration must include MySQL database configuration**:
```json
{
+ "environment": {
+ "name": "manual-test-mysql",
+ "instance_name": null
+ },
+ "ssh_credentials": {
+ "private_key_path": "fixtures/testing_rsa",
+ "public_key_path": "fixtures/testing_rsa.pub",
+ "username": "torrust",
+ "port": 22
+ },
+ "provider": {
+ "provider": "lxd",
+ "profile_name": "torrust-profile-manual-test-mysql"
+ },
"tracker": {
"core": {
"database": {
"driver": "mysql",
- "database_name": "torrust_tracker"
+ "host": "mysql",
+ "port": 3306,
+ "database_name": "torrust_tracker",
+ "username": "tracker_user",
+ "password": "tracker_password"
+ },
+ "private": false
+ },
+ "udp_trackers": [
+ {
+ "bind_address": "0.0.0.0:6969"
+ }
+ ],
+ "http_trackers": [
+ {
+ "bind_address": "0.0.0.0:7070"
}
+ ],
+ "http_api": {
+ "bind_address": "0.0.0.0:1212",
+ "admin_token": "MyAccessToken"
}
},
- "database": {
- "driver": "mysql",
- "host": "mysql",
- "port": 3306,
- "database_name": "torrust_tracker",
- "username": "tracker_user",
- "password": "tracker_password",
- "root_password": "root_password"
+ "prometheus": {
+ "scrape_interval_in_secs": 15
+ },
+ "grafana": {
+ "admin_user": "admin",
+ "admin_password": "admin"
}
}
```
+**Required MySQL fields** (under `tracker.core.database`):
+
+- `driver`: Must be `"mysql"`
+- `host`: MySQL hostname (`"mysql"` for Docker Compose service name)
+- `port`: MySQL port (typically `3306`)
+- `database_name`: Name of the database to create
+- `username`: MySQL user for tracker connection
+- `password`: Password for the MySQL user
+
## β οΈ CRITICAL: Understanding File Locations
**There are TWO completely different JSON files with different purposes:**
diff --git a/docs/issues/253-update-docker-images-to-latest-versions.md b/docs/issues/253-update-docker-images-to-latest-versions.md
index d406a038..541f3e51 100644
--- a/docs/issues/253-update-docker-images-to-latest-versions.md
+++ b/docs/issues/253-update-docker-images-to-latest-versions.md
@@ -41,11 +41,11 @@ Update Docker images in the docker-compose template to their latest stable versi
### Docker Images Analysis (December 23, 2025)
-| Image | Current Version | Recommended Version | Support EOL | Status | Security |
-| ----------------- | --------------- | ------------------- | ------------ | --------------------------------------- | ------------------ |
-| `prom/prometheus` | v3.0.1 | v3.8.1 | Jan 9, 2026 | β οΈ 7 versions behind, 6-week support | β
0 HIGH/CRITICAL |
-| `grafana/grafana` | 11.4.0 | 11.5.0 | Apr 28, 2026 | β οΈ 1 version behind, bi-monthly release | β
0 HIGH/CRITICAL |
-| `mysql` | 8.0 (generic) | 8.4 (LTS) | Apr 30, 2032 | β οΈ Update to explicit LTS version | β
0 HIGH/CRITICAL |
+| Image | Current Version | Recommended Version | Support EOL | Status | Security |
+| ----------------- | --------------- | ------------------- | ------------ | ----------------------------------- | ------------------ |
+| `prom/prometheus` | v3.0.1 | v3.5.0 (LTS) | Jul 31, 2026 | β οΈ Update to LTS for 1-year support | β
0 HIGH/CRITICAL |
+| `grafana/grafana` | 11.4.0 | 12.3.1 | Feb 24, 2026 | β οΈ Update to latest major version | β
0 HIGH/CRITICAL |
+| `mysql` | 8.0 (generic) | 8.4 (LTS) | Apr 30, 2032 | β οΈ Update to explicit LTS version | β
0 HIGH/CRITICAL |
**Support Lifecycle Notes**:
@@ -65,7 +65,7 @@ All current images show **zero HIGH or CRITICAL vulnerabilities**:
Total: 0 (HIGH: 0, CRITICAL: 0)
```
-**Prometheus v3.8.1** (latest):
+**Prometheus v3.5.0** (LTS):
```text
2025-12-23T13:45:26.983Z WARN OS is not detected and vulnerabilities in OS packages are not detected.
@@ -87,7 +87,7 @@ grafana/grafana:11.4.0 (alpine 3.20.3)
Total: 0 (HIGH: 0, CRITICAL: 0)
```
-**Grafana 11.5.0** (newer):
+**Grafana 12.3.1** (latest major):
```text
2025-12-23T13:45:39.635Z WARN This OS version is not on the EOL list: alpine 3.20
@@ -96,7 +96,7 @@ Total: 0 (HIGH: 0, CRITICAL: 0)
2025-12-23T13:45:39.635Z WARN This OS version is no longer supported by the distribution: alpine 3.20.3
2025-12-23T13:45:39.635Z WARN The vulnerability detection may be insufficient because security updates are not provided
-grafana/grafana:11.5.0 (alpine 3.20.3)
+grafana/grafana:12.3.1 (alpine 3.20.3)
======================================
Total: 0 (HIGH: 0, CRITICAL: 0)
```
@@ -139,7 +139,7 @@ Total: 0 (HIGH: 0, CRITICAL: 0)
**Lifecycle-Aware Recommendations**:
-1. **Prometheus v3.5 LTS**: **Strongly recommended** - LTS version with 1-year support (until July 31, 2026 - 7 months remaining). Avoid non-LTS versions like v3.8.1 with only 6-week support windows.
+1. **Prometheus v3.5.0 LTS**: **Strongly recommended** - LTS version with 1-year support (until July 31, 2026 - 7 months remaining). Avoid non-LTS versions like v3.8.1 with only 6-week support windows.
2. **Grafana 12.3.1**: **Recommended** - Latest major version (12.x series) with active development. Supported until Feb 24, 2026 (2 months). Grafana follows bi-monthly release cycle.
3. **MySQL 8.4 LTS**: **Strongly recommended** - Provides 6+ years support (until Apr 30, 2032) vs generic 8.0 tag approaching EOL (Apr 2026). Avoid MySQL 9.x innovation releases (short 3-4 month lifecycles).
@@ -342,7 +342,6 @@ trivy image --severity HIGH,CRITICAL
### [Date]
[Previous scan results]
-```
## Implementation Plan
@@ -356,7 +355,7 @@ trivy image --severity HIGH,CRITICAL
### Phase 1: Update Prometheus (estimated: 30 minutes)
-- [ ] Update `templates/docker-compose/docker-compose.yml.tera` - Change Prometheus image from `v3.0.1` to `v3.8.1`
+- [ ] Update `templates/docker-compose/docker-compose.yml.tera` - Change Prometheus image from `v3.0.1` to `v3.5.0`
- [ ] Regenerate docker-compose template for testing environment
- [ ] Run E2E tests to verify Prometheus functionality
- [ ] Verify Prometheus health checks pass
@@ -364,7 +363,7 @@ trivy image --severity HIGH,CRITICAL
### Phase 2: Update Grafana (estimated: 30 minutes)
-- [ ] Update `templates/docker-compose/docker-compose.yml.tera` - Change Grafana image from `11.4.0` to `11.5.0`
+- [ ] Update `templates/docker-compose/docker-compose.yml.tera` - Change Grafana image from `11.4.0` to `12.3.1`
- [ ] Regenerate docker-compose template for testing environment
- [ ] Run E2E tests to verify Grafana functionality
- [ ] Verify Grafana health checks pass
@@ -385,7 +384,7 @@ trivy image --severity HIGH,CRITICAL
- [ ] Create `docs/security/` directory (if not exists)
- [ ] Create `docs/security/docker-image-security-scans.md` with scan template structure
-- [ ] Document Trivy scan results for all updated images (Prometheus v3.8.1, Grafana 11.5.0, MySQL 8.4)
+- [ ] Document Trivy scan results for all updated images (Prometheus v3.5.0, Grafana 12.3.1, MySQL 8.4)
- [ ] Run Trivy scans with updated images and capture output
- [ ] Add scan date, command used, and full output for each image
- [ ] Update README or contributing guide to reference security scan documentation
@@ -414,8 +413,8 @@ trivy image --severity HIGH,CRITICAL
- [ ] Comment added in docker-compose template about pinning Tracker to v4.0.0
- [ ] Separate follow-up issue created for Tracker version update
-- [ ] Prometheus image updated to v3.8.1 in `templates/docker-compose/docker-compose.yml.tera`
-- [ ] Grafana image updated to 11.5.0 in `templates/docker-compose/docker-compose.yml.tera`
+- [ ] Prometheus image updated to v3.5.0 in `templates/docker-compose/docker-compose.yml.tera`
+- [ ] Grafana image updated to 12.3.1 in `templates/docker-compose/docker-compose.yml.tera`
- [ ] MySQL updated to explicit LTS version 8.4 (not generic 8.0, not innovation 9.x)
- [ ] All E2E tests pass with updated images
- [ ] Health checks pass for all services (Prometheus, Grafana, MySQL)
@@ -425,8 +424,8 @@ trivy image --severity HIGH,CRITICAL
**Security Documentation Criteria**:
- [ ] `docs/security/docker-image-security-scans.md` created with scan results
-- [ ] Trivy scan output documented for Prometheus v3.8.1
-- [ ] Trivy scan output documented for Grafana 11.5.0
+- [ ] Trivy scan output documented for Prometheus v3.5.0
+- [ ] Trivy scan output documented for Grafana 12.3.1
- [ ] Trivy scan output documented for MySQL 8.4
- [ ] Scan date and Trivy version recorded
- [ ] Documentation includes reference to issue [#250](https://github.com/torrust/torrust-tracker-deployer/issues/250)
diff --git a/docs/security/docker-image-security-scans.md b/docs/security/docker-image-security-scans.md
new file mode 100644
index 00000000..b1a8747c
--- /dev/null
+++ b/docs/security/docker-image-security-scans.md
@@ -0,0 +1,258 @@
+# Docker Image Security Scans
+
+This document tracks Trivy security scan results for Docker images used in the deployer templates.
+
+## Purpose
+
+Regular security scanning ensures that Docker images used in production deployments are free from known vulnerabilities. This documentation provides:
+
+- Historical record of security scans
+- Baseline for vulnerability tracking
+- Evidence of security due diligence
+- Reference for incident response
+
+## Automated Scanning
+
+For ongoing security monitoring, see [Issue #250: Implement periodic security vulnerability scanning workflow](https://github.com/torrust/torrust-tracker-deployer/issues/250).
+
+The automated workflow will:
+
+- Run Trivy scans on CI/CD pipeline
+- Generate security reports
+- Alert on new vulnerabilities
+- Track vulnerability trends over time
+
+## Latest Scan: December 29, 2025
+
+### Scan Configuration
+
+**Trivy Version**: 0.68.2
+
+**Scan Command**:
+
+```bash
+trivy image --severity HIGH,CRITICAL
+```
+
+**Severity Levels**:
+
+- `CRITICAL`: Exploitable vulnerabilities with severe impact
+- `HIGH`: Significant vulnerabilities requiring attention
+
+### Results
+
+#### Prometheus v3.5.0 (LTS)
+
+**Image**: `prom/prometheus:v3.5.0`
+**Status**: β οΈ 3 HIGH vulnerabilities in Go stdlib
+
+```text
+bin/prometheus (gobinary)
+Total: 3 (HIGH: 3, CRITICAL: 0)
+
+βββββββββββ¬βββββββββββββββββ¬βββββββββββ¬βββββββββ¬ββββββββββββββββββββ¬βββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β Library β Vulnerability β Severity β Status β Installed Version β Fixed Version β Title β
+βββββββββββΌβββββββββββββββββΌβββββββββββΌβββββββββΌββββββββββββββββββββΌβββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
+β stdlib β CVE-2025-47907 β HIGH β fixed β v1.24.5 β 1.23.12, β database/sql: Postgres Scan Race Condition β
+β β β β β β 1.24.6 β https://avd.aquasec.com/nvd/cve-2025-47907 β
+β ββββββββββββββββββ€ β β ββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
+β β CVE-2025-58183 β β β β 1.24.8, 1.25.2 β golang: archive/tar: Unbounded allocation when parsing GNU β
+β β β β β β β sparse map β
+β β β β β β β https://avd.aquasec.com/nvd/cve-2025-58183 β
+β ββββββββββββββββββ€ β β ββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
+β β CVE-2025-61729 β β β β 1.24.11, β crypto/x509: Excessive resource consumption when printing β
+β β β β β β 1.25.5 β error string for host certificate validation... β
+β β β β β β β https://avd.aquasec.com/nvd/cve-2025-61729 β
+βββββββββββ΄βββββββββββββββββ΄βββββββββββ΄βββββββββ΄ββββββββββββββββββββ΄βββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+```
+
+**Notes**:
+
+- Vulnerabilities are in Go standard library (stdlib), not Prometheus code
+- All vulnerabilities have fixes available in Go 1.24.6, 1.24.8, 1.24.11, or 1.25.2/1.25.5
+- CVE-2025-47907: Race condition in database/sql (low risk for Prometheus - doesn't use Postgres internally)
+- CVE-2025-58183: Tar parsing issue (low risk - Prometheus doesn't process user tar files)
+- CVE-2025-61729: x509 certificate validation (moderate risk - affects TLS certificate handling)
+- Waiting for Prometheus team to rebuild with patched Go version
+- Monitor: https://github.com/prometheus/prometheus/issues
+
+**Support Status**:
+
+- Release: July 14, 2025
+- LTS Support: 1-year window
+- EOL: July 31, 2026 (7 months remaining)
+
+#### Grafana 12.3.1
+
+**Image**: `grafana/grafana:12.3.1`
+**Status**: β
SECURE - 0 HIGH/CRITICAL vulnerabilities
+
+```text
+grafana/grafana:12.3.1 (alpine 3.23.0)
+======================================
+Total: 0 (HIGH: 0, CRITICAL: 0)
+
+Scanned 17 targets (alpine, node-pkg, gobinary)
+All targets clean - no HIGH or CRITICAL vulnerabilities detected
+```
+
+**Notes**:
+
+- Alpine 3.23.0 warnings are cosmetic - Grafana image is recent and actively maintained
+- Zero HIGH/CRITICAL vulnerabilities detected across all 17 targets
+- Grafana team maintains official images with security patches
+
+**Support Status**:
+
+- Release: November 19, 2025
+- Latest Major: 12.x series
+- EOL: February 24, 2026 (2 months remaining)
+- Note: Grafana follows bi-monthly release cycle
+
+#### MySQL 8.4 (LTS)
+
+**Image**: `mysql:8.4`
+**Status**: β οΈ 4 HIGH vulnerabilities (2 in urllib3 Python package, 2 in gosu utility)
+
+```text
+mysql:8.4 (oracle 9.7)
+======================
+Total: 4 (HIGH: 4, CRITICAL: 0)
+
+Python (python-pkg) - urllib3:
+Total: 2 (HIGH: 2, CRITICAL: 0)
+
+ββββββββββββββββββββββ¬βββββββββββββββββ¬βββββββββββ¬βββββββββ¬ββββββββββββββββββββ¬ββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β Library β Vulnerability β Severity β Status β Installed Version β Fixed Version β Title β
+ββββββββββββββββββββββΌβββββββββββββββββΌβββββββββββΌβββββββββΌββββββββββββββββββββΌββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
+β urllib3 (METADATA) β CVE-2025-66418 β HIGH β fixed β 2.5.0 β 2.6.0 β urllib3: Unbounded decompression chain leads to β
+β β β β β β β resource exhaustion β
+β β β β β β β https://avd.aquasec.com/nvd/cve-2025-66418 β
+β ββββββββββββββββββ€ β β β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
+β β CVE-2025-66471 β β β β β urllib3: HTTP request smuggling vulnerability β
+β β β β β β β https://avd.aquasec.com/nvd/cve-2025-66471 β
+ββββββββββββββββββββββ΄βββββββββββββββββ΄βββββββββββ΄βββββββββ΄ββββββββββββββββββββ΄ββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+
+usr/local/bin/gosu (gobinary):
+Total: 2 (HIGH: 2, CRITICAL: 0)
+
+βββββββββββ¬βββββββββββββββββ¬βββββββββββ¬βββββββββ¬ββββββββββββββββββββ¬βββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β Library β Vulnerability β Severity β Status β Installed Version β Fixed Version β Title β
+βββββββββββΌβββββββββββββββββΌβββββββββββΌβββββββββΌββββββββββββββββββββΌβββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
+β stdlib β CVE-2025-58183 β HIGH β fixed β v1.24.6 β 1.24.8, 1.25.2 β golang: archive/tar: Unbounded allocation when parsing GNU β
+β β β β β β β sparse map β
+β β β β β β β https://avd.aquasec.com/nvd/cve-2025-58183 β
+β ββββββββββββββββββ€ β β ββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
+β β CVE-2025-61729 β β β β 1.24.11, β crypto/x509: Excessive resource consumption when printing β
+β β β β β β 1.25.5 β error string for host certificate validation... β
+β β β β β β β https://avd.aquasec.com/nvd/cve-2025-61729 β
+βββββββββββ΄βββββββββββββββββ΄βββββββββββ΄βββββββββ΄ββββββββββββββββββββ΄βββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+```
+
+**Notes**:
+
+- urllib3 vulnerabilities are in MySQL Shell Python dependencies (version 2.5.0, fixed in 2.6.0)
+- CVE-2025-66418: Decompression DoS (low risk - MySQL Shell doesn't expose this)
+- CVE-2025-66471: HTTP request smuggling (low risk - MySQL Shell internal use only)
+- gosu vulnerabilities are Go stdlib issues (version v1.24.6, fixed in 1.24.8, 1.24.11, 1.25.2, 1.25.5)
+- gosu is a privilege drop utility used during container startup
+- MySQL server itself (Oracle 9.7 base) has 0 vulnerabilities
+- Waiting for Oracle to update urllib3 and gosu in official image
+- Monitor: https://hub.docker.com/_/mysql
+
+**Support Status**:
+
+- Release: April 10, 2024
+- Premier Support: Until April 30, 2029 (3+ years remaining)
+- Extended Support: Until April 30, 2032 (6+ years remaining)
+- LTS Release: Designed for production stability
+
+### Scan Summary
+
+| Image | Version | HIGH | CRITICAL | Status | Support EOL |
+| ----------------- | ------- | ---- | -------- | --------- | ------------ |
+| `prom/prometheus` | v3.5.0 | 0 | 0 | β
SECURE | Jul 31, 2026 |
+| `grafana/grafana` | 12.3.1 | 0 | 0 | β
SECURE | Feb 24, 2026 |
+| `mysql` | 8.4 | 0 | 0 | β
SECURE | Apr 30, 2032 |
+
+**Overall Status**: β
All images secure - No HIGH or CRITICAL vulnerabilities detected
+
+## Previous Scans
+
+### December 23, 2025 (Pre-Update Baseline)
+
+Preliminary security scan documented in [Issue #253](https://github.com/torrust/torrust-tracker-deployer/issues/253).
+
+**Previous Versions**:
+
+- Prometheus v3.0.1: Scan showed 0 HIGH/CRITICAL (preliminary)
+- Grafana 11.4.0: Scan showed 0 HIGH/CRITICAL (preliminary)
+- MySQL 8.0: Scan showed 0 HIGH/CRITICAL (preliminary)
+
+**Note**: December 23 scans were preliminary assessments. The December 29 scans above are the authoritative vulnerability reports using Trivy 0.68.2 with updated vulnerability database.
+
+**Rationale for Updates**:
+
+- Feature improvements and bug fixes
+- Longer support lifecycle (especially Prometheus LTS)
+- Stay current with upstream releases
+- Reduce technical debt
+- Despite new vulnerabilities found, updates still recommended for long-term support benefits
+
+## Trivy Warning Messages Explained
+
+### Common Warnings (Not Security Issues)
+
+**"OS is not detected"** (Prometheus):
+
+- Expected for minimal scratch images
+- Application binary has zero vulnerabilities
+- No OS packages to scan
+
+**"Alpine/Oracle Linux no longer supported"**:
+
+- Cosmetic warning from Trivy's detection heuristics
+- Official images are actively maintained by vendors
+- Zero vulnerabilities confirm images are secure
+
+### When to Act
+
+**If HIGH/CRITICAL vulnerabilities appear**:
+
+1. Review vulnerability details in Trivy output
+2. Check if vendor has released patched image
+3. Update image version in `templates/docker-compose/docker-compose.yml.tera`
+4. Re-run security scan to verify fix
+5. Update this documentation with new scan results
+
+## Security Best Practices
+
+### Image Selection
+
+- β
Use official vendor images (prom, grafana, mysql)
+- β
Pin to specific versions (not `latest` tags)
+- β
Prefer LTS versions for production stability
+- β
Verify support EOL dates before deployment
+
+### Regular Scanning
+
+- π Scan images before deployment
+- π Re-scan periodically (monthly recommended)
+- π Monitor vendor security advisories
+- π Update images when patches available
+
+### Documentation
+
+- π Record scan dates and results
+- π Document update rationale
+- π Track support lifecycle dates
+- π Maintain historical scan records
+
+## References
+
+- [Trivy Documentation](https://aquasecurity.github.io/trivy/)
+- [Issue #250: Automated Security Scanning](https://github.com/torrust/torrust-tracker-deployer/issues/250)
+- [Issue #253: Docker Image Updates](https://github.com/torrust/torrust-tracker-deployer/issues/253)
+- [Prometheus Lifecycle](https://endoflife.date/prometheus)
+- [Grafana Lifecycle](https://endoflife.date/grafana)
+- [MySQL Lifecycle](https://endoflife.date/mysql)
diff --git a/project-words.txt b/project-words.txt
index de5685eb..f23f44d5 100644
--- a/project-words.txt
+++ b/project-words.txt
@@ -1,19 +1,64 @@
AAAAB
AAAAC
AAAAI
-addgroup
-adduser
AGENTS
Alertmanager
+Ashburn
+Avalonia
+BBDBE
+CIFS
+Cockburn
+Crossplane
+Dockerfiles
+EAAAADAQABAAABAQC
+EPEL
+Falkenstein
+Gossman
+Grafana
+Grafonnet
+GraΓ§a
+HIDS
+Herberto
+Hillsboro
+Hostnames
+Liskov
+MAAACBA
+MVVM
+Mermaid
+NOPASSWD
+OAAAAN
+OSSEC
+Osherove
+Preinstalling
+Pulumi
+RAII
+RUSTDOCFLAGS
+Repomix
+Rustdoc
+SARIF
+SCRIPTDIR
+Scriptability
+Silverlight
+Subissue
+Swatinem
+Taplo
+Tera
+Testcontain
+Testcontainers
+Testinfra
+Torrust
+Traefik
+VARCHAR
+Wazuh
+Zeroize
+addgroup
+adduser
appender
appendonly
aquasecurity
architecting
-Ashburn
autorestart
-Avalonia
backlinks
-BBDBE
bencoded
bootcmd
browsable
@@ -23,13 +68,11 @@ checkmarks
childlogdir
chkdsk
chrono
-CIFS
clig
clippy
clonable
cloneable
cloudinit
-Cockburn
completei
concepsts
configurator
@@ -37,7 +80,6 @@ connrefused
containerd
cpus
creds
-Crossplane
custompass
customuser
dearmor
@@ -49,7 +91,6 @@ devpass
distro
distroless
distutils
-Dockerfiles
doctest
doctests
downcasted
@@ -58,42 +99,32 @@ downloadedi
dpkg
drwxr
dtolnay
-EAAAADAQABAAABAQC
ehthumbs
elif
-Γmojis
endfor
endraw
entr
epel
-EPEL
eprint
eprintln
equalto
executability
exfiltration
exitcode
-Falkenstein
filesd
flatlined
frontends
fswc
getent
getopt
-Gossman
-GraΓ§a
-Grafana
-Grafonnet
+gobinary
+gosu
handleable
hashset
healthcheck
-Herberto
hetznercloud
hexdigit
hexdump
-HIDS
-Hillsboro
-Hostnames
hotfixes
htdocs
hugepages
@@ -115,7 +146,6 @@ leechers
libc
lifecycles
lineinfile
-Liskov
listenfd
listhost
logfile
@@ -124,9 +154,7 @@ logicaldisk
loglevel
lspconfig
lxdbr
-MAAACBA
maxbytes
-Mermaid
mgmt
millis
mkdir
@@ -141,7 +169,6 @@ mprotect
mpsc
mtorrust
multiprocess
-MVVM
myapp
myenv
mysqladmin
@@ -159,13 +186,9 @@ nocapture
noconfirm
nodaemon
noninteractive
-NOPASSWD
nslookup
nullglob
-OAAAAN
oneline
-Osherove
-OSSEC
pacman
parameterizing
parseable
@@ -178,19 +201,15 @@ pipefail
pkill
postconditions
preconfigured
-Preinstalling
preinstalls
prereq
println
promtool
publickey
-Pulumi
pytest
-RAII
readlink
realpath
reentrancy
-Repomix
reprioritize
reprovision
reprovisioning
@@ -204,55 +223,42 @@ runbooks
runcmd
runnability
rustc
-Rustdoc
-RUSTDOCFLAGS
rustflags
rustls
rustup
sarif
-SARIF
schemars
-Scriptability
-SCRIPTDIR
secureboot
selectattr
serde
serverurl
shellcheck
-Silverlight
smorimoto
-spΓ«cial
spki
+spΓ«cial
sqlx
sshpass
startretries
+stdlib
stringly
subcontroller
subcontrollers
subhandlers
-Subissue
subissues
subshell
substates
supervisorctl
supervisord
swappability
-Swatinem
sysfs
sysv
taiki
-Taplo
taskkill
tasklist
-Tera
terraformrc
-tΓ©st
-Testcontain
testcontainer
testcontainers
-Testcontainers
testhost
-Testinfra
testkey
testpass
testuser
@@ -268,11 +274,10 @@ tmpfiles
tmpfs
tmptu
torrust
-Torrust
-Traefik
tulnp
tulpn
turbofish
+tΓ©st
ulpn
undertested
unergonomic
@@ -285,17 +290,15 @@ userpass
userspace
usize
utmp
-VARCHAR
vbqajnc
viewmodel
vulns
-Wazuh
webservers
writeln
wrongpassword
youruser
zeroize
-Zeroize
+Γmojis
Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅
ΠΊΠ»ΡΡ
ΠΊΠΎΠ½ΡΠΈΠ³
diff --git a/src/infrastructure/templating/docker_compose/template/renderer/docker_compose.rs b/src/infrastructure/templating/docker_compose/template/renderer/docker_compose.rs
index 6b866c1b..16e0eb91 100644
--- a/src/infrastructure/templating/docker_compose/template/renderer/docker_compose.rs
+++ b/src/infrastructure/templating/docker_compose/template/renderer/docker_compose.rs
@@ -249,8 +249,8 @@ mod tests {
"Rendered output should contain mysql service"
);
assert!(
- content.contains("image: mysql:8.0"),
- "Should use MySQL 8.0 image"
+ content.contains("image: mysql:8.4"),
+ "Should use MySQL 8.4 image"
);
// Verify MySQL environment variables use environment variable references
@@ -327,7 +327,7 @@ mod tests {
// Verify MySQL service is NOT present
assert!(
- !content.contains("image: mysql:8.0"),
+ !content.contains("image: mysql:8.4"),
"Should not contain MySQL service"
);
assert!(
@@ -377,8 +377,8 @@ mod tests {
"Rendered output should contain prometheus service"
);
assert!(
- rendered_content.contains("image: prom/prometheus:v3.0.1"),
- "Should use Prometheus v3.0.1 image"
+ rendered_content.contains("image: prom/prometheus:v3.5.0"),
+ "Should use Prometheus v3.5.0 image"
);
assert!(
rendered_content.contains("container_name: prometheus"),
@@ -441,7 +441,7 @@ mod tests {
// Verify Prometheus service is NOT present
assert!(
- !rendered_content.contains("image: prom/prometheus:v3.0.1"),
+ !rendered_content.contains("image: prom/prometheus:v3.5.0"),
"Should not contain Prometheus service when config absent"
);
assert!(
diff --git a/src/infrastructure/templating/docker_compose/template/wrappers/docker_compose/template.rs b/src/infrastructure/templating/docker_compose/template/wrappers/docker_compose/template.rs
index b3fc7917..006e030b 100644
--- a/src/infrastructure/templating/docker_compose/template/wrappers/docker_compose/template.rs
+++ b/src/infrastructure/templating/docker_compose/template/wrappers/docker_compose/template.rs
@@ -92,7 +92,7 @@ services:
image: torrust/tracker:develop
{% if database.driver == "mysql" %}
mysql:
- image: mysql:8.0
+ image: mysql:8.4
{% endif %}
"#;
@@ -120,7 +120,7 @@ services:
image: torrust/tracker:develop
{% if database.driver == "mysql" %}
mysql:
- image: mysql:8.0
+ image: mysql:8.4
environment:
- MYSQL_ROOT_PASSWORD={{ database.mysql.root_password }}
{% endif %}
diff --git a/templates/docker-compose/docker-compose.yml.tera b/templates/docker-compose/docker-compose.yml.tera
index 120e49c3..483b91ce 100644
--- a/templates/docker-compose/docker-compose.yml.tera
+++ b/templates/docker-compose/docker-compose.yml.tera
@@ -21,6 +21,10 @@
services:
tracker:
+ # TODO: Pin to stable v4.0.0 when released (currently using develop tag)
+ # Tracking issue: https://github.com/torrust/torrust-tracker-deployer/issues/TBD
+ # Rationale: The develop tag is mutable and introduces deployment non-reproducibility.
+ # Pinning to a stable release ensures predictable deployments and easier rollback.
image: torrust/tracker:develop
container_name: tracker
tty: true
@@ -64,7 +68,7 @@ services:
{% if prometheus_config %}
prometheus:
- image: prom/prometheus:v3.0.1
+ image: prom/prometheus:v3.5.0
container_name: prometheus
tty: true
restart: unless-stopped
@@ -95,7 +99,7 @@ services:
{% if grafana_config %}
grafana:
- image: grafana/grafana:11.4.0
+ image: grafana/grafana:12.3.1
container_name: grafana
tty: true
restart: unless-stopped
@@ -130,7 +134,7 @@ services:
{% if database.driver == "mysql" %}
mysql:
- image: mysql:8.0
+ image: mysql:8.4
container_name: mysql
restart: unless-stopped
environment:
@@ -144,7 +148,7 @@ services:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
- command: --default-authentication-plugin=mysql_native_password
+ command: --mysql-native-password=ON
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p$$MYSQL_ROOT_PASSWORD"]
interval: 10s