前書き

Webアプリケーションは、多くの場合、3つの異なる層で設計されています。

  • 最初の層は_presentation layer_です。これはユーザーに表示されます。

  • 次は、アプリケーションのhttps://en.wikipedia.org/wiki/Business_logic [ビジネスロジック]を提供する_application layer_です。

  • 最後に、_data layer_はアプリケーションに必要なデータを保存します。

Ruby on Railsアプリケーションでは、これはプレゼンテーション層のWebサーバー、アプリケーション層のRailsサーバー、およびデータ層のデータベースに大まかにマッピングされます。 この設定では、アプリケーション層はデータ層と通信してアプリケーションのデータを取得し、プレゼンテーション層を介してユーザーに表示します。

これらすべてのアプリケーションを単一のサーバーにインストールすることは可能ですが、各レイヤーを独自のサーバーに配置すると、アプリケーションのスケーリングが容易になります。 たとえば、Railsサーバーがボトルネックになる場合、他の2つのレイヤーに影響を与えずにアプリケーションサーバーを追加できます。

このチュートリアルでは、3つの個別のサーバーに一意のソフトウェアセットをインストールし、各サーバーとそのコンポーネントが通信および機能するように構成し、SSHトンネルでそれらの間の接続を保護することにより、Railsアプリを3層構成で展開します。 ソフトウェアスタックの場合、https://www.nginx.com/ [Nginx]をプレゼンテーション層のWebサーバーとして使用し、http://puma.io/ [Puma]をアプリケーション層のRailsアプリケーションサーバーとして使用します。 、およびデータ層のデータベースとしてhttps://www.postgresql.org/[PostgreSQL]。

前提条件

このチュートリアルを完了するには、3つのUbuntu 16.04サーバーを起動する必要があります。 これらに* web-server app-server 、および database-server *という名前を付け、それぞれにプライベートネットワークを有効にする必要があります。

