Oracle Cloud無料枠でのWebサーバ構築手順書

## 1. Oracle Cloudアカウント作成と無料枠の有効化

* **Oracle Cloudアカウントの登録:** Oracle Cloud公式サイトから新規アカウントを作成します。登録時にクレジットカード情報の入力がありますが、無料枠（Always Free）を利用する限り料金は発生しません。
* **無料枠（Always Free）の概要:** アカウント作成後、常時無料対象リソースが利用可能になります。Oracle Cloudの無料枠では、Armベースのインスタンスで最大4つのCPU（OCPU）と合計24GBメモリまで無料提供されており、加えてx86ベースの1コア・1GBメモリのVMインスタンスを2台まで無料で利用できます。これらのリソース内で構築を行うことで費用をかけずにサーバを運用できます。
* **利用リージョンの選択:** Oracle Cloudはリージョンによって利用できるサービスが異なります。基本的に無料枠はどのリージョンでも有効ですが、Armインスタンス（Ampere A1）の提供リージョンを選ぶと最大リソースを活用できます。日本地域では「東京リージョン」などが選択可能です。サインアップ時またはコンソール画面右上のリージョン選択メニューから任意のリージョンを選びます。

## 2. コンピュートインスタンス（VM）の作成手順

1. **OCIコンソールにログイン:** アカウント作成後、Oracle Cloud Infrastructure (OCI)のコンソールにログインします。メニューから「コンピュート (Compute)」→「インスタンス (Instances)」を選択し、「インスタンスの作成」(Create Instance)ボタンをクリックします。
2. **基本情報の入力:** インスタンスの名前（任意の識別名）を入力します。また、コンパートメントはデフォルトのままで問題ありません（必要に応じて任意のコンパートメントを指定可能）。
3. **イメージ（OS）の選択:** 使用するOSイメージを選択します。**Rocky Linux** または **Ubuntu** を選べます（本手順書では両方に対応した案内を行います）。例えば、Ubuntu 22.04やRocky Linux 9などのバージョンを選択してください。
4. **シェイプ（形状）の選択:** インスタンスの形状を無料枠対応のものに変更します。「イメージとシェイプ」の項目で**シェイプ（Shape）**を編集し、**常時無料対象 (Always Free Eligible)** と記載のあるシェイプを選びます。例: Armベースの**VM.Standard.A1.Flex**や、x86の場合**VM.Standard.E2.1.Micro**などがあります。ArmのA1.Flexを選ぶ場合、OCPU数とメモリサイズを指定できます（無料枠内では最大 OCPU=4、メモリ=24GBまで）。必要に応じて1～4 OCPU、メモリ数GB（例えば1 OCPUあたり6GB程度）を設定します。x86のE2.1.Microの場合は固定で1 OCPU・1GBメモリです。
5. **ネットワークの設定:** インスタンスを配置する仮想クラウド・ネットワーク(VCN)とサブネットを指定します。初めてインスタンスを作成する場合は、ウィザードで「新しい仮想クラウド・ネットワークの作成」を選ぶことで自動的にVCNとパブリックサブネットが作成されます。既存のVCNがある場合はそれを選択し、パブリックサブネットにインスタンスを置きます。

   * **パブリックIPの割り当て:** パブリックサブネットを選んだ場合、デフォルトで「パブリックIPv4アドレスを割り当てる」オプションが有効になっています（これによりインターネットから接続できるグローバルIPがインスタンスに付与されます）。このオプションが有効になっていることを確認します。
6. **SSHキーの追加:** インスタンスへSSH接続するための公開鍵を設定します。\*\*「SSHキーの追加」\*\*の項目で、以下のいずれかの方法を選択します。

   * **キーペアを自動生成:** Oracle側に鍵ペアの生成を任せる場合、「新しいキー・ペアを生成」を選択し、「公開鍵を保存」「秘密鍵を保存」をクリックして自分の端末に鍵ファイルをダウンロードします。
   * **既存の公開鍵を使用:** すでにSSHキーを持っている場合、「SSH鍵をアップロード」または「キーをペースト」を選び、自分の公開鍵 (`id_rsa.pub`など) を登録します。

   > ※以降のSSH接続でこの公開鍵に対応する秘密鍵が必要になります。安全に保管してください。
7. **その他の設定:** ブートボリュームのサイズや暗号化はデフォルトのままで構いません（無料枠では標準で十分です）。設定内容を確認し、「作成」ボタンを押してインスタンスを起動します。
8. **インスタンスの起動確認:** コンソール上でインスタンスが「起動中」から「実行中」(Running)になるまで数分待ちます。実行中になったらインスタンス詳細画面を開き、**パブリックIP**アドレスをメモしておきます（後でSSH接続やドメイン設定に使用します）。

## 3. サーバへの接続方法（SSHクライアントおよびCloud Shell）

インスタンス作成後、リモートからサーバに接続して作業を行います。基本はSSHクライアントを使った接続ですが、Oracle Cloudの提供するWeb上のターミナル「Cloud Shell」を利用する方法もあります。

* **SSHクライアントからの接続:**

  * ご自身のPCからターミナル（Linux/Macの場合）またはPuTTY等のSSHクライアント（Windowsの場合）を用いてインスタンスに接続します。接続コマンドは以下の形式です（ユーザー名はOSにより異なります）。

    ```bash
    ssh -i <秘密鍵ファイルのパス> <ユーザー名>@<インスタンスのパブリックIP>
    ```

    * **Rocky Linuxの場合:** ユーザー名は`opc`または`rocky`です（Oracle提供のRocky Linuxイメージでは`opc`ユーザーがデフォルトになっている可能性があります）。
    * **Ubuntuの場合:** ユーザー名は`ubuntu`です。
      ※ Oracle CloudのLinux系イメージでは、RHEL系は`opc`、Ubuntu系は`ubuntu`というデフォルトユーザー名が割り当てられています。初回ログイン時はこのユーザーを使用し、必要に応じて後述するように別の管理ユーザーを作成します。
  * コマンドを実行すると、初回接続時はホストキー確認のメッセージが表示されるので`yes`と入力します。その後、秘密鍵が正しく指定されていればパスフレーズなしでログインできるはずです（秘密鍵にパスフレーズを設定している場合は入力）。

