この記事は続きものになっています。今回は実践編です。
前回→紹介編
前回のあらすじ
クラウド開発環境はいいぞ。
構築してみる
ここからは実際にクラウド開発環境を構築していきましょう!
なお今回はMacからやってますんで、Windowsだとコマンドとかちょっと違う場合があるかもしれません。
まあ細かいところが違うだけで流れは同じです。なんかできなさそうなことあったら調べてみてください。代替するものはあるはずです。
1. Compute Engineのインスタンスを作成する
Compute Engineにアクセスし、プロジェクトが無い場合はプロジェクトを作成します。
課金の設定がなければ課金設定に飛ぶので、カード情報とかを入力して課金情報を登録しましょう。
課金情報が無ければ当然インスタンスを使用することはできません。
課金情報も登録できたら、Compute Engine APIを有効にします。有効にするだけなら特にお金はかかりません。

有効になったらこんな画面になります!インスタンスを作りましょう!

インスタンス作成画面では、スペックを選択することができ、そのスペックに応じた費用を右側に出してくれます。

自分は以下の設定にしていますが、こちらは臨機応変に変えていきましょう。クラウドの強みであります💪
| 項目 | 値 |
|---|---|
| シリーズ | N1 |
| マシンタイプ | n1-standard-2(2 vCPU、7.5 GB メモリ) |
| OS | Debian |
| ディスク種類 | バランス永続ディスク |
| ディスク容量 | 30GB |
| その他 | デフォルト |
ファイヤーウォールには何もチェックを入れないようにしましょう。後で設定します

作成ボタンを押せばインスタンスが作成され、さっきは何も無かったインスタンス一覧に新しくインスタンスが起動した状態で追加されます!

ステータスが緑のチェックになり、外部IPにそれっぽいIPアドレスが入ってると思います(ここでは隠してます)
これで無事インスタンスが作成されました!しかしこれだけだとまだインスタンスに入って作業できません。次にインスタンスにSSH接続できるようにしましょう。
2. 作成したインスタンスに接続できるようにする
外部IP右の「SSH」を使えばブラウザからインスタンスに入れはするんですが、まあ使い勝手は悪いので自分のローカル環境からSSH接続してインスタンスに入るようにします。
2の1. ssh-keygenする
SSH接続するために、公開鍵と秘密鍵を作成しましょう。
適当にターミナル開いて
$ ssh-keygen
sshキーの保存先が聞かれます。デフォルトは~/.ssh/id_rsaです。
複数の鍵を作る場合は名前分けたほうがいいですが、まだ何もない場合はデフォルトで良いのでそのままEnterでもOKです。
その後パスフレーズが聞かれますが、こちらは特に何も書かずにEnterでいいと思います。1
こんなやつ出てくれば成功です
The key's randomart image is:
+---[RSA 3072]----+
| . oo. o. |
| o o.=.. |
| + =.o. |
| oooE |
| S .o * . |
| .oo .% + |
| .==+B B . |
| o+O+ * . |
| .=o++ . |
+----[SHA256]-----+
ls ~/.sshでファイルを確認すると、id_rsaとid_rsa.pubが生成されているはずです。
2の2. 公開鍵をGCPに登録
Compute EngineのSSH認証鍵から公開鍵(id_rsa.pub)を登録します

出てきた入力欄にid_rsa.pubの中身をコピペしてください。

これで保存すればOKです!
2の3. 接続の確認
これで起動しているインスタンスにSSH接続できるようになってるはずです!
接続してみましょう
# ssh [ホスト] 的な感じ
$ ssh 111.111.111.111
ホストのところには入りたいインスタンスの外部IPを入れましょう。
鍵ファイルの名前を自分で指定した場合はファイル先のパスを指定してやる必要があります。例えばこんな感じ
$ ssh 111.11.1.0 -i ~/.ssh/bo_id_rsa
初回ログイン時はなんかcontinue connecting?とか聞かれますが、適当にyesしておきましょう。
なんかターミナルの感じが変われば成功です!これでインスタンスに接続できるようになりました!
2の4. ファイアウォールの設定
このままだとインスタンスにhttpで接続できない(=ブラウザから実行結果が開けない)ので、ファイアウォールを設定してhttpとhttpsで接続できるようにします。
ファイアウォールの設定を開きます。

