Dockerfile 内でコンテナの時刻を変数として流用し、年に対応した rpmパッケージ の GPG署名 をインストールする

Dockerコンテナ をビルドする際にコンテナ内の時刻(年)を他のコマンドに流用したくなりました。その方法をいくつか試したのでメモしておきます。

経緯

AlmaLinux で PHP7.4系 をインストールする際に Remiリポジトリ からインストールしようとしました。

RUN rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-8.rpm && \
    rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi2021
# disable default module
RUN dnf module reset -y php
# install php 7.4
RUN dnf module install -y php:remi-7.4

rpm を使用して Remiリポジトリ をインストールしています。

rpm ではパッケージインストールではパッケージが破損していないか、改ざんされていないかをチェックするために GPG署名 を用いています。

その公開鍵の取得も、 Remiリポジトリ のインストールと同時に行っています。

RUN rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-8.rpm && \
    rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi2021

ここでふと思ったのは、URLに年が入っていること。2022年になったら

RUN rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-8.rpm && \
    rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi2022

に変えたい。かといってそれを毎年手動で更新するのは面倒なので、自動化したい。

であれば、 date コマンドの値を awk に通すなどして年だけ取り出し、それを上述コマンドに流用できないか、と。

検証

まずは AlmaLinux のコンテナをビルド・起動します。

docker run --name yeartest -it almalinux:8 /bin/bash
# \cp -pf /usr/share/zoneinfo/Japan /etc/localtime

## タイムゾーン変更

# dnf -y update && yum -y install sudo epel-release

## 略

パッケージを入れたり前準備。

date から年のみ取り出す

# date
Wed Dec 29 22:28:18 JST 2021

普通に date を叩きます。ふむ、6番目ですね……。

# sudo date | sudo awk '{print $6}'
2021

そこでパイプで繋いで awk に渡します。無事、年のみを取り出せました。

rpm の GPG署名 について

一応インポートされている GPG署名 について確認しておきます。

# rpm -qa "gpg-pubkey*"
gpg-pubkey-3abb34f8-5ffd890e

まずデフォルトの状態。1つのみインポートされていますね。

# rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi2021
# rpm -qa "gpg-pubkey*"
gpg-pubkey-3abb34f8-5ffd890e
gpg-pubkey-478f8947-5ff329c5

次に RPM-GPG-KEY-remi2021 をインポートします。増えました。

# rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi
# rpm -qa "gpg-pubkey*"
gpg-pubkey-3abb34f8-5ffd890e
gpg-pubkey-478f8947-5ff329c5
gpg-pubkey-00f97f56-467e318a

さらに RPM-GPG-KEY-remi をインポートすると増えました。

検証2

以上を踏まえて、 Docker Compose からの Dockerfile ビルドで試験。

FROM almalinux:8
RUN \cp -pf /usr/share/zoneinfo/Japan /etc/localtime
RUN dnf -y update && yum -y install \
    sudo \
    epel-release
RUN mkdir /home/temp/
# パターン1
RUN GEOFFROY=$(sudo date | sudo awk 'END{print $6}') \
    && sudo echo ${GEOFFROY} >> /home/temp/geoffroy.txt
# パターン2
RUN FROMONT=$(sudo date | sudo awk 'END{print $6}')
RUN sudo echo ${FROMONT} >> /home/temp/fromont.txt
# パターン3
RUN sudo echo \
    | sudo date \
    | sudo awk 'END{print $6}' \
    >> /home/temp/carillon.txt

一応3つパターンを試してみます。さあ、それぞれのファイルには何が出力されるのか……。

# パターン1
RUN GEOFFROY=$(sudo date | sudo awk 'END{print $6}') \
    && sudo echo ${GEOFFROY} >> /home/temp/geoffroy.txt
# 2021

# パターン2
RUN FROMONT=$(sudo date | sudo awk 'END{print $6}')
RUN sudo echo ${FROMONT} >> /home/temp/fromont.txt
#

# パターン3
RUN sudo echo \
    | sudo date \
    | sudo awk 'END{print $6}' \
    >> /home/temp/carillon.txt
# 2021

結果、意図した出力になったのは1つ目と3つ目のパターンでした。 RUN ごとにコンテナが変わるとのことなので2は望み薄だと思っていましたが……。

そこで、パターン1を使って次のように組んでみます。

FROM almalinux:8
RUN \cp -pf /usr/share/zoneinfo/Japan /etc/localtime
RUN dnf -y update && yum -y install \
    sudo \
    epel-release
RUN mkdir /home/temp/
# args

RUN MELUSINE=$(sudo date | sudo awk 'END{print $6}') \
    && rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-8.rpm \
    && rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi${MELUSINE}

これでビルド・起動したコンテナに bash で入って確認。

# rpm -qa "gpg-pubkey*"
gpg-pubkey-3abb34f8-5ffd890e
gpg-pubkey-478f8947-5ff329c5

内容的にデフォルトと2021の公開鍵が入っているように見えます。

# rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi
# rpm -qa "gpg-pubkey*"
gpg-pubkey-3abb34f8-5ffd890e
gpg-pubkey-478f8947-5ff329c5
gpg-pubkey-00f97f56-467e318a

手動で RPM-GPG-KEY-remi を入れると増えました。

# rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi2021
# rpm -qa "gpg-pubkey*"
gpg-pubkey-3abb34f8-5ffd890e
gpg-pubkey-478f8947-5ff329c5
gpg-pubkey-00f97f56-467e318a

ついでに手動で RPM-GPG-KEY-remi2021 を入れようとしましたが、数は増えませんでした。先のコードで RPM-GPG-KEY-remi2021 がインストールできていることが確認できました。OKです。

余談

実は上述の通り年指定のない http://rpms.famillecollet.com/RPM-GPG-KEY-remi があるので、それを入れてしまえば終わりのような気もするのですが……折角なのでチャレンジしてみた次第です。

参考

PHP インストール

もしかして、そもそもいらない……?

rpm と GPG署名

この記事を書いた人

アルム=バンド

フロントエンド・バックエンド・サーバエンジニア。LAMPやNodeからWP、Gulpを使ってejs,Scss,JSのコーディングまで一通り。たまにRasPiで遊んだり、趣味で開発したり。