* **Oracle Cloud Shell（ブラウザ上のSSH）の利用:**
  Oracle Cloudコンソールの上部メニューからワンクリックで起動できるCloud Shellを使い、ブラウザ上からSSH接続することも可能です。Cloud Shellは常時無料で提供されている小規模なLinux環境で、OCI CLIなどが利用できます。

  1. OCIコンソール右上の「Cloud Shell」アイコンをクリックし、ターミナルを起動します（初回利用時は数十秒程度セットアップ時間があります）。
  2. Cloud Shellのプロンプトが表示されたら、SSH秘密鍵ファイルをCloud Shell環境にアップロードします。画面上部のメニューからファイルアップロード機能を使うか、エディタを開いて貼り付けて保存します。
  3. Cloud ShellからインスタンスにSSH接続します。例えば秘密鍵を`oci_key.pem`として保存した場合、次のように実行します。

     ```bash
     chmod 600 oci_key.pem  # 鍵ファイルの権限を適切に設定
     ssh -i oci_key.pem opc@<インスタンスのパブリックIP>
     ```

     無事ログインできれば、Cloud Shell上でインスタンスのシェル操作が可能です。ネットワークモードが「パブリック」に設定されていれば、パブリックIP宛のSSH通信が許可されています。

（※この他、OCIのコンソールからインスタンスのシリアルコンソールに接続する方法もありますが、基本的な操作はSSHで問題ありません。）

## 4. OSの初期設定とセキュリティ強化

SSHでサーバに接続できたら、Webサーバ構築に先立ちOSの基本設定とセキュリティ対策を行います。以下の手順は**Rocky Linux系**と**Ubuntu系**で共通する部分と異なる部分があります。OSに合わせて適宜読み替えてください。

* **パッケージのアップデート:** 接続後まずシステムを最新状態に更新します。

  * Rocky Linuxの場合: `sudo dnf update -y`
  * Ubuntuの場合: `sudo apt update && sudo apt upgrade -y`
    セキュリティ修正やバグ修正を適用し、再起動を促される場合は後でサーバ再起動を行います。

* **タイムゾーンとロケールの設定（必要に応じて）:** システム時刻のタイムゾーンを日本時間に合わせます。`sudo timedatectl set-timezone Asia/Tokyo` を実行し、`timedatectl status`で設定を確認してください。言語/ロケールも必要であれば`sudo localectl set-locale LANG=ja_JP.UTF-8`等で設定可能です（ただしサーバ用途では英語のままでも問題ありません）。

* **新規ユーザーの作成（任意）:** デフォルトユーザー（opcやubuntu）は管理者権限(sudo)を持っていますが、必要に応じて独自の管理ユーザーを作成できます。例として`admin`というユーザーを作りsudo権限を与える手順を示します。

  1. `sudo adduser admin` で新規ユーザーを追加します（Ubuntuでは`adduser`、Rockyでは`useradd`コマンドでも可）。
  2. `sudo passwd admin` でパスワードを設定します（公開鍵認証のみで運用する場合は省略可）。
  3. `sudo usermod -aG sudo admin` または `usermod -aG wheel admin` により、`admin`ユーザーを管理グループ（Ubuntuではsudo、Rockyではwheel）に追加します。これで`admin`ユーザーがsudo可能となります。
  4. SSH公開鍵を新ユーザーでも使えるようにします。現在のユーザーの`~/.ssh/authorized_keys`の内容を`/home/admin/.ssh/authorized_keys`にコピーし、所有者をadminに変更します。

     ```bash
     sudo mkdir -p /home/admin/.ssh
     sudo cp ~/.ssh/authorized_keys /home/admin/.ssh/
     sudo chown -R admin:admin /home/admin/.ssh
     sudo chmod 700 /home/admin/.ssh && sudo chmod 600 /home/admin/.ssh/authorized_keys
     ```
  5. 設定後、一度新ユーザーでログインできるかテストしてください（例：`ssh -i <鍵ファイル> admin@<サーバIP>`）。問題なければ今後はこのユーザーで運用し、必要に応じてデフォルトユーザーのSSHログインを無効化することも検討します。

* **ファイアウォールの設定:** OCIインスタンスでは、OSレベルでもファイアウォール設定が存在します。初期状態では\*\*SSH(22番)\*\*しか許可されておらず、HTTP(80)やHTTPS(443)はブロックされています。そのためWebサーバとして動作させるにはこれらポートを開放します。

  * **Rocky Linux (firewalld 使用時):**

    ```bash
    sudo firewall-cmd --add-service=http --add-service=https --permanent --zone=public
    sudo firewall-cmd --reload
    sudo firewall-cmd --list-all    # 許可されたポート/サービスを確認
    ```

    上記によりHTTPとHTTPSが恒久的に許可されました。`firewall-cmd`が利用できない場合、iptablesコマンドでの設定も可能です。
  * **Ubuntu (UFW使用時):** Ubuntuでは`ufw`（Uncomplicated Firewall）が利用できます。

    ```bash
    sudo ufw allow OpenSSH
    sudo ufw allow "Nginx Full"   # 80/tcpと443/tcpを許可
    sudo ufw enable              # ファイアウォールを有効化（初回のみ）
    sudo ufw status              # ステータスと許可ルールの確認
    ```

    ※`Nginx Full`はプロファイル名で、80と443両方を指します。対話的に聞かれた場合は`y`で有効化します。

