AlmaLinux 10 総合ガイド 第10章: 実践 – 総合演習

記事内に広告が含まれています。

AlmaLinux 10 総合ガイド
第10章: 実践 – 総合演習

【この章で学ぶこと】 これまでの知識を統合した実際のサービス構築
【なぜ重要か】 実践経験が実務スキルに直結する
【前提知識】 第1〜9章完了、すべての基礎スキル習得済み
【所要時間】 約4〜6時間(プロジェクトによる)

おめでとうございます。ここまでの8つの章を通じて、あなたはLinuxサーバー管理の基礎をしっかりと身につけました。コマンドライン操作、パッケージ管理、ストレージ管理、サービス管理、ネットワーク設定、セキュリティ、ログ管理、そしてバックアップと運用まで、インフラエンジニアとして必要な土台が整いました。

この章では、これまで学んだすべてを統合して、実際に動くサービスを構築します。3つのプロジェクトから興味のあるものを選び、手を動かしながら学んでください。失敗しても構いません。むしろ、トラブルシューティングこそが最大の学びです。


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 構築前の準備(要件定義)

サービスを構築する前に、「何を作るのか」を明確にしておきましょう。実務では、この「要件定義」が非常に重要です。

確認すべき項目:

  1. 目的: 何のためにこのサービスを構築するのか
  2. 構成: どのコンポーネントが必要か
  3. 前提条件: 必要なリソース(メモリ、ディスク、ネットワーク)
  4. 成功基準: どうなったら「完成」と言えるか

各プロジェクトでは、これらの項目を冒頭で明示します。

10.1.4 構築の流れ(計画→実装→検証)

すべてのプロジェクトは、以下の流れで進めます。

  1. 計画: 必要なパッケージ、設定項目、ポート番号を洗い出す
  2. 実装: 一つずつ順番にインストール・設定を行う
  3. 検証: 各ステップで動作確認を行い、問題があれば対処
  4. セキュリティ: ファイアウォール、SELinux、パーミッションを確認
  5. ドキュメント: 何をしたかを記録する

重要なルール: 各ステップで必ず動作確認を行う

一度にすべてを設定してから確認するのではなく、小さな単位で確認しながら進めます。問題が発生した場合、直前のステップが原因である可能性が高くなり、トラブルシューティングが容易になります。


【プロジェクト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-fpmphpパッケージの依存関係として自動的にインストールされますが、ここでは明示的に指定します。

[実行ユーザー: 一般ユーザー(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 httpdactive (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 mariadbactive (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-fpmactive (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_dbonになっている
  • ドキュメントルートのファイルが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: リクエストを転送する先のURL
  • proxy_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_connectonになっている

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時、ようやく「リリース完了」の連絡を出せました。疲労困憊でしたが、大きな学びがありました。

この経験から学んだこと:

  1. 検証環境と本番環境の差異を把握する: SELinuxの設定、リソース、ネットワーク構成など
  2. チェックリストを作成する: 事前に確認すべき項目をリスト化しておく
  3. 負荷テストを行う: 本番に近い負荷で動作確認する
  4. 一人で抱え込まない: 困ったら早めに助けを求める
  5. 失敗から学ぶ: 同じ失敗を繰り返さないよう、記録を残す

今では笑い話ですが、当時は本当に焦りました。でも、この経験があったからこそ、今ではリリース前のチェックリストを必ず作成し、検証環境と本番環境の設定差異を事前に確認するようになりました。

失敗は誰にでもあります。大切なのは、そこから学び、次に活かすこと。あなたもきっと、トラブルを乗り越えて成長していけるはずです。

📘 VPS環境で学習している方へ

本ガイドで使用しているVPS環境は、この話に出てくる「本番サーバー」と同じく、インターネットに公開された環境です。つまり、あなたが今構築しているサーバーも、世界中からアクセス可能な状態にあります。

「学習用だから」と油断せず、セキュリティ設定は本番環境と同じ意識で行いましょう。この習慣が、将来本番環境を扱う際に必ず役立ちます。


章末まとめ

この章では、以下の内容を実践しました:

  • プロジェクトA(LAMP): Apache、PHP-FPM、MariaDBを組み合わせたWebアプリケーション環境
  • プロジェクトB(Nginx): リバースプロキシとロードバランシング
  • プロジェクトC(Podman): コンテナアプリケーションとsystemd統合(Quadlet)
  • 共通セクション: セキュリティ、パフォーマンス、ドキュメント化、バックアップ

これまで第1章から第9章で学んだ知識を統合し、実際に動くサービスを構築できました。トラブルに遭遇し、それを解決するプロセスこそが、最も価値のある学習体験です。


練習問題(総合問題)

問題1: LAMP環境でPHPスクリプトがMariaDBに接続できない場合、どのような順序で調査を進めますか?調査項目を5つ挙げ、それぞれの確認コマンドを書いてください。

解答例を見る
  1. PHP-FPMサービスの確認
    systemctl status php-fpm
  2. MariaDBサービスの確認
    systemctl status mariadb
  3. 接続情報(ホスト、ユーザー、パスワード、DB名)の確認
    mariadb -u webuser -p testdb(コマンドラインから直接接続テスト)
  4. SELinuxブール値の確認
    getsebool httpd_can_network_connect_db
  5. ログの確認
    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

Linux