Xserver VPSにReact+ExpressのWebアプリをデプロイする方法

Xserver VPSにReact + Express環境を構築する

本ページはプロモーションが含まれています

Xserver VPSを使ってReactアプリをデプロイする方法を解説します。

目次

デプロイするReactアプリの構成

今回デプロイするReactアプリの構成は以下の通りです。

ソフトウェアバージョン
React18.2.0
Node.js18.18.0
Express4.19.2
MySQL8.0
Nginx1.20.1
React + Expressアプリの構成

Reactアプリをデプロイする手順

上記のReactアプリをXserver VPSにデプロイしていきます。

Xserver VPSにはReact環境を一発で構築してくれるテンプレートは用意されていないので、一から環境構築していきます。

Xserver VPSに申し込む

Xserver VPSの契約がまだの方は以下の手順で申し込みができます。

【7月29日17:00まで】月額581円〜!
最大30%OFFキャンペーン

Xserver VPSの公式サイトはこちら

まだXserver VPSを契約していない方は、Xserver VPSの公式サイトから申し込み手続きをします。

公式サイトの「お申し込みはこちら」をクリックしてください。

すでにXserver VPSをお申し込み済みの方はOS再インストールから好きなOSを選んでください。

OS再インストールを行うと運用中のサーバーは一度リセットされてしまいます。申し込んでいるサーバーで別のアプリケーションを運用中の方は新しくサーバーを追加申し込みしてください。

Xserver VPSの申し込みボタン
Xserver VPSの申し込みボタン

すでにXserverアカウントを持っている方は「ログイン」初めて申し込む方は「すぐにスタート!新規お申込み」をクリックしてください。

お申し込みフォームの選択ボタン
お申し込みフォームの選択ボタン

申し込みフォームが表示されます。

STEP
お客様情報を入力する

Xserverアカウントを作成するために、お客様情報を入力します。

必要項目を入力しましょう。

お客様情報の入力画面
お客様情報の入力画面

入力が完了したら、「次へ進む」をクリックしてください。

続いて、本人認証のために確認コードがメールで送られます。

Xserverから届いた確認コード
Xserverから届いた確認コード

メールを確認して、確認コードを入力しましょう。

確認コードの入力画面
確認コードの入力画面

最後に入力内容を確認して、問題がなければ「この内容で登録しサーバー申し込みへ進む」をクリックします。

Xserverアカウントの確認画面

これでシン・アカウントの作成は完了です。

STEP
お申し込み内容を入力する

続いて、VPSの申し込みをします。

こちらも必要項目を入力していきます。

Xserver VPSのお申し込み画面
Xserver VPSのお申し込み画面

今回は「CentOS」を使用します。皆さんはお好きなOSを選択してください。

rootパスワードは後ほど必要になりますので、忘れないようにどこかに控えておきましょう。

入力が完了したら、「お申し込み内容を確認する」をクリックしてください。

確認画面で申し込み内容を確認します。

Xserver VPSのお申し込み確認画面
Xserver VPSのお申し込み確認画面

問題がなければ、「お支払いへ進む」をクリックしてください。

STEP
お支払い情報を入力する

支払い設定を行います。

Xserver VPSではクレジットカード決済とあと払い(ペイディ)に対応しています。

お支払い設定画面
お支払い設定画面

支払い方法を選択して、「決済画面へ進む」をクリックします。

クレジットカード情報の入力画面
クレジットカード情報の入力画面

クレジットカード情報を入力して、「確認画面へ進む」をクリックしてください。

クレジットカード払いの確認画面
クレジットカード払いの確認画面

内容を確認して、問題がなければ「支払いをする」をクリックしてください。

これでXserver VPSの申し込みは完了です。

ポートの解放設定を行う

続いて、ポートの解放設定を行います。

Xserver VPSではポートの解放設定をVPSパネルの「パケットフィルター設定」で行います。9

パケットフィルター設定ボタン
パケットフィルター設定ボタン

パケットフィルター設定が「ONにする(推奨)」になっていることを確認してください。

Xserver VPSのパケットフィルター設定
Xserver VPSのパケットフィルター設定

「パケットフィルター設定を追加する」をクリックして「SSH」と「Web」、「MySQL」を追加してください。