* **SELinuxの設定 (Rocky Linuxの場合):** Rocky Linux（RHEL系）ではSELinuxが既定で有効(Enforcing)になっています。SELinuxはセキュリティを強化しますが、適切に設定しないと後述のWebアプリ（WordPressやNode.jsのプロキシ動作など）がアクセス拒否される場合があります。基本的にはSELinuxポリシーやブール値を調整して対応しますが、設定が難しい場合は一時的にPermissiveモードにするか、必要に応じて無効化する方法も取られています。

  * **Permissive（一時的緩和）:** 一時的にSELinuxを緩和するには`sudo setenforce 0`を実行します。このコマンドは再起動まで有効です（`getenforce`で現在のモード確認可能）。Permissiveでは違反ログは記録しますが動作をブロックしません。
  * **無効化（開発用途向け）:** 完全に無効にするには設定ファイルを編集します。`sudo vi /etc/selinux/config`を開き、`SELINUX=enforcing`となっている行を`SELINUX=disabled`に変更し保存します。その後サーバを再起動するとSELinuxは無効になります。【※本番環境ではSELinux無効化は推奨されないため、可能なら適切なポリシー設定を行ってください】
  * **SELinux設定の調整例:** SELinuxを有効に保つ場合、WordPressがデータベースに接続できるよう\*\*`httpd_can_network_connect_db`**、Node.jsプロキシ接続のため**`httpd_can_network_connect`\*\*等のSELinuxブール値を有効化する必要があります。例えば:

    ```bash
    sudo setsebool -P httpd_can_network_connect on      # Webサーバから外部(内部)への接続許可
    sudo setsebool -P httpd_can_network_connect_db on   # WebサーバからDB接続を許可
    ```

    また、Webコンテンツを配置するディレクトリのコンテキストを`httpd_sys_content_t`に設定する（`chcon`/`restorecon`コマンドの利用）などの対応も必要です。

* **SSH設定の確認:** セキュリティのため、公開鍵認証でのSSH接続を基本とし、パスワード認証は無効化しておきます（OCIイメージでは初期状態でパスワード認証無効・rootログイン禁止になっていますが念のため確認）。`sudo vi /etc/ssh/sshd_config`で設定ファイルを開き、`PasswordAuthentication no` および `PermitRootLogin no` が設定されていることを確認します。変更した場合は`sudo systemctl reload sshd`で設定を反映してください。

以上でOSレベルの初期設定は完了です。次にWebサーバ環境（Nginxや各種アプリケーション）のセットアップに移ります。

## 5. Nginxのインストールと基本設定

Webサーバソフトウェアとして**Nginx**をインストールします。Nginxは軽量高速なHTTPサーバで、リバースプロキシとしても機能し、静的コンテンツ配信から動的アプリケーションのフロントエンドまで幅広く利用できます。

* **パッケージのインストール:**

  * Rocky Linuxの場合: `sudo dnf install -y nginx`
  * Ubuntuの場合: `sudo apt install -y nginx`
    上記コマンドで公式リポジトリからNginxをインストールします。インストール後、自動的にサービスが開始される場合があります。念のため以下を実行してNginxを起動・自動起動設定します。

  ```bash
  sudo systemctl enable --now nginx   # サービスを起動し、再起動後も自動起動するように有効化
  sudo systemctl status nginx         # ステータス確認（Active(running)になっていればOK）
  ```

* **ファイアウォール設定の確認:** 先にファイアウォールでHTTP/HTTPSを許可していれば、現在NginxのデフォルトWEBページにアクセス可能な状態になっています。試しにブラウザからインスタンスのパブリックIP (または後で設定する独自ドメイン) にhttpでアクセスし、「Welcome to nginx」等のデフォルトページが表示されることを確認してください。

* **Nginxのディレクトリ構成:**

  * Rocky Linux系では、設定ファイルは`/etc/nginx/nginx.conf`および`/etc/nginx/conf.d/`ディレクトリ内の各設定ファイル、ドキュメントルートは`/usr/share/nginx/html`がデフォルトです。
  * Ubuntu系では、`/etc/nginx/nginx.conf`に加え、仮想ホスト設定用に`/etc/nginx/sites-available/`と`sites-enabled/`ディレクトリが用意されています（デフォルトサイト設定は`/etc/nginx/sites-available/default`）。ドキュメントルートは`/var/www/html`がデフォルトになっています。

* **Nginx設定ファイルのバックアップ（推奨）:** 後述の設定変更に備え、現状のNginx設定をバックアップしておきます。例: `sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak` および Ubuntuの場合 `sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.bak` など。

* **サーバブロック（仮想ホスト）の準備:** 複数のサイトやアプリをホストするため、Nginxのサーバブロックを分離して設定します。本手順では以下のように想定します。

  * 静的コンテンツ用サイト（例: **example.com**）
  * WordPressサイト（例: **blog.example.com**）
  * Node.jsアプリ用サイト（例: **app.example.com**）
    それぞれ別のドメイン（またはサブドメイン）でアクセスし、Nginxがホスト名で振り分けを行う構成にします（名前ベースのバーチャルホスト）。以降の手順では、実際に取得した独自ドメイン名に読み替えて設定してください。

## 6. 静的HTMLサイトのデプロイとNginx設定

まずシンプルな静的コンテンツの配信から構築します。例えば社内サイトの案内ページやポートフォリオサイトなど、特別な処理を必要としないHTML/CSS/画像のみのサイトを想定します。

