はじめに:LinuxサーバーへのWebアプリデプロイの全体像
自作したHTML5サイトや、React・Vue・Viteなどで開発したWebアプリケーション(SPA: Single Page Application)をインターネット上に公開する際、VPSやクラウドなどのLinuxサーバーを自前で構築してデプロイする手法は、インフラの基礎構造を理解する上で非常に重要です。
PaaS(VercelやNetlifyなど)を使えば手軽に公開できますが、独自のサーバー設定、きめ細やかなセキュリティ管理、パフォーマンスチューニング、コスト最適化を行うには、Linuxサーバーでの運用スキルが欠かせません。
本記事で構築する環境・前提条件(Ubuntu / Nginx)
本手順書では、初学者から実務開発者まで最も扱いやすく、情報量も豊富な構成を前提に進めます。
- サーバーOS: Ubuntu Server 22.04 LTS / 24.04 LTS
- Webサーバー: Nginx(エンジンエックス)
- 対象アプリケーション: 静的HTML5/CSS/JavaScript、またはビルド済みのSPA(React, Vue, Svelte, Next.js static export など)
- 必須の準備物:
- VPSまたはクラウドインスタンス(ConoHa VPS, さくらのVPS, さくらのクラウド, Linode等)
- 管理者(root)権限
- 独自ドメイン(お名前.com、Cloudflare等で取得済みのもの)
なお、サーバーOSの選定基準について詳しく知りたい方は「Web開発環境のOSはCentOSとUbuntuどっちがおすすめ?」を、VPSではなくAWSの仮想サーバー上で環境を立ち上げたい方は「【初心者向け】AWS EC2を使ったモダンなWebサーバー構築入門」も参考にしてください。
デプロイ完了までのロードマップ(6ステップ)
安全かつ確実にWebアプリを本番公開するために、以下の6つのステップに沿って構築を進めます。
| ステップ | 作業内容 | 主な目的・ポイント |
| STEP 1 | サーバーの初期セットアップ | 一般ユーザー作成、SSH鍵認証、UFWファイアウォールによるセキュリティ強化 |
| STEP 2 | Webサーバー(Nginx)の導入 | Nginxのインストール、サービス起動、自動起動の有効化 |
| STEP 3 | Webアプリのファイル配置 | /var/www/ 配下のディレクトリ作成、ファイルの転送、所有権・パーミッション設定 |
| STEP 4 | Nginxの設定(バーチャルホスト) | サーバーブロックの記述、SPAでリロード時に404を出さないためのルーティング設定 |
| STEP 5 | 独自ドメイン・SSL化(HTTPS) | DNSレコード設定、Certbot(Let’s Encrypt)による無料SSL証明書の発行 |
| STEP 6 | トラブルシューティング | 403 Forbiddenやログ確認方法の把握 |
【STEP 1】サーバーの初期セットアップとセキュリティ対策
新しいLinuxサーバーを立ち上げたら、Webサーバーを導入する前にセキュリティの基礎を固めます。初期状態のままrootユーザーで作業を続けたり、パスワード認証のSSHを放置したりすると、不正アクセスや総当たり攻撃(ブルートフォース攻撃)のリスクが高まります。
パッケージの最新化(apt update & upgrade)
まずはサーバーにインストールされている全パッケージを最新状態に更新します。
Bash
sudo apt update && sudo apt upgrade -y
作業用一般ユーザーの作成とsudo権限付与
日常的な運用で root ユーザーを直接使い続けるのは、誤操作やセキュリティ上のリスクがあります。作業用の一般ユーザーを作成し、管理者権限(sudo権限)を付与します。
Bash
# ユーザー「deployer」を作成(ユーザー名は任意)
sudo adduser deployer
# 作成したユーザーをsudoグループに追加
sudo usermod -aG sudo deployer
SSH公開鍵認証の設定とパスワードログインの無効化
パスワード認証を廃止し、公開鍵認証のみでSSH接続できるように設定します。
1. ローカル端末でSSHキーペアを作成(未作成の場合)
Bash
# ローカルPCで実行
ssh-keygen -t ed25519 -C "your_email@example.com"
2. 公開鍵をサーバーに登録
Bash
# ローカルPCから公開鍵を転送(例: ユーザー名 deployer, サーバーIP 192.0.2.1)
ssh-copy-id -i ~/.ssh/id_ed25519.pub deployer@192.0.2.1
3. サーバー側でパスワード認証とroot直接ログインを無効化
Bash
sudo nano /etc/ssh/sshd_config
設定ファイル内の以下の項目を変更・確認します。
Plaintext
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
設定を反映させるためにSSHデーモンを再起動します。
Bash
sudo systemctl restart ssh
注意: 現在の接続を切断する前に、別のターミナルウィンドウを開いて
ssh deployer@192.0.2.1で鍵認証ログインできることを必ず確認してください。
UFWによるファイアウォール設定(SSH / HTTP / HTTPS)
Ubuntu標準のファイアウォール管理ツール「UFW」を使い、必要な通信ポートのみを開放します。
Bash
# 1. すべての受信を拒否、送信を許可(デフォルトルール)
sudo ufw default deny incoming
sudo ufw default allow outgoing
# 2. SSH接続を許可(※これを忘れてUFWを有効化するとサーバーから締め出されます)
sudo ufw allow OpenSSH
# 3. Web通信用ポート(80: HTTP, 443: HTTPS)を許可
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# 4. UFWの有効化
sudo ufw enable
# 5. 設定状況の確認
sudo ufw status verbose
ポート開放やセキュリティ設定の仕組みについてさらに詳しく知りたい場合や、チャット機能・リアルタイム通知などWebSocketを使ったアプリを運用する際のポート管理については「WebSocket通信時のポート開放とファイアウォール設定の基礎」も参考にしてください。
【STEP 2】Webサーバー(Nginx)の導入と起動確認
Webサーバーには、世界中で広く採用されているオープンソースソフトウェア「Nginx(エンジンエックス)」を使用します。
Nginxはイベント駆動型のアーキテクチャを採用しており、大量の同時接続や静的ファイルの配信、リバースプロキシ処理において非常に優れたパフォーマンスを発揮します。静的HTML5やSPA(Single Page Application)の配信サーバーとしても最適です。
Webサーバーの選定にあたり、従来標準的だったApacheとの詳細なアーキテクチャの違いや使い分けを知りたい場合は「【Webサーバー構築】ApacheとNginxの違いと選び方を比較」もご覧ください。
Nginxのインストールと自動起動設定
APTパッケージマネージャーを使用してNginxをインストールし、サーバー再起動時にも自動的に立ち上がるよう設定します。
Bash
# Nginxのインストール
sudo apt install nginx -y
# サービスの起動
sudo systemctl start nginx
# サーバー起動時の自動立ち上げを有効化
sudo systemctl enable nginx
# 稼働ステータスの確認(Active: active (running) となっていれば成功)
sudo systemctl status nginx
IPアドレスにアクセスしてデフォルトページの表示確認
サービスが正常に起動したら、ブラウザからサーバーのパブリックIPアドレスに直接アクセスしてみます。
Plaintext
http://<あなたのサーバーIPアドレス>/
ブラウザ上に「Welcome to nginx!」という初期画面が表示されれば、Webサーバーとしての基本機能が正常に稼働しています。
【STEP 3】Webアプリ(HTML5 / SPA)のファイル配置
Webサーバーが正常に起動したら、公開したいHTML5ファイルやビルド済みのWebアプリケーション成果物をサーバー内に配置します。
公開用ディレクトリの作成(/var/www/配下の設計)
Linux環境では、Webサイトの公開ファイルは /var/www/ ディレクトリ配下にドメイン名やプロジェクト名ごとのディレクトリを作成して管理するのが標準的な作法です。
Bash
# ドメイン名またはプロジェクト名のディレクトリを作成(例: example.com)
sudo mkdir -p /var/www/example.com/html
ファイルの転送手順(Git clone / SCP / rsync)
Webアプリのファイルをサーバーに配置する方法は、開発フローに合わせて主に以下のいずれかを選択します。
方法1: Gitリポジトリからビルド成果物を取得する場合
GitHubなどのリモートリポジトリから直接ソースコードを取得してサーバー上でビルド、またはビルド済みブランチをクローンします。
Bash
cd /var/www/example.com/html
git clone https://github.com/your-account/your-app.git .
方法2: ローカルPCからSCPコマンドでビルド成果物を直接転送する場合
ReactやVue(Vite等)を使ってローカルでビルド(npm run build)した成果物(dist や build フォルダの中身)を直接サーバーに転送します。
Bash
# ローカルPCのターミナルで実行(例: dist配下の全ファイルをサーバーへ転送)
scp -r ./dist/* deployer@<サーバーIPアドレス>:/var/www/example.com/html/
ファイル所有権とパーミッションの設定(403エラー対策)
デプロイ後にブラウザからアクセスした際、最も多く発生するトラブルが「403 Forbidden(閲覧権限なし)」エラーです。これは、Nginxの実行プロセス(通常は www-data ユーザー)が対象ファイルやディレクトリを読み取れない場合に発生します。
公開ディレクトリの所有者をWebサーバー実行ユーザーに設定し、適切な権限を付与します。
Bash
# ディレクトリとファイルの所有者を Nginx の実行ユーザー「www-data」に変更
sudo chown -R www-data:www-data /var/www/example.com/html
# ディレクトリの権限を 755(所有者は書込可能、他は読取・実行可能)に設定
sudo chmod -R 755 /var/www/example.com/html
ポイント: デプロイ作業ユーザー(
deployerなど)からも編集可能にしたい場合は、作業ユーザーをwww-dataグループに所属させ、グループ書き込み権限(775)を付与する運用も有効です。
【STEP 4】Nginxの設定(バーチャルホスト & SPAルーティング対策)
配置したアプリケーションをドメイン経由で正しく配信するために、Nginxの設定ファイル(サーバーブロック)を作成します。
特にReact、Vue、SvelteなどのSPA(Single Page Application)では、ページをリロードした際に404エラーが発生する問題を解決するためのルーティング設定が必須となります。
設定ファイル(サーバーブロック)の新規作成
UbuntuのNginxでは、設定ファイルを /etc/nginx/sites-available/ に作成し、有効化したいファイルのみを /etc/nginx/sites-enabled/ へシンボリックリンクで紐付ける設計になっています。
まずは新しい設定ファイルを作成して開きます。
Bash
sudo nano /etc/nginx/sites-available/example.com
SPAで必須のルーティング設定(try_filesディレクティブ)
設定ファイル内に以下のブロックを記述します(example.com やパスはご自身の環境に合わせて置き換えてください)。
Nginx
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com/html;
index index.html index.htm;
location / {
# 実ファイルが存在すればそれを返し、なければ /index.html にフォールバック
try_files $uri $uri/ /index.html;
}
# セキュリティ向上のための隠しファイル非表示設定
location ~ /\. {
deny all;
}
# 静的アセットのキャッシュ設定(パフォーマンス向上)
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
# エラーログとアクセスログの設定
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
}
なぜ try_files $uri $uri/ /index.html; が重要なのか?
HTML5の「History API」を採用しているモダンなWebフロントエンドでは、ブラウザ側のJavaScriptがURL(例: [example.com/dashboard](https://example.com/dashboard))を擬似的に書き換えて画面遷移を行っています。
しかし、そのURLのままユーザーがページを再読み込み(リロード)したり、ブックマークから直接アクセスしたりすると、Webサーバー(Nginx)は /dashboard という実在しないディレクトリやファイルを探しに行き、404 Not Foundを返してしまいます。
try_files $uri $uri/ /index.html; を記述しておくことで、「リクエストされた実ファイル($uri)やディレクトリ($uri/)が存在しない場合は、すべて index.html に処理を委譲する」という挙動になり、SPA側で正常にルーティングが処理されます。
設定のシンボリックリンク作成と構文チェック(nginx -t)
作成した設定ファイルを有効化し、構文にミスがないか検証した上でNginxを再読み込みします。
Bash
# 1. sites-enabled にシンボリックリンクを作成して有効化
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
# 2. 初期設定(default)のシンボリックリンクを削除(競合を防ぐため)
sudo rm /etc/nginx/sites-enabled/default
# 3. Nginx設定の構文チェック
sudo nginx -t
nginx -t を実行し、ターミナルに以下のように表示されれば設定は正常です。
Plaintext
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
問題がなければ、Nginxに設定をリロード(再読み込み)させます。
Bash
sudo systemctl reload nginx
【STEP 5】独自ドメインの設定と無料SSL化(HTTPS対応)
Webアプリケーションを本番環境で公開するにあたり、独自ドメインの設定とHTTPS(SSL/TLS暗号化)化はセキュリティおよびSEOの両面で不可欠です。
現在では「Let’s Encrypt」を利用することで、無料で信頼性の高いSSLサーバー証明書を取得し、自動更新を設定できます。
ドメインの名前解決や通信暗号化の仕組みを基礎から学びたい方は、「【図解】DNSの仕組みとは?Webサイトがブラウザに表示されるまで」や「SSL/TLS証明書の仕組みとWebサーバーへの設定手順まとめ」もあわせてご覧ください。
DNSのAレコード設定と浸透確認
ドメイン管理サービス(お名前.com、Cloudflare、Route 53など)のDNS設定画面を開き、サーバーのパブリックIPアドレスを紐付ける「Aレコード」を設定します。
| タイプ | ホスト名(名前) | 値(レコード値) | TTL |
| A | @(または空欄) | <あなたのサーバーIPアドレス> | 300〜3600 |
| A | www | <あなたのサーバーIPアドレス> | 300〜3600 |
DNSレコードが正常に反映されているか、ローカルPCのターミナルから確認します。
Bash
# dig または nslookup コマンドで確認
dig example.com +short
設定したサーバーのIPアドレスが返ってくれば、DNSの名前解決が正常に機能しています。
Certbot(Let’s Encrypt)の導入とSSL証明書の発行
Ubuntu公式リポジトリまたはSnap経由で、Let’s Encryptの自動発行ツール「Certbot」をインストールします。
Bash
# CertbotおよびNginx用プラグインのインストール
sudo apt install certbot python3-certbot-nginx -y
# SSL証明書の発行とNginx設定の自動更新
sudo certbot --nginx -d example.com -d www.example.com
実行中にメールアドレスの入力と利用規約への同意(Y)を求められます。また、「HTTPアクセスを自動的にHTTPSへリダイレクトするか?」と聞かれた場合は「2: Redirect」を選択します。
コマンドが成功すると、Nginxの設定ファイル(/etc/nginx/sites-available/example.com)にSSL関連の設定が自動追記されます。
HTTPSリダイレクトの動作確認と証明書の自動更新テスト
ブラウザを開き、
にアクセスします。URLバーに鍵マークが表示され、HTTPでアクセスした際も自動的にHTTPSへ転送されることを確認してください。
Let’s Encryptの証明書有効期限は90日間ですが、Certbot導入時に systemd タイマーまたは cron による自動更新タスクが自動登録されます。
自動更新が正常に機能するか、テストコマンド(Dry-run)を実行して確認します。
Bash
# 自動更新プロセスのシミュレーション実行
sudo certbot renew --dry-run
ターミナルに Congratulations, all simulated renewals succeeded と表示されれば、今後の証明書更新も全自動で行われます。
デプロイ時によくあるトラブルと対処法
LinuxサーバーにWebアプリをデプロイする際、設定のわずかな記述ミスや権限の不整合によってエラーが発生することがあります。代表的なトラブルの原因と解決手順をまとめました。
403 Forbidden(アクセス権限がない)が出た場合
ブラウザに 403 Forbidden が表示される場合、Nginxの実行ユーザー(www-data)に対象ファイルや親ディレクトリの読み取り・実行権限がありません。
主な原因と解決策:
- 公開ディレクトリの所有者設定ミスBash
sudo chown -R www-data:www-data /var/www/example.com/html - パーミッション不足 親ディレクトリ(
/var/wwwや/var/www/example.com)の実行権限(+x)が欠落していないか確認します。Bashsudo chmod 755 /var/www sudo chmod 755 /var/www/example.com sudo chmod -R 755 /var/www/example.com/html - index.html の指定ミス Nginx設定ファイルの
index index.html;の指定と、実際のファイル名の大文字・小文字が一致しているか確認してください。
404 Not Found(SPAのページ遷移後に再読み込みすると消える)が出た場合
トップページ(/)は正常に表示されるのに、下層ページ(例: /about や /dashboard)でリロードすると 404 Not Found になる現象です。
主な原因と解決策: Nginxのサーバーブロック内に try_files ディレクティブが正しく設定されていないことが原因です。
/etc/nginx/sites-available/example.com の location / ブロックを確認し、以下のように記述されているかチェックしてください。
Nginx
location / {
try_files $uri $uri/ /index.html;
}
修正後は必ず構文チェックを行い、Nginxをリロードします。
Bash
sudo nginx -t && sudo systemctl reload nginx
502 Bad Gateway / 接続できない場合のログ確認手順
設定を変更したのに反映されない場合や、サーバーへの接続が拒否される場合は、Nginxのエラーログをリアルタイムで確認しながらブラウザを更新することで、正確な原因を特定できます。
Bash
# Nginxのエラーログをリアルタイム表示
sudo tail -f /var/log/nginx/error.log
# サイト固有のエラーログ(設定している場合)
sudo tail -f /var/log/nginx/example.com.error.log
また、ファイアウォール(UFW)でポートがブロックされていないかも合わせて確認します。
Bash
sudo ufw status verbose
80/tcp および 443/tcp が ALLOW になっていることを確認してください。
まとめ・次のステップ
本記事では、Linux(Ubuntu)サーバーの初期セキュリティ設定から、Nginxの導入、Webアプリ・SPAのファイル配置、ルーティング対策、そして独自ドメインとLet’s EncryptによるSSL化までの全手順を解説しました。
自前でLinuxサーバーを立ち上げてWebアプリを公開する経験は、PaaS(VercelやNetlify等)の内部でどのような処理が行われているのかを構造的に理解するための大きな足がかりとなります。
定期的な保守・バックアップとスキルアップへの展望
本番運用を安定して継続するために、公開後は以下のステップにも取り組んでみてください。
- パッケージの定期アップデート
- セキュリティパッチを適用するため、定期的に
sudo apt update && sudo apt upgradeを実施します。
- セキュリティパッチを適用するため、定期的に
- ログの定期確認とローテーション
- アクセスログやエラーログのサイズ肥大化を防ぐため、
logrotateの設定状況を確認しておきます。
- アクセスログやエラーログのサイズ肥大化を防ぐため、
- CI/CDによるデプロイ自動化
- 毎回手動でファイルを転送する代わりに、GitHub Actionsなどを活用して「
mainブランチにプッシュされたら自動でサーバーにビルド成果物を転送・反映する」パイプラインを組むと、運用効率が劇的に向上します。
- 毎回手動でファイルを転送する代わりに、GitHub Actionsなどを活用して「
Webエンジニアとしてフロントエンドやバックエンドの枠を超え、インフラやネットワークの理解を深めることは、トラブルシューティング能力やシステム設計力の向上に直結します。
さらにインフラ学習の重要性やキャリアへの影響について知りたい方は、「WebエンジニアにLinux知識はどこまで必要?インフラ基礎の重要性」もぜひ参考にしてください。
