Skip to content

fix: [#428] Docker vulnerability remediation pass 1 (all 8 images) #25

fix: [#428] Docker vulnerability remediation pass 1 (all 8 images)

fix: [#428] Docker vulnerability remediation pass 1 (all 8 images) #25

# Backup Container workflow for Torrust Tracker Deployer
#
# This workflow builds, tests, and publishes the backup Docker image.
# Following patterns from container.yaml workflow.
#
# Triggers:
# - Push to main/develop branches (only when backup container files change)
# - Pull requests to main/develop (only when backup container files change)
# - Manual dispatch
#
# Publishing:
# - Images are pushed to Docker Hub on push to main/develop (not PRs)
# - Requires Docker Hub credentials in repository secrets (dockerhub-torrust-backup environment)
name: Backup Container
on:
push:
branches:
- "develop"
- "main"
paths:
- "docker/backup/**"
- ".github/workflows/backup-container.yaml"
pull_request:
branches:
- "develop"
- "main"
paths:
- "docker/backup/**"
- ".github/workflows/backup-container.yaml"
workflow_dispatch:
env:
CARGO_TERM_COLOR: always
DOCKER_HUB_USERNAME: torrust
jobs:
test:
name: Build & Test
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build Image
uses: docker/build-push-action@v6
with:
# CRITICAL: Context must be ./docker/backup (not ./)
# Docker COPY/ADD commands resolve paths RELATIVE TO BUILD CONTEXT, not Dockerfile location.
# Setting context: ./docker/backup allows the Dockerfile to use simple relative paths like:
# COPY backup.sh /scripts/backup.sh
# This creates consistency between local builds and CI builds.
#
# Regression History: commit 9d297cc5 used context: . with full paths in Dockerfile
# (e.g., COPY docker/backup/backup.sh). This worked but was confusing and error-prone
# for future changes. The current approach is cleaner and prevents regression.
#
# See docker/backup/README.md "Building the Container" section for details.
context: ./docker/backup
file: ./docker/backup/Dockerfile
target: production
push: false
load: true
tags: torrust/tracker-backup:local
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Inspect Image
run: docker image inspect torrust/tracker-backup:local
- name: Verify Container Structure
run: |
echo "=== Verifying backup container structure ==="
echo "=== Checking backup script exists ==="
docker run --rm --entrypoint ls torrust/tracker-backup:local -lh /scripts/backup.sh
echo "=== Checking backup directories ==="
docker run --rm --entrypoint ls torrust/tracker-backup:local -ld /backups/mysql /backups/sqlite /backups/config
echo "=== Verifying tools installed ==="
docker run --rm --entrypoint which torrust/tracker-backup:local bash
docker run --rm --entrypoint which torrust/tracker-backup:local mysql
docker run --rm --entrypoint which torrust/tracker-backup:local sqlite3
docker run --rm --entrypoint which torrust/tracker-backup:local gzip
docker run --rm --entrypoint which torrust/tracker-backup:local tar
echo "=== Checking entrypoint ==="
docker inspect --format='{{.Config.Entrypoint}}' torrust/tracker-backup:local
- name: Test Container Execution
run: |
echo "=== Testing backup container without config (should fail gracefully) ==="
docker run --rm torrust/tracker-backup:local || true
context:
name: Context
needs: test
runs-on: ubuntu-latest
outputs:
continue: ${{ steps.check.outputs.continue }}
type: ${{ steps.check.outputs.type }}
steps:
- name: Check Context
id: check
run: |
if [[ "${{ github.repository }}" == "torrust/torrust-tracker-deployer" ]]; then
if [[ "${{ github.event_name }}" == "push" ]]; then
if [[ "${{ github.ref }}" == "refs/heads/main" ]]; then
echo "type=production" >> $GITHUB_OUTPUT
echo "continue=true" >> $GITHUB_OUTPUT
elif [[ "${{ github.ref }}" == "refs/heads/develop" ]]; then
echo "type=development" >> $GITHUB_OUTPUT
echo "continue=true" >> $GITHUB_OUTPUT
fi
fi
fi
# Default: don't continue
if [[ -z "$(cat $GITHUB_OUTPUT 2>/dev/null)" ]]; then
echo "continue=false" >> $GITHUB_OUTPUT
fi
publish_development:
name: Publish (Development)
environment: dockerhub-torrust-backup
needs: context
if: needs.context.outputs.continue == 'true' && needs.context.outputs.type == 'development'
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Docker Meta
id: meta
uses: docker/metadata-action@v5
with:
images: |
${{ env.DOCKER_HUB_USERNAME }}/tracker-backup
tags: |
type=ref,event=branch
type=sha,prefix=dev-
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ env.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and Push
uses: docker/build-push-action@v6
with:
context: ./docker/backup
file: ./docker/backup/Dockerfile
target: production
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
publish_production:
name: Publish (Production)
environment: dockerhub-torrust-backup
needs: context
if: needs.context.outputs.continue == 'true' && needs.context.outputs.type == 'production'
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Docker Meta
id: meta
uses: docker/metadata-action@v5
with:
images: |
${{ env.DOCKER_HUB_USERNAME }}/tracker-backup
tags: |
type=raw,value=latest
type=ref,event=branch
type=sha
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ env.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and Push
uses: docker/build-push-action@v6
with:
context: ./docker/backup
file: ./docker/backup/Dockerfile
target: production
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max