- ブログ
最小構成で始めるAWSデプロイ〜後編:EC2へのSSH接続からデプロイまで〜
2026.01.20 Tue

遅くなりましたが、新年明けましておめでとうございます。
Webエンジニアのsimonです。
本年もしっかりとブログを更新していく予定ですので、ホエールテックをどうぞよろしくお願いいたします。
さて、本記事は前回投稿したこちらの記事の続きになります。
これまでの流れの整理
まずは、ここまでの流れを整理しましょう。
3.EC2サーバーへのSSH接続 〜 デプロイ作業(本記事でやること)
今回はEC2に接続しデプロイ作業を行います。
コマンドによる作業がメインになりますので、前回よりも難しいかもしれませんが恐れずに頑張りましょう!
EC2サーバーへのSSH接続
まずは、作成したEC2サーバーにSSH接続します。
前回作成し、ダウンロードした秘密鍵(.pem)が必要になりますのでご用意ください。
秘密鍵はキーペアを新しく作成したタイミングで自動でダウンロードされていますので、ダウンロードフォルダにあるはずです。

※AWSから再度のダウンロードはできないようになっています
見当たらない場合、EC2インスタンスもしくはキーペアを再度作り直してからダウンロードしてください
まず最初に、ダウンロードした秘密鍵のあるディレクトリを移動します。
(※今回は「Downloads」に秘密鍵がある前提で進めますが、業務などでリモートホストにSSH接続する際にはわかりやすい場所に「Key」フォルダを作ってそこに秘密鍵を保管するようにしてください)
ターミナルを起動し、lsコマンドを実行してください。
ls以下はカレントディレクトリにてlsコマンドを実行した場合の参考例になります。

秘密鍵のある場所に移動します。
cd Downloadsその後、lsコマンドを実行するとダウンロードした秘密鍵(.pem)が表示されるはずです。
次に、以下のコマンドを実行してください。
chmod 400 my-vue-app-key.pemこのコマンドを実行すると、秘密鍵が自分にしか読めない状態になります。
| 要素 | 意味 | 補足 |
| chmod | ファイルの権限を変更するコマンド | – |
| 400 | パーミッション(※) | この数字が「400」の場合は、 所有者だけが「読む」ことを許可する設定となる |
(表の補足)
パーミッション(※)について
→ファイル等の権限に関する設定で、以下のように3桁の数字で「誰が」「何をできるか」を表します
「誰が」
| 桁 | 対象 |
| 1桁目 | 所有者 |
| 2桁目 | グループ |
| 3桁目 | その他 |
「何をできるか」(ベースの数字)
| 数字 | 権限 |
| 4 | 読む(read) |
| 2 | 書く(write) |
| 1 | 実行(execute) |
上記の数字の組み合わせで(足し算)、以下のように実際の権限を設定できます。
「何をできるか」(実際の権限)
| 数字 | 要素 | 意味 |
| 7 | 4 + 2 + 1 | 読む・書く・実行 |
| 6 | 4 + 2 | 読む・書く |
| 5 | 4 + 1 | 読む・実行 |
| 4 | 4 | 読むのみ |
| 0 | なし | 何もできない |
例えば「chmod 644 index.html」とした場合は、index.htmlを
所有者:読み/書きができる
グループ:読むことのみできる
その他ユーザー:読むことのみできる
という権限に設定する、という意味になります。
パーミッションの設定が終わったら、以下のコマンドを実行してEC2サーバーに接続してください。
ssh -i my-vue-app-key.pem ec2-user@<パブリックIP>コマンドの意味は以下の通りです。
| 要素 | 意味 | 補足 |
| ssh | SSH クライアントコマンド | – |
| -i | iidentity file オプション | 使用する秘密鍵を指定 |
| ec2-user | ユーザー名 | 接続先OSのログインユーザー |
| <パブリックIP> | 接続先EC2インスタンスの「パブリックIPアドレス」 | – |
パブリックIPは、作成したインスタンス概要の以下の箇所からコピーできます。

SSH接続の際に
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
と聞かれたら、yesを入力してください。
成功すると、以下のような画面になります。

ここが 「AWS上のサーバーの中」 です。
💡SSH接続で、「Permission denied (publickey)」が出た時
原因は概ね以下のどれかです
・pemファイルが違う(別インスタンスの鍵orファイル名のスペルミス)
・ユーザー名が違う
・インスタンス作成時にそのpemを紐づけてない
🔧 確認
EC2 → 対象インスタンス → 「詳細」に キーペア名 が出ているので、それと手元のpemが一致してるかチェック。