* **コンテンツ配置用ディレクトリの作成:** 静的サイト用にドキュメントルートとなるディレクトリを用意します。例として`/var/www/example.com`ディレクトリを作成します（ディレクトリ名は分かりやすくドメイン名にしていますが任意です）。

  ```bash
  sudo mkdir -p /var/www/example.com
  ```

  ここにHTMLファイルや画像、CSSなどの静的ファイルを配置します。テストとして簡単な`index.html`を作成してみましょう。

  ```bash
  echo "<h1>Welcome to Example.com</h1><p>これは静的コンテンツのテストページです。</p>" | sudo tee /var/www/example.com/index.html
  ```

* **ディレクトリの権限設定:** コンテンツディレクトリの所有者をWebサーバユーザーに変更します。

  * Rocky Linux (nginxユーザー): `sudo chown -R nginx:nginx /var/www/example.com`
  * Ubuntu (www-dataユーザー): `sudo chown -R www-data:www-data /var/www/example.com`

* **Nginxサーバブロックの設定:** 静的サイト用にNginxの仮想ホスト設定を追加します。Ubuntuの場合はsites-availableに新規ファイルを作成し、Rockyの場合はconf.dにファイルを作成します。ここでは`example.com.conf`という設定ファイルを作成します。

  ```bash
  # Ubuntuの場合（sites-availableに作成し、sites-enabledにシンボリックリンク）
  sudo vi /etc/nginx/sites-available/example.com.conf
  # Rocky Linuxの場合（conf.dに直接作成）
  sudo vi /etc/nginx/conf.d/example.com.conf
  ```

  ファイルに以下の内容を記述します（`example.com`の箇所は自身のドメイン名に置き換えてください）。

  ```nginx
  server {
      listen       80;
      server_name  example.com www.example.com;
      root         /var/www/example.com;
      index        index.html;
      
      access_log   /var/log/nginx/example.access.log;
      error_log    /var/log/nginx/example.error.log;
      
      location / {
          try_files $uri $uri/ =404;
      }
  }
  ```

  ポイント:

  * `listen 80;` はHTTPのデフォルトポートで待ち受ける設定です。必要に応じてIPv6対応で`listen [::]:80;`も追加します。
  * `server_name` に静的サイトに割り当てる独自ドメインを指定します（スペース区切りで複数指定可。上記では`example.com`と`www.example.com`の両方をこのサーバブロックで扱います）。
  * `root` に先ほど作成したコンテンツディレクトリを指定します。
  * `index` はデフォルトのインデックスファイル名です。複数指定も可能ですが、このサイトでは`index.html`のみとしています。
  * `try_files $uri $uri/ =404;` はリクエストされたパスに対応する実ファイルまたはディレクトリが存在しない場合に404エラーを返す設定です。静的サイトではこれで十分です。

  設定ファイルを保存したら、有効化します（Ubuntuの場合はsites-enabledにリンクを張る）。

  ```bash
  # Ubuntuのみ
  sudo ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/
  ```

* **Nginx設定の検証とリロード:** 構文エラーがないか確認し、Nginxをリロードして新しい設定を適用します。

  ```bash
  sudo nginx -t && sudo systemctl reload nginx
  ```

  `nginx -t`で`syntax is ok`と表示されれば成功です。

* **動作確認:** ブラウザで `http://example.com` にアクセスし、先ほど作成したテストページの内容（"Welcome to Example.com"）が表示されれば静的コンテンツの配信設定は完了です。

## 7. WordPressサイトの構築（PHP + MySQL/MariaDB + Nginx）

次に、動的なWEBアプリケーションの代表として**WordPress**をセットアップします。WordPressはPHPで動作するCMS（コンテンツ管理システム）であり、データベースとしてMySQL系を使用します。Nginx上でWordPressを動かす構成（一般に「LEMPスタック」: Linux, **Nginx**, MySQL(MariaDB), PHP）を構築します。

### 7.1 データベースサーバ（MySQL/MariaDB）のインストールと設定

* **データベースの選択:** 無料枠環境では軽量な**MariaDB**（MySQL互換のオープンソースDB）を使用することをお勧めします。MariaDBはMySQLとほぼ同じ操作で利用でき、各ディストリの標準リポジトリに含まれています。以下ではMariaDBを使用しますが、必要に応じてMySQL公式をインストールしても構いません。

* **インストール:**

  * Rocky Linux: `sudo dnf install -y mariadb-server`
  * Ubuntu: `sudo apt install -y mariadb-server`
    インストールが完了したらデータベースサービスを起動・有効化します。

  ```bash
  sudo systemctl enable --now mariadb
  sudo systemctl status mariadb    # Activeになっていることを確認
  ```

* **初期セキュリティ設定:** データベースの初期セットアップとしてセキュリティ強化を行います。MySQL系では`mysql_secure_installation`スクリプトを使って不要な初期設定を削除できます。対話形式で以下の設定を行います。

  ```bash
  sudo mysql_secure_installation
  ```

  対話内容の例:

  * 現在のrootパスワード入力: （初回なので空のままEnter）
  * rootパスワード設定: 強力な新パスワードを設定
  * 匿名ユーザーの削除: **Y**（はい）
  * リモートからのrootログイン禁止: **Y**
  * テストデータベースの削除: **Y**
  * 権限テーブルのリロード: **Y**
    これでデータベースのrootユーザー保護と不要データ削除が完了します。

