@@ -265,15 +265,18 @@ mounted files).
265265
266266``` text
267267docker/backup/
268- ├── Dockerfile # Backup container image
268+ ├── Dockerfile # Backup container image (base: debian:bookworm-slim)
269269├── backup.sh # Main backup script (58 unit tests)
270270└── README.md # Container documentation
271271```
272272
273273** Tasks** :
274274
275275- [ ] Create ` docker/backup/ ` directory
276- - [ ] Copy POC artifacts (` Dockerfile ` , ` backup.sh ` ) from research directory
276+ - [ ] Review and refactor POC artifacts (` Dockerfile ` , ` backup.sh ` ) from research directory
277+ - Align with project-specific conventions
278+ - Ensure production-ready quality
279+ - Base image: ` debian:bookworm-slim ` (from POC)
277280- [ ] Add README.md documenting the container's purpose and usage
278281- [ ] Verify container builds and runs correctly locally
279282
@@ -306,11 +309,23 @@ manual testing procedures.
306309** Tasks** :
307310
308311- [ ] Create ` .github/workflows/backup-container.yaml `
309- - [ ] Publish to Docker Hub as ` torrust/backup `
310- - [ ] Add Trivy security scanning
311- - [ ] Tag with version and ` latest `
312-
313- ** Manual Testing** : Verify image is published and pullable from Docker Hub.
312+ - Follow same pattern as ` .github/workflows/container.yaml ` (deployer image)
313+ - Use ` dockerhub-torrust-backup ` environment (not ` dockerhub-torrust ` )
314+ - Trigger on changes to ` docker/backup/** ` path
315+ - Publish to Docker Hub as ` torrust/backup `
316+ - Tag with version and ` latest `
317+ - [ ] Run manual security scan as per ` docs/security/docker/README.md `
318+ - ` trivy image --severity HIGH,CRITICAL torrust/backup:latest `
319+ - Document scan results
320+ - [ ] Add backup image to ` .github/workflows/docker-security-scan.yml `
321+ - Add to ` scan-project-images ` matrix
322+ - Add SARIF upload step in ` upload-sarif-results ` job
323+
324+ ** Manual Testing** :
325+
326+ - Verify image is published and pullable from Docker Hub
327+ - Confirm no HIGH/CRITICAL vulnerabilities in Trivy scan
328+ - Verify security scan workflow includes backup image
314329
315330---
316331
@@ -351,10 +366,27 @@ pub struct BackupConfig {
351366}
352367
353368/// Validated cron schedule (5-field format)
369+ /// Uses the `cron` crate for full validation (ranges, steps, lists)
354370#[derive(Debug , Clone , Serialize , Deserialize , PartialEq , Eq )]
355371pub struct CronSchedule (String );
372+
373+ impl CronSchedule {
374+ /// Validates cron expression using the `cron` crate
375+ /// Rejects invalid schedules like "70 * * * *" or "0 0 32 * *"
376+ pub fn new (schedule : String ) -> Result <Self , BackupError > {
377+ use cron :: Schedule ;
378+ use std :: str :: FromStr ;
379+
380+ Schedule :: from_str (& schedule )
381+ . map_err (| e | BackupError :: InvalidCronSchedule (schedule . clone (), e . to_string ()))? ;
382+
383+ Ok (Self (schedule ))
384+ }
385+ }
356386```
357387
388+ ** Dependencies** : Add ` cron = "0.12" ` to ` Cargo.toml ` for validation
389+
358390** Topology Domain** (` src/domain/topology/ ` ):
359391
360392The backup service must be registered in the topology module, which defines all
0 commit comments