【GitHub Actions】XserverにSSHで自動デプロイできるようにしよう

## この記事が役立つ人

GitHub Actions を使用して、Xserver のサーバーに自動でデプロイする手順を解説します。
こんな人に対して向けた記事になっています。
- Xserver上にGitで管理したプロジェクトファイルが置いてある
- GitHub上のリポジトリにPushしたり、マージ（PR）が完了したら自動でデプロイできるようにしたい

また、以下のような方でも読めるような記事となっています。
- Xserverを初めて契約したばかり
- Xserverの試用期間中
- GitHub Actionsを初めて使う（自分で作ったことが無い）

## この記事で実現できること
- mainブランチにpush（マージ）すると自動デプロイが開始される
- GitHub ActionsからXserverにSSH接続し、Xserver側のプロジェクトフォルダでpullする

## 前提条件
- Xserver の契約済みサーバーを持っていること
- GitHub のリポジトリを用意していること
- 既にXserver上にGitでクローンしたプロジェクトフォルダが反映済みであること

また、後続の手順については **実施済みのものは飛ばして構いません。**

## 1. Xserver で SSH 接続を有効化
1. **Xserverのサーバーパネル** にログイン
2. **「SSH設定」** を開く
3. 「SSH設定の変更」で **ON にする**
4. **SSH接続情報を確認**（ホスト名、ユーザー名、ポート番号）

## 2. SSHキーを作成
### 2.1. サーバーパネルでSSH公開鍵を作成
1. Xserverのサーバーパネルから **「SSH設定」** を開く
2. 「公開鍵の登録・更新」で **「登録して秘密鍵をダウンロードする」** を選択（パスフレーズを設定しない方を推奨）
3. 公開鍵を作成後、秘密鍵となるアクセスキーファイルをダウンロード
（内容を後でGitHub Secretsにコピペします）
今後も使う大切なファイルとなりますので、**絶対に無くさない & 他人が見えない場所**に保管してください。

### 2.2. Xserver に接続確認
Macの方はターミナル上などで、Windowsの方はGitBashでも良いのでLinuxで動くプロンプト上で実行してください。
```bash
ssh -i [2.1でダウンロードしたアクセスキーファイルのパス] -p 10022 [ユーザー名]@[ホスト名]
```
ユーザー名とホスト名は、サーバーパネルの「SSH設定」⇒「SSHソフト設定」で確認できます。

:::note info
**例）**
```bash
ssh -i ~/.ssh/example.key -p 10022 name123@sv999.xser.ne.jp
```
:::

## 3. GitHub Secrets にSSH情報を登録
GitHub のリポジトリで **「Settings」→「Secrets and variables」→「Actions」** を開き、以下の情報を登録。

| Name            | Value                  |
|----------------|------------------------|
| SSH_HOST       | `Xserverのホスト名`     |
| SSH_PORT       | `10022` |
| SSH_USERNAME   | `Xserverのユーザー名`   |
| SSH_PRIVATE_KEY | `2.1でダウンロードしたアクセスキー` の内容 |

SSH_PRIVATE_KEYに設定するものは、`-----BEGIN OPENSSH PRIVATE KEY-----`から始まり`-----END OPENSSH PRIVATE KEY-----`で終わるはずです。
上記の文字列も全て含めてコピペしてください。

:::note warn
※ **秘密鍵の管理には注意！**

**秘密鍵の管理についての注意点:**
- 秘密鍵 (`2.1でダウンロードしたアクセスキー`) は **絶対に他人に共有しない**。
- クラウドストレージやリモートリポジトリにアップロードしない。（または厳密な管理ができる共有ドライブなど、チームと相談して保管方法を決めてください）
- 必要がなくなったら、**新しい鍵を生成して古い鍵を無効化する**。
:::

## 4. GitHub Actions のワークフローを作成
（ローカルPCのリポジトリで操作可）
リポジトリ内に `.github/workflows/` が無い場合、フォルダを作成。
リポジトリの `.github/workflows/` に`deploy.yml`を作成し、以下を記入。

```yaml
name: Deploy to Server

on:
  push:
    branches:
      - main  # mainブランチにpushされたときに実行

jobs:
  deploy:
    runs-on: ubuntu-latest  # 実行するOSを指定
    env: # GitHub Secretsから取得した内容で環境変数を設定
      SSH_HOST: ${{ secrets.SSH_HOST }}
      SSH_PORT: ${{ secrets.SSH_PORT }}
      SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
      SSH_USERNAME: ${{ secrets.SSH_USERNAME }}

    steps:
      # コードを取得
      - name: Checkout code
        uses: actions/checkout@v3

      # SSH接続用キーファイルを設定
      - name: Set up SSH key
        run: |
          mkdir -p ~/.ssh
          echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
          chmod 600 ~/.ssh/id_rsa
          ssh-keyscan -p $SSH_PORT -H $SSH_HOST >> ~/.ssh/known_hosts

      # SSH接続を行い、Xserver上でpullしてデプロイを行う
      - name: Deploy to server
        run: |
          ssh -p $SSH_PORT $SSH_USERNAME@$SSH_HOST << 'EOF'
            cd {プロジェクトフォルダのパス} || exit
            git pull origin main || exit
          EOF
```
:::note info
**{プロジェクトフォルダのパス}について**
`{プロジェクトフォルダのパス}`と書いているところを、実際の Xserver上にあるプロジェクトフォルダのパスに書き換えてください。
:::

## 5. 動作確認
1. `main` ブランチにコードを push
2. GitHub Actions の **「Actions」タブ** で実行状況を確認
3. デプロイが成功したかを確認

### トラブルシューティング
デプロイが失敗した場合は、以下の点を確認してください。
- **GitHub Actions のログ**: `Actions` タブでエラーメッセージを確認
- **SSH 接続の確認**: `ssh -p [SSH_PORT] [SSH_USERNAME]@[SSH_HOST]` で手動接続可能か確認
- **Secrets の設定**: GitHub Secrets に正しい値が設定されているか確認。（GitHub上で再度編集を行おうとしても空白になっていますが、これは設定されていない訳ではなく、内容を隠すための正しい動作であり実際には値が設定されています。）
- **ファイアウォール設定**: Xserver側で国外IP制限がある場合、国外IP制限設定をOFFにする
（「SSH設定」の「国外アクセス制限」をOFF）

## まとめ
この方法を使うことで、Xserver に **GitHub Actions を利用した自動デプロイ** が可能になります。
LaravelやWordPressのテーマ更新や静的サイトのデプロイ、Node.jsアプリケーションの自動デプロイなどにも応用できます。ぜひ活用してみてください！