【CentOS7】EL7 用の公式 RPM がない Redis 8 を rpmbuild する

はじめに

お久しぶりです。
最近後輩の研修が終わりかけていて焦りを覚え始めている 24 卒のミコトです。
今回は、先日社内の方に教わって初めて存在を知った rpmbuild について取り上げたいと思います。

当時 CentOS7 の環境に Redis 8系 をインストールしたくて方法を調べていたのですが、公式から el7 の RPM が配布されておらず、ソースアーカイブのコンパイルしかないのか、、と思っていたところ。

「昔 .rpm 作ったと思う」

そんな衝撃的なことを聞きました。(まだひよっこなのでご容赦ください)
そこで、検証環境を使って実際に rpmbuild で RPM を作ってローカルインストールまでをやってみたのでその過程とハマったことについて紹介しようと思います!

環境について

環境

Vagrant を使用しています。
リンクも張っておりますので、もし Vagrant を触ったことがない方がいらっしゃいましたら是非お使いくださいね!

(Vagrant での環境構築方法についてのブログも作成中です)

過去に偉大なる先輩が Vagrant について解説してくださっていたので、こちらもぜひご覧くださいね!

Vagrantというコマンドラインツールを使用して自分だけの検証環境を構築する方法

rpmbuild の環境構築

rpmbuild の環境の構築については こちら が参考になりました!
そもそも知識 0 から挑んだので当時は構造すら知りませんでしたが、、 (^ ^ ;)

# 必要なツールのインストール
$ sudo yum install rpmdevtools yum-utils

# rpmbuild の環境構築
$ rpmdev-setuptree

rpmbuild のセットアップを完了すると、以下のようなディレクトリが現れます。
うげ、、となるかもしれないですが、基本的にビルド前に調整が必要なのは SOURCES と SPECS です。

~/rpmbuild
  ├ BUILD        # 作業用ディレクトリ
  ├ BUILDROOT    # 完成品を一時的にインストールする仮想ルート
  ├ RPMS         # 完成した .rpm の置き場
  ├ SOURCES      # ソースアーカイブ等ビルドに必要な入力ファイルの置き場
  ├ SPECS        # .spec ファイルの置き場
  └ SRPMS        # .src.rpm の置き場

最終的なビルド時の ~/rpmbuild/ の中身

四苦八苦してようやくたどり着いた ~/rpmbuild 配下の構成は以下のような感じです。
その後はビルド時に自動で入ったものだと思うので特に触ってないです。(多分)

SOURCES
  ├ redis-8.0.2.tar.gz
  ├ redis.conf
  └ redis.service

SPECS
  └ redis-8.0.2.spec

これをする前に単純に redis-8.0.2.tar.gz をコンパイルしてみたのですが、systemctl の Unit の登録も手動でしないといけないみたいだったので、今回は redis.service ファイルもインストール時に適用されるようにしています。
また、アーカイブの方に conf ファイルも存在してはいたものの、データの置き場所が違ったので今回はこちらで用意したものをインストール後に参照するため、redis.conf を含めています。

※注意 アプデ前に Redis がデータ永続化設定になっているか確認しましょう

私の環境では Redis  のデータは最初から永続化設定になっていたのですが、設定によっては永続化設定がされていなくて再起動されたら吹っ飛ぶ、、なんて悲劇が起こるかもしれないので必ず確認しましょう!

# redis-cli CONFIG GET save
1) "save"
2) "3600 1 300 100 60 10000"

↑見た感じ RDB スナップショットの永続化はできているみたいですね!ここにいつスナップショットを取るのかという条件が書いていない場合、永続化できていない可能性があります。

SPEC を知ったきっかけ

Failed to read spec file

手順を確認しつつ、無邪気に rpmbuild コマンドで redis-8.0.2.tar.gz をビルドしたら .rpm ができるんだ! と思いながらコマンドを実行しました。

しかし……

rpmbuild -tb --clean redis-8.0.2.tar.gz
error: Failed to read spec file from redis-8.0.2.tar.gz

 

「え、spec file がないって何?」

筆者は単純にそう思いました。
そこから色々検索してみて、自分で作成しないといけないと気付いたのです。

spec ファイルとは

spec ファイルとは、rpm パッケージの構築方法が書かれているファイルのことを指しています。
実際のビルド手順、パッケージの conf ファイルの置き場所、systemctl への登録などなどを書いています。

tar.gz などに含まれていることもあるみたいなんですが今回はそれがなかったため、エラーが出てしまいました。。

ないなら作ればいいじゃない

その後ググったり AI に聞いたりして手動で作成できることを知り、いろいろな力を駆使して何とか spec ファイルを作りました。

そして四苦八苦した結果、冒頭で書いていた ~/rpmbuild/SPECS にファイルを突っ込んでビルドに至りました。

SPECS
  └ redis-8.0.2.spec ★

ドキュメントを見た限りだと完全手動じゃなく、コマンドで型を作ってもらえるそうですね……?
次の機会に参考にさせていただこうと思います(独り言)

