-
Notifications
You must be signed in to change notification settings - Fork 24
build(dgw): add ARM64 Docker image support #1607
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -110,7 +110,6 @@ jobs: | |||||||||||||||||||||||||||
| strategy: | ||||||||||||||||||||||||||||
| fail-fast: false | ||||||||||||||||||||||||||||
| matrix: | ||||||||||||||||||||||||||||
| arch: [x86_64] | ||||||||||||||||||||||||||||
| os: [linux] | ||||||||||||||||||||||||||||
| base-image: [bookworm-slim] | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
@@ -127,17 +126,22 @@ jobs: | |||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| - name: Prepare artifacts | ||||||||||||||||||||||||||||
| id: prepare-artifacts | ||||||||||||||||||||||||||||
| # Multi-arch Docker build strategy: | ||||||||||||||||||||||||||||
| # We prepare separate build contexts for amd64 and arm64 because each architecture | ||||||||||||||||||||||||||||
| # needs its own pre-compiled binary and architecture-specific native libraries (libxmf.so). | ||||||||||||||||||||||||||||
| # This approach is more reliable than trying to use COPY --platform in the Dockerfile, | ||||||||||||||||||||||||||||
| # which would require the binaries to be organized in a specific directory structure. | ||||||||||||||||||||||||||||
| - name: Prepare artifacts (amd64) | ||||||||||||||||||||||||||||
| id: prepare-artifacts-amd64 | ||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||
| Set-PSDebug -Trace 1 | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| $PkgDir = Join-Path docker $Env:RUNNER_OS # RUNNER_OS is camelcase | ||||||||||||||||||||||||||||
| echo "package-path=$PkgDir" >> $Env:GITHUB_OUTPUT | ||||||||||||||||||||||||||||
| $PkgDir = Join-Path docker $Env:RUNNER_OS "amd64" | ||||||||||||||||||||||||||||
| echo "package-path-amd64=$PkgDir" >> $Env:GITHUB_OUTPUT | ||||||||||||||||||||||||||||
| Write-Host "PkgDir = $PkgDir" | ||||||||||||||||||||||||||||
| Get-ChildItem -Path "$PkgDir" | ||||||||||||||||||||||||||||
| New-Item -ItemType Directory -Path $PkgDir -Force | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| $SourceFileName = "DevolutionsGateway_$($Env:RUNNER_OS)_${{ needs.preflight.outputs.version }}_${{ matrix.arch }}" | ||||||||||||||||||||||||||||
| $SourceFileName = "DevolutionsGateway_$($Env:RUNNER_OS)_${{ needs.preflight.outputs.version }}_x86_64" | ||||||||||||||||||||||||||||
| $TargetFileName = "devolutions-gateway" | ||||||||||||||||||||||||||||
| Write-Host "SourceFileName = $SourceFileName" | ||||||||||||||||||||||||||||
| Write-Host "TargetFileName = $TargetFileName" | ||||||||||||||||||||||||||||
|
|
@@ -147,13 +151,10 @@ jobs: | |||||||||||||||||||||||||||
| Write-Host "SourcePath = $SourcePath" | ||||||||||||||||||||||||||||
| Write-Host "TargetPath = $TargetPath" | ||||||||||||||||||||||||||||
| Copy-Item -Path $SourcePath -Destination $TargetPath | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| if ($Env:RUNNER_OS -eq "Linux") { | ||||||||||||||||||||||||||||
| Invoke-Expression "chmod +x $TargetPath" | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| chmod +x $TargetPath | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| $XmfFileName = "libxmf.so" | ||||||||||||||||||||||||||||
| $XmfSourcePath = Get-ChildItem -Recurse -Filter $XmfFileName -File -Path native-libs | ||||||||||||||||||||||||||||
| $XmfSourcePath = Join-Path "native-libs" "linux" "x64" $XmfFileName | Resolve-Path | ||||||||||||||||||||||||||||
| $XmfTargetPath = Join-Path $PkgDir $XmfFileName | ||||||||||||||||||||||||||||
| Write-Host "XmfSourcePath = $XmfSourcePath" | ||||||||||||||||||||||||||||
| Write-Host "XmfTargetPath = $XmfTargetPath" | ||||||||||||||||||||||||||||
|
|
@@ -170,42 +171,154 @@ jobs: | |||||||||||||||||||||||||||
| $psModuleArchiveHash = (Get-FileHash -Path "$PowerShellArchive").Hash | ||||||||||||||||||||||||||||
| Write-Host "PS module archive hash: $psModuleArchiveHash" | ||||||||||||||||||||||||||||
| tar -xvf "$PowerShellArchive" -C "$PkgDir" | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| # Copy Dockerfile and entrypoint | ||||||||||||||||||||||||||||
| Copy-Item -Path "docker/Linux/Dockerfile" -Destination $PkgDir | ||||||||||||||||||||||||||||
| Copy-Item -Path "docker/Linux/entrypoint.ps1" -Destination $PkgDir | ||||||||||||||||||||||||||||
| shell: pwsh | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| - name: Build container | ||||||||||||||||||||||||||||
| id: build-container | ||||||||||||||||||||||||||||
| - name: Prepare artifacts (arm64) | ||||||||||||||||||||||||||||
| id: prepare-artifacts-arm64 | ||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||
| Set-PSDebug -Trace 1 | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| $Version = "${{ needs.preflight.outputs.version }}" | ||||||||||||||||||||||||||||
| $ImageName = "devolutions/devolutions-gateway:$Version" | ||||||||||||||||||||||||||||
| $LatestImageName = "devolutions/devolutions-gateway:latest" | ||||||||||||||||||||||||||||
| $PkgDir = Join-Path docker $Env:RUNNER_OS "arm64" | ||||||||||||||||||||||||||||
| echo "package-path-arm64=$PkgDir" >> $Env:GITHUB_OUTPUT | ||||||||||||||||||||||||||||
| Write-Host "PkgDir = $PkgDir" | ||||||||||||||||||||||||||||
| New-Item -ItemType Directory -Path $PkgDir -Force | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| $SourceFileName = "DevolutionsGateway_$($Env:RUNNER_OS)_${{ needs.preflight.outputs.version }}_arm64" | ||||||||||||||||||||||||||||
| $TargetFileName = "devolutions-gateway" | ||||||||||||||||||||||||||||
| Write-Host "SourceFileName = $SourceFileName" | ||||||||||||||||||||||||||||
| Write-Host "TargetFileName = $TargetFileName" | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| $SourcePath = Get-ChildItem -Recurse -Filter $SourceFileName -File -Path devolutions-gateway | ||||||||||||||||||||||||||||
| $TargetPath = Join-Path $PkgDir $TargetFileName | ||||||||||||||||||||||||||||
| Write-Host "SourcePath = $SourcePath" | ||||||||||||||||||||||||||||
| Write-Host "TargetPath = $TargetPath" | ||||||||||||||||||||||||||||
| Copy-Item -Path $SourcePath -Destination $TargetPath | ||||||||||||||||||||||||||||
| chmod +x $TargetPath | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| $XmfFileName = "libxmf.so" | ||||||||||||||||||||||||||||
| $XmfSourcePath = Join-Path "native-libs" "linux" "arm64" $XmfFileName | Resolve-Path | ||||||||||||||||||||||||||||
| $XmfTargetPath = Join-Path $PkgDir $XmfFileName | ||||||||||||||||||||||||||||
| Write-Host "XmfSourcePath = $XmfSourcePath" | ||||||||||||||||||||||||||||
| Write-Host "XmfTargetPath = $XmfTargetPath" | ||||||||||||||||||||||||||||
| Copy-Item -Path $XmfSourcePath -Destination $XmfTargetPath | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| $WebAppArchive = Get-ChildItem -Recurse -Filter "devolutions_gateway_webapp_*.tar.gz" | Select-Object -First 1 | ||||||||||||||||||||||||||||
| $TargetPath = Join-Path $PkgDir "webapp" "client" | ||||||||||||||||||||||||||||
| Write-Host "WebAppArchive = $WebAppArchive" | ||||||||||||||||||||||||||||
| Write-Host "TargetPath = $TargetPath" | ||||||||||||||||||||||||||||
| New-Item -ItemType Directory -Path $TargetPath | ||||||||||||||||||||||||||||
| tar -xvzf $WebAppArchive.FullName -C $TargetPath --strip-components=1 | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| docker build -t "$ImageName" -t "$LatestImageName" . | ||||||||||||||||||||||||||||
| echo "image-name=$ImageName" >> $Env:GITHUB_OUTPUT | ||||||||||||||||||||||||||||
| echo "latest-image-name=$LatestImageName" >> $Env:GITHUB_OUTPUT | ||||||||||||||||||||||||||||
| $PowerShellArchive = Get-ChildItem -Recurse -Filter "DevolutionsGateway-ps-*.tar" | Select-Object -First 1 | ||||||||||||||||||||||||||||
| $psModuleArchiveHash = (Get-FileHash -Path "$PowerShellArchive").Hash | ||||||||||||||||||||||||||||
| Write-Host "PS module archive hash: $psModuleArchiveHash" | ||||||||||||||||||||||||||||
| tar -xvf "$PowerShellArchive" -C "$PkgDir" | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| Get-ChildItem -Recurse | ||||||||||||||||||||||||||||
| # Copy Dockerfile and entrypoint | ||||||||||||||||||||||||||||
| Copy-Item -Path "docker/Linux/Dockerfile" -Destination $PkgDir | ||||||||||||||||||||||||||||
| Copy-Item -Path "docker/Linux/entrypoint.ps1" -Destination $PkgDir | ||||||||||||||||||||||||||||
|
Comment on lines
+222
to
+223
|
||||||||||||||||||||||||||||
| Copy-Item -Path "docker/Linux/Dockerfile" -Destination $PkgDir | |
| Copy-Item -Path "docker/Linux/entrypoint.ps1" -Destination $PkgDir | |
| Copy-Item -Path "docker/package/Linux/Dockerfile" -Destination $PkgDir | |
| Copy-Item -Path "docker/package/Linux/entrypoint.ps1" -Destination $PkgDir |
Copilot
AI
Dec 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docker buildx build commands lack explicit error handling. If a build fails, the script will continue to the next steps. Consider adding error checking after each docker command (e.g., if ($LASTEXITCODE -ne 0) { throw "Build failed" }) to ensure failures are caught and the workflow stops appropriately.
Copilot
AI
Dec 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docker buildx build commands lack explicit error handling. If a build fails, the script will continue to the next steps. Consider adding error checking after each docker command (e.g., if ($LASTEXITCODE -ne 0) { throw "Build failed" }) to ensure failures are caught and the workflow stops appropriately.
Copilot
AI
Dec 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docker buildx imagetools create commands lack explicit error handling. If manifest creation fails, the script will continue. Consider adding error checking after each command (e.g., if ($LASTEXITCODE -ne 0) { throw "Manifest creation failed" }) to ensure failures are caught and the workflow stops appropriately.
| Write-Host "Creating multi-arch manifest for latest..." | |
| docker buildx imagetools create ` | |
| --tag "${ImageName}:latest" ` | |
| "${ImageName}:${Version}-amd64" ` | |
| "${ImageName}:${Version}-arm64" | |
| if ($LASTEXITCODE -ne 0) { throw "Manifest creation for version ${Version} failed" } | |
| Write-Host "Creating multi-arch manifest for latest..." | |
| docker buildx imagetools create ` | |
| --tag "${ImageName}:latest" ` | |
| "${ImageName}:${Version}-arm64" | |
| if ($LASTEXITCODE -ne 0) { throw "Manifest creation for latest failed" } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,26 @@ | ||
| FROM debian:bookworm-slim | ||
| LABEL maintainer="Devolutions Inc." | ||
|
|
||
| # Install PowerShell and dependencies | ||
| # Microsoft's APT repository doesn't have PowerShell for ARM64, so we install from GitHub releases | ||
| RUN apt-get update \ | ||
| && apt-get install -y --no-install-recommends wget ca-certificates \ | ||
| && wget -q https://packages.microsoft.com/config/debian/12/packages-microsoft-prod.deb -O packages-microsoft-prod.deb \ | ||
| && dpkg -i packages-microsoft-prod.deb \ | ||
| && rm packages-microsoft-prod.deb \ | ||
| && apt-get update \ | ||
| && apt-get install -y --no-install-recommends \ | ||
| powershell openssl \ | ||
| && apt-get install -y --no-install-recommends wget ca-certificates openssl \ | ||
| && ARCH=$(dpkg --print-architecture) \ | ||
| && if [ "$ARCH" = "arm64" ]; then \ | ||
| PWSH_VERSION=7.4.6 \ | ||
|
||
| && wget -q "https://github.com/PowerShell/PowerShell/releases/download/v${PWSH_VERSION}/powershell-${PWSH_VERSION}-linux-arm64.tar.gz" \ | ||
| && mkdir -p /opt/microsoft/powershell/7 \ | ||
| && tar -xzf "powershell-${PWSH_VERSION}-linux-arm64.tar.gz" -C /opt/microsoft/powershell/7 \ | ||
| && chmod +x /opt/microsoft/powershell/7/pwsh \ | ||
| && ln -s /opt/microsoft/powershell/7/pwsh /usr/bin/pwsh \ | ||
| && rm "powershell-${PWSH_VERSION}-linux-arm64.tar.gz"; \ | ||
| else \ | ||
| wget -q https://packages.microsoft.com/config/debian/12/packages-microsoft-prod.deb -O packages-microsoft-prod.deb \ | ||
| && dpkg -i packages-microsoft-prod.deb \ | ||
| && rm packages-microsoft-prod.deb \ | ||
| && apt-get update \ | ||
| && apt-get install -y --no-install-recommends powershell; \ | ||
| fi \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
|
|
||
| ENV XDG_CACHE_HOME="/tmp/.cache" | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect path to Dockerfile and entrypoint.ps1. The 'docker' artifact uploaded in package.yml contains files at
package/Linux/Dockerfileandpackage/Linux/entrypoint.ps1, which when downloaded will be atdocker/package/Linux/Dockerfileanddocker/package/Linux/entrypoint.ps1, notdocker/Linux/Dockerfile. This path should be"docker/package/Linux/Dockerfile"and"docker/package/Linux/entrypoint.ps1".