Skip to content

Commit 59d6ea2

Browse files
authored
refactor!: enforce an optimize single platform docker-build with failure on CRITICAL or HIGH fixed vulnerabilities detection (#98)
1 parent 7249559 commit 59d6ea2

File tree

2 files changed

+88
-46
lines changed

2 files changed

+88
-46
lines changed

.github/workflows/docker-build.yml

Lines changed: 62 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ on:
4343
description: "Enable Hadolint"
4444
default: true
4545
type: boolean
46-
platforms:
47-
description: "Build platforms"
48-
default: "linux/amd64,linux/arm64"
46+
platform:
47+
description: "Build platform"
48+
default: "linux/amd64"
4949
type: string
5050
secrets:
5151
username:
@@ -56,7 +56,35 @@ on:
5656
jobs:
5757
build:
5858
runs-on: ubuntu-latest
59+
60+
# avoid shell injection through string interpolation
61+
env:
62+
PLATFORM: ${{ inputs.platform }}
63+
OCI_IMAGE: ${{ inputs.image-name }}:${{ inputs.image-tag }}
64+
REPORT_MODE: ${{ inputs.security-report }}
65+
5966
steps:
67+
- name: Validate platform input
68+
run: |
69+
if [ "$PLATFORM" != "linux/amd64" ] && [ "$PLATFORM" != "linux/arm64" ] ; then
70+
echo "❌ Error: Invalid platform: $PLATFORM"
71+
echo "Valid platforms are 'linux/amd64' or 'linux/arm64'"
72+
exit 1
73+
fi
74+
75+
echo "✅ Platform validation passed: $PLATFORM"
76+
77+
- name: Validate security report mode input
78+
if: ${{ inputs.security-scan }}
79+
run: |
80+
if [ "$REPORT_MODE" != "comment" ] && [ "$REPORT_MODE" != "sarif" ] ; then
81+
echo "❌ Error: Invalid security report mode: $REPORT_MODE"
82+
echo "Valid modes are 'comment' or 'sarif'"
83+
exit 1
84+
fi
85+
86+
echo "✅ Security report mode validation passed: $REPORT_MODE"
87+
6088
- name: Checkout Repository
6189
uses: actions/checkout@v4
6290

@@ -74,40 +102,25 @@ jobs:
74102
username: ${{ secrets.username }}
75103
password: ${{ secrets.password }}
76104

77-
- name: Build Docker Image
105+
- name: Build Docker image
78106
uses: docker/build-push-action@v6
79107
with:
80108
build-args: ${{ inputs.build-args }}
81109
context: ${{ inputs.context }}
82110
file: ${{ inputs.dockerfile }}
83-
platforms: ${{ inputs.platforms }}
84-
push: ${{ inputs.push }}
111+
platforms: ${{ inputs.platform }}
112+
load: true # Make the image available on runner
113+
push: false # Don't push yet, wait for security checks
85114
tags: ${{ inputs.image-name }}:${{ inputs.image-tag }}
86115

87-
- name: Build Docker Image as Tarball
88-
if: ${{ inputs.security-scan }}
89-
run: |
90-
BUILD_ARGS=""
91-
if [ -n "${{ inputs.build-args }}" ]; then
92-
while IFS= read -r line; do
93-
if [ -n "$line" ]; then
94-
BUILD_ARGS="$BUILD_ARGS --build-arg $line"
95-
fi
96-
done <<< "${{ inputs.build-args }}"
97-
fi
98-
docker build $BUILD_ARGS -t ${{ inputs.image-name }}:${{ inputs.image-tag }} -f ${{ inputs.dockerfile }} ${{ inputs.context }}
99-
docker save -o vuln-image.tar ${{ inputs.image-name }}:${{ inputs.image-tag }}
100-
101116
- name: Run Trivy vulnerability scanner
102117
id: trivy
103118
if: ${{ inputs.security-scan }}
104-
uses: aquasecurity/trivy-action@0.29.0
119+
uses: aquasecurity/trivy-action@0.33.1
105120
with:
106-
input: vuln-image.tar
121+
image-ref: ${{ inputs.image-name }}:${{ inputs.image-tag }}
107122
format: ${{ (inputs.security-report == 'sarif' && 'sarif') || 'table' }}
108-
ignore-unfixed: true
109123
vuln-type: "os,library"
110-
severity: "CRITICAL,HIGH"
111124
hide-progress: true
112125
output: ${{ (inputs.security-report == 'sarif' && 'trivy-results.sarif') || 'trivy.txt' }}
113126

@@ -126,7 +139,7 @@ jobs:
126139
with:
127140
issue-number: ${{ github.event.pull_request.number }}
128141
comment-author: "github-actions[bot]"
129-
body-includes: "Trivy Security Scan Results"
142+
body-includes: "Trivy Security ${{ inputs.platform }} Scan Results"
130143

131144
- name: Create or update Trivy comment
132145
if: github.event_name == 'pull_request' && inputs.security-scan && inputs.security-report == 'comment'
@@ -138,7 +151,7 @@ jobs:
138151
edit-mode: replace
139152
body: |
140153
<!-- trivy-scan -->
141-
### 🔒 Trivy Security Scan Results
154+
### 🔒 Trivy Security ${{ inputs.platform }} Scan Results
142155
<details><summary>Click to expand detailed results</summary>
143156
144157
```bash
@@ -196,3 +209,26 @@ jobs:
196209
${{ steps.read_hadolint.outputs.report }}
197210
```
198211
</details>
212+
213+
- name: Fail build on CRITICAL or HIGH vulnerabilities
214+
if: ${{ inputs.security-scan }}
215+
uses: aquasecurity/trivy-action@0.33.1
216+
with:
217+
image-ref: ${{ inputs.image-name }}:${{ inputs.image-tag }}
218+
format: table
219+
ignore-unfixed: true
220+
vuln-type: "os,library"
221+
severity: "CRITICAL,HIGH"
222+
hide-progress: true
223+
skip-setup-trivy: true
224+
exit-code: 1
225+
226+
- name: Push Docker image
227+
if: ${{ inputs.push }}
228+
run: docker push "$OCI_IMAGE"
229+
230+
- name: Cleanup files
231+
if: always()
232+
run: |
233+
rm -f trivy.txt trivy-results.sarif
234+
docker image rm -f "$OCI_IMAGE"

docker-build/README.md

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,40 @@
22

33
## 🔍 Overview
44

5-
This reusable GitHub Actions workflow automates the process of building and pushing Docker images to Docker Hub. It simplifies the Docker build process in your CI/CD pipeline by handling authentication, building, and tagging in a standardized way. Perfect for teams looking to streamline their containerization workflow with minimal configuration.
5+
This reusable GitHub Actions workflow automates the process of building and pushing Docker images to a Docker Registry.
6+
It simplifies the Docker build process in your CI/CD pipeline by handling authentication, building, and tagging in a standardized way.
7+
Perfect for teams looking to streamline their containerization workflow with minimal configuration.
68

79
## ✨ Features
810

9-
- 🔐 Securely authenticates with Docker Hub using best practices
11+
- 🔐 Securely authenticates with a Docker Registry using best practices
1012
- 🏗️ Builds optimized Docker images from a specified Dockerfile
11-
- 🏷️ Intelligently tags and pushes images to Docker Hub
12-
- 🔎 Scan for vulnerabilities
13+
- 🏷️ Intelligently tags and pushes images to a Docker Registry
14+
- 🔎 Scan for vulnerabilities with Trivy
1315
- 👍 Lint dockerfile
1416
- 🛡️ Handles authentication securely using GitHub Secrets
1517
- 🚀 Optimizes build performance with layer caching
16-
- 📦 Supports multi-platform builds (AMD64, ARM64)
18+
- 📦 Supports AMD64 and ARM64 platforms (one per workflow run)
19+
20+
> [!IMPORTANT]
21+
> Due to a limitation on Trivy analysis, the workflow targets a single platform.
22+
> A workflow instance should be configured for each intended targeted platform.
1723
1824
## ⚙️ Inputs
1925

20-
| Name | Description | Required | Default |
21-
| ----------------- | ---------------------------------------------------------------------------------- | -------- | --------------------------- |
22-
| `build-args` | Docker build arguments (multiline format: `KEY1=value1\nKEY2=value2`) | No | `""` |
23-
| `context` | Path to Docker Build Context | No | `"."` |
24-
| `dockerfile` | Path to the Dockerfile to build (e.g., './Dockerfile', './docker/Dockerfile') | No | `"Dockerfile"` |
25-
| `hadolint` | Enable Hadolint | No | `true` |
26-
| `image-name` | Name of Docker Image (e.g., 'myimage', 'myorg/myimage') | true | - |
27-
| `image-tag` | Tag to apply to the built image (e.g., 'latest', 'v1.2.3') | No | `"latest"` |
28-
| `platforms` | Indicates which platforms the image should be built for | No | `"linux/amd64,linux/arm64"` |
29-
| `push` | Push Docker Image to Registry | No | `false` |
30-
| `registry` | Docker Registry | No | `"docker.io"` |
31-
| `security-report` | Security Report Mode (`"sarif"` \| `"comment"`; ignored if `security-scan: false`) | No | `"sarif"` |
32-
| `security-scan` | Enable Trivy Security Scan | No | `true` |
26+
| Name | Description | Required | Default |
27+
| ----------------- | ---------------------------------------------------------------------------------- | -------- | --------------- |
28+
| `build-args` | Docker build arguments (multiline format: `KEY1=value1\nKEY2=value2`) | No | `""` |
29+
| `context` | Path to Docker Build Context | No | `"."` |
30+
| `dockerfile` | Path to the Dockerfile to build (e.g., './Dockerfile', './docker/Dockerfile') | No | `"Dockerfile"` |
31+
| `hadolint` | Enable Hadolint | No | `true` |
32+
| `image-name` | Name of Docker Image (e.g., 'myimage', 'myorg/myimage') | true | - |
33+
| `image-tag` | Tag to apply to the built image (e.g., 'latest', 'v1.2.3') | No | `"latest"` |
34+
| `platform` | Indicates which platform the image should be built for | No | `"linux/amd64"` |
35+
| `push` | Push Docker Image to Registry | No | `false` |
36+
| `registry` | Docker Registry | No | `"docker.io"` |
37+
| `security-report` | Security Report Mode (`"sarif"` \| `"comment"`; ignored if `security-scan: false`) | No | `"sarif"` |
38+
| `security-scan` | Enable Trivy Security Scan | No | `true` |
3339

3440
## 🔐 Secrets
3541

@@ -73,15 +79,15 @@ jobs:
7379
7480
## 📝 Notes
7581
76-
- 🔒 Ensure your Docker Hub credentials are stored securely as GitHub Secrets
82+
- 🔒 Ensure your Docker Registry credentials are stored securely as GitHub Secrets
7783
- 🔄 The workflow will automatically handle the Docker build and push process
7884
- 🏷️ You can specify any valid Docker tag format in the `tag` input
7985
- 📅 Consider using dynamic tags based on git tags, commit SHAs, or dates
8086
- 🧪 For testing purposes, you can use the `--dry-run` flag in your own implementation
8187

8288
## 🛠️ Troubleshooting
8389

84-
- If you encounter authentication issues, verify your Docker Hub credentials are correct and have appropriate permissions
90+
- If you encounter authentication issues, verify your Docker Registry credentials are correct and have appropriate permissions
8591
- For build failures, check your Dockerfile syntax and ensure all referenced files exist
8692
- Large images may take longer to push - consider optimizing your Dockerfile with multi-stage builds
8793
- If you need to debug the build process, you can add the `ACTIONS_STEP_DEBUG` secret set to `true` in your repository

0 commit comments

Comments
 (0)