今回最終的にアップデートが成功したスペックファイルはこんな感じです

Name: redis
Version: 8.0.2
Release: 1%{?dist}
Summary: Redis is an in-memory database that persists on disk

License: BSD
URL: https://redis.io/
Source0: redis-8.0.2.tar.gz
# redis.service を同梱する場合
Source1: redis.service

# ビルドに必要なパッケージ
BuildRequires: gcc
# 他に必要があれば適宜追加
# BuildRequires: make, systemd, etc.

# (任意) 実行時に必要な依存があれば
# Requires: systemd

%description
Redis is an open source (BSD licensed), in-memory data structure store, used as a database, cache and message broker.

%prep
# tar.gz を展開
%setup -q -n redis-8.0.2

%build
# Redis のビルド
make

%install
# buildroot を掃除
rm -rf %{buildroot}

# バイナリを配置するためのディレクトリを作成
mkdir -p %{buildroot}/usr/bin

# ビルド済みの実行ファイルをインストール
install -p -m 0755 src/redis-server %{buildroot}/usr/bin/redis-server
install -p -m 0755 src/redis-cli %{buildroot}/usr/bin/redis-cli

# /etc/redis ディレクトリを作成し、redis.conf を配置
mkdir -p %{buildroot}/etc/redis
install -p -m 0644 %{_sourcedir}/redis.conf %{buildroot}/etc/redis/redis.conf

# systemd ユニットを配置
# %{_unitdir} は通常 /usr/lib/systemd/system に展開される
mkdir -p %{buildroot}%{_unitdir}
install -p -m 0644 %{SOURCE1} %{buildroot}%{_unitdir}/redis.service

%files
# バイナリ
/usr/bin/redis-server
/usr/bin/redis-cli

# 設定ファイル (noreplace オプションで、ユーザーが編集しても上書きされないようにする)
%config(noreplace) /etc/redis/redis.conf

# systemd ユニットファイル
%{_unitdir}/redis.service

%post
# インストール直後の処理
if [ $1 -eq 1 ] ; then
# 新規インストール時に systemd ユニットを有効化
/bin/systemctl enable redis.service &>/dev/null || :
fi

# インストール・アップデート後に systemd 初期化(再読込)
/bin/systemctl daemon-reload &>/dev/null || :

%preun
# パッケージ削除の処理
if [ $1 -eq 0 ] ; then
# アンインストール時のみサービスを停止・無効化
/bin/systemctl stop redis.service &>/dev/null || :
/bin/systemctl disable redis.service &>/dev/null || :
fi

%postun
# アンインストール・アップデート後の処理
/bin/systemctl daemon-reload &>/dev/null || :

%changelog
* Sat Jun 14 2025 John Doe <[email protected]> - 8.0.2-1
- Initial build of Redis with systemd unit

rpm を作ってインストールする

まずは材料の確認

ここが一番大事ですね。
まずは前述した SOURCESSPEC の中身のおさらいからしましょう。
後に備忘録として記述していますが、各 SOURCE の中身の確認も怠ると大変なことになるので注意深く確認しましょう(戒め)

SOURCES
├ redis-8.0.2.tar.gz
├ redis.conf
└ redis.service
SPECS
└ redis-8.0.2.spec

ビルドしてみる

実際にビルドに使ったコマンドは↓です。
作成した spec ファイルを元に .rpm を作成します。

rpmbuild -bb /root/rpmbuild/SPECS/redis-8.0.2.spec

※ -bb というのは、.rpm ファイルのみ作成するというオプションになります。必要に応じて、-ba(.src.rpm 及び .rpm を作成)等変更します。

エラーなく処理が終わったら、ビルドは完了です!

アプデ前にデータを突っ込んでおく

アップデート前に適当なデータを入れておきましょう。
アップデートできてもデータが飛んでいたら意味がないですからね!
↑検証中に何度もデータ飛ばした人

# redis-cli set beyond "24365"
# redis-cli get beyond
"24365"

出来上がった .rpm パッケージをローカルインストールする

出来上がったパッケージは ~/rpmbuild/RPMS/x86_64/redis-8.0.2-1.el7.x86_64.rpm にありました。
無事入っていることを確認して早速インストールしていきましょう!

# yum localinstall ~/rpmbuild/RPMS/x86_64/redis-8.0.2-1.el7.x86_64.rpm
Examining ~/rpmbuild/RPMS/x86_64/redis-8.0.2-1.el7.x86_64.rpm: redis-8.0.2-1.el7.x86_64
Marking ~/rpmbuild/RPMS/x86_64/redis-8.0.2-1.el7.x86_64.rpm to be installed
Resolving Dependencies
--> Running transaction check
---> Package redis.x86_64 0:8.0.2-1.el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

============================================================================================================================================================================
Package Arch Version Repository Size
============================================================================================================================================================================
Installing:
redis x86_64 8.0.2-1.el7 /redis-8.0.2-1.el7.x86_64 4.4 M

Transaction Summary
============================================================================================================================================================================
Install 1 Package

