In this section, you’ll build a multi-architecture container image and perform vulnerability scanning using Trivy on an Azure Cobalt 100 Arm64 Ubuntu VM.
You will:
Before starting, ensure you have:
To install Docker on your Arm64 VM, follow the Docker installation guide .
Once Docker is installed, verify it’s running:
docker --version
uname -m
You should see Docker version information and aarch64 architecture output.
Update your system and install required tools for Docker installation.
sudo apt update
sudo apt install -y ca-certificates curl gnupg lsb-release
Add Docker’s official signing key so packages are trusted.
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
Register Docker’s package source for Arm64 Ubuntu.
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Install Docker Engine and Buildx for multi-architecture builds.
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin
sudo usermod -aG docker $USER
newgrp docker
Adds the user to the docker group and applies the new group permissions immediately, enabling non-root access to Docker.
Confirm Docker is running natively on Arm64.
docker info | grep Architecture
You should see a result similar to:
Architecture: aarch64
Create builder:
Create a special Docker builder capable of building images for multiple CPU architectures.
docker buildx create --name multiarch-builder --use
Prepare the builder to support multi-platform builds.
docker buildx inspect --bootstrap
The first command creates a builder instance capable of cross-platform builds. The second command initializes it to support multiple platforms.
Set up a workspace for your demo container:
mkdir $HOME/trivy-multiarch-demo
cd $HOME/trivy-multiarch-demo
Create a Dockerfile:
FROM nginx:latest
COPY index.html /usr/share/nginx/html/index.html
Create an index.html file:
<h1>Multi-Architecture NGINX on Azure Cobalt Arm64</h1>
Run the Docker login command to authenticate:
docker login
Docker displays a one-time device code and a login URL:
https://login.docker.com/activate
Steps to complete login:
Once authentication completes, the terminal will show:
WARNING! Your credentials are stored unencrypted in '/home/azureuser/.docker/config.json'.
Configure a credential helper to remove this warning. See
https://docs.docker.com/go/credential-store/
Login Succeeded
This confirms your system is now authenticated with Docker Hub and ready to push or pull container images.
Next, run the docker login again:
docker login
Note the “Username” that is presented and save it, as you’ll use it in the next step (as DOCKER_USERNAME below).
Finally, create a personal access token in Docker Hub. Log into Docker Hub with your Docker username and password, then select “Account Settings” -> “Personal Access Token” to create a token. Select “Read-Only” privileges and copy and save the token, as it will become your “DOCKER_PASSWORD” in future steps.
Build your image for both amd64 and arm64 architectures. Replace <DOCKER_USERNAME> with your Docker username:
cd $HOME/trivy-multiarch-demo
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t <DOCKER_USERNAME>/trivy-multiarch-nginx:latest \
--push .
This command builds the container for both architectures and pushes the multi-architecture image directly to Docker Hub. The same image specification can now run on both x86 and Arm systems.
Download the Arm64-compatible Trivy scanner:
cd $HOME
wget https://github.com/aquasecurity/trivy/releases/download/v0.68.1/trivy_0.68.1_Linux-ARM64.deb
The Arm Ecosystem Dashboard recommends Trivy 0.29.0 or later for Arm platforms.
Install Trivy on your system:
sudo dpkg -i trivy_0.68.1_Linux-ARM64.deb
Verify the installation:
trivy version
You should see version information displayed.
Scan your Docker Hub image (replace <DOCKER_USERNAME> with your username):
trivy image <DOCKER_USERNAME>/trivy-multiarch-nginx:latest
Trivy analyzes the container layers and reports all detected vulnerabilities with severity levels (LOW, MEDIUM, HIGH, CRITICAL).
Create a machine-readable report for audits and CI pipelines:
trivy image \
--format json \
-o trivy-report.json \
<DOCKER_USERNAME>/trivy-multiarch-nginx:latest
Create a machine-readable vulnerability report for audits and CI pipelines.
2026-01-23T06:42:30Z INFO [vuln] Vulnerability scanning is enabled
2026-01-23T06:42:30Z INFO [secret] Secret scanning is enabled
2026-01-23T06:42:30Z INFO [secret] If your scanning is slow, please try '--scanners vuln' to disable secret scanning
2026-01-23T06:42:30Z INFO [secret] Please see https://trivy.dev/docs/v0.68/guide/scanner/secret#recommendation for faster secret detection
2026-01-23T06:42:32Z INFO Detected OS family="debian" version="12.5"
2026-01-23T06:42:32Z INFO [debian] Detecting vulnerabilities... os_version="12" pkg_num=149
2026-01-23T06:42:33Z INFO Number of language-specific files num=0
2026-01-23T06:42:33Z WARN Using severities from other vendors for some vulnerabilities. Read https://trivy.dev/docs/v0.68/guide/scanner/vulnerability#severity-selection for details.
In this section, you:
You now have a working local security scanning setup. Next, you’ll integrate Trivy into a GitHub Actions CI/CD pipeline to automate security scanning on every code push.