ここまでをおさらいしておきましょう。
今は
「まっさらなAmazon Linux 2023のPCを1台借りて、
黒い画面(ターミナル等)で直接操作している」
状態です。
ここから
・OSの初期化
・Nginxのインストール
・アプリをgit管理下におく
といったことをやっていきます。
普通のLinuxサーバーをデプロイできるWebサーバーに育てる作業です。
Nginxのインストール
まずはパッケージを最新化します。
sudo dnf update -yこのコマンドはそれぞれ以下のような要素で成り立っています。
| 要素 | 意味 |
| sudo | ・コマンドを管理者権限で実行する際に使用する |
| dnf update | ・dnfはRedHatLinux系のパッケージマネージャー updateコマンドで、インストール済みパッケージを、リポジトリ上の最新バージョンに合わせて更新する |
| -y | ・実行して良いかの確認をスキップし、全自動で実行するオプション (今回は学習目的の為、dnf update時の確認をスキップしています) |
次に、Webサーバー(として動作するソフト)である Nginx をインストールします。
以下のコマンドを順番に実行してください。
sudo dnf install -y nginx
sudo systemctl start nginx
sudo systemctl enable nginx

これで、Nginxをインストールし、さらに起動することができました。
「sudo systemctl enable nginx」によって、サーバーの再起動時も自動でNginxが
立ち上がるように設定されています。
この状態で、
ブラウザから
「http://(EC2のパブリックIP)」
にアクセスすると
Welcome to nginx! が表示されます。
以下のような画面が表示されれば、ここまではバッチリです!

Node.js、npm、gitのインストール
GitHubに置いたVueアプリをクローンします。
まずは、nodejs、npm、gitをインストールしてください。
sudo dnf install -y nodejs
sudo dnf install -y npm
sudo dnf install -y git

上のような画面になっていればインストールは完了です。
それぞれ以下のような役割になります。
| ツール | 役割 |
| Node.js | ・JavaScriptの実行環境 →ビルド処理を動かすために必要 |
| npm | ・ライブラリ管理 →Vue/Viteの依存関係を揃えるために必要 |
| git | ・ソースコードのバージョン管理 →GitHubからコードを取得・更新するために必要 |
それぞれのツールがきちんとインストールされたかを確かめるために、バージョンを確認します。
git --version「git version 2.43.0」のようなバージョン情報が表示されるはずです。
今回gitのみを書いていますが、「(ツールの略称コマンド名) -v/–version」といった形で他のツールでも同じです!(–versionと-vどちらでも同じになります)
git clone https://github.com/xxx/my-vue-app.git 以前作成したgithub上のリモートリポジトリにpushしているコードをEC2サーバーに用意します。
「xxx」:自分のgitのアカウント名
「my-vue-app.git」:リポジトリ名
を記入してください。
npm install、npm run build
cd my-vue-app
npm install
npm run build
「npm install」でアプリを実行するのに必要なライブラリを一通り揃え、「npm run build」でこれらを本番環境向けにビルド(開発用に書かれたソースコードを、実際に実行・配信できる形式へ変換・整理する処理)し、マシンが実行できる状態にします。
エラーの対処について
npm installの際に以下のようなエラーが出たかと思います。
[ec2-user@ip-xxx-xx-x-x my-vue-app]$ npm install
npm warn EBADENGINE Unsupported engine {
npm warn EBADENGINE package: '@vitejs/plugin-vue@6.0.3',
npm warn EBADENGINE required: { node: '^20.19.0 || >=22.12.0' },
npm warn EBADENGINE current: { node: 'v18.20.8', npm: '10.8.2' }
npm warn EBADENGINE }
npm warn EBADENGINE Unsupported engine {
npm warn EBADENGINE package: 'vite@7.3.0',
npm warn EBADENGINE required: { node: '^20.19.0 || >=22.12.0' },
npm warn EBADENGINE current: { node: 'v18.20.8', npm: '10.8.2' }
npm warn EBADENGINE }
added 35 packages, and audited 36 packages in 2sこれは「このパッケージは
Node 20.19以上 or 22.12以上で動く前提で作られている。
でも今の環境は Node 18.20.8。」
といった内容になります。
Vite(+ plugin-vue)が Node 20.19+ か 22.12+ を要求しているが、でもEC2には最初 Node 18.20.8 が入っていた。これが原因で依存関係が噛み合わない状態になっています。
これはEC2のバージョンであるAmazonLinux2023のデフォルト設定によるものとなります。
そこで、現在のNodeを削除し、Node20系を入れる作業を行います。
sudo dnf remove -y nodejs nodejs-npm nodejs-libs
curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash -
sudo dnf install -y nodejs
node -v
rm -rf node_modules package-lock.json
npm install
npm run build上記では、以下のようなことをやっています。
① バージョン違いの Node.js を削除
(sudo dnf remove -y nodejs nodejs-npm nodejs-libs)
② Node.js 20 を使えるように設定変更
(curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash -)
③ Node.js を再インストール・確認
(sudo dnf install -y nodejs / node -v)
④ 以前の依存関係ファイルを削除
(rm -rf node_modules package-lock.json)
⑤ 依存関係を再構築・ビルド
(npm install → npm run build)
さて、上記のコマンドの実行により、今度は画像のように、Node.jsでバージョン20系を入れることができ、これによりnpm install、npm run buildが成功したことがわかるかと思います。


