コンテナ環境でよく利用されている Alpine Linux のパッケージをビルドする話です。
例として、OpenVPN 2.6.17 のalpineパッケージ (apk) の作り方を紹介します。
目的
- コンテナを使ってソースコードから Alpine Linuxのパッケージをビルドできるようになる
- Alpine Linux側のパッケージ提供を待たなくても、迅速に自分で対応できる(緊急性が高い脆弱性にも速攻で対応!)
ビルド環境
- Windows、Linux、Macなど、
podmanやdockerコマンドが使える環境- 本記事では、
Windows 11、Podman Desktop、Git BashまたはPowerShellを使用
- 本記事では、
ビルド方法
既存の APKBUILD を参考に自分でバージョンアップし、ビルドする
-
例)openvpn - alpine linux
https://gitlab.alpinelinux.org/alpine/aports/-/tree/master/main/openvpn- コード > ディレクトリのダウンロードで、zip または tar.gzで取得
- aports-master-main-openvpn.zip
- unzip aports-master-main-openvpn.zip
-
zipを展開すると、
aports-master-main-openvpn/main/openvpnにAPKBUILDなどのファイルがあるのでカスタマイズする
例)openvpn-2.6.17 をビルドしたい場合
- APKBUILD のバージョンを修正する
-
例) pkgverを
2.6.17に変更するpkgname=openvpn pkgver=2.6.17 pkgrel=0- パッケージ名: openvpn-2.6.17-r0.apk となる
-
sha512sumsの部分は削除するsha512sums=" .... "
-
準備するファイル
-
Dockerfile.apk- パッケージビルド用のDockerfile - 参考)
build-apk.shまたはbuild-apk.ps1- ビルドスクリプト
(Windows環境のPodman Desktop、PowerShell、Git Bashを使って確認しています)
パッケージビルド用Dockerfile
- Dockerfile.apk
# Alpine APK builder FROM alpine:3.22.2 AS builder # Install build dependencies RUN apk add --no-cache \ alpine-sdk \ sudo \ linux-headers \ lz4-dev \ lzo-dev \ openssl-dev \ linux-pam-dev \ net-tools \ libcap-ng-dev \ pkgconf \ cmake \ autoconf \ automake \ iproute2-minimal \ cmocka-dev \ libtool # Create build user RUN adduser -D builder && \ addgroup builder abuild && \ echo "builder ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/builder # Setup abuild USER builder WORKDIR /home/builder RUN abuild-keygen -a -i -n # Create APKBUILD RUN mkdir -p /home/builder/openvpn && \ cd /home/builder/openvpn COPY aports-master-main-openvpn/main/openvpn/* /home/builder/openvpn/ # Build the package WORKDIR /home/builder/openvpn RUN abuild checksum && \ abuild -r # Export the built package FROM alpine AS export COPY --from=builder /home/builder/packages/ /packages/
ビルドについて補足
- コンテナ名:
openvpn-apk-builder - パッケージの出力先:
./packages/builder/x86_64/ -
podmanコマンドを使用しているため、dockerの場合はpodman→dockerに置換 - スクリプトを作成して実行することで、ビルド→パッケージが生成される
- ビルドに必要となるパッケージは、
APKBUILDに書かれている makedependsなどを参考に
Shellでビルドを実行する場合 (Linux / Git Bashなど、podman使用)
- 例) build-apk.sh
#!/bin/bash # OpenVPN APK Package Build Script set -e echo "=== OpenVPN APK Package Build Script ===" # Build APK package echo "Step 1: Building OpenVPN APK package..." podman build -f Dockerfile.apk -t openvpn-apk-builder . echo "Step 2: Extracting APK packages..." CONTAINER_ID=$(docker create openvpn-apk-builder) podman cp "${CONTAINER_ID}:/packages" ./packages podman rm "${CONTAINER_ID}" echo "Step 3: Organizing package directory..." if [ -d "./packages/packages" ]; then rm -rf ./packages/builder mv ./packages/packages/builder ./packages/ rm -rf ./packages/packages fi echo "Step 4: Verifying packages..." ls -lh ./packages/builder/x86_64/*.apk echo "=== Build completed successfully! ===" echo "Generated packages:" find ./packages/builder/x86_64/ -name "*.apk" -exec basename {} \;
Windows / PowerShell でビルドを実行する場合 (Podman Desktop)
- 例) build-apk.ps1
Write-Host "=== OpenVPN APK Package Build Script ===" Write-Host "Step 1: Building OpenVPN APK package..." podman build -f Dockerfile.apk -t openvpn-apk-builder . Write-Host "Step 2: Extracting APK packages..." $containerId = podman create openvpn-apk-builder podman cp "${containerId}:/packages" ./packages podman rm $containerId Write-Host "Step 3: Organizing package directory..." if (Test-Path "./packages/packages") { Remove-Item -Recurse -Force ./packages/builder -ErrorAction SilentlyContinue Move-Item ./packages/packages/builder ./packages/ Remove-Item -Recurse -Force ./packages/packages } Write-Host "Step 4: Verifying packages..." Get-ChildItem ./packages/builder/x86_64/*.apk | ForEach-Object { Write-Host " - $($_.Name) ($([math]::Round($_.Length/1KB, 2)) KB)" } Write-Host "=== Build completed successfully! ===" Write-Host "Generated packages:" Get-ChildItem ./packages/builder/x86_64/*.apk | ForEach-Object { Write-Host " - $($_.Name)" }
ビルド結果の確認
ビルドに成功すると、./packages/builder/x86_64 にファイルが生成されます。
- ビルド結果:
=== Build completed successfully! === Generated packages: openvpn-2.6.17-r0.apk openvpn-auth-pam-2.6.17-r0.apk openvpn-dev-2.6.17-r0.apk openvpn-doc-2.6.17-r0.apk openvpn-openrc-2.6.17-r0.apk
あとは、既存のDockerfileを修正してapkをインストールすればOK
- 例) Dockerfile (一部抜粋)
# Copy local APK packages COPY packages/builder/x86_64/openvpn-2.6.17-r0.apk /tmp/apk/ # Install OpenVPN 2.6 from local APK and other dependencies RUN apk add --allow-untrusted /tmp/apk/openvpn-2.6.17-r0.apk && \ ...
留意事項
OSSの利用は自己責任となります。
ソフトウェアに脆弱性があっても、修正版のパッケージが早急にリリースされない場合が多くあります。
最近は、AIエージェントに「ソースコードからalpineのパッケージ作って」と指示すれば作ってくれますが、今まで使っていたパッケージとの互換性が気になる場合など、自分でも対応できるとよいでしょう。
迅速にするためのひとつの手段としてご参考になれば幸いです。
参考
Alpine Linux
https://www.alpinelinux.org/
- LATEST DEVELOPMENT で更新されたパケージがわかる
- リリース情報、End of support
https://www.alpinelinux.org/releases/
Alpine Linuxのパッケージ検索
https://pkgs.alpinelinux.org/packages
Alpine Linux aports repository
https://gitlab.alpinelinux.org/alpine/aports
このリポジトリには、すべての Alpine Linux パッケージの APKBUILD ファイルと、必要なパッチおよびスクリプト(存在する場合)が含まれています。