Dockerイメージをオフライン配布する際の「export/import」活用とログ肥大化対策
はじめに
「WSL(x64)環境で開発しているが、デプロイ先はRaspberry Pi(ARM)だ」というケースは多いはずです。
本記事では、x64環境でのARMイメージのビルド方法から、レジストリを使わないイメージのインポート/エクスポート(軽量化)、忘れがちなログローテーション設定まで、実務で躓きやすいポイントをTIPSとしてまとめました。
WSL(X64)でARMのDockerイメージを作成する
WSL上でDockerをインストールした直後は、x64のイメージしか作れません。Raspberry PiなどARM環境向けのイメージをビルドするには、buildx と binfmt を使った設定が必要です。
buildxしたDockerイメージは、WSLのdocker image上には作成されません。
docker exportした時のファイルイメージと同じものです。
ビルド対象のプラットフォームにて、Dockerイメージをインポートするを参照にインポートしてください。
Raspberry PiのOSが32ビットと64ビットではターゲットが変わってきますのでお気を付けください。
- 32ビット:
linux/arm/v7 - 64ビット:
linux/arm64
※32ビットでは確認したのですが、64ビットでは確認していません。もし64ビットで不具合があったらコメントで教えてください。
tonistiigi/binfmtとは?
tonistiigi/binfmtは、マルチアーキテクチャの実行環境を追加するための仕組みです。これを導入することで、x64環境でもARM用のバイナリをクロスビルドできます。
# 各種アーキテクチャのサポートを追加
docker run --rm --privileged tonistiigi/binfmt:latest \
--install linux/amd64,linux/arm64,linux/ppc64le,linux/s390x,linux/386,linux/arm/v7,linux/arm/v6
# buildx を有効化
docker buildx use default
# 利用可能なプラットフォームを確認
docker buildx ls
ここでlinux/arm/v7またはlinux/arm64が表示されればRaspberry Pi用のビルドが可能です。
Dockerイメージ作成スクリプト
以下のスクリプトで、ARM向けのイメージをビルドします。

#!/usr/bin/env bash
EXPORT_FILE="app_container.tar"
IMAGE_NAME="app-image"
# Raspberry Pi 32ビット(arm/v7) 用にビルド
docker buildx build --no-cache --platform linux/arm/v7 \
--output type=tar,dest=$EXPORT_FILE \
-t $IMAGE_NAME . -f Dockerfile
サンプルDockerfile
FROM python:3.12.2-slim-bullseye
USER root
RUN apt-get update && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* && \
pip install --upgrade pip
WORKDIR /opt/app
COPY requirement.txt ./
RUN pip install -r requirement.txt
Dockerイメージをインポートする
別環境から持ち込んだイメージを取り込む場合は、docker import を使います。
Dockerイメージインポートスクリプト
#!/usr/bin/env bash
IMPORT_FILE="app_container.tar"
IMAGE_NAME="app-image"
# イメージをインポート
docker import $IMPORT_FILE $IMAGE_NAME:latest
BUILD_STATUS=$?
if [ $BUILD_STATUS -ne 0 ]; then
echo "Docker import failed with status code $BUILD_STATUS"
exit 1
else
echo "インポート完了:$IMPORT_ZIP_FILE"
fi
Dockerイメージをエクスポートする
インポートしたイメージを、再度ファイルとしてエクスポートできます。これにより、別の環境へ配布できます。
saveでもイメージを保存できますが、ビルドしたときのメタ情報も保存されますので、saveよりexportの方が保存されるファイルのサイズが小さくなります。
Dockerイメージエクスポートスクリプト
#!/usr/bin/env bash
IMAGE_NAME="app-image"
EXPORT_FILE="app_container.tar"
# イメージをエクスポート
docker export $IMAGE_NAME:latest > $EXPORT_FILE
BUILD_STATUS=$?
if [ $BUILD_STATUS -ne 0 ]; then
echo "Docker export failed with status code $BUILD_STATUS"
exit 1
else
echo "Docker export succeeded."
fi
echo "Dockerイメージが $EXPORT_FILE にエクスポートされました。"
docker saveを使うことで、現在ローカルにあるイメージを.tar.gz形式に変換できます。
Dockerのログファイルのローテートを設定する
コンテナのログはデフォルトでは肥大化しやすいため、ローテーションを設定するのがおすすめです。
前述のものとは毛色が違いますが、これを知らずにいたためお客様へご迷惑をおかけしましたので、教訓として入れました。
docker runコマンドのサンプル
#!/usr/bin/env bash
INSTALL_SOURCE="/opt/app"
IMAGE_NAME="app-image"
docker run -d \
--restart always \
-p 80:8000 \
--name app \
-e TZ=Asia/Tokyo \
-w $INSTALL_SOURCE \
-v $INSTALL_SOURCE:$INSTALL_SOURCE \
-v /dev/shm:$INSTALL_SOURCE/logs \
--log-driver=json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
$IMAGE_NAME:latest \
python main.py
ここでは--log-driver=json-fileと--log-optを使い、1ファイルあたり最大10MB・最大3ファイル保持という設定にしています。
👉 この流れを押さえることで、x64 環境から ARM デバイス向けにイメージをビルドし、配布・運用まで行う 一連の手順を再現できます。
後、プログラムの実行は自己責任でお願いします。
Discussion