3つのサーバーにはそれぞれ、 `+ sudo `特権を持つ非rootユーザーと、SSH接続を許可するように設定されたファイアウォールが必要です(https://www.digitalocean.com/community/tutorials/initialを使用して設定できます) -server-setup-with-ubuntu-16-04 [初期サーバーセットアップガイド])。 このチュートリアルのコンテキストでは、各サーバーの「 sudo +」ユーザーの名前は* sammy *です。

さらに、3つのサーバーにはそれぞれ固有の構成要件があります。

  • ウェブサーバー

  • Nginx Webサーバーをインストールして構成します。 これを行うには、https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-16-04 [Ubuntu 16.04にNginxをインストールする方法]のチュートリアルに従ってください。

  • * app-server *で:

  • https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-ubuntu-16-04#how-to-install-で説明されているように、公式のPPAを使用してNode.jsをインストールしますusing-a-ppa [Ubuntu 16.04にNode.jsをインストールする方法]。 Asset PipelineなどのいくつかのRails機能はJavaScriptランタイムに依存しており、Node.jsはこの機能を提供します。

  • Ruby on Railsフレームワークをインストールします。 これを行うには、https://www.digitalocean.com/community/tutorials/how-to-install-ruby-on-rails-with-rbenv-on-ubuntu-16-04 [Rubyのインストール方法]のガイドに従ってください。 Ubuntu 16.04のrbenvを使用したRailsで]。 このチュートリアルを進める際には、Rubyの最新バージョンをインストールしてください。これは、この記事の執筆時点ではRuby 2.5.1です。

  • チュートリアルの最初のセクションhttps://www.digitalocean.com/community/tutorials/how-to-use-postgresql-with-your-ruby-on-rails-application-on-ubuntu-に示すように、PostgreSQLをインストールします14-04#install-postgresql [Ubuntu 14.04でRuby on RailsアプリケーションでPostgreSQLを使用する方法]。 このセクションでは、この3層セットアップに必要な別のパッケージである `+ libpq-dev +`のインストール方法についても説明します。

  • Pumaを使用してRailsアプリをデプロイします。 展開する独自のアプリがない場合は、https://www.digitalocean.com/community/tutorials/how-to-deploy-a-rails-app-with-puma-and-のガイドに従ってくださいnginx-on-ubuntu-14-04 [PumaとNginxを使用してRailsアプリを展開する方法]を使用して、サンプルアプリを展開します。 この前提条件の「rbenv-varsプラグインのインストール」セクションでは、* database-server *にPostgreSQLをインストールするときに使用する値を反映するように、データベースユーザーとパスワードを設定する必要があります。 また、「本番データベースの作成」セクションが機能するためには、ファイアウォールを介したポート「3000」を許可する必要があります。 最後に、この前提条件チュートリアルの最後の2つの手順「Puma Upstartスクリプトの作成」と「Nginxのインストールと構成」を完了する必要はありません。

  • データベースサーバー

  • PostgreSQLデータベースソフトウェアをインストールして構成します。 手順については、https://www.digitalocean.com/community/tutorials/how-to-install-and-use-postgresql-on-ubuntu-16-04 [Ubuntu 16.04にPostgreSQLをインストールして使用する方法]のガイドに従ってください。これを行う方法について。 この前提条件チュートリアルに従って、 `+ superuser +`権限を持つRailsアプリのPostgreSQLロールと、PostgreSQLロールと同じ名前のデータベースを作成します。 このチュートリアルでは、PostgreSQLロールとデータベースは両方とも* sammy *と呼ばれます。

  • 新しく作成されたPostgreSQLロールのパスワードを設定します。 「https://www.digitalocean.com/community/tutorials/how-to-deploy-a-rails-app-with-puma-and-nginx-on-ubuntu-14-04#createの最初のコマンドをスキップしますPumaチュートリアルの「-production-database-user [Create Production Database User]」セクション(* app-server のセットアップにも使用)、およびそのセクションの残りのコマンドに従ってデータベースユーザーのパスワードを変更します。 。 PostgreSQLロールの名前と database-server に設定するパスワードは、 app-server *のPostgreSQLインストールで設定したものと同じである必要があります。

手順1-SSHトンネル用のユーザーの作成

_SSHトンネル_は、あるサーバーのポートから別のサーバーのポートにデータを送信できる暗号化された接続であり、2番目のサーバーのリッスンプログラムが最初のサーバーで実行されているように見えます。 SSHトンネル専用のユーザーがいると、セットアップのセキュリティが向上します。侵入者がサーバーのいずれかの* sammy ユーザーにアクセスすると、3層セットアップの他のサーバーにアクセスできなくなります。 。 同様に、侵入者が tunnel *ユーザーにアクセスしようとした場合、Railsアプリディレクトリ内のファイルを編集することも、 `+ sudo +`コマンドを使用することもできません。

各サーバーで、* tunnel という名前の追加ユーザーを作成します。 * tunnel *ユーザーの唯一の機能は、SSHトンネルを作成してサーバー間の通信を容易にすることです。したがって、 sammy とは異なり、 tunnel * `+ sudo +`特権を付与しないでください。 また、* tunnel ユーザーには、Railsアプリディレクトリへの書き込みアクセス権を与えないでください。 各サーバーで次のコマンドを実行して、 tunnel *ユーザーを追加します。

sudo adduser tunnel
  • web-server マシンで、 tunnel *ユーザーに切り替えます。

sudo su tunnel
  • tunnel *ユーザーとして、SSHキーペアを生成します。

ssh-keygen

デフォルトの場所にキーを保存し、キーのパスフレーズを作成しないでください。パスフレーズを作成すると、後でサーバー間にSSHトンネルを作成するときに認証が複雑になる可能性があります。

キーペアを作成したら、* sammy *ユーザーに戻ります。

exit
  • app-server *に切り替えて、同じコマンドを再度実行します。

sudo su tunnel
ssh-keygen
exit

これで、チュートリアルの残りに必要なすべてのユーザーを構成できました。 ネットでは、SSHトンネルの作成プロセスを合理化するために、各* tunnel *ユーザーの `+ / etc / hosts +`ファイルにいくつかの変更を加えます。

手順2-ホストファイルの構成

このチュートリアル全体を通して、コマンドで* app-server または database-server のIPアドレスを参照する必要がある場合が何度もあります。 これらのIPアドレスを毎回覚えて入力する代わりに、 app-server および database-server *のプライベートIPを各サーバーの `+ / etc / hosts +`ファイルに追加できます。 これにより、アドレスの代わりに後続のコマンドで名前を使用できるようになり、SSHトンネルのセットアッププロセスがはるかにスムーズになります。

物事を単純にするために、このチュートリアルでは、* app-server database-server *の両方のプライベートIPアドレスを3つのそれぞれの `+ / etc / hosts `ファイルに追加するように指示します。サーバー。 技術的には* app-server *または* database-server *のプライベートIPアドレスをそれぞれの「 hosts +」ファイルに追加する必要はありませんが、追加しても問題は発生しません。 ここで説明する方法は、単に速度と利便性のために選択されたものです。

最初に、* app-server および database-server *のプライベートIPアドレスを見つけます。 DigitalOcean Dropletsを使用している場合は、コントロールパネルに移動して、これらのドロップレットの名前をクリックします。 ドロップレット固有のページでは、ページの上部近くにパブリックIPアドレスとプライベートIPアドレスの両方が表示されます。

次に、各サーバーで、お気に入りのテキストエディターで `+ / etc / hosts +`ファイルを開き、次の行を追加します。

sudo nano /etc/hosts

/ etc / hosts

. . .
app-server
database-server

これらの行を各サーバーのこのファイルに追加することにより、通常これらのサーバーのIPアドレスを使用する必要があるコマンドで、名前* app-server および database-server を使用できます。 この機能を使用してSSHキーをセットアップし、各 tunnel *ユーザーが他のサーバーに接続できるようにします。

ステップ3-SSHログインのセットアップ

3つのサーバーすべてに* tunnel *ユーザーと更新された `+ / etc / hosts +`ファイルがあるので、サーバー間のSSH接続の作成を開始できます。

この手順を実行するときに、ピラミッドのような3つの層を考えてみてください。下部に* database-server 、中央に app-server 、上部に web-server があります。 Railsアプリに必要なデータにアクセスするには、 app-server database-server に接続できなければならず、 web-server app-server *に接続できる必要があります。ユーザーに提示するものがあります。

したがって、各* tunnel ユーザーのSSH公開鍵をサーバーの「下」に追加するだけです。つまり、 web-server * * tunnel ユーザーの公開鍵を app-server *に追加し、 * app-server * * tunnel * * database-server *へのユーザーの公開鍵。 これにより、階層間に暗号化されたSSHトンネルを確立し、ネットワーク上の盗聴者がそれらの間を通過するトラフィックを読み取れないようにすることができます。

このプロセスを開始するには、 `+ / home / tunnel / .ssh / id_rsa.pub `にある* web-server *の* tunnel *ユーザーの公開鍵を ` / home / tunnel /にコピーします。 * app-server *上のssh / authorized_keys + `ファイル。

  • web-server で、次のコマンドを使用して、ターミナルで tunnel *ユーザーの公開鍵を表示します。

sudo cat /home/tunnel/.ssh/id_rsa.pub

テキスト出力を選択し、システムのクリップボードにコピーします。

別のターミナルセッションで* app-server *にSSH接続し、トンネルユーザーに切り替えます。

sudo su tunnel

システムクリップボードのキーを* app-server *の `+ authorized_keys`ファイルに追加します。 次のコマンドを使用して、1ステップでこれを行うことができます。 `+ tunnel_ssh_publickey_copied_from_web_server +`をシステムのクリップボードの公開キーに置き換えてください:

echo "" >> /home/tunnel/.ssh/authorized_keys

その後、 `+ authorized_keys +`ファイルの許可を変更して、不正なアクセスを防ぎます:

chmod 600 /home/tunnel/.ssh/authorized_keys

次に、* sammy *ユーザーに戻ります。

exit

次に、「+ / home / tunnel / .ssh / id_rsa.pub + にある* app-server tunnel *ユーザーの公開鍵を表示し、それを + / home / tunnel /に貼り付けます。 * database-server *上のssh / authorized_keys + `ファイル:

sudo cat /home/tunnel/.ssh/id_rsa.pub
sudo su tunnel
  • database-server *でSSHキーペアを生成しなかったため、 `+ / home / tunnel / .ssh +`フォルダーを作成し、そのアクセス許可を調整する必要があります。

mkdir /home/tunnel/.ssh
chmod 700 /home/tunnel/.ssh

次に、* app-server *の公開キーを `+ authorized_keys +`ファイルに追加し、そのアクセス許可を調整します。

echo "" >> /home/tunnel/.ssh/authorized_keys
chmod 600 /home/tunnel/.ssh/authorized_keys

次に、* sammy *ユーザーに戻ります。

exit

次に、* tunnel ユーザーとして web-server から app-server *に接続するためにSSHを使用して最初の接続をテストします。

sudo su tunnel
  • web-server から app-server に初めて接続すると、接続しているマシンが信頼できるかどうかを確認するメッセージが表示されます。 「はい」と入力して、 app-server *の信頼性を受け入れます。

OutputThe authenticity of host '111.111.11.111 (111.111.11.111)' can't be established.
ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
Are you sure you want to continue connecting (yes/no)?
  • app-server からウェルカムバナーが表示され、 app-server にログインしていることがコマンドプロンプトに表示されます。 これにより、 web-server から app-server *へのSSH接続が正しく機能していることが確認されます。

  • app-server へのSSH接続を終了し、 tunnel ユーザーを終了して web-server sammy *ユーザーに戻ります。

exit
exit

次に、これらの同じ手順に従って、* app-server から database-server *へのSSH接続をテストします。

sudo su tunnel
  • database-server の信頼性も受け入れます。 * database-server *からウェルカムバナーとコマンドプロンプトが表示されたら、 app-server から database-server *へのSSH接続が期待どおりに機能していることがわかります。

  • database-server へのSSH接続を終了してから、 tunnel *ユーザーを終了します。

exit
exit

このステップで設定したSSH接続は、3つのサーバー層の間で安全な通信を可能にするSSHトンネルの基礎を形成します。 ただし、現在の形式では、これらの接続はクラッシュに対して脆弱であるため、信頼性はそれほど高くありません。 ただし、追加のソフトウェアをいくつかインストールし、トンネルをサービスとして機能するように構成することにより、これらの脆弱性を軽減できます。

手順4-データベースサーバーへの永続的なSSHトンネルのセットアップ

最後の手順では、ローカルサーバーからリモートサーバーのコマンドプロンプトにアクセスしました。 SSHトンネルを使用すると、ローカルホストのポートからリモートホストのポートにトラフィックをトンネリングすることにより、これ以上のことができます。 ここでは、SSHトンネルを使用して、* app-server database-server *間の接続を暗号化します。

このチュートリアルのすべての前提条件に従った場合、* app-server database-server の両方にPostgreSQLをインストールしています。 ポート番号の衝突を防ぐには、これらのサーバー間のSSHトンネルを設定して、 app-server のポート `+ 5433 `から* database-server *のポート ` 5432 +`に接続を転送する必要があります。 後で、( app-server でホストされている)Railsアプリケーションを再構成して、 database-server *で実行されているPostgreSQLのインスタンスを使用します。

  • app-server sammy ユーザーとして開始し、ステップ1で作成した tunnel *ユーザーに切り替えます。

sudo su tunnel

次のフラグとオプションを指定して `+ ssh +`コマンドを実行し、* app-server database-server *の間にトンネルを作成します。

ssh -f -N -L 5433:localhost:5432 [email protected]
  • `+ -f `オプションは、バックグラウンドに ` ssh +`を送信します。 これにより、トンネルがバックグラウンドプロセスとして実行されている間に、既存のプロンプトで新しいコマンドを実行できます。

  • `+ -N `オプションは、リモートコマンドを実行しないように ` ssh +`に指示します。 ポートのみを転送するため、ここで使用されます。

  • + -L +`オプションの後に設定値 `+5433:localhost:5432 +`が続きます。 これは、ローカル側のポート `+ 5433 +(* app-server )からのトラフィックが、リモートサーバー( database-server )の localhost のポート `+ 5432 +`に転送されることを指定します。 ここでの localhost *は、リモートサーバーの観点からのものであることに注意してください。

  • コマンドの最後の部分、「+ tunnel @ database-server +」は、接続するユーザーとリモートサーバーを指定します。

SSHトンネルを確立した後、* sammy *ユーザーに戻ります。

exit

この時点で、トンネルは実行中ですが、トンネルが立ち上がっていることを確認するためにトンネルを監視するものは何もありません。 プロセスがクラッシュすると、トンネルがダウンし、Railsアプリはデータベースと通信できなくなり、エラーが表示されるようになります。

より信頼性の高いセットアップを行うため、今作成したトンネルを削除します。 接続はバックグラウンドにあるため、接続を強制終了するにはプロセスIDを見つける必要があります。 すべてのトンネルは* tunnel *ユーザーによって作成されるため、現在のプロセスをリストし、キーワード「tunnel」の出力をフィルタリングすることで、プロセスIDを見つけることができます。

ps axu | grep tunnel

これにより、以下の出力のようなものが返されます。

Outputtunnel     0.0  0.1  44920   692 ?        Ss   14:12   0:00 ssh -f -N -L 5433:localhost:5432 [email protected]
sammy    21816  0.0  0.2  12916  1092 pts/0    S+   14:12   0:00 grep --color=auto tunnel

`+ kill +`コマンドに続けてプロセスIDを実行して、プロセスを停止します。

sudo kill

アプリケーションサーバーとデータベース間の永続的なSSH接続を維持するには、 `+ autossh `をインストールします。 ` autossh +`はSSH接続を開始および監視するプログラムで、接続が停止するかトラフィックの通過を停止した場合に再起動します。

sudo apt-get install autossh

https://www.digitalocean.com/community/tutorials/understanding-systemd-units-and-unit-files [`+ systemd `はUbuntuのデフォルトの_init system_です]は、システム起動後のプロセスを管理することを意味します。 ` systemd `を使用して、サーバーの再起動時にSSHトンネルを管理および自動的に開始するサービスを作成できます。 これを行うには、 ` systemd `ユニットファイルが保存される標準の場所である ` / lib / systemd / system / `ディレクトリ内に ` db-tunnel.service +`というファイルを作成します。

sudo nano /lib/systemd/system/db-tunnel.service

新しいファイルに次のコンテンツを追加して、 `+ systemd +`が管理するサービスを設定します。

/lib/systemd/system/db-tunnel.service

[Unit]
Wants=network-online.target
After=network-online.target

[Service]
User=tunnel
WorkingDirectory=/home/tunnel
ExecStart=/bin/bash -lc 'autossh -N -L 5433:localhost:5432 [email protected]'
Restart=always
StandardInput=null
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=%n
KillMode=process

[Install]
WantedBy=multi-user.target

ここで重要なのは、「+ ExecStart 」です。 これは、コマンドへのフルパスと、プロセスを開始するために実行する必要がある引数を指定します。 ここでは、新しい ` bash `シェルを起動してから、 ` autossh +`プログラムを実行します。

ファイルを保存して閉じ、 `+ systemd +`設定をリロードして、新しいサービスファイルが確実に選択されるようにします。

sudo systemctl daemon-reload

サーバーが起動するたびに* database-server *へのトンネルが自動的に開始されるように、 `+ db-tunnel +`サービスを有効にします。

sudo systemctl enable db-tunnel.service

次に、サービスを開始します。

sudo systemctl start db-tunnel.service

次のコマンドを再度実行して、トンネルが起動しているかどうかを確認します。

ps axu | grep tunnel

出力では、 `+ autossh +`がトンネルを監視しているため、今回実行中のプロセスがさらにあることがわかります。

Outputtunnel   25925  0.0  0.1   4376   704 ?        Ss   14:45   0:00 /usr/lib/autossh/autossh -N -L 5432:localhost:5432 [email protected]
tunnel   25939  0.2  1.0  44920  5332 ?        S    14:45   0:00 /usr/bin/ssh -L 61371:127.0.0.1:61371 -R 61371:127.0.0.1:61372 -N -L 5432:localhost:5432 [email protected]
sammy    25941  0.0  0.2  12916  1020 pts/0    S+   14:45   0:00 grep --color=auto tunnel

トンネルが稼働しているので、 `+ psql +`を使用して* database-server *への接続をテストして、正しく機能していることを確認できます。

+ psql`クライアントを起動し、 + localhost`に接続するように指示します。 SSHトンネルを介して* database-server *のPostgreSQLインスタンスに接続するには、ポート `+ 5433 +`も指定する必要があります。 前に作成したデータベース名を指定し、プロンプトが表示されたらデータベースユーザー用に作成したパスワードを入力します。

psql -hlocalhost -p5433

次の出力のようなものが表示される場合、データベース接続は正しくセットアップされています。

Outputpsql (9.5.10)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

sammy=#

PostgreSQLプロンプトを閉じるには、「+ \ q 」と入力し、「 ENTER +」を押します。

最後に、* app-server database-server 間のトラフィックを暗号化する永続的で信頼性の高いSSHトンネルがあります。 * app-server *のRailsアプリが database-server *のPostgreSQLインスタンスと通信するのはこのトンネルを経由するため、トンネルのセキュリティ機能が重要です。

ステップ5-リモートデータベースを使用するようにRailsを構成する

  • app-server から database-server へのトンネルが設定されたので、これをRailsアプリの安全なチャネルとして使用して、トンネルを介して database-server *のPostgreSQLインスタンスに接続できます。

アプリケーションのデータベース構成ファイルを開きます。

nano /home/sammy//config/database.yml

ポート番号が環境変数として指定されるように、「+ production」セクションを更新します。 それは今このように見えるはずです:

/home/sammy/appname/config/database.yml

. . .
production:
 <<: *default
 host: localhost
 adapter: postgresql
 encoding: utf8
 database: appname_production
 pool: 5
 username: <%= ENV['APPNAME_DATABASE_USER'] %>
 password: <%= ENV['APPNAME_DATABASE_PASSWORD'] %>

このファイルを保存して閉じ、アプリケーションディレクトリの `+ .rbenv-vars +`ファイルを開き、環境変数を編集します。

nano /home/sammy//.rbenv-vars
  • database-server のPostgreSQLロールに別の名前とパスワードを設定した場合、ここで置き換えます(以下の例では、PostgreSQLロールの名前は sammy *です)。 また、データベースのポートを指定する新しい行を追加します。 これらの変更を行った後、 `+ .rbenv-vars +`ファイルは次のようになります。

/home/sammy/appname/.rbenv-vars

SECRET_KEY_BASE=
_DATABASE_USER=
_DATABASE_PASSWORD=
_DATABASE_PORT=5433

終了したら、このファイルを保存して閉じます。

Railsアプリをデプロイした* app-server ではなく、 database-server *でPostgreSQLインスタンスを使用しているため、データベースを再度セットアップする必要があります。

  • app-server *で、アプリのディレクトリに移動し、 `+ rake +`コマンドを実行してデータベースをセットアップします。

cd /home/sammy/
rake db:setup

このコマンドが完了すると、Railsアプリは* database-server *上のPostgreSQLインスタンスと暗号化されたSSHトンネルを介して通信を開始します。 次に行うことは、Pumaを管理しやすくするために「+ systemd +」サービスとして設定することです。

ステップ6-Pumaの構成と開始

手順4で `+ db-tunnel `サービスを設定する方法と同様に、Puma(前提条件の一部として* app-server *にインストールしたサーバーソフトウェア)をサービスとして実行するように ` systemd +`を設定します。 Pumaをサービスとして実行すると、サーバーの起動時に自動的に起動したり、クラッシュした場合に自動的に再起動したりできるため、展開の堅牢性が向上します。

`+ / lib / systemd / system / `ディレクトリ内に ` puma.service +`という新しいファイルを作成します:

sudo nano /lib/systemd/system/puma.service

Puma’s + systemd + documentationから変更された以下のコンテンツを新しいファイルに追加します。 独自の設定を反映するために、 + User、` + WorkingDirectory`、および `+ ExecStart`ディレクティブで強調表示されている値を必ず更新してください。

/lib/systemd/system/puma.service

[Unit]
Description=Puma HTTP Server
After=network.target

[Service]
# Foreground process (do not use --daemon in ExecStart or config.rb)
Type=simple

# Preferably configure a non-privileged user
User=

# The path to the puma application root
# Also replace the "<WD>" place holders below with this path.
WorkingDirectory=/home//

# Helpful for debugging socket activation, etc.
# Environment=PUMA_DEBUG=1

Environment=RAILS_ENV=production

# The command to start Puma.
ExecStart=/home//.rbenv/bin/rbenv exec bundle exec puma -b tcp://127.0.0.1:9292

Restart=always

[Install]
WantedBy=multi-user.target

ファイルを保存して閉じます。 次に、 `+ systemd +`をリロードし、Pumaサービスを有効にして、Pumaを起動します。

sudo systemctl daemon-reload
sudo systemctl enable puma.service
sudo systemctl start puma.service

この後、サービスのステータスを確認して、Pumaが実行されていることを確認します。

sudo systemctl status puma.service

実行中の場合、次のような出力が表示されます。

Outputpuma.service - Puma HTTP Server
  Loaded: loaded (/lib/systemd/system/puma.service; enabled; vendor preset: enabled)
  Active: active (running) since Tue 2017-12-26 05:35:50 UTC; 1s ago
Main PID: 15051 (bundle)
   Tasks: 2
  Memory: 31.4M
     CPU: 1.685s
  CGroup: /system.slice/puma.service
          └─15051 puma 3.11.0 (tcp://127.0.0.1:9292) []

Dec 26 05:35:50 app systemd[1]: Stopped Puma HTTP Server.
Dec 26 05:35:50 app systemd[1]: Started Puma HTTP Server.
Dec 26 05:35:51 app rbenv[15051]: Puma starting in single mode...
Dec 26 05:35:51 app rbenv[15051]: * Version 3.11.0 (ruby 2.4.3-p205), codename: Love Song
Dec 26 05:35:51 app rbenv[15051]: * Min threads: 5, max threads: 5
Dec 26 05:35:51 app rbenv[15051]: * Environment: production

次に、 `+ curl `を使用してWebページのコンテンツにアクセスして印刷し、正しく配信されていることを確認できるようにします。 次のコマンドは、ポート ` 9292 `で* app-server *で起動したばかりのPumaサーバーにアクセスするように ` curl +`に指示します。

curl localhost:9292/tasks

以下のコードのようなものが表示された場合、Pumaとデータベース接続の両方が正しく機能していることを確認します。

Output...

<h1>Tasks</h1>

<table>
 <thead>
   <tr>
     <th>Title</th>
     <th>Note</th>
     <th colspan="3"></th>
   </tr>
 </thead>

 <tbody>
 </tbody>
</table>

...

RailsアプリがPumaによって提供され、* database-server でリモートPostgreSQLインスタンスを使用するように正しく構成されていることを確認できたら、 web-server と*アプリサーバー

手順7-アプリケーションサーバーへのSSHトンネルのセットアップと永続化

  • app-server が起動して実行されたので、これを web-server に接続できます。 手順4で行ったプロセスと同様に、別のSSHトンネルを設定してこれを行います。 このトンネルにより、 web-server のNginxは、 app-server *のPumaに暗号化された接続を介して安全に接続できます。

  • web-server *に `+ autossh +`をインストールすることから始めます:

sudo apt-get install autossh

`+ / lib / systemd / system / `ディレクトリに ` app-tunnel.service +`という新しいファイルを作成します:

sudo nano /lib/systemd/system/app-tunnel.service

このファイルに次のコンテンツを追加します。 繰り返しますが、キー行は `+ ExecStart `で始まる行です。 ここで、この行は* web-server *のポート ` 9292 `をPumaがリッスンしている* app-server *のポート ` 9292 +`に転送します:

/lib/systemd/system/app-tunnel.service

[Unit]
StopWhenUnneeded=true
Wants=network-online.target
After=network-online.target

[Service]
User=tunnel
WorkingDirectory=/home/tunnel
ExecStart=/bin/bash -lc 'autossh -N -L 9292:localhost:9292 [email protected]'
Restart=always
StandardInput=null
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=%n
KillMode=process

[Install]
WantedBy=multi-user.target

`+ systemd `をリロードして新しいサービスファイルを読み取り、 ` app-tunnel +`サービスを有効にして開始します。

sudo systemctl daemon-reload
sudo systemctl enable app-tunnel.service
sudo systemctl start app-tunnel.service

トンネルが稼働していることを確認します。

ps axu | grep tunnel

以下の出力に似たものが表示されるはずです。

Outputtunnel   19469  0.0  0.1   4376   752 ?        Ss   05:45   0:00 /usr/lib/autossh/autossh -N -L 9292:localhost:9292 [email protected]
tunnel   19482  0.5  1.1  44920  5568 ?        S    05:45   0:00 /usr/bin/ssh -L 54907:127.0.0.1:54907 -R 54907:127.0.0.1:54908 -N -L 9292:localhost:9292 [email protected]
sammy    19484  0.0  0.1  12916   932 pts/0    S+   05:45   0:00 grep --color=auto tunnel

このフィルター処理されたプロセスのリストは、 `+ autossh `が実行中であり、* web-server *と* app-server *の間に実際の暗号化トンネルを作成する別の ` ssh +`プロセスを開始したことを示しています。

2番目のトンネルが起動し、* web-server app-server *間の通信を暗号化します。 3層のRailsアプリを起動して実行するために行うべきことは、リクエストをPumaに渡すようにNginxを設定することだけです。

ステップ8-Nginxの構成

この時点で、必要なすべてのSSH接続とトンネルがセットアップされ、3つのサーバー層のそれぞれが互いに通信できるようになりました。 このパズルの最後のピースは、Pumaにリクエストを送信してセットアップを完全に機能させるようにNginxを構成することです。

  • web-server *で、 `+ / etc / nginx / sites-available / +`に新しいNginx設定ファイルを作成します:

sudo nano /etc/nginx/sites-available/

次のコンテンツをファイルに追加します。 このNginx構成ファイルは、https://www.digitalocean.com/community/tutorials/how-to-deploy-a-rails-app-with-puma-and-nginxのガイドに従っている場合に使用したものと類似しています。 -on-ubuntu-14-04#install-and-configure-nginx [PumaとNginxを使用してRailsアプリをデプロイする方法]。 主な違いは、アップストリームアプリの場所です。この設定は、ローカルソケットファイルを使用する代わりに、ポート `+ 9292 +`でリッスンするSSHトンネルをNginxにポイントします。

/ etc / nginx / sites-available / appname

upstream app {
   server 127.0.0.1:9292;
}

server {
   listen 80;
   server_name localhost;

   root /home/sammy//public;

   try_files $uri/index.html $uri @app;

   location @app {
       proxy_pass http://app;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_set_header Host $http_host;
       proxy_redirect off;
   }

   error_page 500 502 503 504 /500.html;
   client_max_body_size 4G;
   keepalive_timeout 10;
}

このファイルを保存して閉じ、サイトを有効にして、変更をアクティブにします。

最初に、デフォルトのサイトを削除します。

sudo rm /etc/nginx/sites-enabled/default

Nginxの `+ sites-enabled`ディレクトリに移動します:

cd /etc/nginx/sites-enabled

+ sites-enabled`ディレクトリに、今作成した + sites-available + `ディレクトリにファイルへのシンボリックリンクを作成します。

sudo ln -s /etc/nginx/sites-available/

Nginx構成の構文エラーをテストします。

sudo nginx -t

エラーが報告された場合は、先に戻ってファイルを確認してから続行してください。

準備ができたら、Nginxを再起動して新しい設定を読み取ります。

sudo systemctl restart nginx

前提条件のPumaチュートリアルに従えば、* app-server にNginxとPostgreSQLをインストールしたことになります。 両方とも、他の2つのサーバーで実行される個別のインスタンスに置き換えられたため、これらのプログラムは冗長です。 したがって、これらのパッケージを app-server *から削除する必要があります。

sudo apt remove nginx
sudo apt remove postgresql

これらのパッケージを削除した後、ファイアウォールルールを更新して、不要なトラフィックがこれらのポートにアクセスしないようにしてください。

これで、Railsアプリが実稼働しています。 ウェブブラウザで*ウェブサーバー*のパブリックIPにアクセスして、動作を確認します。

http:///tasks

結論

このチュートリアルに従って、3層アーキテクチャーにRailsアプリケーションをデプロイし、* web-server から app-server へ、および app-server から database-serverへの接続を保護しました。 *暗号化されたSSHトンネルを使用。

アプリケーションのさまざまなコンポーネントを別々のサーバーに配置すると、サイトが受信するトラフィックの量に基づいて、各サーバーに最適な仕様を選択できます。 これを行う最初のステップは、サーバーが消費しているリソースを監視することです。 サーバーのCPU使用率を監視する方法については、https://www.digitalocean.com/community/tutorials/how-to-monitor-cpu-use-on-digitalocean-droplets [CPU監視に関するガイド]をご覧ください。 1つの層でのCPUまたはメモリの使用量が非常に高い場合、その層のみでサーバーのサイズを変更できます。 サーバーサイズの選択に関するその他のアドバイスについては、https://www.digitalocean.com/community/tutorials/choosing-the-right-droplet-for-your-application [アプリケーションに適したドロップレットの選択]のガイドを参照してください。

すぐに次のステップとして、* web-server にSSL証明書をインストールして、ユーザーから web-server *への接続を保護する必要があります。 手順については、https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-16-04 [Nginx Let’s Encrypt tutorial]をご覧ください。 また、SSHトンネルの使用について詳しく知りたい場合は、https://www.digitalocean.com/community/tutorials/ssh-essentials-working-with-ssh-servers-clients-and-keys#setting- up-ssh-tunnels [このガイド]。