SSHポートの許可設定
SSHポートの許可設定

これでポートの解放設定は完了です。

独自ドメインの設定

まだ独自ドメインを取得していない方はVPS管理から「ドメイン取得」をクリックしてください。

ドメイン取得ボタン
ドメイン取得ボタン

すでに取得済みの方は「取得した独自ドメインをサーバーと紐つける」に飛んでください。

取得したいドメイン名を入力希望のドメイン末尾を選択して、「ドメインを検索する」をクリックしてください。

Xserverドメインのドメイン検索画面
Xserverドメインのドメイン検索画面

取得可能なドメイン一覧が表示されます。

希望のドメインにチェックを入れ利用規約に同意して、「お申し込み内容の確認と支払いへ進む」をクリックしてください。

ドメイン検索結果画面
ドメイン検索結果画面

内容を確認して、支払い方法を選択します。

支払い方法選択画面

「支払いをする」をクリックしてください。

クレジットカードの支払いボタン
クレジットカードの支払いボタン

これで独自ドメインが取得できました。

支払い完了画面
支払い完了画面

取得した独自ドメインをサーバーと紐つける

取得した独自ドメインをサーバーと紐つけます。

VPS管理画面の「DNS設定」をクリックしてください。

Xserver VPSのDNS設定ボタン
Xserver VPSのDNS設定ボタン

「ドメインの追加」をクリックします。

Xserver VPSのドメイン追加ボタン
Xserver VPSのドメイン追加ボタン

取得したドメインを入力してください。

DNS設定のドメイン名入力画面
DNS設定のドメイン名入力画面

追加したドメイン名の「選択する」をクリックしてください。

DNS設定のドメイン選択画面
DNS設定のドメイン選択画面

「DNSレコード設定の追加」をクリックします。

DNSレコードの追加ボタン
DNSレコードの追加ボタン

「種別」に「A」を選択し、「内容」にサーバーのIPアドレスを入力してください。

DNSレコード追加画面
DNSレコード追加画面

「確認画面へ進む」をクリックします。

DNSレコードとは?

DNSレコードは、インターネット上のWebサイトやメールなどのサービスを見つけるための指示書のようなものです。

各Webサイトには、それぞれに割り当てられた一意のIPアドレスがあります。

DNSレコードは、これらのIPアドレスを人が覚えやすいドメイン名(例:www.example.com)に関連付ける役割を持ちます。

つまり、DNSレコードは、特定のドメインがどのIPアドレスに関連付けられているかを示しています。

上記で設定した「A」レコードは「アドレス」の略であり、DNSレコードの最も基本的な種類です。与えられたドメインのIP アドレスを示しています。

内容を確認して、「設定を追加する」をクリックしてください。

追加するDNS設定の確認画面
追加するDNS設定の確認画面

これでDNS設定は完了です。

DNS設定の追加完了画面
DNS設定の追加完了画面

DNSの設定は即時反映されるわけではなく、数時間から長ければ72時間ほどかかる場合もあります。

SSH接続してみる

VPSの契約が完了して、ポートの解放設定ができたらSSH接続してみます。

ssh root@{IPアドレス}

IPアドレスはVPS管理ページに記載されています。

パスワードはVPSのお申し込み時に設定した「rootパスワード」です。

Xserver VPSのVPSパネル
Xserver VPSのVPSパネル

今回はReactの実行環境を構築することに重きを置いていますので、rootログインの禁止や鍵交換方式の認証設定などSSH周りの設定は省略します。

ログインできたら何はともあれパッケージを更新しておきます。

yum update -y

Nginxインストール

今回はWebサーバーにNginxを選びました。

yum install -y epel-release
yum install -y nginx
systemctl start nginx
systemctl enable nginx

無事にインストールできているか確認しましょう。IPアドレスにブラウザからアクセスしてみます。

HTTP Server Test Page
HTTP Server Test Page

正常にインストールされています。

MySQLのインストール

DBサーバーとしてMySQLをインストールします。

yum install -y mysql-server

MySQLを起動し、有効化します。

systemctl start mysqld
systemctl enable mysqld

MySQLの初期設定

先にMySQLの基本的なセキュリティ設定を行います。

mysql_secure_installation

セキュリティに関する設定を順に聞いてくれますので、順に答えていきます。