ここまでが、環境構築等のデプロイの準備になります。
デプロイの核になるのはこの後の箇所になります。
デプロイ作業
ここでのデプロイは「Vue の build成果物(静的ファイル)をNginxが配信する場所へ置く」ことを意味します。
これにより、不特定多数の人に自分のWebページにアクセスしてもらい、みてもらうことができるようになるためです。
cd dist
ls
# assets index.html vite.svg
ls -la /usr/share/nginx/html
# (必要に応じて)Nginxが静的ファイルを読めるように、ディレクトリ/ファイルの権限を確認
多くの場合はデフォルトで問題ないが、コピー手順や権限状態によっては調整が必要
sudo chown -R root:root /usr/share/nginx/html
sudo chmod -R 755 /usr/share/nginx/html
sudo systemctl restart nginx
curl -s http://localhost/ | head -n 30
先ほどのnpm run buildにより dist ディレクトリが生成されています。
これは、元のsrcディレクトリ(vueファイル等が含まれます)の中身をビルドした成果物であり、これが今回世界に公開するものの中身となります。
ここのコマンドですが、全体としては以下のようなことをやっています。
———————————————————————————————-
①Vue のビルド成果物(dist)の中身を確認
→assets index.html があればOK
②Nginx が実際に公開しているディレクトリの権限設定等の確認
→その他のユーザー(Nginxもここに含まれる)が読み取りができる設定ならOK
※もし、Nginxが読めない状態ならNginx が読めるように、権限設定を修正
→Nginx を再起動して設定・状態を反映
③(ブラウザではなく)サーバー内部から HTTP 配信を確認
———————————————————————————————-
実際の結果をみると、おそらく以下のようになっているのではないでしょうか?

htmlファイルのその他ユーザーにrが設定されていることがわかります
ここまでで、元からあるhtmlファイルがきちんと読み取れることがわかります。
この段階では「curl -s http://localhost/ | head -n 30」の実行結果は以下のようになっていると思います。

デフォルトのNginxのhtmファイルですね。
これを、Nginxが公開場所と決めているディレクトリに置くことで、デプロイができます。
Nginxの公開ディレクトリに配置
Nginxの公開先は以下です。
「/usr/share/nginx/html」
既存のファイルを退避し、
Vueの dist をコピーします。
sudo mv /usr/share/nginx/html /usr/share/nginx/html.bak
sudo mkdir -p /usr/share/nginx/html
sudo cp -r ./* /usr/share/nginx/html/
curl -s http://localhost/ | head -n 30
🔹上記コマンドでは、
①今までのWebファイルを消さずに保管(バックアップ)
②空の公開ディレクトリを作り直す
(①のmvにより、「/usr/share/nginx/html」→「/usr/share/nginx/html.bak」と名称が変更され、公開ディレクトリはなくなっています)
③新しいビルド成果物をそこに配置する
④中身を再度確認
といったことをやっています。
「-p」は、途中の階層ディレクトリがなくてもまとめて作る、といった意味です。
また、sudoが全てについていますが、これは/usr配下は一般ユーザーに書き込み権限がない領域であるためです。他に、/varや/etcなども同様です。
試しにsudoなしで実行してみてください、「permission denied」が表示されるかと思います。
さて、今回の作業で言えば
「sudo cp -r ./* /usr/share/nginx/html/」
上記がデプロイの肝になります。
| 要素 | 種類 | 意味 | ここでの役割 |
| cp | コマンド | copy(コピー) | ファイルを別の場所へ複製する |
| -r | オプション | recursive(再帰的) | フォルダと中身をすべてコピーする |
| ./* | コピー元 | カレントディレクトリ配下すべて | dist 内の全ファイル(index.html, assets など) ※前の流れで、distがカレントディレクトリになっている |
| /usr/share/nginx/html/ | コピー先 | nginx の公開ディレクトリ | 世界に公開される場所 |
これにより、作成したWebページが世界に公開されたことになります!
一通り実行したあとの「curl -s http://localhost/ | head -n 30」の結果が、画像のように先ほどと変わっているのがわかるでしょうか?

実際に確認してみましょう。
ブラウザで、再度以下にアクセスします。
「http://(EC2のパブリックIP)」
最初は Nginx の初期画面がキャッシュされて表示されることがありますが、
ハードリロード(Cmd + Shift + R) を行うと、
Vueアプリが表示されます。

(IPアドレスは伏せていますが、ブラウザのレイアウトやcountボタンが押された形跡から、これがデプロイされたWebページ上のものであることがおわかりいただけると思います)
無事デプロイ完了です!
(余談)
実は、この後「今度、アプリのソースコードを更新した後で再度デプロイするには?」など、気になるテーマはあるのですが、今回はここまででご容赦ください‥
デプロイは、自動化や品質管理等、テーマが広く深い分野ですので、みなさまもぜひ学ばれてみてください。
終わりに
前回と今回に渡り
・AWSアカウント作成
・EC2起動
・SSH接続
・Nginx構築
・Vueアプリのデプロイ
という一連の流れを、
できるだけシンプルな構成 で体験しました。
最後まで読んでいただき、ありがとうございました。
参考サイト
【初心者向け】 基本のLinuxコマンド一覧!操作別に紹介|Udemy メディア
【Node.js入門】npmとは?パッケージを管理するnpmの基礎的なコマンド一覧 │ TechMania