デフォルトでなんか色々ありますが、全部使わないので削除しちゃって大丈夫です。
必要になったらルール作りゃいいんすよ
色々設定する項目ありますが、以下のように設定しましょう
| 項目 | なんなんそれ | 設定例 |
|---|---|---|
| 名前 | ルールの名前。そのまんま | bo-dev-ip |
| ターゲット | このルールを適用するインスタンスをフィルタリングできる。設定分けないならネットワーク上のすべてのインスタンスでおk |
ネットワーク上のすべてのインスタンス |
| ソースフィルタ | フィルタを設定して接続範囲を限定する。IP範囲を選択 | IP 範囲 |
| ソースIPの範囲 | 指定したIPアドレスでしか接続できないようにする。 自分のIPアドレスの確認はこちらから。サブネットマスクまで指定する必要がありますが、 /32って書いときゃ大丈夫です |
114.51.4.19/32 |
| プロトコルとポート | 接続できるポート番号を指定する。プロトコルはTCPで、SSH、http、httpsで接続できるようにしたいのでそれぞれに対応する番号22,80,443を入力します。 |
✅ tcp: 22,80,443 |
| その他 | デフォルトでおk |
あとは「作成」ボタンを押して完了です👍
今一度SSH接続をやってみて接続できることを確認しておきましょう。22番ポートが解放されていればSSH接続できますので、それでファイアウォール設定がうまくいってるか確認できます。
3. エディタからインスタンスに接続する
ここではVS Codeでの接続例を提示します。他のエディタの接続方法はわからんぽよなので、他のエディタを使用する場合、このステップはなんとかご自身で頑張ってください。
3の1. 拡張機能のインストール
ぼくが大好きRemote - SSHくんをインストールしましょう

VS Codeの拡張機能で「Remote SSH」なんかで検索すれば一番上に出てきます。それをインストールしましょう。
3の2. 設定ファイルを書く
以下のいずれかの方法で設定ファイル(~/.ssh/config)を開きます

-
F1→remoteと検索して出てくるRemote-SSH: Open SSH Configuration File...を選択 - Remote - SSHで追加されるタブ「リモートエクスプローラー」の設定アイコンをクリックし、
Remote-SSH: Open SSH Configuration File...を選択
- nanoとかviで直接開く(
nano ~/.ssh/config)
設定ファイルが開けたら、以下の設定を追記します。
Host bo-dev # 名前。なんでもいい
# 起動させたインスタンスの外部IP。
HostName 11.45.14.19
# 公開鍵についてるユーザー名。
# 今回のようにssh-keygenでユーザー名指定してないならローカルでログイン中のいつものユーザー名でおk
User bo-yakitarako
# 秘密鍵への絶対パス。ssh-keygenでファイル指定してないなら「~/.ssh/id_rsa」になるはず
IdentityFile /Users/bo-yakitarako/.ssh/bo_id_rsa
言わなくても大丈夫だと思うけど上記のものは一例であって、そのまんま書いてもダメですからね?各々で対応するものに値を設定してください。
これで上記の場合はbo-devという接続先に接続する準備が整いました。
3の3. 接続!
以下のいずれかの方法で接続します。
設定がうまくいってれば、VS CodeでSSHに接続した形になります!

うまく接続できたら最初にエクスプローラーからフォルダを開いておきましょう。フォルダを開いておけば、後から直接開いたフォルダに行けるようになります。
Connect to Host...から来るよりフォルダに行ったほうがなにかと便利やね
| こうして | こうじゃ |
|---|---|
![]() |
![]() |
ひとまずOKしてユーザーのホームディレクトリを開いておきます。
フォルダから入るには以下の方法があります。
3の4. watch上限を最大にする
なにやらwatch上限なるものがあって、HMRとかgitとかが監視するファイルの最大数が設定されているらしいのです。
デフォルトでも65536くらいあるっぽいのででかくなんなきゃ大丈夫だと思うんですが、これ超えちゃうとHMRができなくなっちゃうんで、一応最大まで上げておきましょう。
このコマンドを実行してくだせえ
$ sudo sh -c 'echo fs.inotify.max_user_watches=524288 >> /etc/sysctl.conf' && sudo sysctl -p
fs.inotify.max_user_watches=524288とか言われたら適用できてます🌞
3の5. 拡張機能入れる
ローカルとクラウドで拡張機能の管理は別なので、ローカルに入ってる拡張機能は入れ直す必要があります。
といってもLocal - インストール済みって具合にローカルで入れてる拡張機能に絞って表示してくれて楽にインストールできると思います。ありがたや...ありがたや...

