AlmaLinux 10 総合ガイド
第10章: 実践 – 総合演習
【この章で学ぶこと】 これまでの知識を統合した実際のサービス構築
【なぜ重要か】 実践経験が実務スキルに直結する
【前提知識】 第1〜9章完了、すべての基礎スキル習得済み
【所要時間】 約4〜6時間(プロジェクトによる)
おめでとうございます。ここまでの8つの章を通じて、あなたはLinuxサーバー管理の基礎をしっかりと身につけました。コマンドライン操作、パッケージ管理、ストレージ管理、サービス管理、ネットワーク設定、セキュリティ、ログ管理、そしてバックアップと運用まで、インフラエンジニアとして必要な土台が整いました。
この章では、これまで学んだすべてを統合して、実際に動くサービスを構築します。3つのプロジェクトから興味のあるものを選び、手を動かしながら学んでください。失敗しても構いません。むしろ、トラブルシューティングこそが最大の学びです。
- 10.1 総合演習の進め方
- 【プロジェクトA】LAMP環境の構築
- 10.2 プロジェクトA概要
- 10.3 Step 1: 環境準備
- 10.4 Step 2: Apache の設定
- 10.5 Step 3: MariaDB の設定
- 10.6 Step 4: PHP の設定
- 10.7 Step 5: SELinux 設定
- 10.8 Step 6: 動作確認とトラブルシューティング
- 【プロジェクトB】Nginx リバースプロキシの構築
- 10.9 プロジェクトB概要
- 10.10 Step 1: Nginx のインストールと基本設定
- 10.11 Step 2: バックエンドサーバーの準備
- 10.12 Step 3: リバースプロキシ設定
- 10.13 Step 4: ロードバランシング設定
- 【プロジェクトC】コンテナアプリケーション実行(Podman)
- 10.14 プロジェクトC概要
- 10.15 Step 1: Podman のインストール
- 10.16 Step 2: コンテナイメージの取得
- 10.17 Step 3: コンテナの実行
- 10.18 Step 4: データの永続化
- 10.19 Step 5: systemd 統合
- 【共通セクション】
- 10.20 共通: セキュリティチェック
- 10.21 共通: パフォーマンスチューニング基礎
- 10.22 共通: ドキュメント化
- 10.23 共通: バックアップとリカバリ
- 10.24 総合演習のまとめ
- 【コラム9】初めての本番リリースで学んだこと
- 章末まとめ
- 練習問題(総合問題)
- 次章への橋渡し
10.1 総合演習の進め方
10.1.1 この章の目的と到達目標
総合演習の目的は、個別に学んだ知識を「つなげて使う」ことです。実務では、パッケージをインストールするだけでは終わりません。サービスを起動し、ファイアウォールを設定し、SELinuxを調整し、動作確認をして、バックアップを設定する。これらすべてが連携して初めて「サービスが稼働している」と言えます。
到達目標:
- 複数のコンポーネントを組み合わせてサービスを構築できる
- 構築手順を自分で考え、実行できる
- 問題が発生した場合に、ログを読んで原因を特定できる
- セキュリティを考慮した設定ができる
- 構築した内容をドキュメントとして残せる
10.1.2 3つのプロジェクトから選択
この章では、以下の3つのプロジェクトを用意しました。すべてを実施する必要はありません。まずは1つを最後までやり切ることを目標にしてください。
| プロジェクト | 難易度 | 内容 | 学習ポイント |
|---|---|---|---|
| A: LAMP環境構築 | 初級〜中級 | Apache + MariaDB + PHP | Webサーバーの基本、DB連携 |
| B: Nginxリバースプロキシ | 中級 | Nginx + バックエンド + ロードバランシング | プロキシの概念、負荷分散 |
| C: コンテナアプリケーション | 中級〜上級 | Podman + コンテナ + systemd統合 | コンテナ技術、永続化 |
💡 どれを選ぶか迷ったら
「Webアプリケーションを動かしたい」→ プロジェクトA(LAMP)
「複数サーバーの前にプロキシを置きたい」→ プロジェクトB(Nginx)
「最新のコンテナ技術を学びたい」→ プロジェクトC(Podman)
初めての方はプロジェクトAをおすすめします。最も基本的な構成であり、多くの実務で遭遇するパターンです。
10.1.3 構築前の準備(要件定義)
サービスを構築する前に、「何を作るのか」を明確にしておきましょう。実務では、この「要件定義」が非常に重要です。
確認すべき項目:
- 目的: 何のためにこのサービスを構築するのか
- 構成: どのコンポーネントが必要か
- 前提条件: 必要なリソース(メモリ、ディスク、ネットワーク)
- 成功基準: どうなったら「完成」と言えるか
各プロジェクトでは、これらの項目を冒頭で明示します。
10.1.4 構築の流れ(計画→実装→検証)
すべてのプロジェクトは、以下の流れで進めます。
- 計画: 必要なパッケージ、設定項目、ポート番号を洗い出す
- 実装: 一つずつ順番にインストール・設定を行う
- 検証: 各ステップで動作確認を行い、問題があれば対処
- セキュリティ: ファイアウォール、SELinux、パーミッションを確認
- ドキュメント: 何をしたかを記録する
重要なルール: 各ステップで必ず動作確認を行う
一度にすべてを設定してから確認するのではなく、小さな単位で確認しながら進めます。問題が発生した場合、直前のステップが原因である可能性が高くなり、トラブルシューティングが容易になります。
【プロジェクトA】LAMP環境の構築
10.2 プロジェクトA概要
10.2.1 LAMPとは(Linux, Apache, MariaDB, PHP)
LAMPは、Webアプリケーションを動かすための定番の組み合わせです。
- Linux: オペレーティングシステム(AlmaLinux 10)
- Apache: Webサーバーソフトウェア(httpd)
- MariaDB: データベースサーバー(MySQL互換)
- PHP: サーバーサイドプログラミング言語
WordPressやDrupalといった有名なCMS(コンテンツ管理システム)も、このLAMP環境で動作します。Webアプリケーション開発の基盤として、今でも広く使われています。
10.2.2 構築するシステムの全体像
📘 AlmaLinux 10でのPHP実行方式について
RHEL 9以降(およびAlmaLinux 10)では、ApacheでのPHP実行はPHP-FPM(FastCGI Process Manager)を使用するのが標準です。
従来のmod_php(Apacheモジュール)方式と異なり、PHP-FPMは独立したサービスとして動作します。この方式のメリットは、PHPプロセスをApacheから分離することで、リソース管理が柔軟になり、パフォーマンスが向上することです。
10.2.3 必要なコンポーネント一覧
| コンポーネント | パッケージ名 | バージョン(AlmaLinux 10) |
|---|---|---|
| Webサーバー | httpd | 2.4.62 |
| データベースサーバー | mariadb-server | 10.11 |
| PHP本体 | php | 8.3 |
| PHP-FPM | php-fpm | 8.3 |
| PHP-MariaDB連携 | php-mysqlnd | 8.3 |
10.3 Step 1: 環境準備
10.3.1 システムアップデート
最初に、システムを最新の状態にします。これは第3章で学んだ内容の実践です。
[実行ユーザー: 一般ユーザー(sudo使用)]
# システムの最新化
$ sudo dnf5 update -y
# 完了後、カーネルが更新された場合は再起動
$ sudo reboot
10.3.2 必要パッケージのインストール
Apache、MariaDB、PHPを一括でインストールします。php-fpmはphpパッケージの依存関係として自動的にインストールされますが、ここでは明示的に指定します。
[実行ユーザー: 一般ユーザー(sudo使用)]
# LAMP関連パッケージのインストール
$ sudo dnf5 install httpd mariadb-server php php-fpm php-mysqlnd -y
# 出力例:
Dependencies resolved.
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
httpd x86_64 2.4.62-1.el10 appstream 1.4 M
mariadb-server x86_64 3:10.11.x-1.el10 appstream 11 M
php x86_64 8.3.x-1.el10 appstream 1.5 M
php-fpm x86_64 8.3.x-1.el10 appstream 1.6 M
php-mysqlnd x86_64 8.3.x-1.el10 appstream 150 k
Installing dependencies:
...(依存パッケージが多数表示される)
Complete!
各パッケージの役割:
httpd: Apache Webサーバーmariadb-server: MariaDBデータベースサーバーphp: PHP本体(コマンドライン実行用)php-fpm: PHP FastCGI Process Manager(ApacheからPHPを実行するためのサービス)php-mysqlnd: PHPからMariaDB/MySQLに接続するためのドライバ
10.3.3 インストール確認
各コンポーネントが正しくインストールされたか確認します。
[実行ユーザー: 一般ユーザー]
# Apacheのバージョン確認
$ httpd -v
Server version: Apache/2.4.62 (AlmaLinux)
Server built: ...
# MariaDBのバージョン確認
$ mariadb --version
mariadb Ver 15.1 Distrib 10.11.x-MariaDB, for Linux (x86_64)
# PHPのバージョン確認
$ php -v
PHP 8.3.x (cli) (built: ...)
Copyright (c) The PHP Group
Zend Engine v4.3.x, Copyright (c) Zend Technologies
# PHP-FPMがインストールされているか確認
$ rpm -q php-fpm
php-fpm-8.3.x-1.el10.x86_64
✅ ここまでの確認ポイント
- すべてのコマンドでバージョンが表示されればOK
- 「command not found」が出る場合は、インストールが完了していない可能性あり
10.4 Step 2: Apache の設定
10.4.1 httpd サービスの起動と自動起動設定
第5章で学んだsystemctlを使って、Apacheを起動します。
[実行ユーザー: 一般ユーザー(sudo使用)]
# サービスの起動と自動起動の有効化を同時に行う
$ sudo systemctl enable --now httpd
# 出力例:
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service.
# ステータス確認
$ systemctl status httpd
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; preset: disabled)
Active: active (running) since Mon 2026-01-26 10:00:00 JST; 5s ago
Docs: man:httpd.service(8)
Main PID: 1234 (httpd)
Status: "Started, listening on: port 80"
Tasks: 213 (limit: 22951)
Memory: 22.5M
CPU: 125ms
CGroup: /system.slice/httpd.service
├─1234 /usr/sbin/httpd -DFOREGROUND
...
active (running) と表示されていれば、Apacheは正常に起動しています。
10.4.2 基本設定の確認(/etc/httpd/conf/httpd.conf)
Apacheのメイン設定ファイルを確認しましょう。今回は変更しませんが、主要な設定項目を理解しておきます。
[実行ユーザー: 一般ユーザー]
# 設定ファイルの主要項目を確認
$ grep -E "^(ServerRoot|Listen|DocumentRoot|ServerAdmin)" /etc/httpd/conf/httpd.conf
ServerRoot "/etc/httpd"
Listen 80
ServerAdmin root@localhost
DocumentRoot "/var/www/html"
主要な設定項目の意味:
ServerRoot: Apacheの設定ファイルが配置されているディレクトリListen 80: HTTPリクエストを待ち受けるポート番号DocumentRoot: Webコンテンツを配置するディレクトリServerAdmin: エラーページに表示される管理者メールアドレス
10.4.3 ドキュメントルートの理解(/var/www/html)
/var/www/htmlは、WebブラウザからアクセスされるHTMLファイルやPHPファイルを配置する場所です。ここにファイルを置くと、Webブラウザからアクセスできるようになります。
[実行ユーザー: 一般ユーザー]
# ドキュメントルートの確認
$ ls -la /var/www/html/
total 0
drwxr-xr-x. 2 root root 6 May 15 00:00 .
drwxr-xr-x. 4 root root 33 Jan 26 10:00 ..
現時点では空のディレクトリです。
10.4.4 テストページの作成と確認
簡単なHTMLファイルを作成して、Apacheが動作しているか確認します。
[実行ユーザー: 一般ユーザー(sudo使用)]
# テスト用HTMLファイルを作成
$ echo "<h1>Apache is working on AlmaLinux 10!</h1>" | sudo tee /var/www/html/index.html
# ファイルが作成されたか確認
$ cat /var/www/html/index.html
<h1>Apache is working on AlmaLinux 10!</h1>
ローカルからcurlでアクセスして確認します。
[実行ユーザー: 一般ユーザー]
# curlでローカルアクセスを確認
$ curl http://localhost/
<h1>Apache is working on AlmaLinux 10!</h1>
HTMLが返ってくれば、Apacheは正常に動作しています。
10.4.5 ファイアウォール設定(HTTP/HTTPS)
第6章で学んだfirewalldを使って、HTTP(80番ポート)を許可します。
[実行ユーザー: 一般ユーザー(sudo使用)]
# 現在の設定を確認
$ sudo firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: enp0s3
sources:
services: cockpit dhcpv6-client ssh
...
# HTTPサービスを永続的に許可
$ sudo firewall-cmd --permanent --add-service=http
success
# 設定を反映(初期構築時はreloadで問題ありません)
$ sudo firewall-cmd --reload
success
# 確認
$ sudo firewall-cmd --list-services
cockpit dhcpv6-client http ssh
httpが追加されていればOKです。
10.4.6 ブラウザからの動作確認
サーバーのIPアドレスを確認し、Webブラウザからアクセスします。
[実行ユーザー: 一般ユーザー]
# IPアドレスの確認
$ ip -4 addr show | grep inet
inet 127.0.0.1/8 scope host lo
inet 192.168.1.100/24 brd 192.168.1.255 scope global dynamic noprefixroute enp0s3
上記の例では、192.168.1.100がサーバーのIPアドレスです。Webブラウザでhttp://192.168.1.100/にアクセスし、「Apache is working on AlmaLinux 10!」と表示されれば成功です。
✅ Step 2 完了チェック
systemctl status httpdがactive (running)を表示curl http://localhost/でHTMLが返ってくる- ファイアウォールで
httpサービスが許可されている - ブラウザからサーバーにアクセスできる
10.5 Step 3: MariaDB の設定
10.5.1 mariadb サービスの起動と自動起動設定
[実行ユーザー: 一般ユーザー(sudo使用)]
# サービスの起動と自動起動の有効化
$ sudo systemctl enable --now mariadb
# ステータス確認
$ systemctl status mariadb
● mariadb.service - MariaDB 10.11 database server
Loaded: loaded (/usr/lib/systemd/system/mariadb.service; enabled; preset: disabled)
Active: active (running) since Mon 2026-01-26 10:10:00 JST; 5s ago
Docs: man:mariadbd(8)
https://mariadb.com/kb/en/library/systemd/
Main PID: 2345 (mariadbd)
Status: "Taking your SQL requests now..."
Tasks: 14 (limit: 22951)
Memory: 92.5M
CPU: 524ms
CGroup: /system.slice/mariadb.service
└─2345 /usr/libexec/mariadbd --basedir=/usr
10.5.2 セキュリティ初期設定(mysql_secure_installation)
MariaDBをセキュアに設定するための対話式スクリプトを実行します。これは非常に重要なステップです。
[実行ユーザー: 一般ユーザー(sudo使用)]
$ sudo mysql_secure_installation
# 以下、対話形式で進みます
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!
Enter current password for root (enter for none):
# → 初回なので何も入力せずEnter
OK, successfully used password, moving on...
Switch to unix_socket authentication [Y/n] n
# → パスワード認証を使うため「n」を入力
Change the root password? [Y/n] Y
# → rootパスワードを設定するため「Y」を入力
New password: ********
# → 強力なパスワードを入力
Re-enter new password: ********
# → 同じパスワードを再入力
Remove anonymous users? [Y/n] Y
# → 匿名ユーザーを削除するため「Y」を入力
Disallow root login remotely? [Y/n] Y
# → rootのリモートログインを禁止するため「Y」を入力
Remove test database and access to it? [Y/n] Y
# → テストデータベースを削除するため「Y」を入力
Reload privilege tables now? [Y/n] Y
# → 権限テーブルをリロードするため「Y」を入力
All done! If you've completed all of the above steps, your MariaDB
installation should now be secure.
Thanks for using MariaDB!
⚠️ パスワードは必ず記録しておく
設定したrootパスワードは安全な場所に記録してください。忘れると、データベースにアクセスできなくなります。
10.5.3 データベースの作成
テスト用のデータベースを作成します。
[実行ユーザー: 一般ユーザー(sudo使用)]
# MariaDBにrootでログイン
$ sudo mariadb -u root -p
Enter password: ********
# → 先ほど設定したパスワードを入力
Welcome to the MariaDB monitor. Commands end with ; or \g.
...
# データベースの作成
MariaDB [(none)]> CREATE DATABASE testdb;
Query OK, 1 row affected (0.001 sec)
# 作成されたか確認
MariaDB [(none)]> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| testdb |
+--------------------+
4 rows in set (0.001 sec)
10.5.4 ユーザーの作成と権限付与
PHPアプリケーション用のユーザーを作成します。rootユーザーをアプリケーションから直接使うのはセキュリティ上好ましくありません。
# ユーザーの作成
MariaDB [(none)]> CREATE USER 'webuser'@'localhost' IDENTIFIED BY 'WebPass123!';
Query OK, 0 rows affected (0.002 sec)
# testdbへの全権限を付与
MariaDB [(none)]> GRANT ALL PRIVILEGES ON testdb.* TO 'webuser'@'localhost';
Query OK, 0 rows affected (0.001 sec)
# 権限の反映
MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.001 sec)
# 終了
MariaDB [(none)]> EXIT;
Bye
'webuser'@'localhost'は、「localhostからのみ接続できるwebuserというユーザー」を意味します。
10.5.5 接続テスト
作成したユーザーでデータベースに接続できるか確認します。
[実行ユーザー: 一般ユーザー]
# webuserでログイン
$ mariadb -u webuser -p testdb
Enter password: WebPass123!
Welcome to the MariaDB monitor...
MariaDB [testdb]> SELECT DATABASE();
+------------+
| DATABASE() |
+------------+
| testdb |
+------------+
1 row in set (0.000 sec)
MariaDB [testdb]> EXIT;
Bye
✅ Step 3 完了チェック
systemctl status mariadbがactive (running)を表示mysql_secure_installationが完了しているtestdbデータベースが作成されているwebuserユーザーでtestdbに接続できる
10.6 Step 4: PHP の設定
10.6.1 PHP-FPMサービスの起動
AlmaLinux 10では、PHPはPHP-FPMサービスを通じて動作します。まず、PHP-FPMを起動しましょう。
[実行ユーザー: 一般ユーザー(sudo使用)]
# PHP-FPMサービスの起動と自動起動の有効化
$ sudo systemctl enable --now php-fpm
# ステータス確認
$ systemctl status php-fpm
● php-fpm.service - The PHP FastCGI Process Manager
Loaded: loaded (/usr/lib/systemd/system/php-fpm.service; enabled; preset: disabled)
Active: active (running) since Mon 2026-01-26 10:30:00 JST; 5s ago
Main PID: 3456 (php-fpm)
Status: "Processes active: 0, idle: 5, Requests: 0, ..."
Tasks: 6 (limit: 22951)
Memory: 12.5M
CPU: 45ms
CGroup: /system.slice/php-fpm.service
├─3456 "php-fpm: master process (/etc/php-fpm.conf)"
├─3457 "php-fpm: pool www"
...
📘 PHP-FPMとApacheの連携について
AlmaLinux 10のデフォルト設定では、ApacheとPHP-FPMの連携が自動的に設定されています。具体的には、/etc/httpd/conf.d/php.confに設定が含まれており、.phpファイルへのリクエストが自動的にPHP-FPMに転送されます。
10.6.2 PHP動作確認(phpinfo.php作成)
PHPがApacheと連携して動作しているか確認するため、phpinfo()を使ったテストページを作成します。
[実行ユーザー: 一般ユーザー(sudo使用)]
# phpinfo.phpを作成
$ echo "<?php phpinfo(); ?>" | sudo tee /var/www/html/phpinfo.php
# Apacheを再起動(設定を確実に反映させるため)
$ sudo systemctl restart httpd
ブラウザでhttp://サーバーIP/phpinfo.phpにアクセスします。PHPの設定情報が詳細に表示されれば、PHPは正常に動作しています。
🔒 セキュリティ注意
phpinfo.phpはサーバーの詳細情報を表示するため、動作確認後は必ず削除してください。
$ sudo rm /var/www/html/phpinfo.php
10.6.3 Apache との連携確認
ApacheがPHP-FPMへリクエストを転送できるように設定されているか確認します。
[実行ユーザー: 一般ユーザー]
# PHP-FPMが動作しているか確認
$ systemctl is-active php-fpm
active
# ApacheがFCGIプロキシモジュールをロードしているか確認
$ httpd -M | grep proxy_fcgi
proxy_fcgi_module (shared)
# PHP連携設定ファイルの存在確認
$ ls /etc/httpd/conf.d/php.conf
/etc/httpd/conf.d/php.conf
proxy_fcgi_moduleが表示され、php.confが存在していれば、連携設定は正常です。
10.6.4 PHP設定ファイルの確認(/etc/php.ini)
PHPのメイン設定ファイルを確認します。
[実行ユーザー: 一般ユーザー]
# 主要な設定項目を確認
$ grep -E "^(memory_limit|upload_max_filesize|post_max_size|display_errors)" /etc/php.ini
memory_limit = 128M
upload_max_filesize = 2M
post_max_size = 8M
display_errors = Off
主要な設定項目の意味:
memory_limit: スクリプトが使用できる最大メモリupload_max_filesize: アップロード可能な最大ファイルサイズpost_max_size: POSTデータの最大サイズdisplay_errors: エラーを画面に表示するか(本番環境ではOff推奨)
10.6.5 簡単なPHPスクリプトでDB接続テスト
最後に、PHPからMariaDBに接続できるか確認します。
[実行ユーザー: 一般ユーザー(sudo使用)]
# DB接続テストスクリプトを作成
$ sudo tee /var/www/html/dbtest.php << 'EOF'
<?php
$host = 'localhost';
$dbname = 'testdb';
$user = 'webuser';
$pass = 'WebPass123!';
try {
$pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8mb4", $user, $pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "<h1>Database connection successful!</h1>";
echo "<p>Connected to: $dbname on $host</p>";
echo "<p>PHP Version: " . phpversion() . "</p>";
echo "<p>Server API: " . php_sapi_name() . "</p>";
} catch (PDOException $e) {
echo "<h1>Database connection failed!</h1>";
echo "<p>Error: " . $e->getMessage() . "</p>";
}
?>
EOF
ブラウザでhttp://サーバーIP/dbtest.phpにアクセスします。
成功時の表示:
Database connection successful! Connected to: testdb on localhost PHP Version: 8.3.x Server API: fpm-fcgi
Server API: fpm-fcgiと表示されていれば、PHP-FPMが正しく動作しています。
🔒 セキュリティ注意
このテストファイルにはパスワードが含まれているため、確認後は必ず削除してください。
$ sudo rm /var/www/html/dbtest.php
✅ Step 4 完了チェック
systemctl status php-fpmがactive (running)を表示- phpinfo.phpでPHP情報が表示される
- Apacheに
proxy_fcgi_moduleが読み込まれている - dbtest.phpで「Database connection successful!」と表示される
- Server APIが
fpm-fcgiになっている
10.7 Step 5: SELinux 設定
10.7.1 SELinux コンテキストの確認
第7章で学んだSELinuxの実践です。まず、現在のSELinuxモードを確認します。
[実行ユーザー: 一般ユーザー]
# SELinuxのモード確認
$ getenforce
Enforcing
Enforcingと表示されていれば、SELinuxは有効です。ドキュメントルートのコンテキストを確認しましょう。
# /var/www/html のコンテキスト確認
$ ls -Z /var/www/html/
unconfined_u:object_r:httpd_sys_content_t:s0 index.html
httpd_sys_content_tは、Apacheがアクセスできるファイルであることを示しています。
10.7.2 httpd の DB接続許可(setsebool)
SELinuxはデフォルトで、ApacheからMariaDBへの接続を禁止しています。先ほどのDB接続テストが成功したのは、同じサーバー上でUnixソケット経由で接続しているためです。ネットワーク経由の接続を許可するには、SELinuxのブール値を変更する必要があります。
[実行ユーザー: 一般ユーザー(sudo使用)]
# 現在のブール値を確認
$ getsebool httpd_can_network_connect_db
httpd_can_network_connect_db --> off
# ブール値を永続的に有効化
$ sudo setsebool -P httpd_can_network_connect_db on
# 確認
$ getsebool httpd_can_network_connect_db
httpd_can_network_connect_db --> on
-Pオプションは「永続的(Permanent)」の意味で、再起動後も設定が保持されます。
10.7.3 カスタムディレクトリ使用時のコンテキスト設定
もし/var/www/html以外のディレクトリをドキュメントルートとして使う場合は、適切なSELinuxコンテキストを設定する必要があります。
[実行ユーザー: 一般ユーザー(sudo使用)]
# 例: /srv/www/mysite をドキュメントルートにする場合
# ディレクトリを作成
$ sudo mkdir -p /srv/www/mysite
# コンテキストを設定(ルールを追加)
$ sudo semanage fcontext -a -t httpd_sys_content_t "/srv/www/mysite(/.*)?"
# コンテキストを反映
$ sudo restorecon -Rv /srv/www/mysite
Relabeled /srv/www/mysite from unconfined_u:object_r:var_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0
# 確認
$ ls -Zd /srv/www/mysite
unconfined_u:object_r:httpd_sys_content_t:s0 /srv/www/mysite
10.7.4 audit ログの確認と対処
SELinuxが原因でアクセスが拒否された場合、/var/log/audit/audit.logに記録されます。
[実行ユーザー: 一般ユーザー(sudo使用)]
# SELinux関連の拒否ログを確認
$ sudo ausearch -m avc -ts recent
# もしくは、audit2whyで原因を分析
$ sudo ausearch -m avc -ts recent | audit2why
問題がなければ、「<no matches>」と表示されます。
✅ Step 5 完了チェック
- SELinuxが
Enforcingモードで動作している httpd_can_network_connect_dbがonになっている- ドキュメントルートのファイルが
httpd_sys_content_tコンテキストを持っている - audit.logにSELinux関連の拒否ログがない
10.8 Step 6: 動作確認とトラブルシューティング
10.8.1 全体の動作確認
LAMP環境の構築が完了しました。最終確認として、すべてのコンポーネントが正常に動作しているか確認します。
[実行ユーザー: 一般ユーザー]
# 1. サービスの状態確認
$ systemctl is-active httpd mariadb php-fpm
active
active
active
# 2. ポートのリスニング状態確認
$ ss -tlnp | grep -E "(80|3306)"
LISTEN 0 511 *:80 *:*
LISTEN 0 80 127.0.0.1:3306 *:*
# 3. ファイアウォールの確認
$ sudo firewall-cmd --list-services
cockpit dhcpv6-client http ssh
# 4. SELinuxの確認
$ getenforce
Enforcing
# 5. Webアクセスの確認
$ curl -I http://localhost/
HTTP/1.1 200 OK
...
10.8.2 よくある問題と対処
403 Forbidden エラー
原因: パーミッションまたはSELinuxの問題
[実行ユーザー: 一般ユーザー(sudo使用)]
# パーミッションの確認
$ ls -la /var/www/html/
# ファイルがrootでしか読めない場合は修正
$ sudo chmod 644 /var/www/html/*
$ sudo chmod 755 /var/www/html
# SELinuxコンテキストの確認
$ ls -Z /var/www/html/
# httpd_sys_content_t でない場合は修正
$ sudo restorecon -Rv /var/www/html/
500 Internal Server Error
原因: PHPスクリプトのエラー、PHP-FPMの問題、設定ファイルの構文エラー
[実行ユーザー: 一般ユーザー(sudo使用)]
# Apacheのエラーログを確認
$ sudo tail -20 /var/log/httpd/error_log
# PHP-FPMのエラーログを確認
$ sudo tail -20 /var/log/php-fpm/www-error.log
# PHP-FPMサービスの状態確認
$ systemctl status php-fpm
# Apache設定の構文チェック
$ sudo httpd -t
Syntax OK
PHPファイルがダウンロードされる(処理されない)
原因: PHP-FPMが起動していない、またはApacheとの連携設定の問題
[実行ユーザー: 一般ユーザー(sudo使用)]
# PHP-FPMが起動しているか確認
$ systemctl status php-fpm
# 起動していなければ起動
$ sudo systemctl start php-fpm
# PHP連携設定ファイルの確認
$ ls /etc/httpd/conf.d/php.conf
# Apacheを再起動
$ sudo systemctl restart httpd
データベース接続エラー
原因: 認証情報の誤り、SELinux、サービス未起動
[実行ユーザー: 一般ユーザー(sudo使用)]
# MariaDBサービスの確認
$ systemctl status mariadb
# 接続テスト(コマンドラインから)
$ mariadb -u webuser -p testdb
# パスワードを入力して接続できるか確認
# SELinuxブール値の確認
$ getsebool httpd_can_network_connect_db
# offの場合は有効化
$ sudo setsebool -P httpd_can_network_connect_db on
10.8.3 ログからのエラー特定
トラブルシューティングの基本は、第8章で学んだログの確認です。LAMP環境で確認すべきログファイルを整理します。
| 問題の種類 | 確認するログ | コマンド |
|---|---|---|
| Webアクセスエラー | /var/log/httpd/error_log | sudo tail -f /var/log/httpd/error_log |
| アクセスログ | /var/log/httpd/access_log | sudo tail -f /var/log/httpd/access_log |
| PHP-FPMエラー | /var/log/php-fpm/www-error.log | sudo tail -f /var/log/php-fpm/www-error.log |
| データベースエラー | /var/log/mariadb/mariadb.log | sudo tail -f /var/log/mariadb/mariadb.log |
| SELinux拒否 | /var/log/audit/audit.log | sudo ausearch -m avc -ts recent |
🎉 プロジェクトA完了!
おめでとうございます!LAMP環境の構築が完了しました。以下ができるようになりました:
- Apache Webサーバーのインストールと設定
- PHP-FPMの設定とApacheとの連携
- MariaDBデータベースの構築とユーザー管理
- PHPからのデータベース接続
- SELinuxの適切な設定
- トラブルシューティングの基本
【プロジェクトB】Nginx リバースプロキシの構築
10.9 プロジェクトB概要
10.9.1 リバースプロキシとは
リバースプロキシは、クライアントとバックエンドサーバーの間に位置し、クライアントからのリクエストを受け取り、適切なバックエンドサーバーに転送する役割を持ちます。
リバースプロキシのメリット:
- 負荷分散: 複数のバックエンドサーバーにリクエストを分散
- SSL終端: プロキシでSSL/TLSを処理し、バックエンドは非暗号化通信
- キャッシュ: 静的コンテンツをキャッシュしてバックエンドの負荷を軽減
- セキュリティ: バックエンドサーバーを直接公開しない
10.9.2 構築するシステムの全体像
10.9.3 Nginx vs Apache
| 特徴 | Nginx | Apache |
|---|---|---|
| アーキテクチャ | イベント駆動(非同期) | プロセス/スレッドベース |
| 静的コンテンツ配信 | 非常に高速 | 高速 |
| リバースプロキシ | 得意(標準機能) | 可能(モジュール使用) |
| メモリ使用量 | 少ない | 多め |
| .htaccessサポート | なし | あり |
| 設定の柔軟性 | シンプル | 非常に柔軟 |
リバースプロキシとしては、Nginxが広く使われています。設定がシンプルで、メモリ効率も良いためです。
10.10 Step 1: Nginx のインストールと基本設定
10.10.1 Nginx のインストール
[実行ユーザー: 一般ユーザー(sudo使用)]
# Nginxのインストール
$ sudo dnf5 install nginx -y
# バージョン確認
$ nginx -v
nginx version: nginx/1.26.x
10.10.2 サービスの起動と自動起動設定
[実行ユーザー: 一般ユーザー(sudo使用)]
# サービスの起動と自動起動の有効化
$ sudo systemctl enable --now nginx
# ステータス確認
$ systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: disabled)
Active: active (running) since Mon 2026-01-26 11:00:00 JST; 5s ago
...
10.10.3 基本動作確認
[実行ユーザー: 一般ユーザー(sudo使用)]
# ファイアウォールでHTTPを許可
$ sudo firewall-cmd --permanent --add-service=http
$ sudo firewall-cmd --reload
# ローカルでアクセス確認
$ curl -I http://localhost/
HTTP/1.1 200 OK
Server: nginx/1.26.x
...
ブラウザでhttp://サーバーIP/にアクセスし、Nginxのウェルカムページが表示されることを確認します。
10.11 Step 2: バックエンドサーバーの準備
10.11.1 簡易HTTPサーバーの起動(Python等)
リバースプロキシの動作を確認するため、バックエンドとして簡易HTTPサーバーを起動します。Pythonのhttp.serverモジュールを使います。
[実行ユーザー: 一般ユーザー]
# バックエンド用のディレクトリを作成
$ mkdir -p ~/backend1 ~/backend2
# バックエンド1用のHTMLを作成
$ echo "<h1>Backend Server 1 (Port 8080)</h1>" > ~/backend1/index.html
# バックエンド2用のHTMLを作成
$ echo "<h1>Backend Server 2 (Port 8081)</h1>" > ~/backend2/index.html
10.11.2 複数バックエンドの準備
2つのターミナルを開いて、それぞれでバックエンドサーバーを起動します。セキュリティのため、--bind 127.0.0.1オプションを付けてlocalhostのみでリッスンさせます。これにより、Nginx経由でのみアクセスできるようになります。
ターミナル1(バックエンド1):
[実行ユーザー: 一般ユーザー]
# バックエンド1を8080番ポートで起動(localhostにバインド)
$ cd ~/backend1
$ python3 -m http.server 8080 --bind 127.0.0.1
Serving HTTP on 127.0.0.1 port 8080 (http://127.0.0.1:8080/) ...
ターミナル2(バックエンド2):
[実行ユーザー: 一般ユーザー]
# バックエンド2を8081番ポートで起動(localhostにバインド)
$ cd ~/backend2
$ python3 -m http.server 8081 --bind 127.0.0.1
Serving HTTP on 127.0.0.1 port 8081 (http://127.0.0.1:8081/) ...
📘 –bind 127.0.0.1 オプションについて
このオプションにより、バックエンドサーバーはlocalhostからのアクセスのみを受け付けます。外部から直接アクセスできないため、セキュリティが向上します。クライアントは必ずNginxリバースプロキシを経由してバックエンドにアクセスします。
ターミナル3(動作確認):
[実行ユーザー: 一般ユーザー]
# バックエンド1の確認(localhostからはアクセス可能)
$ curl http://127.0.0.1:8080/
<h1>Backend Server 1 (Port 8080)</h1>
# バックエンド2の確認
$ curl http://127.0.0.1:8081/
<h1>Backend Server 2 (Port 8081)</h1>
✅ Step 2 完了チェック
- バックエンド1(127.0.0.1:8080)にアクセスできる
- バックエンド2(127.0.0.1:8081)にアクセスできる
10.12 Step 3: リバースプロキシ設定
10.12.1 Nginx 設定ファイルの構造
Nginxの設定ファイルは以下の構造になっています。
/etc/nginx/
├── nginx.conf # メイン設定ファイル
├── conf.d/ # 追加設定ファイル(*.conf)
│ └── default.conf # デフォルトサーバー設定
└── ...
追加の設定は/etc/nginx/conf.d/ディレクトリに.confファイルとして配置します。
10.12.2 リバースプロキシ設定ファイルの作成
[実行ユーザー: 一般ユーザー(sudo使用)]
# デフォルト設定をバックアップ
$ sudo mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bak
# リバースプロキシ設定を作成
$ sudo tee /etc/nginx/conf.d/reverse-proxy.conf << 'EOF'
# シンプルなリバースプロキシ設定
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
EOF
10.12.3 proxy_pass ディレクティブとヘッダー転送の設定
各ディレクティブの説明:
proxy_pass: リクエストを転送する先のURLproxy_set_header Host $host: 元のHostヘッダーを転送proxy_set_header X-Real-IP $remote_addr: クライアントの実際のIPアドレスを転送proxy_set_header X-Forwarded-For: プロキシチェーンのIPアドレスを転送proxy_set_header X-Forwarded-Proto $scheme: 元のプロトコル(http/https)を転送
10.12.4 設定の検証(nginx -t)
[実行ユーザー: 一般ユーザー(sudo使用)]
# 構文チェック
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
「syntax is ok」「test is successful」と表示されれば、設定に問題ありません。
10.12.5 リロードと動作確認
[実行ユーザー: 一般ユーザー(sudo使用)]
# SELinuxでNginxのネットワーク接続を許可
$ sudo setsebool -P httpd_can_network_connect on
# 設定をリロード
$ sudo systemctl reload nginx
# 動作確認
$ curl http://localhost/
<h1>Backend Server 1 (Port 8080)</h1>
Nginx経由でバックエンド1のコンテンツが返ってきました。
✅ Step 3 完了チェック
nginx -tで構文エラーがないcurl http://localhost/でバックエンドの内容が返ってくる- SELinuxで
httpd_can_network_connectがonになっている
10.13 Step 4: ロードバランシング設定
10.13.1 upstream ディレクティブ
複数のバックエンドサーバーに負荷を分散するため、upstreamブロックを使います。
[実行ユーザー: 一般ユーザー(sudo使用)]
# ロードバランシング設定に更新
$ sudo tee /etc/nginx/conf.d/reverse-proxy.conf << 'EOF'
# ロードバランシング付きリバースプロキシ設定
upstream backend {
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
EOF
10.13.2 負荷分散アルゴリズム
Nginxは複数の負荷分散アルゴリズムをサポートしています。
# デフォルト: ラウンドロビン(順番に振り分け)
upstream backend {
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}
# least_conn: 接続数が最も少ないサーバーに振り分け
upstream backend {
least_conn;
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}
# ip_hash: クライアントIPに基づいて同じサーバーに振り分け(セッション維持)
upstream backend {
ip_hash;
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}
# weight: 重み付け(処理能力に応じて振り分け量を調整)
upstream backend {
server 127.0.0.1:8080 weight=3;
server 127.0.0.1:8081 weight=1;
}
10.13.3 ヘルスチェック(パッシブ)
Nginxオープンソース版では、パッシブヘルスチェック(接続失敗を検知して一時的に除外)を使用します。
upstream backend {
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
server 127.0.0.1:8081 max_fails=3 fail_timeout=30s;
}
max_fails=3: 3回連続で失敗したらサーバーを一時除外fail_timeout=30s: 30秒後に再度試行
10.13.4 動作確認
[実行ユーザー: 一般ユーザー(sudo使用)]
# 設定を検証してリロード
$ sudo nginx -t && sudo systemctl reload nginx
# 複数回アクセスして負荷分散を確認
$ for i in {1..6}; do curl http://localhost/ 2>/dev/null; done
<h1>Backend Server 1 (Port 8080)</h1>
<h1>Backend Server 2 (Port 8081)</h1>
<h1>Backend Server 1 (Port 8080)</h1>
<h1>Backend Server 2 (Port 8081)</h1>
<h1>Backend Server 1 (Port 8080)</h1>
<h1>Backend Server 2 (Port 8081)</h1>
リクエストが2つのバックエンドに交互に振り分けられています。
🎉 プロジェクトB完了!
おめでとうございます!Nginxリバースプロキシの構築が完了しました。以下ができるようになりました:
- Nginxのインストールと基本設定
- リバースプロキシの設定
- 複数バックエンドへのロードバランシング
- ヘッダー転送の設定
- バックエンドのセキュアな構成(localhost限定)
【プロジェクトC】コンテナアプリケーション実行(Podman)
10.14 プロジェクトC概要
10.14.1 コンテナ技術とは
コンテナは、アプリケーションとその依存関係をパッケージ化し、どの環境でも同じように動作させる技術です。仮想マシンと比較すると、より軽量で起動が速いという特徴があります。
10.14.2 Podman vs Docker
| 特徴 | Podman | Docker |
|---|---|---|
| アーキテクチャ | デーモンレス(フォークモデル) | デーモン必須(Docker daemon) |
| root権限 | rootless動作可能 | 基本的にroot必要 |
| CLI互換性 | Dockerと互換(aliasで使用可) | – |
| systemd統合 | 優れている(Quadlet) | 別途設定が必要 |
| RHEL系での採用 | 標準 | 追加インストール |
AlmaLinux 10では、Podmanがコンテナ技術の標準として採用されています。
10.14.3 構築するシステムの全体像
10.15 Step 1: Podman のインストール
10.15.1 Podman パッケージのインストール
[実行ユーザー: 一般ユーザー(sudo使用)]
# Podmanのインストール
$ sudo dnf5 install podman -y
# 確認
$ rpm -qa | grep podman
podman-5.x.x-1.el10.x86_64
10.15.2 バージョン確認
[実行ユーザー: 一般ユーザー]
# Podmanのバージョン確認
$ podman --version
podman version 5.4.0
# 詳細情報の確認
$ podman info
host:
arch: amd64
buildahVersion: 1.38.0
cgroupControllers:
- memory
- pids
cgroupManager: systemd
cgroupVersion: v2
...
10.15.3 rootless モードの理解
Podmanの大きな特徴の一つがrootlessモードです。root権限なしでコンテナを実行できるため、セキュリティが向上します。
[実行ユーザー: 一般ユーザー]
# 現在のユーザーでPodmanが使えるか確認
$ podman run --rm hello-world
Resolved "hello-world" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
Trying to pull quay.io/podman/hello:latest...
Getting image source signatures
Copying blob ...
Copying config ...
Writing manifest to image destination
!... Hello Podman World ...!
.--"--.
/ - - \
/ (O) (O) \
~~~| -=(,Y,)=- |
.---. /` \ |~~
~/ o o \~~~~.----. ~~
| =(X)= |~ / (O (O) \
~~~~~~~ ~| =(Y_)=- |
~~~~ ~~~| U |~
Project: https://github.com/containers/podman
Website: https://podman.io
...
一般ユーザーでコンテナが実行できました。
✅ Step 1 完了チェック
- Podmanがインストールされている
podman --versionでバージョンが表示されるpodman run hello-worldが成功する
10.16 Step 2: コンテナイメージの取得
10.16.1 podman search でイメージ検索
Nginxコンテナイメージを検索します。
[実行ユーザー: 一般ユーザー]
# Nginxイメージを検索
$ podman search nginx --limit 5
INDEX NAME DESCRIPTION STARS OFFICIAL
docker.io docker.io/library/nginx Official build of Nginx. 20000 [OK]
docker.io docker.io/nginx/nginx-ingress NGINX and NGINX Plus Ingress Controllers for... 100
docker.io docker.io/bitnami/nginx Bitnami nginx Docker Image 200
...
10.16.2 podman pull でイメージ取得
[実行ユーザー: 一般ユーザー]
# 公式Nginxイメージを取得
$ podman pull docker.io/library/nginx:latest
Trying to pull docker.io/library/nginx:latest...
Getting image source signatures
Copying blob ...
Copying config ...
Writing manifest to image destination
e4720093a3c1352e2c...
10.16.3 podman images で確認
[実行ユーザー: 一般ユーザー]
# ダウンロード済みイメージの一覧
$ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/library/nginx latest e4720093a3c1 2 weeks ago 192 MB
quay.io/podman/hello latest 5dd467fce50b 3 months ago 786 kB
10.17 Step 3: コンテナの実行
10.17.1 podman run でコンテナ起動
[実行ユーザー: 一般ユーザー]
# Nginxコンテナを起動
$ podman run --name my-nginx -d -p 8080:80 nginx:latest
abc123def456...
# 説明:
# --name my-nginx : コンテナに名前を付ける
# -d : バックグラウンドで実行(デタッチモード)
# -p 8080:80 : ホストの8080番ポートをコンテナの80番ポートにマッピング
10.17.2 ポートマッピング(-p オプション)
rootlessモードでは、デフォルトで1024番以下のポートにバインドできません。そのため、8080番ポートを使用しています。
10.17.3 バックグラウンド実行(-d オプション)
-dオプションを付けると、コンテナがバックグラウンドで実行されます。
10.17.4 podman ps でコンテナ確認
[実行ユーザー: 一般ユーザー]
# 実行中のコンテナを確認
$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
abc123def456 docker.io/library/nginx:latest nginx -g daemon o... 2 minutes ago Up 2 minutes 0.0.0.0:8080->80/tcp my-nginx
# 動作確認
$ curl http://localhost:8080/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
💡 外部からアクセスする場合
ファイアウォールで8080番ポートを開放する必要があります:
$ sudo firewall-cmd --permanent --add-port=8080/tcp
$ sudo firewall-cmd --reload
✅ Step 3 完了チェック
- Nginxコンテナが起動している(
podman psで確認) curl http://localhost:8080/でNginxページが返ってくる
10.18 Step 4: データの永続化
10.18.1 ボリュームの作成
コンテナを削除するとデータも失われます。永続化するためにボリュームを使用します。
[実行ユーザー: 一般ユーザー]
# ボリュームの作成
$ podman volume create nginx-data
# ボリュームの確認
$ podman volume ls
DRIVER VOLUME NAME
local nginx-data
# ボリュームの詳細確認
$ podman volume inspect nginx-data
[
{
"Name": "nginx-data",
"Driver": "local",
"Mountpoint": "/home/developer/.local/share/containers/storage/volumes/nginx-data/_data",
...
}
]
10.18.2 ボリュームのマウント
既存のコンテナを停止・削除し、ボリュームを使用して再起動します。
[実行ユーザー: 一般ユーザー]
# 既存のコンテナを停止・削除
$ podman stop my-nginx
$ podman rm my-nginx
# ボリュームをマウントして起動
$ podman run --name my-nginx -d -p 8080:80 \
-v nginx-data:/usr/share/nginx/html:Z \
nginx:latest
# 説明:
# -v nginx-data:/usr/share/nginx/html:Z
# nginx-data ボリュームを /usr/share/nginx/html にマウント
# :Z はSELinuxコンテキストを自動設定
10.18.3 ホストディレクトリのバインドマウント
ボリュームの代わりに、ホストのディレクトリを直接マウントすることもできます。
[実行ユーザー: 一般ユーザー]
# ホスト側にコンテンツディレクトリを作成
$ mkdir -p ~/nginx-content
$ echo "<h1>Hello from Podman Container!</h1>" > ~/nginx-content/index.html
# バインドマウントで起動
$ podman stop my-nginx && podman rm my-nginx
$ podman run --name my-nginx -d -p 8080:80 \
-v ~/nginx-content:/usr/share/nginx/html:Z \
nginx:latest
# 確認
$ curl http://localhost:8080/
<h1>Hello from Podman Container!</h1>
ホスト側の~/nginx-content/index.htmlを編集すると、即座に反映されます。
10.19 Step 5: systemd 統合
10.19.1 Quadletによるユニットファイル生成
Podman 4.4以降では、Quadletというsystemdジェネレーターを使用します。.containerファイルを作成するだけで、systemdユニットファイルが自動生成されます。
[実行ユーザー: 一般ユーザー]
# まず既存のコンテナを停止・削除
$ podman stop my-nginx && podman rm my-nginx
# Quadlet設定用ディレクトリを作成
$ mkdir -p ~/.config/containers/systemd
# Quadlet設定ファイルを作成
$ tee ~/.config/containers/systemd/my-nginx.container << 'EOF'
[Unit]
Description=Nginx Container
After=local-fs.target
[Container]
Image=docker.io/library/nginx:latest
PublishPort=8080:80
Volume=%h/nginx-content:/usr/share/nginx/html:Z
[Install]
WantedBy=multi-user.target default.target
EOF
%hはホームディレクトリに展開されます。
10.19.2 systemd への登録
[実行ユーザー: 一般ユーザー]
# systemdにQuadlet設定を読み込ませる
$ systemctl --user daemon-reload
# 生成されたユニットファイルを確認
$ systemctl --user list-unit-files | grep nginx
my-nginx.service generated -
10.19.3 自動起動設定
[実行ユーザー: 一般ユーザー]
# サービスを開始
$ systemctl --user start my-nginx.service
# 状態確認
$ systemctl --user status my-nginx.service
● my-nginx.service - Nginx Container
Loaded: loaded (/home/developer/.config/containers/systemd/my-nginx.container; generated)
Active: active (running) since Mon 2026-01-26 14:00:00 JST; 5s ago
Main PID: 12345 (conmon)
Tasks: 3 (limit: 22951)
Memory: 15.2M
CPU: 234ms
CGroup: /user.slice/user-1000.slice/[email protected]/app.slice/my-nginx.service
├─conmon --api-version 1 ...
└─nginx: master process nginx ...
# 自動起動を有効化
$ systemctl --user enable my-nginx.service
# ユーザーがログアウトしてもサービスを継続(linger有効化)
$ loginctl enable-linger $USER
loginctl enable-lingerは重要です。これがないと、ユーザーがログアウトするとコンテナも停止してしまいます。
[実行ユーザー: 一般ユーザー]
# 動作確認
$ curl http://localhost:8080/
<h1>Hello from Podman Container!</h1>
🎉 プロジェクトC完了!
おめでとうございます!Podmanコンテナアプリケーションの構築が完了しました。以下ができるようになりました:
- Podmanのインストールとrootless実行
- コンテナイメージの取得と実行
- ボリュームによるデータ永続化
- Quadletを使ったsystemd統合
- 自動起動設定(linger含む)
【共通セクション】
10.20 共通: セキュリティチェック
どのプロジェクトを実施した場合でも、以下のセキュリティチェックを行ってください。
🚨 VPS/クラウド環境をお使いの方へ
本ガイドで推奨しているVPS環境(シンVPSなど)は、インターネットに直接公開されたサーバーです。ローカルの仮想マシンとは異なり、世界中から常にアクセス可能な状態にあります。
サービスを構築したら、必ず以下の点を確認してください:
- 不要なポートが開いていないか
- テスト用のファイル(phpinfo.php、dbtest.phpなど)を削除したか
- デフォルトのパスワードを変更したか
- SSHの鍵認証を設定し、パスワード認証を無効化したか
セキュリティ設定を怠ると、不正アクセスやマルウェア感染のリスクがあります。
10.20.1 ファイアウォール設定の見直し
[実行ユーザー: 一般ユーザー(sudo使用)]
# 現在の設定を確認
$ sudo firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: enp0s3
sources:
services: cockpit dhcpv6-client http ssh
ports: 8080/tcp
...
# 不要なサービス/ポートがあれば削除
# 例: 開発時にのみ使用したポートを削除
$ sudo firewall-cmd --permanent --remove-port=8080/tcp
$ sudo firewall-cmd --reload
10.20.2 SELinux 設定の確認
[実行ユーザー: 一般ユーザー(sudo使用)]
# SELinuxが有効か確認
$ getenforce
Enforcing
# 拒否ログがないか確認
$ sudo ausearch -m avc -ts today --interpret | head -20
# 設定したブール値の確認
$ getsebool -a | grep httpd
httpd_can_network_connect --> on
httpd_can_network_connect_db --> on
...
10.20.3 不要なサービスの停止
[実行ユーザー: 一般ユーザー(sudo使用)]
# 有効なサービスの確認
$ systemctl list-unit-files --type=service --state=enabled
# 使用していないサービスは無効化を検討
# 例: Bluetooth(サーバーでは不要)
$ sudo systemctl disable bluetooth.service
10.20.4 ログ監視の設定
第8章で学んだログ監視を設定します。
[実行ユーザー: 一般ユーザー(sudo使用)]
# ログの永続化設定確認
$ cat /etc/systemd/journald.conf | grep Storage
Storage=persistent
# 重要なログをリアルタイムで監視する例
$ sudo journalctl -f -p err
10.20.5 セキュリティチェックリスト
| チェック項目 | 確認コマンド | 期待する結果 |
|---|---|---|
| SELinux有効 | getenforce |
Enforcing |
| ファイアウォール有効 | systemctl is-active firewalld |
active |
| SSHパスワード認証無効 | grep PasswordAuthentication /etc/ssh/sshd_config |
no(推奨) |
| rootログイン禁止 | grep PermitRootLogin /etc/ssh/sshd_config |
no |
| 自動アップデート設定 | systemctl is-enabled dnf-automatic.timer |
enabled(推奨) |
| 不要なポートが閉じている | sudo firewall-cmd --list-ports |
必要最小限のみ |
| テストファイル削除済み | ls /var/www/html/*.php |
phpinfo.php、dbtest.php等がない |
💡 VPS環境での追加確認
VPSプロバイダーによっては、OS側のファイアウォールとは別に「パケットフィルター」や「セキュリティグループ」といった機能が提供されています。両方で適切に設定することで、より強固なセキュリティを実現できます。シンVPSの場合は、VPSパネルから「パケットフィルター設定」を確認してください。
10.21 共通: パフォーマンスチューニング基礎
10.21.1 リソース使用状況の確認
[実行ユーザー: 一般ユーザー]
# CPU・メモリの使用状況(リアルタイム)
$ top
# メモリ使用量の確認
$ free -h
total used free shared buff/cache available
Mem: 3.7Gi 1.2Gi 1.5Gi 12Mi 1.0Gi 2.2Gi
Swap: 2.0Gi 0B 2.0Gi
# ディスク使用量の確認
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 50G 12G 38G 24% /
/dev/sda1 1.0G 200M 800M 20% /boot
10.21.2 ボトルネックの特定
[実行ユーザー: 一般ユーザー]
# ディスクI/Oの確認
$ iostat -x 1 3
# ネットワーク接続の確認
$ ss -s
Total: 180
TCP: 25 (estab 5, closed 8, orphaned 0, timewait 3)
# プロセスごとのリソース使用
$ ps aux --sort=-%mem | head -10
10.21.3 基本的なチューニング手法
以下は参考情報です。本番環境では、影響を十分に検証してから適用してください。
Apache の場合:
- MaxRequestWorkers の調整
- KeepAlive の設定
Nginx の場合:
- worker_processes の調整(通常はauto)
- worker_connections の設定
MariaDB の場合:
- innodb_buffer_pool_size の調整(メモリの50-70%程度)
10.21.4 負荷テストの実施(ab コマンド)
ab(Apache Bench)は簡易的な負荷テストツールです。
[実行ユーザー: 一般ユーザー(sudo使用)]
# httpd-toolsのインストール
$ sudo dnf5 install httpd-tools -y
# 負荷テスト実行(100リクエスト、同時接続10)
$ ab -n 100 -c 10 http://localhost/
# 結果の例:
Server Software: Apache/2.4.62
Server Hostname: localhost
...
Requests per second: 1234.56 [#/sec] (mean)
Time per request: 8.100 [ms] (mean)
...
⚠️ 注意
負荷テストは必ずテスト環境で行ってください。本番環境で実行すると、サービスに影響を与える可能性があります。
10.22 共通: ドキュメント化
10.22.1 構築手順のドキュメント化
第9章で学んだドキュメンテーションを実践します。構築した内容を記録しておくことで、同じ環境を再構築する際や、他のチームメンバーに引き継ぐ際に役立ちます。
10.22.2 設定内容の記録
以下のテンプレートを参考に、構築した内容を記録してください。
# サーバー構築記録 ## 基本情報 - サーバー名: srv-web-01 - IPアドレス: 192.168.1.100 - OS: AlmaLinux 10 - 構築日: 2026-01-26 - 構築者: 山田太郎 ## インストールしたパッケージ - httpd 2.4.62 - mariadb-server 10.11.x - php 8.3.x - php-fpm 8.3.x - php-mysqlnd 8.3.x ## 設定変更箇所 ### /etc/httpd/conf/httpd.conf - 変更なし(デフォルト使用) ### ファイアウォール - httpサービスを許可 ### SELinux - httpd_can_network_connect_db = on ## サービス - httpd: enabled, active - mariadb: enabled, active - php-fpm: enabled, active ## データベース - データベース名: testdb - ユーザー: webuser ## 確認コマンド - systemctl status httpd mariadb php-fpm - curl http://localhost/
10.22.3 トラブルシューティング記録
構築中に遭遇した問題とその解決方法も記録しておくと、将来役立ちます。
# トラブルシューティング記録 ## 問題1: PHPファイルがダウンロードされる - 発生日時: 2026-01-26 10:45 - 症状: PHPファイルにアクセスすると処理されずにダウンロードされる - 原因: php-fpmサービスが起動していなかった - 解決方法: sudo systemctl start php-fpm - 参考: AlmaLinux 10ではPHP-FPMが必須 ## 問題2: 403 Forbidden エラー - 発生日時: 2026-01-26 11:30 - 症状: ブラウザでアクセスすると403エラー - 原因: SELinuxコンテキストが不正 - 解決方法: restorecon -Rv /var/www/html/ - 参考: 第7章 7.4節
10.22.4 運用手順書の作成
日常的な運用で使う手順も記録しておきます。
# 運用手順書 ## 日次作業 1. ログ確認 - sudo tail -100 /var/log/httpd/error_log - sudo tail -100 /var/log/php-fpm/www-error.log - sudo journalctl -p err --since yesterday ## 週次作業 1. システムアップデート - sudo dnf5 update -y - 必要に応じて再起動 ## 障害時の対応 1. まずログを確認 - /var/log/httpd/error_log - /var/log/php-fpm/www-error.log - /var/log/mariadb/mariadb.log - sudo ausearch -m avc -ts recent 2. サービスの状態確認 - systemctl status httpd mariadb php-fpm 3. 再起動を試す - sudo systemctl restart httpd php-fpm
10.23 共通: バックアップとリカバリ
10.23.1 バックアップ対象の特定
各プロジェクトでバックアップすべきファイルを整理します。
| プロジェクト | バックアップ対象 | 理由 |
|---|---|---|
| A: LAMP | /var/www/html/ | Webコンテンツ |
| /etc/httpd/ | Apache設定 | |
| /etc/php.ini, /etc/php-fpm.d/ | PHP設定 | |
| MariaDBデータ | データベース内容 | |
| B: Nginx | /etc/nginx/ | Nginx設定 |
| バックエンドコンテンツ | Webコンテンツ | |
| C: Podman | ~/.config/containers/ | Quadlet設定 |
| ボリューム/バインドマウント | コンテナデータ |
10.23.2 バックアップスクリプトの作成
プロジェクトAの場合のバックアップスクリプト例:
[実行ユーザー: 一般ユーザー(sudo使用)]
$ sudo tee /usr/local/sbin/backup-lamp.sh << 'EOF'
#!/bin/bash
# LAMP環境バックアップスクリプト
DATE=$(date +%Y%m%d)
BACKUP_DIR="/backup/lamp"
# バックアップディレクトリの作成
mkdir -p "$BACKUP_DIR"
# Webコンテンツのバックアップ
tar -czf "$BACKUP_DIR/www-$DATE.tar.gz" /var/www/html/
# Apache設定のバックアップ
tar -czf "$BACKUP_DIR/httpd-conf-$DATE.tar.gz" /etc/httpd/
# PHP設定のバックアップ
tar -czf "$BACKUP_DIR/php-conf-$DATE.tar.gz" /etc/php.ini /etc/php-fpm.d/
# MariaDBのダンプ
mysqldump -u root -p'パスワード' --all-databases > "$BACKUP_DIR/mariadb-$DATE.sql"
gzip "$BACKUP_DIR/mariadb-$DATE.sql"
# 古いバックアップの削除(7日以上前)
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +7 -delete
find "$BACKUP_DIR" -name "*.sql.gz" -mtime +7 -delete
echo "Backup completed: $DATE"
EOF
$ sudo chmod 700 /usr/local/sbin/backup-lamp.sh
10.23.3 リストア手順の確認
バックアップは、リストアできて初めて意味があります。リストア手順も確認しておきましょう。
# Webコンテンツのリストア
$ sudo tar -xzf /backup/lamp/www-20260126.tar.gz -C /
# Apache設定のリストア
$ sudo tar -xzf /backup/lamp/httpd-conf-20260126.tar.gz -C /
$ sudo systemctl restart httpd
# PHP設定のリストア
$ sudo tar -xzf /backup/lamp/php-conf-20260126.tar.gz -C /
$ sudo systemctl restart php-fpm
# MariaDBのリストア
$ gunzip -c /backup/lamp/mariadb-20260126.sql.gz | sudo mysql -u root -p
10.23.4 定期バックアップの自動化
第5章で学んだcronを使って、バックアップを自動化します。
[実行ユーザー: 一般ユーザー(sudo使用)]
# rootのcrontabを編集
$ sudo crontab -e
# 毎日深夜3時にバックアップを実行
0 3 * * * /usr/local/sbin/backup-lamp.sh >> /var/log/backup-lamp.log 2>&1
10.24 総合演習のまとめ
10.24.1 構築を通じて学んだこと
総合演習を通じて、以下のスキルを実践的に身につけました:
- 第1章: AlmaLinux 10の環境を使用
- 第2章: コマンドライン操作でファイルを作成・編集
- 第3章: dnf5でパッケージをインストール
- 第4章: (ボリューム管理、データ永続化)
- 第5章: systemctlでサービスを管理、cronで自動化
- 第6章: firewall-cmdでポートを開放、ネットワーク設定を確認
- 第7章: SELinuxのブール値を設定、スクリプトを作成
- 第8章: ログを読んでトラブルシューティング
- 第9章: バックアップスクリプトを作成、ドキュメント化
10.24.2 つまずいたポイントと解決方法
多くの方がつまずくポイントをまとめます:
| 問題 | 原因 | 解決方法 |
|---|---|---|
| サービスにアクセスできない | ファイアウォールでポートが閉じている | firewall-cmd –add-service/port |
| 403 Forbidden | SELinuxコンテキストが不正 | restorecon -Rv |
| PHPファイルがダウンロードされる | PHP-FPMが起動していない | systemctl start php-fpm |
| DB接続エラー | SELinuxブール値がoff | setsebool -P httpd_can_network_connect_db on |
| サービスが起動しない | 設定ファイルの構文エラー | httpd -t / nginx -t で確認 |
| コンテナが停止する | lingerが無効 | loginctl enable-linger |
10.24.3 次の改善点
基本的な構築ができたら、以下の改善を検討してください:
- SSL/TLS対応: Let’s Encryptで証明書を取得し、HTTPS化
- 監視設定: サービスが停止したら通知
- パフォーマンス最適化: 負荷テストに基づくチューニング
- 高可用性: 複数サーバーでの冗長構成
10.24.4 実務への応用
この章で学んだ内容は、実務で以下のように活用できます:
- 社内システム構築: WordPressやRedmineなどのWebアプリケーション
- 開発環境構築: チーム共用の開発サーバー
- テスト環境構築: 本番に近い環境でのテスト
- コンテナ運用: マイクロサービスやCI/CD環境
【コラム9】初めての本番リリースで学んだこと
私がインフラエンジニア1年目のとき、初めて本番サーバーのリリースを担当しました。LAMPベースの社内向けWebアプリケーションで、検証環境では完璧に動いていたはずでした。
リリース当日、深夜0時。メンテナンス画面を表示し、本番サーバーにデプロイを開始しました。手順書通りにコマンドを実行し、サービスを再起動。「よし、完了!」と思ってブラウザでアクセスすると…
「403 Forbidden」
冷や汗が出ました。検証環境では一度も出なかったエラーです。焦ってApacheのエラーログを確認すると、パーミッションエラーが記録されていました。原因を調べると、本番サーバーではSELinuxがEnforcingになっていたのに対し、検証環境ではPermissiveになっていたのです。
先輩に連絡して、一緒に対処してもらいました。setsebool -P httpd_can_network_connect_db onでブール値を設定し、コンテキストもrestoreconで修正。無事にアプリケーションが動き始めました。
しかし、次の問題が発生しました。アクセスが集中すると、応答が極端に遅くなるのです。検証環境では数人でしかテストしていなかったため、気づきませんでした。結局、MariaDBの接続数上限を調整し、Apacheの設定も見直して、なんとか安定稼働にこぎつけました。
深夜3時、ようやく「リリース完了」の連絡を出せました。疲労困憊でしたが、大きな学びがありました。
この経験から学んだこと:
- 検証環境と本番環境の差異を把握する: SELinuxの設定、リソース、ネットワーク構成など
- チェックリストを作成する: 事前に確認すべき項目をリスト化しておく
- 負荷テストを行う: 本番に近い負荷で動作確認する
- 一人で抱え込まない: 困ったら早めに助けを求める
- 失敗から学ぶ: 同じ失敗を繰り返さないよう、記録を残す
今では笑い話ですが、当時は本当に焦りました。でも、この経験があったからこそ、今ではリリース前のチェックリストを必ず作成し、検証環境と本番環境の設定差異を事前に確認するようになりました。
失敗は誰にでもあります。大切なのは、そこから学び、次に活かすこと。あなたもきっと、トラブルを乗り越えて成長していけるはずです。
📘 VPS環境で学習している方へ
本ガイドで使用しているVPS環境は、この話に出てくる「本番サーバー」と同じく、インターネットに公開された環境です。つまり、あなたが今構築しているサーバーも、世界中からアクセス可能な状態にあります。
「学習用だから」と油断せず、セキュリティ設定は本番環境と同じ意識で行いましょう。この習慣が、将来本番環境を扱う際に必ず役立ちます。
章末まとめ
この章では、以下の内容を実践しました:
- プロジェクトA(LAMP): Apache、PHP-FPM、MariaDBを組み合わせたWebアプリケーション環境
- プロジェクトB(Nginx): リバースプロキシとロードバランシング
- プロジェクトC(Podman): コンテナアプリケーションとsystemd統合(Quadlet)
- 共通セクション: セキュリティ、パフォーマンス、ドキュメント化、バックアップ
これまで第1章から第9章で学んだ知識を統合し、実際に動くサービスを構築できました。トラブルに遭遇し、それを解決するプロセスこそが、最も価値のある学習体験です。
練習問題(総合問題)
問題1: LAMP環境でPHPスクリプトがMariaDBに接続できない場合、どのような順序で調査を進めますか?調査項目を5つ挙げ、それぞれの確認コマンドを書いてください。
解答例を見る
- PHP-FPMサービスの確認
systemctl status php-fpm - MariaDBサービスの確認
systemctl status mariadb - 接続情報(ホスト、ユーザー、パスワード、DB名)の確認
mariadb -u webuser -p testdb(コマンドラインから直接接続テスト) - SELinuxブール値の確認
getsebool httpd_can_network_connect_db - ログの確認
sudo tail -50 /var/log/php-fpm/www-error.log
sudo ausearch -m avc -ts recent | grep httpd
SELinuxが原因の場合は、sudo setsebool -P httpd_can_network_connect_db onで解決できます。
問題2: Nginxリバースプロキシで「502 Bad Gateway」エラーが発生しています。考えられる原因を3つ挙げ、それぞれの確認方法と対処法を説明してください。
解答例を見る
原因1: バックエンドサーバーが起動していない
- 確認:
curl http://127.0.0.1:8080/(バックエンドに直接アクセス) - 対処: バックエンドサービスを起動する
原因2: SELinuxがネットワーク接続をブロックしている
- 確認:
getsebool httpd_can_network_connect - 対処:
sudo setsebool -P httpd_can_network_connect on
原因3: proxy_passの設定が間違っている
- 確認:
sudo nginx -t(構文チェック)、cat /etc/nginx/conf.d/*.conf(設定確認) - 対処: proxy_passのURLを正しく設定し、
sudo systemctl reload nginx
調査の際は、sudo tail -f /var/log/nginx/error.logでエラーログをリアルタイム監視するのも有効です。
問題3: Podmanコンテナをsystemdで自動起動させる手順を説明してください。Quadletを使用し、コンテナは「nginx」イメージ、ポートは「8080:80」とします。
解答例を見る
# 1. Quadlet設定ディレクトリの作成
mkdir -p ~/.config/containers/systemd
# 2. .containerファイルの作成
cat > ~/.config/containers/systemd/my-nginx.container << 'EOF'
[Unit]
Description=Nginx Container
After=local-fs.target
[Container]
Image=docker.io/library/nginx:latest
PublishPort=8080:80
[Install]
WantedBy=multi-user.target default.target
EOF
# 3. systemdにQuadlet設定を読み込ませる
systemctl --user daemon-reload
# 4. サービスを開始
systemctl --user start my-nginx.service
# 5. 自動起動を有効化
systemctl --user enable my-nginx.service
# 6. ログアウト後もサービスを継続(linger有効化)
loginctl enable-linger $USER
これにより、システム再起動後も自動的にNginxコンテナが起動します。
次章への橋渡し
おめでとうございます!第10章「総合演習」を完了しました。
これで、あなたはAlmaLinux 10サーバーの基礎から応用までを学び、実際にサービスを構築できるスキルを身につけました。インフラエンジニアとしての第一歩を、確実に踏み出しています。
次の第11章「次のステップへ」では、ここからさらにスキルアップするための道筋を示します。コンテナオーケストレーション(Kubernetes)、構成管理ツール(Ansible)、監視システム(Prometheus/Grafana)、そしてクラウドインフラへの展開など、より高度なトピックへの入口を紹介します。
また、継続的に学習するためのリソースや、インフラエンジニアとしてのキャリアパスについてもお話しします。
<p