所属するプロジェクトのセキュリティポリシーやお好みで設定してください。

mysql_secure_installationで設定可能な設定項目

  • root ユーザーのパスワードの変更
  • VALIDATE PASSWORD プラグインのインストール
  • ポリシーに沿った root ユーザーパスワードの設定 (VALIDATE PASSWORD プラグインをインストールした場合)
  • anonymous ユーザーの削除
  • リモートホストから root ユーザーでログインするのを禁止する
  • testデータベースの削除 (存在する場合)

続いて、データベースとユーザーを作成します。

MySQLにログインします。

mysql -u root -p

以下のコマンドをMySQLシェルで実行します。

CREATE DATABASE your_database_name;

CREATE USER 'your_username'@'localhost' IDENTIFIED BY 'your_password';

GRANT ALL PRIVILEGES ON your_database_name.* TO 'your_username'@'localhost';

FLUSH PRIVILEGES;

your_database_nameデータベース名とyour_usernameMySQLユーザー名、your_passwordパスワードはご自身の環境に合わせて入力してください。

データベースが正常に作成されているか確認します。

SHOW databases;

これでMySQLの環境設定は完了です。

Node.jsとPM2のインストール

Node.jsとPM2をインストールしていきます。

# NodeSourceリポジトリを追加
curl -fsSL https://rpm.nodesource.com/setup_18.x | sudo bash -

# Node.jsをインストール
yum install -y nodejs

# PM2をグローバルにインストール
npm install -g pm2

アプリケーションファイルをデプロイ

ローカルで開発したアプリケーションをビルドして、VPSにアップロードします。

React(フロントエンド)をビルド&デプロイ

フロントエンドをビルドします。手元のReactアプリのプロジェクトファイルがあるディレクトリに移動して、npm run buildしてください。

npm install
npm run build

ビルドが完了したら、dist ディレクトリが生成されますので、中身をVPSのルートディレクトリアップロードします。

今回は/var/www/html/をドキュメントルートにします。