* **WordPress用データベースとユーザーの作成:** 続いてWordPressが使用するデータベースとDBユーザーを作成します。先ほど設定したDBのrootパスワードを用いてMySQLクライアントに接続し、SQLコマンドを実行します。

  ```bash
  mysql -u root -p   # プロンプトが出たらrootのDBパスワード入力
  ```

  接続できたら、以下のSQLを順に実行します（`;`までが1コマンドです）。

  ```sql
  CREATE DATABASE wordpress DEFAULT CHARACTER SET utf8mb4;
  CREATE USER 'wpuser'@'%' IDENTIFIED BY '強力なパスワード';
  GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'%';
  FLUSH PRIVILEGES;
  EXIT;
  ```

  上記により、`wordpress`という名前のデータベースと、`wpuser`というユーザー（パスワードは任意の強固なものを設定）を作成しました。`GRANT`文で当該DBへの全権限を付与し、`FLUSH`で反映しています。

  > セキュリティメモ: `'%'`ホストは全てのホストからの接続を許可する指定です。WordPressが同一サーバ内で動作する場合、本番運用では`'localhost'`に限定してユーザーを作成するとより安全です。

### 7.2 PHPおよび必要パッケージのインストール

WordPressを動かすにはPHPの実行環境が必要です。特にNginxではPHPを**PHP-FPM**（FastCGI Process Manager）という仕組みで動かします。また、WordPressに必要な各種PHP拡張をインストールします。

* **PHP本体とPHP-FPMのインストール:**

  * Rocky Linux: `sudo dnf install -y php php-fpm php-mysqlnd`
  * Ubuntu: `sudo apt install -y php-fpm php-mysql`
    上記は最低限のPHP本体と、データベース接続用のMySQLモジュールです。

* **追加のPHP拡張モジュール:** WordPressの各種機能（画像処理やマルチバイト、XML等）に必要な拡張をインストールします。

  * Rocky Linux: `sudo dnf install -y php-gd php-mbstring php-xml php-json php-curl php-zip php-opcache` など
  * Ubuntu: `sudo apt install -y php-gd php-mbstring php-xml php-curl php-zip` など
    ディストリによってパッケージ名が多少異なりますが、上記で主要な拡張はカバーできます。必要に応じて他の拡張（例えば画像関連のphp-imagickや国際化php-intl等）も追加してください。

* **PHP-FPMの起動と有効化:**

  ```bash
  sudo systemctl enable --now php-fpm
  sudo systemctl status php-fpm
  ```

  `active (running)` になっていることを確認します。以降、PHPはこの常駐するPHP-FPMによって実行されます。

* **PHP-FPMソケット/ポートの確認:** PHP-FPMはWebサーバとの通信に**ソケットファイル**もしくは**TCPポート**を使用します。Ubuntuでは通常`/run/php/phpX.X-fpm.sock`というソケットで待ち受け、Rocky Linuxでは`/run/php-fpm/www.sock`がデフォルトです。ただしソケットの場合、Nginxとのユーザー権限の整合性を取る必要があります。簡便化のため、ここでは**TCPポート**でPHP-FPMが待ち受ける設定に変更します。

  * 設定ファイルを開きます: `sudo vi /etc/php-fpm.d/www.conf` (Rocky) または `sudo vi /etc/php/*/fpm/pool.d/www.conf` (Ubuntu、パスはPHPバージョンにより異なる)
  * 次の項目を確認・変更します:

    ```
    listen = 127.0.0.1:9000
    ```

    デフォルトでソケット指定になっている場合は上記のように`127.0.0.1:9000`に書き換えます（多くの環境でコメントアウトされた別設定行が用意されています）。変更後、`sudo systemctl restart php-fpm`でPHP-FPMを再起動します。これでPHP-FPMはローカルホストのポート9000番で待ち受けます。

### 7.3 WordPressファイルの配置

* **WordPressパッケージのダウンロード:** 最新のWordPressを公式サイトからダウンロードします。日本語版を利用する場合は日本語版サイトから取得できます。

  ```bash
  cd /var/www
  sudo wget https://ja.wordpress.org/latest-ja.tar.gz -O wordpress.tar.gz
  sudo tar -xzvf wordpress.tar.gz
  sudo mv wordpress blog.example.com
  ```

  上記では`/var/www/blog.example.com`というディレクトリに展開しています（ドメインに合わせたディレクトリ名にしていますが任意です）。`latest-ja.tar.gz`を使用すると日本語版WordPressが取得できます。英語版で良い場合は`https://wordpress.org/latest.tar.gz`を使用してください。

* **所有権と権限の設定:** 展開したWordPressディレクトリの所有者をWebサーバユーザーに変更します。

  * Rocky: `sudo chown -R nginx:nginx /var/www/blog.example.com`
  * Ubuntu: `sudo chown -R www-data:www-data /var/www/blog.example.com`
    これにより、WordPressがキャッシュファイルを生成したりプラグインをインストールしたりする際に必要な書き込み権限が適切に設定されます。

* **(SELinux利用時のみ) コンテキストの調整:** SELinuxが有効な場合、WordPressディレクトリに適切なコンテキストを付与します。

  ```bash
  sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/blog.example.com(/.*)?"
  sudo restorecon -Rv /var/www/blog.example.com
  ```

  これでWordPressファイルがNginxからアクセス可能になります。

### 7.4 Nginxの設定（WordPress用サイト）

WordPress用のNginxサーバブロックを設定します。ドメインに合わせて新しい設定ファイルを用意します（例として`blog.example.com.conf`）。

```bash
# Ubuntuの場合
sudo vi /etc/nginx/sites-available/blog.example.com.conf
# Rocky Linuxの場合
sudo vi /etc/nginx/conf.d/blog.example.com.conf
```

編集内容の例（必要に応じて調整してください）:

```nginx
server {
    listen       80;
    server_name  blog.example.com;
    root         /var/www/blog.example.com;
    index        index.php index.html;
    
    access_log   /var/log/nginx/blog.access.log;
    error_log    /var/log/nginx/blog.error.log;
    
    client_max_body_size 100M;
    
    location / {
        try_files $uri $uri/ /index.php?$args;
    }
    
    location ~ \.php$ {
        include       fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass  127.0.0.1:9000;
    }
}
```