Remote-SSHのトラブルあるある
Q. Permission Deniedとか言われて接続できない!
以下の原因が考えられます。
Q. Could not establish connectionとか言われるんだけど?
→**known_hostsにIPが登録されてるかも**
同時に起動しないと複数のインスタンスで同じ外部IPを共有します。known_hostsには最初にcontinueしたインスタンスとそのときのIPアドレスが登録されるのですが、それ以外のインスタンスでそのIPアドレスに接続しようとするとこのエラーになります。
対応策は簡単で、~/.ssh/known_hostsを開いて該当するIPアドレスが書かれてる行を削除するだけです。
4. nginxでhttp接続できるようにする
ブラウザからアクセスできるようにするために、nginxを設定します。
ここからはDockerでやったほうが良さみですが、Dockerよくわかんない(大敗)のでシステム直接いじっていきます。
とにもかくにもまずはインスールじゃい!
$ sudo apt-get update
$ sudo apt-get install nginx
インストールが完了したっぽかったら、nginxが動いてるか確認しましょう。
$ sudo systemctl status nginx
なにやら仰々しく色々でてきてたらOKです。
そうしたら、設定ファイルを書きます。
詳しい説明は省きますが、/etc/nginx/conf.d以下に設定ファイル(***.conf)を置くようにしていきます。
$ nano /etc/nginx/conf.d/dev.conf
nanoとかviで開いたら、以下のように入力します。(nanoとかviの使い方はググってちょ)
server {
listen 80;
server_name bo-dev;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location / {
proxy_pass http://localhost:3000/;
}
}
書けたら保存して、nginxを再起動させて設定を適用しましょう。
$ sudo systemctl restart nginx
特になんも言われなければおkでごぜーます。
ブラウザからhttp://bo-devに接続すると、nginxがプロキシになってインスタンス内のlocalhost:3000に繋いでくれるという流れですね。
とはいえbo-devの名前解決もやってないですし、そもそもlocalhost:3000も立ってないのでこの段階では接続はできません。
5. 開発用ドメインを名前解決する
突然http://bo-devが出てきてちょっと困惑したかもしれません。申し訳NASA
というのもクラウド環境にlocalhostで接続するのはちょっとアレなんで、開発用ドメインを勝手に用意してそこに接続する形にしたいんですよね。
その開発用ドメインというのが今回でいうところのbo-devドメインです。これはわりと自由に決められるのでお好きな文字列をお使いいただけます。
自由に決められると言いつつ、多分これを見てるあなたにbo-devは使えないかもしれませんが。は?
というのもですね、他の人が既にどこかで開発用ドメインを名前解決してたら使えないっぽいんですよね。bo-devは僕が名前解決しちゃったのでみなさんは使えないというわけです。
でももしかしたら使えるかも。DNSようわからんぽよ...
ちなみにdevは使えませんでした。残念でした〜
話が逸れましたね。名前解決するとかなんか物々しいこと言ってますが、そんなに難しいことじゃありません。ローカルPCのhostsファイルに1行追加すればいいだけです。
ローカルPCだからね!インスタンスのほうじゃないからね!間違えないでね!
- Mac/Linuxの場合:
nano /etc/hostsで開きます。(sudo必要かも) - Windowsの場合:
Winキー+Rを押して出てきた入力欄にdriversと入力→etcフォルダに行ってその中のhostsを管理者権限で開く
末尾に以下のように入力して保存しまつ。
# 開発用ドメイン
xxx.xxx.xxx.xxx XXXXXX
なにやらxxxとか並んでますが**xxx.xxx.xxx.xxxにはインスタンスの外部IPを、XXXXXXには開発用ドメインを入力します**。bo-devの場合は
# 開発用ドメイン
114.51.4.19 bo-dev
みたいな感じです。
保存できたらブラウザからhttp://開発用ドメインに接続してみましょう。nginxの502画面が開くはずです。