mkdir -p /var/www/html/
scp -r /path/to/your/react-app/dist/* root@your_vps_ip:/var/www/html/

{your_vps_ip}の部分はご自身のVPSに割り当てられているIPアドレスにしてください。

Express(バックエンド)をビルド&デプロイ

続いてExpressアプリをVPSにアップロードします。

Expressアプリのプロジェクトファイルがあるディレクトリに移動して、npm installしておきます。

npm install

/var/www/api ディレクトリを作成して、VPSにアップロードします。

mkdir -p /var/www/api/
scp -r /path/to/your/express-app your_user@your_vps_ip:/var/www/api

今回は/var/www/配下にapi ディレクトリを作成し、そこにアップロードしましたが、任意のディレクトリで問題ありません。

PM2でバックエンドを起動

PM2を使ってExpressアプリを起動します。

cd /var/www/api

pm2 start index.js --name your-app-name

pm2 startup

pm2 save

Nginxの設定

先にVimをインストールします。

yum install -y vim

Nginxの設定ファイルにドキュメントルートの設定とサーバー名の設定を追加します。

vim /etc/nginx/nginx.conf

serverブロックの41行目にあるserver_name ディレクティブに独自ドメインを入力し、さらに42行目にあるデフォルトのrootディレクティブをコメントアウトして、43行目にドキュメントルートの設定を追加しています。

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 4096;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80;
        listen       [::]:80;
        server_name  example.com;
        #root        /usr/share/nginx/html;
        root         /var/www/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }

# Settings for a TLS enabled server.
#
#    server {
#        listen       443 ssl http2;
#        listen       [::]:443 ssl http2;
#        server_name  _;
#        root         /usr/share/nginx/html;
#
#        ssl_certificate "/etc/pki/nginx/server.crt";
#        ssl_certificate_key "/etc/pki/nginx/private/server.key";
#        ssl_session_cache shared:SSL:1m;
#        ssl_session_timeout  10m;
#        ssl_ciphers PROFILE=SYSTEM;
#        ssl_prefer_server_ciphers on;
#
#        # Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;
#
#        error_page 404 /404.html;
#            location = /40x.html {
#        }
#
#        error_page 500 502 503 504 /50x.html;
#            location = /50x.html {
#        }
#    }

}

Nginxを再起動します。

systemctl restart nginx

ブラウザからIPアドレスにアクセスしてみてください。

アップロードしたindex.htmlが表示されると思います。

リバースプロキシの設定

バックエンドに作成したAPIサーバーのリバースプロキシの設定も行います。

56行目にリバースプロキシ設定を追加しています。

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 4096;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80;
        listen       [::]:80;
        server_name  example.com;
        #root        /usr/share/nginx/html;
        root         /var/www/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }

     #リバースプロキシ設定を追加
        location /api {
           proxy_pass http://localhost:3000;
           proxy_http_version 1.1;
           proxy_set_header Upgrade $http_upgrade;
           proxy_set_header Connection 'upgrade';
           proxy_set_header Host $host;
           proxy_cache_bypass $http_upgrade;
        }
    }

# Settings for a TLS enabled server.
#
#    server {
#        listen       443 ssl http2;
#        listen       [::]:443 ssl http2;
#        server_name  _;
#        root         /usr/share/nginx/html;
#
#        ssl_certificate "/etc/pki/nginx/server.crt";
#        ssl_certificate_key "/etc/pki/nginx/private/server.key";
#        ssl_session_cache shared:SSL:1m;
#        ssl_session_timeout  10m;
#        ssl_ciphers PROFILE=SYSTEM;
#        ssl_prefer_server_ciphers on;
#
#        # Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;
#
#        error_page 404 /404.html;
#            location = /40x.html {
#        }
#
#        error_page 500 502 503 504 /50x.html;
#            location = /50x.html {
#        }
#    }

}

リバースプロキシサーバーが正常に動作しているか確認します。

APIのエンドポイントにcurlコマンドでアクセスしてください。

curl -i http://your_domain_or_ip/api/your_endpoint

{your_domain_or_ip}と{your_endpoint}はご自身のIPアドレスとアプリケーションで設定しているエンドポイントを入力してください。

HTTP/1.1 200 OK と結果が返ってくれば正常に動作しています。

SSL設定

SSL化対応もしておきます。

今回はLet’s Encryptの証明書を使用します。

まずは、certbotプログラムをインストールします。

yum install -y certbot python3-certbot-nginx

cartbotコマンドを使ってSSL証明書を取得します。

certbot --nginx -d your_domain.com

更新やセキュリティ通知を受け取るメールアドレスを登録します。

Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): 

利用規約について同意することを求められます。Yと入力します。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.4-April-3-2024.pdf. You must agree in
order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y

次に電子フロンティア財団とメールアドレス共有し、キャンペーン情報などのDMを受け取るか聞かれます。基本的にNoで良いでしょう。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o:N

これでCertbotが自動的にNginxの設定ファイルを更新し、SSLを有効にしてくれます。

ブラウザから「https:// {your_domain}」にアクセスしてみてください。正常にアクセスできると思います。

ファイアウォール設定

続いて、ファイアウォールの設定をします。

ファイアウォールを有効化しておきます。

systemctl enable firewalld

ファイアウォールを起動します。

systemctl start firewalld

httpサーバーにファイアウォールを設定します。

firewall-cmd --add-service=http --permanent
firewall-cmd --reload

これでReact+Express環境の構築作業がすべて完了しました。

まとめ

今回はReact + Expressで作成したアプリケーションをVPSにデプロイする方法を紹介しました。

SSLの設定周りが複雑かなと思っていたのですが、Cerbotを使えば非常に簡単に証明書の取得から設定まで行うことができました。

個人的に少し詰まってしまったところといえば、MySQL8.0以降はパスワード認証形式が変わりNodeのMySQLクライアントとの接続がうまくいかなったところですね。

対応としてはMySQLのバージョンを5.7にするかNodeのMySQLをクライアントに「MySQL2」を採用するかどちらですが、今回は後者を選択しました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

志賀裕一のアバター 志賀裕一 サーバーチョイス 編集者

Web開発歴6年のフリーランスエンジニア。大学在学中から教育系Webメディアを運営するスタートアップにて、Webディレクターとして従事。独立からこれまでに多くのコーポレートサイトやCRM、予約システムなどのシステム開発、オウンドメディア運営を経験。20以上のレンタルサーバーの使用経験を持つ。

目次