説明:

* `server_name` はWordPressサイト用のドメイン（例: blog.example.com）を指定します。
* `root` はWordPressを配置したディレクトリです。
* `index` に`index.php`を含め、PHPファイルがデフォルトのインデックスとして扱われるようにします。
* `client_max_body_size 100M;` はアップロード可能なファイルサイズの最大値を設定しています（WordPressメディアアップロード用にデフォルト2MBから増やしています。PHP側でも先にphp.iniで`upload_max_filesize=100M`等設定済みなら同じ値をNginxでも許可）。
* `location /` ブロックでは、WordPressの美しいパーマリンクに対応するため、存在しないファイルへのリクエストは`/index.php`に渡すよう`try_files ... /index.php?$args`で設定しています。
* `location ~ \.php$` ブロックでは、PHPファイルのリクエストをPHP-FPMに渡します。`fastcgi_params`はNginx同梱のパラメータ設定をインクルードし、`SCRIPT_FILENAME`で実際のスクリプトのパスを渡しています。`fastcgi_pass 127.0.0.1:9000`はPHP-FPMが待ち受けているローカルの9000番ポートを指定しています（ソケット利用の場合は`unix:/run/php-fpm/www.sock`等となります）。

ファイルを保存したらUbuntuの場合は`sites-enabled`にリンクを作成し、Nginxの設定をテスト・リロードします。

```bash
# Ubuntuのみ
sudo ln -s /etc/nginx/sites-available/blog.example.com.conf /etc/nginx/sites-enabled/
# 共通: 設定テストとリロード
sudo nginx -t && sudo systemctl reload nginx
```

### 7.5 WordPressのインストール初期設定

ブラウザから `http://blog.example.com` にアクセスし、WordPressの初期セットアップ画面が表示されることを確認します。表示されない場合はNginxのエラーログ（`/var/log/nginx/blog.error.log`）やPHP-FPMのログ（`/var/log/php-fpm/...`）を確認してください。

WordPressセットアップ画面では、先ほど作成したデータベース情報を入力します。

1. **言語選択:** （日本語版をダウンロードした場合このステップは省略され日本語固定になります）
2. **データベース情報入力:**

   * データベース名: **wordpress**
   * ユーザー名: **wpuser**
   * パスワード: （設定したDBユーザーパスワード）
   * データベースホスト: **localhost** （データベースが同じサーバ内にあるため）
   * テーブル接頭辞: `wp_`（特に変更不要ですが、複数WordPressを1DBで使う場合は変える）
3. 入力後、「インストール実行」を進めると、問題がなければサイト基本情報の設定になります。
4. **サイト情報と管理ユーザー作成:** サイトのタイトル、管理ユーザーのユーザー名・パスワード・メールアドレスを入力します。管理ユーザーは強力なパスワードを設定してください。検索エンジンのインデックス許可チェックボックスは必要に応じて。
5. **インストール完了:** 完了するとログイン画面へのリンクが表示されます。「ログイン」をクリックし、先ほど設定した管理ユーザーでログインできればWordPressサイトのセットアップ完了です。

これでWordPressサイトがNginx上で動作するようになりました。必要に応じてドメイン名に対してSSL設定（Let's EncryptによるHTTPS化）を行うことで、より安全にサイトを公開できます（SSL設定方法は後述の独自ドメイン設定の節を参照してください）。

## 8. Node.jsアプリケーションの構築と設定

最後に、JavaScriptランタイム環境である**Node.js**で動作するWebアプリケーションのホスティング手順です。ここでは例として簡単なNode.jsアプリを作成し、Nginxでリバースプロキシ設定を行います。

### 8.1 Node.jsのインストール

* **Node.jsのバージョン:** 2025年現在、Node.js 18や20などのLTS版が利用可能です。本手順ではLTS版をインストールします。OS標準リポジトリのNode.jsは古い場合があるため、公式のNodeSourceリポジトリを利用します。

* **インストールコマンド:**

  * Ubuntuの場合:

    ```bash
    curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
    sudo apt install -y nodejs
    ```
  * Rocky Linuxの場合:

    ```bash
    curl -sL https://rpm.nodesource.com/setup_18.x | sudo bash -
    sudo dnf install -y nodejs
    ```

  それぞれNode.jsとパッケージ管理ツールnpmがインストールされます。バージョンを確認してみます。

  ```bash
  node -v   # 例: v18.x.x と表示
  npm -v    # 例: 8.x.x と表示 (npmはNodeに付属)
  ```

* **補足:** `curl`や`wget`が入っていない場合は事前にインストールしてください（Ubuntuでは`curl`は入っている可能性が高いです。Rockyで入っていなければ `sudo dnf install -y curl`）。

### 8.2 Node.jsアプリケーションの配置

* **アプリケーション用ディレクトリ:** Node.jsアプリのコードを配置するディレクトリを用意します。例として`/var/www/nodeapp`ディレクトリを作成します。

  ```bash
  sudo mkdir -p /var/www/nodeapp
  sudo chown -R $USER:$USER /var/www/nodeapp    # カレントユーザーで作業しやすく
  cd /var/www/nodeapp
  ```

  （ここでは一旦作業のため所有者を自分に変更していますが、運用時には適切なユーザー権限に変更します。）

