Dockerfile で apt-key を使わず PPA を追加する

create
2021年07月18日
update
2021年07月19日

🐶はじめに

Docker コンテナで最新版の git をインストールしたかった。

  • UbuntuDebian の場合は add-apt-repository コマンドを使って PPA から簡単にインストールできる。

    • ただ、add-apt-repository が含まれる`software-properties-common` パッケージは依存パッケージが多くてサイズが肥大化しやすいので、コンテナであまり使いたくない。

  • 別の方法として apt-key を使う方法がある。

    • Ubuntu 20.10 (Groovy)Debian 11 からは apt-key が非推奨になるらしい。

そのため、今後推奨される方法である gnupg を使う方法を試してみた。

Table 1. 環境
App Version

Windows10

Docker Desktop

3.5.1

Docker

20.10.7

Ubuntu

20.04

試してみた結果

結論から言えば、次のような Dockerfile にすればいい。

Example 1. Dockerfileのサンプル

最新版の git をインストールしたい場合の例。

Dockerfile
FROM ubuntu:20.04 AS keyrings
WORKDIR /keyrings

RUN \
  apt-get update && \
  apt-get install -y --no-install-recommends \
    gnupg

RUN \
  mkdir -m 700 /tmp/.gnupg && \
  gpg \
    --no-default-keyring \
    --homedir /tmp/.gnupg \
    --keyserver keyserver.ubuntu.com \
    --keyring gnupg-ring:/keyrings/git-archive-keyring.gpg \
    --recv-keys E1DD270288B4E6030699E45FA1715D88E1DF1F24
RUN chmod -R a+r /keyrings

# ----------------
FROM ubuntu:20.04
COPY --from=keyrings /keyrings /usr/share/keyrings/
COPY --chown=root:root ./sourcelists /etc/apt/sources.list.d/

# install git
RUN \
  apt-get update && \
  apt-get install -y --no-install-recommends \
    git && \
  apt-get clean && \
  rm -rf \
    /tmp/* \
    /var/lib/apt/lists/* \
    /var/tmp/*
sourcelists/git.list
deb [signed-by=/usr/share/keyrings/git-archive-keyring.gpg] http://ppa.launchpad.net/git-core/ppa/ubuntu focal main

以下、詳細。

🔌apt-key を使わない PPA 追加方法

  1. リポジトリの公開鍵を登録

  2. リポジトリを追加

  3. 対象パッケージをインストール(apt-get update && apt-get install …​

とすればいい。

リポジトリの公開鍵を登録

Example 2. 公開鍵の登録
リポジトリ公開鍵を登録
mkdir -m 700 /tmp/.gnupg    (1)
gpg \
  --no-default-keyring \
  --homedir /tmp/.gnupg \   (2)
  --keyserver keyserver.ubuntu.com \
  --keyring gnupg-ring:/usr/share/keyrings/<REPOSITRY>-archive-keyring.gpg \    (3)
  --recv-keys <FINGER_PRINT>  (4)
chmod -R a+r /usr/share/keyrings  (5)
1 GnuPG が使うディレクトリを作成しておく。
2 GnuPG が一時ファイルなどを出力するディレクトリのパスを指定。
デフォルト値は $HOME/.gnupg となる。
3 インポートした公開鍵を出力するファイルパスを指定。
非公式リポジトリの鍵は /usr/share/keyrings 以下に保存することを推奨[1]
また、ファイル名の末尾を -archive-keyring とすることが推奨される[1]
4 インポートするリポジトリ公開鍵のフィンガープリントを指定。
Launchpad でリポジトリを検索したときに表示されるものをコピペすればいい。
5 apt-get がインポートしたリポジトリ公開鍵を読み込めるように、読み取り権限を付与。

リポジトリの追加

上記の方法で鍵を /usr/share/keyrings/ 以下に登録したあとは、いつものように /etc/apt/sources.list.d/ 以下に <REPOSITRY>.list ファイルを作成する。
このとき、signed-by オプションを付け加える。

Example 3. リポジトリ追加の例

git-corePPA を追加したい場合は次のようなファイルを作成する。

/etc/apt/sources.list.d/git.list
deb [signed-by=/usr/share/keyrings/git-archive-keyring.gpg] http://ppa.launchpad.net/git-core/ppa/ubuntu focal main
[signed-by=<GPGKEY_PATH>]
このリポジトリの認証に使う鍵を指定する。
鍵を /usr/share/keyrings などに保存している場合に必須

できた!💪💪💪

🛠️トラブルシューティング

公開鍵はインポートできたのに public key is not available: NO_PUBKEY エラー

問題
インポートも設定もできてるはずなのにエラー!ナンデ!?
apt-get update
...
W: GPG error: XXX: The following signatures couldn't be verified
   because the public key is not available: NO_PUBKEY ABCDEFG
E: The repository 'XXX' is not signed.
原因

apt-get が鍵を読み取れない場合にもこのエラーが発生する。
よって公開鍵のパーミッションを 644 にしておく。

やらかしてた例
/usr/share/keyrings 以下にある鍵のパーミッションを一括変更するときに、うっかりディレクトリの実行権限を削除(644 パーミッションに)してた。
解決
/usr/share/keyrings 以下にある鍵を 644 パーミッションに一括変更
chmod -R a=rX,u+w /usr/share/keyrings