Total size: 4.4 M
Installed size: 4.4 M
Is this ok [y/d/N]: y
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : redis-8.0.2-1.el7.x86_64 1/1
Verifying : redis-8.0.2-1.el7.x86_64 1/1

Installed:
redis.x86_64 0:8.0.2-1.el7

Complete!

Complete ! と出ましたね!
でもここからが問題……ちゃんと起動するのか……

● redis.service - Redis In-Memory Data Store
Loaded: loaded (/usr/lib/systemd/system/redis.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2025-06-18 00:07:56 UTC; 7h ago
Main PID: 1151 (redis-server)
CGroup: /system.slice/redis.service
mq1151 /usr/local/bin/redis-server 127.0.0.1:6380

Jun 18 00:07:57 ansible-bastion redis-server[1151]: 1151:C 18 Jun 2025 00:07:57.249 * Redis version=8.0.2, bits=64, commit=00000000, modified=1, pid=1151, just started

立ち上がりました🎉🎉🎉
バージョンもしっかり 8.0.2 になっていますね!

# redis-cli get beyond
"24365"

アップデート後も中身のデータは死んでなさそうです!

spec 調整時の備忘録

spec ファイルの作成時、ビルド時にエラーが出てくれる問題と作った rpm をインストールしてからでないと気付けなかった問題がありました。
実はエラーを吐いてくれた方は修正も楽だったのですが、何事もなくビルドできたパッケージを充ててみたらいろいろと調整が必要で……となったことも多々ありました。

それについて、次回以降気を付けようという戒めを込めてここにまとめておきます。

%changelog の日付は正確に書く

spec ファイルで言うところの %changelog とは、日付を入れるところです。
↓のような感じで、日付、名前、メールアドレス、バージョンを入れます。

%changelog
* Thu Jun 13 2025 Test Taro &amp;amp;lt;[email protected]&amp;amp;gt; - 8.0.2-1

で、ここで良く出たエラーが↓です。
これだけではどこが間違えているのかよくわからないですよね。

RPM build errors:
bogus date in %changelog: Thu Jun 13 2025 Test Taro &amp;amp;lt;[email protected]&amp;amp;gt; - 8.0.2-1

正解はここです。
「Thu Jun 13 2025」

2025年6月13日 は金曜日です。
なので、ここは「Fri Jun 13 2025」にすべきでした。
こういう間違いでも、長い時間をかけてエラーだけ吐き出してくるので気を付けましょう( ^ ^ ;)

redis.conf の場所と中身の差分を確認する

どんなパッケージでもそうですが、バージョンアップをするときは conf ファイルのバックアップを取り、アプデ後に差分を確認して大した差分がないかどうか、それで何か影響を及ぼしてないかを確認しますよね。

他にもいっぱいあると思うのですが、私の場合は作成したパッケージでアプデをかけたときに置き換わる conf ファイルの ポート番号 データの保存先ディレクトリ をしっかりと確認すべきでした。。

やってしまったミスは↓になります。

  • 別ポートを指定していたため、6379 と 6380 でそれぞれ別の Redis が起動してしまった
  • 保存先のディレクトリが間違っていたため、想定とは別のディレクトリにデータが保存されてしまった

▼ポート

# Accept connections on the specified port, default is 6379 (IANA #815344).
# If port 0 is specified Redis will not listen on a TCP socket.
port 6379

▼ディレクトリ

# Note that you must specify a directory here, not a file name.
dir /var/lib/redis

インストールされるコマンドの場所は変えない

Redis を yum からインストールしてきた後って、redis-server であったり redis-cli コマンドはもう使えるよね、と思ったら使えなかった話です。
こちらは特にエラー等も出なかったのですが、実際に充てた後に気づきました。

原因はここです。

# spec ファイルの中身
%files
/usr/local/bin/redis-server
/usr/local/bin/redis-cli

# アプデ対象の Redis 7系 が動いている環境
/usr/bin/redis-server
/usr/bin/redis-cli

この状態でビルドして、redis-server を使おうとしたらこうなります。

[root@test-web redis]# sudo /usr/local/bin/redis-server /etc/redis.conf --daemonize no
sudo: /usr/local/bin/redis-server: command not found

ようやっと入った、動いたと思ったらこれですよ、、設定は細かく確認しましょう。

おわりに

いかがでしたでしょうか。
今回は、rpm を作成してみる過程とハマったことについて書かせていただきました。

色々と自分勝手にカスタマイズした rpm ファイルをインストールして実際に使ってみるのも楽しそうだなぁと思いましたが、まだまだ活用方法があんまり思いついていない今日この頃…。

いつか誰かの役に立てるよう、これからも日々頑張っていきますね!

この記事がお役に立てば【 いいね 】のご協力をお願いいたします!
3
読み込み中...
3 票, 平均: 1.00 / 13
269
X facebook はてなブックマーク pocket

この記事をかいた人

About the author

ミコト

文系学部から2024年4月に入社したインフラエンジニアです。
ニックネームは思いつかなかったので母がよく使っているものにしました。
ハシビロコウってかわいいよね。