* **サンプルアプリの作成:** テスト用にシンプルなHTTPサーバを作成します。本番では既存のNode.jsアプリケーションのコードを配置してください。

  ```bash
  cat > app.js << 'EOF'
  const http = require('http');
  const server = http.createServer((req, res) => {
    res.writeHead(200, {'Content-Type': 'text/plain; charset=utf-8'});
    res.end('Hello! このメッセージはNode.jsアプリからの出力です。');
  });
  server.listen(3000);
  console.log("Node.jsアプリがポート3000で起動しました");
  EOF
  ```

  上記はHTTPモジュールでポート3000番に簡単なサーバを立てるスクリプトです。

* **動作確認 (開発用):** 一度このアプリを手動で起動してみます。

  ```bash
  node app.js
  ```

  ターミナルに`Node.jsアプリがポート3000で起動しました`と表示されていれば起動成功です。一旦Ctrl+Cで停止してください。

### 8.3 プロセス管理ツールの導入（PM2）

Node.jsアプリをサーバ上で常時動かし、サーバ再起動後も自動で起動するようにするには、プロセス管理ツールを使うと便利です。ここでは**PM2**という人気のツールを使用します。

* **PM2のインストール:** npm経由でグローバルインストールします。

  ```bash
  sudo npm install -g pm2
  pm2 -v    # バージョン表示されればOK
  ```

* **アプリのPM2管理下での起動:**

  ```bash
  pm2 start /var/www/nodeapp/app.js --name "nodeapp"
  ```

  これでアプリがデーモンとしてバックグラウンド起動しました。`pm2 list`でプロセス一覧が表示され`online`状態になっていることを確認してください。

* **自動起動設定:** PM2自体とアプリをサーバブート時に起動させます。以下を実行します。

  ```bash
  pm2 startup systemd -u $USER --hp $HOME
  pm2 save
  ```

  1行目は現在のユーザーアカウントに合わせた起動スクリプトを登録するコマンドです。実行すると「\[Unit]～」から始まるsystemdサービスの作成メッセージが出力され、最後に`sudo`で始まるコマンドが表示されます。そのコマンドをコピーして実行してください（例えば`sudo env PATH=$PATH pm2 startup systemd -u ubuntu --hp /home/ubuntu`など）。
  2行目の`pm2 save`は現在PM2で管理中のプロセスリストを保存し、再起動時に復元するためのものです。これでサーバ再起動後もNode.jsアプリが自動で立ち上がるようになります。

> **メモ:** PM2の代替として、Node.jsアプリ専用にsystemdユニットファイルを作成して管理する方法もあります。しかしPM2はログ管理やクラスタリング機能も備えており便利です。

### 8.4 Nginxの設定（Node.jsアプリ用サイト）

Node.jsアプリは内部でポート3000を使っていますが、このままだと直接そのポートにアクセスする必要があり、また複数アプリの共存も難しくなります。そこでNginxをリバースプロキシとして動作させ、外部からのHTTPリクエストをNode.jsアプリに中継します。これにより既存の80番ポートでのサービス提供やドメイン名によるバーチャルホストが可能になります。

