はじめに
業務でFileMaker Cloudを使用しているのですが,不特定多数のユーザを対象にwebからデータベースへアクセスさせる必要が生じました。FileMakerには「webdirect」というデータベースのレイアウトをそのままweb公開させる仕組みがあり,従来そのような不特定多数からのアクセスをさせる場合にはそれ専用のレイアウトを作成してゲストアカウントで接続するようにしていました。
しかし最新のクラウドベースサーバであるFileMaker Cloudにはゲストアカウントが設定できないため,従来のweb directを利用したアクセスが出来ません。一方,「FileMaker Data API」というデータベースに外部からアクセスするためのAPIは用意されています(もちろん認証は必要ですが)。したがって
[Webページ] →(FileMakerで認証)→ [FileMaker Data API]
という形での実装を考えましたが,FileMaker Data APIにはCORS制限がかけられているため,フロントエンドから直接APIを叩くことが出来ません。また,そもそもこれではFileMaker Data APIにアクセスするための認証データをフロントエンド側に保持させる必要があり,セキュリティ上問題が残ります。そこで
[Webページ] →(独自に認証)→ [中継サーバ] →(FileMakerで認証)→ [FileMaker Data API]
という形で中継サーバを立て,そのサーバからFileMaker Data APIへアクセスさせることにしました。
JavaScriptは多少触ったことはあるけれども,今まで本格的なバックエンド開発の経験は無かった筆者が試行錯誤しながらサービスを構築していった過程を共有することで,同じような悩みを持つ方の参考になればと思い公開します。
思いのほか内容が膨大になってしまったので,いくつかの記事に分けてあります。この記事はまず開発環境を整えるまでの内容です。
目的
Xserverのサーバ上にExpressを利用したサーバを立て,その内容をgitで更新できるようにする。
開発環境
既にXserverにはnode/npmがインストールされている前提です。インストールは以下のページなどを参考にしてください。
開発時点でのバージョンは
node v14.17.4
npm 6.14.14
でした。
また,ローカル開発環境ではGitの初期設定が終わっていてGitHub Desktopがインストールされている前提です。
Step 1. ローカルにgitリポジトリを作成し,Xserver側でpull出来るようにする
1-1. ローカルにgitリポジトリを作ってリモートに紐付け
GitHub DesktopでNew Repository...
を選べばローカルでフォルダ作ってgit init
からリモートリポジトリ作成までやってくれる。.gitignore
はNode
を選んでおこう。作成したらひとまずPublish repository
でGitHubへアップ。
1-3. Xserver側でgit pull出来るようにする
先にXserverのgitも下記を参考に最新版にしておく。
GitHubへSSH接続するために,Xserverのsshで公開鍵と秘密鍵を作成しておく。参考↓
~/.ssh
ディレクトリに移動して以下:
$ ssh-keygen -t rsa -b 4096 -C "hoge@sample.com"
最後のはコメントなので適当でOK。途中プロンプトでファイル名やパスフレーズが聞かれるが,これも入力せずEnterでOK。作成されたid_rsa.pub
ファイルをviか何かで開いて内容をコピーし,GitHubの"Settings" > "SSH and GPG keys" > "SSH keys" > "New SSH key"から登録しておく。
先に作成したリモートリポジトリのページに入り,"Code"ボタンからSSHクローン用の文字列を取得。
リポジトリを格納したいディレクトリの中で(今回はpublic_html
と同階層にnode
というディレクトリを作成した),以下を実行する。
$ git clone [GitHubからコピーした文字列]
次のように表示されればOK。
Cloning into '[リポジトリ名]'...
Warning: Permanently added the ECDSA host key for IP address 'xxx.xxx.xxx.xxx' to the list of known hosts.
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (5/5), done.
Receiving objects: 100% (5/5), done.
remote: Total 5 (delta 0), reused 5 (delta 0), pack-reused 0
1-4. Hello Worldでも作って試してみる。
ローカルで適当にjavascriptファイルを作ってみる。
console.log("Hello, World!")
作成したファイルをリモートにpushしてから,Xserver側でpull。
$ git pull
$ node test
Hello,world!
うまくいったっぽい。
Step 2. とりあえずExpressサーバを立ててみる
Node.jsのwebフレームワークとしてはExpressを使用することとした。Expressで超シンプルなサーバを立てて,Webからアクセス出来るようにしてみる。
2-1. サーバ作るよ
とりま,Expressの公式Hello Worldをそのまま使ってみる。
% npm init
% npm install express --save
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
server.jsを保存してから
$ node server
Example app listening on port 3000
ここでとりあえずターミナルからcurlでlocalhost:3000を叩いてみると
% curl -w'\n' localhost:3000
Hello World!
うん,出来てるね。
ではXserver側でもやってみる。
Xserverにsshでログインして
$ git pull
$ npm install
$ node server
Example app listening on port 3000
サーバは問題なく起動しているが,この時点でxserverのドメインに3000番ポートでアクセスしてもページは表示されない。Xserverではデフォルトの80/443番ポート以外への外部からのアクセスが出来ないためだ。なので,内部でそちらに転送してやる必要がある。
Xserverのpublic_htmlディレクトリにある.htaccessファイルで転送を設定する。Wordpressを利用しているサーバだと,Wordpressにより自動的に追加された設定が書き込まれているので,そちらではなく上の方に記述すること。
SetEnvIf Request_URI ".*" Ngx_Cache_NoCacheMode=off
SetEnvIf Request_URI ".*" Ngx_Cache_AllCacheMode
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} !=on [NC]
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
+ RewriteRule ^fmproxy/(.*)$ http://localhost:3000/$1 [P,L]
</IfModule>
# BEGIN WordPress
(略)
# END WordPress
RewriteRuleの詳しい内容は↓このあたりを参照。
これで hogehoge.com/fmproxy/ 以下の全てのアクセスは localhost:3000/ 以下にリダイレクトされることになる。
.htaccessを保存してインターネットからXserverのサイトにアクセスしてみる。
成功。
2-2. Daemon化するよ。
Node.jsで立てたサーバはそのままだとエラーで落ちてしまうので,自動で再起動できるようDaemon化する。Daemon化にはforeverを使うことが多いようだけど,foreverのnpmを見ると「新規にインスコするならpm2かnodemon使いな〜」と書いてある。
Note that this project currently fully depends on the community for implementing fixes and new features. For new installations we encourage you to use pm2 or nodemon
なので大人しく pm2 と nodemon を使う。
pm2 はプロセスの状態を視覚的に管理できたりする一方,console.log
の出力がターミナルへ直接出てこなかったりするので try & error を繰り返す開発環境には不向き。よって開発環境では nodemon を使い,本番環境では pm2 を使うのが良さそうである。
$ npm install pm2 -g
$ npm install nodemon -g
pm2の解説見るとsudo
でインストールしていることが多いけど,Xserverでsudo
を付けずにインストールしても問題無かった。
インストールされたら
$ pm2 start server.js
で pm2 による管理下にプロセスが立ち上がる。
[PM2] Starting /home/hogehoge/hogehoge.com/node/fmproxy/server.js in fork_mode (1 instance)
[PM2] Done.
┌────┬────────────────────┬──────────┬──────┬───────────┬──────────┬──────────┐
│ id │ name │ mode │ ↺ │ status │ cpu │ memory │
├────┼────────────────────┼──────────┼──────┼───────────┼──────────┼──────────┤
│ 0 │ server │ fork │ 0 │ online │ 0% │ 30.0mb │
└────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘
開発環境でファイルの変更を自動的にモニタして再起動して欲しければ--watch
オプションをつけて起動すればよし。ついでにpackage.json
のスクリプトも変えておく。
"scripts": {
"start": "pm2 start server --watch",
"stop": "pm2 stop server",
"restart": "pm2 restart server",
"test": "nodemon server"
}
これでnpm test
でテスト用にnodemonが立ち上がり,npm start
npm stop
npm restart
でそれぞれpm2の制御が可能となった。
2-3. 環境変数を使えるようにしておく
ローカルの開発環境と本番とでデータベースへのアクセス情報が違ったりするので,今のうちに.env
ファイルを使えるようにしておく。
$ npm install dotenv --save
プロジェクトのルートディレクトリに.env
ファイルを作成。とりあえずこんな内容で。
NODE_ENV=development
server.js
をちょっといじって,/
にアクセスされたらOKステータスと環境を返すようにしてみる。
+ require('dotenv').config()
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => {
- res.send('Hello World!')
+ res.json({
+ status:"OK",
+ mode:process.env.NODE_ENV
+ })
})
app.listen(port, () => {
- console.log(`Example app listening on port ${port}`)
+ console.log(`App listening on port ${port}`)
})
この状態で curl からlocalhost:3000
にアクセスしてみる。
% curl -w'\n' localhost:3000
{"status":"OK","mode":"development"}
オッケーオッケー。
ではXserver側には本番環境ということで別の.envファイルを置いておく。最初にgitリポジトリを作成する際,同期無視の設定ファイルである.gitignore
を「Node」にしておくと.env
は同期を無視するファイルとして自動的に登録されている。したがってXserver側でgit pull
しても.env
ファイルは存在していないはずだ。(もし存在していれば同期されてしまっているので,.gitignore
に.env
を追加しておこう。)
プロジェクトのルートディレクトリに.env
ファイルを新規作成し,以下を記述する。
NODE_ENV=production
この状態でサーバを再起動してアクセスしてみる。
しっかりと環境変数の内容が反映されている。素敵
まとめ
ここまで,ローカルの開発環境とXserverとをgitで紐付け,Expressを用いたサーバを起動させるまでを見てきました。次の記事では認証処理まわりの実装を行っていきます。