ここで、外部IPは間違えてないのにうまく接続できなかったら残念ながらそのドメインは使えません。別のドメインをhostsファイルに書きましょう。
そしてこれでようやく準備が整いました。長かったぜベイベー
6. フロントエンド開発するぜ!
ぶっちゃけあとはローカルで開発するときの感覚と変わりないです。Node.js入れてyarn入れて2create-xxx-appしてっていういつもの流れですね。
今回は試しにNext.jsやってみますね。
最初にNode.jsのバージョン変えたりしたいのでnvm入れます。
↓nvmの最新バージョンのインストールスクリプトはこちらから↓
https://github.com/nvm-sh/nvm#install-script
以下のcurlはバージョンが古い可能性があるので最新バージョンのインストールスクリプトをご使用くだせえ
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
$ source ~/.bashrc
$ nvm ls-remote # インストールできるバージョンの確認
$ nvm install v14.18.0 # 現時点の良さげなバージョン入れました
$ node --version # Node.jsが入ってることの確認
$ npm install --global yarn # グッバイnpmお前のことは忘れねえぜ
yarn入れるとこまでです。特別なことは特にやってないですね。
それではここでは~/projects以下にNext.jsプロジェクトを展開したいと思います。この辺はお好みですね
$ mkdir ~/projects
$ cd ~/projects
$ yarn create next-app demo --typescript
いにしゃらいず終わったらフォルダをプロジェクトのトップのところで開き直しましょう。ここでは~/projects/demoですね。
| これで | こうして | こうじゃ! |
|---|---|---|
![]() |
![]() |
![]() |
フォルダが開けたらいつも通りターミナルも開いておきましょう。これで開発プロジェクトを開くのも容易になったZOY!

したらyarn devして開発サーバーを立ち上げましょう。
compiled successfullyになったらさっき502になってたhttp://開発用ドメインにアクセスし直してみましょう。

成し遂げたぜ。
盛り上がってきたのでちょっとタイトル変えてみましょう。
<h1 className={styles.title}>
- Welcome to <a href="https://nextjs.org">Next.js!</a>
+ Welcome to <a href="https://nextjs.org">成し遂げたぜ。</a>
</h1>
ふおおおおおおおおおお変更がすぐ反映されてりゅうううううううううううううううううう
このように、**クラウド環境でもHMRでの開発が可能です!**スゴイデスネ
あとは煮るなり焼くなり好きに開発していきましょう。
注意点
インスタンスは再起動するたびに外部IPが変わります。なので、起動する度に~/.ssh/configと/etc/hostsを書き換える必要があります。
毎回ファイル開いて変えるのもめんどいんで、僕はコマンドラインから$ devip xxx.xxx.xxx.xxxってすると、~/.ssh/configと/etc/hostsの中身が入力したIPアドレスに変わるようにしてます。
具体的にはTypeScriptでスクリプト書いて.zshrcでエイリアス設定してる感じです。
スクリプトはこんな感じ↓
import { readFileSync, writeFileSync } from 'fs';
(() => {
if (process.argv.length <= 4) {
console.log('引数ねンだわ');
return;
}
const [, , hostTitle, domain, IP] = process.argv;
const etcReg = new RegExp(`^[0-9|\\.]+[\\s]+${domain}$`);
const hostsLines = readFileSync('/etc/hosts', 'utf-8')
.split('\n')
.map((text) => {
if (etcReg.test(text)) {
return `${IP} ${domain}`;
}
return text;
});
writeFileSync('/etc/hosts', hostsLines.join('\n'));
type ConfigLines = [string[], boolean];
const configFilePath = '/Users/bo-yakitarako/.ssh/config';
const [configLines] = readFileSync(configFilePath, 'utf-8')
.split('\n')
.reduce(
([lines, canRewrite], text) => {
if (canRewrite && text.includes('HostName')) {
const spaces = [...Array(text.indexOf('HostName') + 1)].join(' ');
return [[...lines, `${spaces}HostName ${IP}`], false] as ConfigLines;
}
const reg = new RegExp(`^[\\s]*Host ${hostTitle}$`);
const isUpdate = canRewrite || reg.test(text);
return [[...lines, text], isUpdate] as ConfigLines;
},
[[], false] as ConfigLines
);
writeFileSync(configFilePath, configLines.join('\n'));
console.log(`${IP}に書き換えといたわよ`);
})();
$ ts-node ./src/index.ts hostTitle domain IP
みたいに使います。(実際にはコンパイルしてます)
-
hostTitle:~/.ssh/configで作った設定の名前 -
domain: 開発用ドメイン -
IP: インスタンスの外部IPアドレス
hostTitleとdomainを指定してIPアドレスだけコマンドライン引数にするという形でエイリアスを作ってます。
alias devip='(){node ~/Desktop/Node/ipreset/build/index.js bo-dev bo-dev $1}'
おわりに
思ったより長くなってしまいましたが、これにてクラウド開発環境の構築は完了です。
ただまだできていないことがあります。httpsでの接続です。
これまたかなり曲者だったので、気が向いたらまた別で記事にしようと思います。
ほいじゃさいなら〜