* **サーバブロックの作成:** Node.jsアプリ用に新たなNginxサーバブロックを追加します（例: `app.example.com.conf`）。

  ```bash
  # Ubuntuの場合
  sudo vi /etc/nginx/sites-available/app.example.com.conf
  # Rocky Linuxの場合
  sudo vi /etc/nginx/conf.d/app.example.com.conf
  ```

  編集内容例:

  ```nginx
  server {
      listen       80;
      server_name  app.example.com;
      
      access_log   /var/log/nginx/nodeapp.access.log;
      error_log    /var/log/nginx/nodeapp.error.log;
      
      location / {
          proxy_pass         http://127.0.0.1:3000;
          proxy_http_version 1.1;
          proxy_set_header   Host $host;
          proxy_set_header   Upgrade $http_upgrade;
          proxy_set_header   Connection "upgrade";
      }
  }
  ```

  * 基本的な構造は他のサーバブロックと同様ですが、`location /`内で`proxy_pass`により、受け取ったリクエストを\*\*[http://127.0.0.1:3000\*\*（Node.jsアプリのアドレス）へ転送しています。](http://127.0.0.1:3000**（Node.jsアプリのアドレス）へ転送しています。)
  * `proxy_set_header`ディレクティブで、元のHostヘッダを維持する設定やWebSocket通信のハンドリング（Upgradeヘッダ）を行っています。Node.jsアプリがWebSocketを使用しない場合でも入れておくと汎用的に対応できます。
  * Node.jsアプリ側はリバースプロキシ経由になるため、クライアントのIPアドレスはNginxから見ると`127.0.0.1`になります。必要に応じて`proxy_set_header X-Forwarded-For $remote_addr;`等も追加すると良いでしょう。

* **設定の有効化とリロード:** ファイルを保存し（Ubuntuはシンボリックリンク作成）、Nginxの設定をテスト後リロードします。

  ```bash
  # Ubuntuのみ
  sudo ln -s /etc/nginx/sites-available/app.example.com.conf /etc/nginx/sites-enabled/
  # 共通
  sudo nginx -t && sudo systemctl reload nginx
  ```

* **動作確認:** ブラウザで `http://app.example.com` にアクセスします。先ほどNode.jsアプリから出力したメッセージ（"Hello! このメッセージはNode.jsアプリからの出力です。"）が表示されれば、Nginxを介したNode.jsアプリの公開に成功しています。もし表示されない場合は、Node.jsアプリが起動しているか（`pm2 list`で確認）、Nginxの設定ミスがないかログを確認してください。

## 9. 独自ドメインのDNS設定とNginx側ドメイン設定

上記では例として`example.com`やそのサブドメインを使用しました。実際に独自ドメインでアクセスできるようにするために、**DNSの設定**とNginx側の**サーバ名設定**の確認を行います。

### 9.1 DNSレコードの設定

独自ドメインを管理しているDNSサービス（ドメイン取得元のレジストラやクラウドDNSサービスなど）にて、以下のレコードを追加します。

* **ルートドメイン（例: example.com）を使用する場合:**
  種別: Aレコード
  ホスト名: `@` (空欄の場合もあり、プロバイダ仕様に従う)
  値: Oracle CloudインスタンスのパブリックIPv4アドレス
  TTL: 適宜（デフォルトで可）

* **サブドメイン（例: blog.example.com, app.example.com）を使用する場合:**
  種別: Aレコード
  ホスト名: `blog` （または`app`など使用するサブドメイン名）
  値: 同じくインスタンスのパブリックIPv4アドレス
  TTL: 適宜

（もしIPv6アドレスもインスタンスに割り当てている場合は、同様にAAAAレコードも追加してください。）

上記設定により、インターネット上でドメイン名があなたのサーバIPに解決されるようになります。DNSの浸透には数分～数時間かかる場合があります。`nslookup`や`dig`コマンドでドメインを引いて、正しくIPが返ってくるか確認してください。

> **外部DNS管理について:** Oracle Cloudの無料枠ではDNSサービス（OCI DNS）も利用可能ですが、すでにお持ちのドメインを外部のDNSで管理している場合はそのまま外部DNSで設定を行って問題ありません。本手順では外部DNSにレコードを追加する前提で進めています。

### 9.2 Nginxのサーバ名設定確認

Nginx側では既に各サーバブロックの`server_name`ディレクティブにドメイン名を設定済みですが、改めて確認します。`/etc/nginx/conf.d/*.conf`や`sites-available/*.conf`内で、使用する独自ドメインが正しく記載されていることを確認してください。例えば:

* `example.com.conf` 内: `server_name example.com www.example.com;`
* `blog.example.com.conf` 内: `server_name blog.example.com;`
* `app.example.com.conf` 内: `server_name app.example.com;`

もし仮に`server_name _;`（ワイルドカード）などのままになっていると、意図しない仮想ホストにマッチしない可能性があります。必ずドメイン名を反映させてください。変更した場合は再度 `nginx -t && systemctl reload nginx` を忘れずに行います。

### 9.3 HTTPS（SSL/TLS）化のオプション

独自ドメインを使用する場合、ウェブサイトを暗号化通信(HTTPS)に対応させることが強く推奨されます。無料の証明書を発行してくれる**Let's Encrypt**を使うのが一般的です。OCIインスタンス上でもCertbotを用いて証明書取得・自動設定が可能です。

**Certbotのインストールと証明書取得（オプション）:**

* Certbotクライアントをインストールします。例: Ubuntuの場合 `sudo apt install -y certbot python3-certbot-nginx`。Rockyの場合は`sudo dnf install -y certbot python3-certbot-nginx`。
* Nginxプラグインを使って証明書を取得し、Nginx設定を自動で変更します。

  ```bash
  sudo certbot --nginx -d example.com -d www.example.com \
               -d blog.example.com -d app.example.com
  ```

  上記では一度に複数ドメイン（およびサブドメイン）を指定しています。対話に従い進めると、自動的に各サーバブロックに証明書パスの設定とポート443でのlistenが追記されます。完了後、https\://〜 で各サイトにアクセスしてみて、証明書が有効であることを確認してください。Certbotは証明書の自動更新も行ってくれます（`/etc/cron.d/certbot`に定期実行設定あり）。

> **注意:** Certbotの自動設定はサーバブロックの構成によっては適切に動作しない場合があります。その際は手動で`ssl_certificate`ディレクティブ等を追加してください（Let's Encrypt証明書は`/etc/letsencrypt/live/<ドメイン>/`に配置されます）。

## 10. サーバの起動と最終テスト

すべての構築手順を終えたら、サーバを再起動して各サービスが自動起動するか、ウェブサイトが問題なく動作するか確認します。

* **サーバの再起動:**

  ```bash
  sudo reboot
  ```

  再起動後、数十秒待ってから再度SSHで接続します（またはOracle Cloudコンソール上でインスタンスの「実行中」ステータスを確認）。

* **サービスのステータス確認:** ログイン後、以下のコマンドで主要なサービスが正常に起動していることを確認します。

  ```bash
  sudo systemctl status nginx
  sudo systemctl status mariadb    # (WordPress使用の場合)
  sudo systemctl status php-fpm    # (WordPress使用の場合)
  pm2 list                         # (Node.js使用の場合、pm2でプロセスが復元されているか)
  ```

  すべて`active (running)`もしくはPM2プロセスが`online`になっていればOKです。

* **ウェブ動作確認:** ブラウザから各サイトにアクセスし、以下をチェックします。

  * 静的サイト (例: [http://example.com](http://example.com)) が正しく表示されること。
  * WordPressサイト (例: [http://blog.example.com](http://blog.example.com)) にアクセスし、正常にページが表示されログインや投稿が行えること。
  * Node.jsアプリ (例: [http://app.example.com](http://app.example.com)) が期待通り応答すること。

* **DNSとドメインの確認:** 独自ドメインでのアクセスがうまくいかない場合、`ping ドメイン名`や`dig ドメイン名`で正しくサーバのIPを引けているか確認します。時間の問題であれば少し待って再度試してみてください。

* **ログの確認:** 何か動作がおかしい場合、以下のログファイルを参考に問題を切り分けます。

  * `/var/log/nginx/*.log` (アクセスログ・エラーログ)
  * `/var/log/mysql/` または `/var/log/mariadb/` 以下のログ (データベースエラー)
  * `/var/log/php-fpm/...` (PHPのエラー)
  * Node.jsアプリのログ（PM2経由なら `pm2 logs <名前>` で表示可能）