前書き
Webアプリケーションは、多くの場合、3つの異なる層で設計されています。
-
最初の層はpresentation layerで、これはユーザーに表示されます。
-
次はapplication layerで、これはアプリケーションのbusiness logicを提供します。
-
最後に、data layerは、アプリケーションに必要なデータを格納します。
Ruby on Railsアプリケーションでは、これはプレゼンテーション層のWebサーバー、アプリケーション層のRailsサーバー、およびデータ層のデータベースに大まかにマップされます。 この設定では、アプリケーション層はデータ層と通信してアプリケーションのデータを取得し、プレゼンテーション層を介してユーザーに表示します。
これらすべてのアプリケーションを単一のサーバーにインストールすることは可能ですが、各レイヤーを独自のサーバーに配置すると、アプリケーションのスケーリングが容易になります。 たとえば、Railsサーバーがボトルネックになる場合、他の2つのレイヤーに影響を与えずにアプリケーションサーバーを追加できます。
このチュートリアルでは、3つの個別のサーバーに一意のソフトウェアセットをインストールし、各サーバーとそのコンポーネントを一緒に通信および機能するように設定し、SSHトンネルでそれらの間の接続を保護することにより、3層構成でRailsアプリをデプロイします。 ソフトウェアスタックの場合、プレゼンテーション層のWebサーバーとしてNginx、アプリケーション層のRailsアプリケーションサーバーとしてPuma、データ層のデータベースとしてPostgreSQLを使用します。 。
前提条件
このチュートリアルを完了するには、3つのUbuntu 16.04サーバーを起動する必要があります。 これらにweb-server、app-server、およびdatabase-serverという名前を付け、それぞれでプライベートネットワークを有効にする必要があります。
3つのサーバーのそれぞれには、sudo
特権を持つroot以外のユーザーと、SSH接続を許可するように構成されたファイアウォール(Initial Server Setup guideを使用して構成できます)が必要です。 このチュートリアルのコンテキストでは、各サーバーのsudo
ユーザーの名前はsammyです。
さらに、3つのサーバーにはそれぞれ固有の構成要件があります。
-
web-serverについて:
-
Nginx Webサーバーをインストールして構成します。 これを行うには、How to Install Nginx on Ubuntu 16.04に関するチュートリアルに従ってください。
-
-
app-serverについて:
-
How To Install Node.js on Ubuntu 16.04で説明されているように、公式PPAを使用してNode.jsをインストールします。 Asset PipelineなどのいくつかのRails機能はJavaScriptランタイムに依存しており、Node.jsはこの機能を提供します。
-
Ruby on Railsフレームワークをインストールします。 これを行うには、How to Install Ruby on Rails with rbenv on Ubuntu 16.04に関するガイドに従ってください。 このチュートリアルを進める際には、Rubyの最新バージョンをインストールしてください。これは、この記事の執筆時点ではRuby 2.5.1です。
-
チュートリアルHow To Use PostgreSQL with Your Ruby on Rails Application on Ubuntu 14.04の最初のセクションに示されているように、PostgreSQLをインストールします。 このセクションでは、この3層セットアップに必要な別のパッケージである
libpq-dev
をインストールする方法についても説明します。 -
Pumaを使用してRailsアプリをデプロイします。 デプロイする独自のアプリがない場合は、How To Deploy a Rails App with Puma and Nginxに関するガイドに従ってサンプルアプリをデプロイしてください。 この前提条件の「インストールrbenv-varsプラグイン」セクションでは、database-serverにPostgreSQLをインストールするときに使用する値を反映するようにデータベースのユーザーとパスワードを設定する必要があることに注意してください。 また、「本番データベースの作成」セクションが機能するには、ファイアウォールを通過するポート
3000
を許可する必要があります。 最後に、この前提条件チュートリアルの最後の2つの手順「Puma Upstartスクリプトの作成」と「Nginxのインストールと構成」を完了する必要はありません。
-
-
database-serverについて:
-
PostgreSQLデータベースソフトウェアをインストールして構成します。 これを行う方法については、How To Install and Use PostgreSQL on Ubuntu 16.04に関するガイドに従ってください。 この前提条件のチュートリアルに従うときに、
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」の最初のコマンドをスキップします-production-database-user [Create Production Database User]」セクション(これはapp-serverの設定にも使用しました)で、そのセクションの残りのコマンドに従ってデータベースユーザーのパスワードを変更します。 。 PostgreSQLの役割の名前とdatabase-serverに設定するパスワードは、app-serverのPostgreSQLインストールで設定したものと同じである必要があることに注意してください。
-
[[step-1 -—- creating-a-user-for-the-ssh-tunnels]] ==ステップ1—SSHトンネルのユーザーの作成
SSH tunnelsは暗号化された接続であり、あるサーバーのポートから別のサーバーのポートにデータを送信できるため、2番目のサーバーのリスニングプログラムが最初のサーバーで実行されているように見えます。 SSHトンネル専用のユーザーがいると、セットアップのセキュリティが向上します。侵入者がサーバーの1つでsammyユーザーにアクセスした場合、侵入者は3つのサーバーの他のサーバーにアクセスできなくなります。層のセットアップ。 同様に、侵入者がtunnelユーザーにアクセスした場合、侵入者はRailsアプリディレクトリ内のファイルを編集することも、sudo
コマンドを使用することもできません。
各サーバーで、tunnelという名前の追加ユーザーを作成します。 tunnelユーザーの唯一の機能は、サーバー間の通信を容易にするSSHトンネルを作成することです。したがって、sammyとは異なり、tunnelsudo
特権を付与しないでください。 また、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
ファイルにいくつかの変更を加えます。
[[step-2 -—- configuring-the-hosts-file]] ==ステップ2—Hostsファイルの構成
このチュートリアル全体を通して、コマンドでapp-serverまたはdatabase-serverのいずれかのIPアドレスを参照する必要がある場合がよくあります。 毎回これらのIPアドレスを覚えて入力する必要はなく、app-serverとdatabase-serverのプライベートIPを各サーバーの/etc/hosts
ファイルに追加できます。 これにより、アドレスの代わりに後続のコマンドで名前を使用できるようになり、SSHトンネルのセットアッププロセスがはるかにスムーズになります。
簡単にするために、このチュートリアルでは、3つのサーバーのそれぞれの/etc/hosts
ファイルにapp-serverとdatabase-serverの両方のプライベートIPアドレスを追加するように指示していることに注意してください。 技術的には、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_private_ip app-server
database-server_private_ip database-server
これらの行を各サーバーのこのファイルに追加することで、通常これらのサーバーのIPアドレスを使用する必要があるコマンドでapp-serverおよびdatabase-serverという名前を使用できます。 この機能を使用してSSHキーを設定し、各tunnelユーザーが他のサーバーに接続できるようにします。
[[step-3 -—- setting-up-ssh-logins]] ==ステップ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-servertunnelユーザーの公開鍵をapp-serverに追加する必要があります。 sを実行し、app-servertunnelユーザーの公開鍵をdatabase-serverに追加します。 これにより、階層間に暗号化されたSSHトンネルを確立し、ネットワーク上の盗聴者がそれらの間を通過するトラフィックを読み取れないようにすることができます。
このプロセスを開始するには、/home/tunnel/.ssh/id_rsa.pub
にあるweb-serverのtunnelユーザーの公開鍵をapp-serverの/home/tunnel/.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 "tunnel_ssh_publickey_copied_from_web-server" >> /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ユーザーの公開鍵を表示し、database-serverの/home/tunnel/.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 "tunnel_ssh_publickey_copied_from_app-server" >> /home/tunnel/.ssh/authorized_keys
chmod 600 /home/tunnel/.ssh/authorized_keys
次に、sammyユーザーに戻ります。
exit
次に、SSHを使用して最初の接続をテストし、web-serverからtunnelユーザーとしてapp-serverに接続します。
sudo su tunnel
ssh tunnel@app-server
web-serverからapp-serverに初めて接続すると、接続先のマシンが信頼できることを確認するように求めるメッセージが表示されます。 「yes」と入力して、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)? yes
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
ssh tunnel@database-server
database-serverの信頼性も受け入れます。 database-serverからウェルカムバナーとコマンドプロンプトが表示されると、app-serverからdatabase-serverへのSSH接続が期待どおりに機能していることがわかります。
database-serverへのSSH接続を終了してから、tunnelユーザーを終了します。
exit
exit
このステップで設定したSSH接続は、3つのサーバー層の間で安全な通信を可能にするSSHトンネルの基礎を形成します。 ただし、現在の形式では、これらの接続はクラッシュに対して脆弱であるため、信頼性はそれほど高くありません。 ただし、追加のソフトウェアをいくつかインストールし、トンネルをサービスとして機能するように構成することにより、これらの脆弱性を軽減できます。
[[step-4 -—- setting-up-a-persistent-ssh-tunnel-to-the-database-server]] ==ステップ4—データベースサーバーへの永続的なSSHトンネルの設定
最後の手順では、ローカルサーバーからリモートサーバーのコマンドプロンプトにアクセスしました。 SSHトンネルを使用すると、ローカルホストのポートからリモートホストのポートにトラフィックをトンネリングすることにより、これ以上のことができます。 ここでは、SSHトンネルを使用して、app-serverとdatabase-serverの間の接続を暗号化します。
このチュートリアルのすべての前提条件を順守すると、app-serverとdatabase-serverの両方にPostgreSQLがインストールされます。 ポート番号の衝突を防ぐには、これらのサーバー間のSSHトンネルを構成して、app-serverのポート5433
からdatabase-serverのポート5432
に接続を転送する必要があります。 後で、database-serverで実行されているPostgreSQLのインスタンスを使用するように、Railsアプリケーション(app-serverでホストされている)を再構成します。
app-serverのsammyユーザーとして開始し、ステップ1で作成したtunnelユーザーに切り替えます。
sudo su tunnel
次のフラグとオプションを指定してssh
コマンドを実行し、app-serverとdatabase-serverの間にトンネルを作成します。
ssh -f -N -L 5433:localhost:5432 tunnel@database-server
-
-f
オプションは、ssh
をバックグラウンドに送信します。 これにより、トンネルがバックグラウンドプロセスとして実行を継続している間に、既存のプロンプトで新しいコマンドを実行できます。 -
-N
オプションは、ssh
にリモートコマンドを実行しないように指示します。 ポートのみを転送するため、ここで使用されます。 -
-L
オプションの後に、構成値5433:localhost:5432
が続きます。 これは、ローカル側のポート5433
(app-server)からのトラフィックがリモートサーバーのlocalhostのポート5432
(database-server)に転送されることを指定します。 ここでのlocalhostは、リモートサーバーの観点からのものであることに注意してください。 -
コマンドの最後の部分である
tunnel@database-server
は、接続するユーザーとリモートサーバーを指定します。
SSHトンネルを確立した後、sammyユーザーに戻ります。
exit
この時点で、トンネルは実行されていますが、トンネルが立ち上がっていることを確認するためにトンネルを監視するものはありません。 プロセスがクラッシュすると、トンネルがダウンし、Railsアプリはデータベースと通信できなくなり、エラーが表示されるようになります。
より信頼性の高いセットアップを行うため、今作成したトンネルを削除します。 接続はバックグラウンドにあるため、接続を強制終了するにはプロセスIDを見つける必要があります。 すべてのトンネルはtunnelユーザーによって作成されるため、現在のプロセスを一覧表示し、キーワード「tunnel」の出力をフィルタリングすることで、そのプロセスIDを見つけることができます。
ps axu | grep tunnel
これにより、以下の出力のようなものが返されます。
Outputtunnel 21814 0.0 0.1 44920 692 ? Ss 14:12 0:00 ssh -f -N -L 5433:localhost:5432 tunnel@database-server
sammy 21816 0.0 0.2 12916 1092 pts/0 S+ 14:12 0:00 grep --color=auto tunnel
kill
コマンドに続けてプロセスIDを実行して、プロセスを停止します。
sudo kill 21814
アプリケーションサーバーとデータベース間の永続的なSSH接続を維持するには、autossh
をインストールします。 autossh
は、SSH接続を開始および監視し、接続が停止するかトラフィックの通過を停止した場合に再起動するプログラムです。
sudo apt-get install autossh
systemd
is the default init system on Ubuntuは、システムの起動後にプロセスを管理することを意味します。 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 tunnel@database-server'
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
db-tunnel
サービスを有効にして、サーバーが起動するたびにdatabase-serverへのトンネルが自動的に開始されるようにします。
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 tunnel@database-server
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 tunnel@database-server
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 sammy
次の出力のようなものが表示される場合、データベース接続は正しくセットアップされています。
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インスタンスと通信するのはこのトンネルを経由するため、トンネルのセキュリティ機能が重要です。
[[step-5 -—- configuring-rails-to-use-a-remote-database]] ==ステップ5—リモートデータベースを使用するためのRailsの構成
app-serverからdatabase-serverへのトンネルが設定されたので、Railsアプリがトンネルを介してdatabase-server上のPostgreSQLインスタンスに接続するための安全なチャネルとして使用できます。 。
アプリケーションのデータベース構成ファイルを開きます。
nano /home/sammy/appname/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'] %>
port: <%= ENV['APPNAME_DATABASE_PORT'] %>
このファイルを保存して閉じてから、アプリケーションディレクトリの.rbenv-vars
ファイルを開き、環境変数を編集します。
nano /home/sammy/appname/.rbenv-vars
database-serverのPostgreSQLロールに別の名前とパスワードを設定した場合は、ここでそれらを置き換えます(以下の例では、PostgreSQLロールの名前はsammyです)。 また、データベースのポートを指定する新しい行を追加します。 これらの変更を行うと、.rbenv-vars
ファイルは次のようになります。
/home/sammy/appname/.rbenv-vars
SECRET_KEY_BASE=secret_key_base
APPNAME_DATABASE_USER=sammy
APPNAME_DATABASE_PASSWORD=database_password
APPNAME_DATABASE_PORT=5433
終了したら、このファイルを保存して閉じます。
Railsアプリをデプロイしたapp-serverではなくdatabase-serverでPostgreSQLインスタンスを使用しているため、データベースを再度セットアップする必要があります。
app-serverで、アプリのディレクトリに移動し、rake
コマンドを実行してデータベースを設定します。
[.note]#Note:このコマンドは、すべてのデータを既存のデータベースから新しいデータベースにnot移行します。 データベースに重要なデータがすでにある場合は、それをバックアップしてから後で復元する必要があります。
#
cd /home/sammy/appname
rake db:setup
このコマンドが完了すると、Railsアプリは暗号化されたSSHトンネルを介してdatabase-server上のPostgreSQLインスタンスとの通信を開始します。 次に行うことは、管理を容易にするためにPumaをsystemd
サービスとして構成することです。
[[step-6 -—- configuring-and-starting-puma]] ==ステップ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=sammy
# The path to the puma application root
# Also replace the "" place holders below with this path.
WorkingDirectory=/home/sammy/appname
# Helpful for debugging socket activation, etc.
# Environment=PUMA_DEBUG=1
Environment=RAILS_ENV=production
# The command to start Puma.
ExecStart=/home/sammy/.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) [appname]
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...
Tasks
Title
Note
...
RailsアプリがPumaによって提供されており、database-serverでリモートPostgreSQLインスタンスを使用するように正しく構成されていることを確認したら、web-serverとの間のSSHトンネルの設定に進むことができます。 app-server。
[[step-7 -—- setting-up-and-persisting-the-ssh-tunnel-to-the-app-server]] ==ステップ7—AppServerへの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 tunnel@app-server'
Restart=always
StandardInput=null
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=%n
KillMode=process
[Install]
WantedBy=multi-user.target
[.note]#Note:ExecStart
行のポート番号は、前の手順でPuma用に構成されたものと同じです。
#
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 tunnel@app-server
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 tunnel@app-server
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を設定することだけです。
[[step-8 -—- configuring-nginx]] ==ステップ8—Nginxの構成
この時点で、必要なすべてのSSH接続とトンネルがセットアップされ、3つのサーバー層のそれぞれが互いに通信できるようになりました。 このパズルの最後のピースは、Pumaにリクエストを送信してセットアップを完全に機能させるようにNginxを構成することです。
web-serverで、/etc/nginx/sites-available/appname
に新しいNginx構成ファイルを作成します。
sudo nano /etc/nginx/sites-available/appname
次のコンテンツをファイルに追加します。 このNginx構成ファイルは、How To Deploy a Rails App with Puma and Nginxに関するガイドに従った場合に使用したものと似ています。 主な違いは、アップストリームアプリの場所です。ローカルソケットファイルを使用する代わりに、この構成はNginxがポート9292
でリッスンしているSSHトンネルを指すようにします。
/etc/nginx/sites-available/appname
upstream app {
server 127.0.0.1:9292;
}
server {
listen 80;
server_name localhost;
root /home/sammy/appname/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
Nginxsites-enabled
ディレクトリに移動します。
cd /etc/nginx/sites-enabled
sites-enabled
ディレクトリにsymbolic linkを作成し、sites-available
ディレクトリに今作成したファイルを作成します。
sudo ln -s /etc/nginx/sites-available/appname appname
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アプリが実稼働しています。 Webブラウザでweb-serverのパブリックIPにアクセスして、実際の動作を確認してください。
http://web-server_public_IP/tasks
結論
このチュートリアルに従うことで、Railsアプリケーションを3層アーキテクチャにデプロイし、web-serverからapp-serverへ、およびapp-serverからdatabase-serverへの接続を保護しました。 ■暗号化されたSSHトンネルを使用します。
アプリケーションのさまざまなコンポーネントを別々のサーバーに配置すると、サイトが受信するトラフィックの量に基づいて、各サーバーに最適な仕様を選択できます。 これを行う最初のステップは、サーバーが消費しているリソースを監視することです。 サーバーのCPU使用率を監視する方法については、our guide on CPU monitoringを参照してください。 1つの層でのCPUまたはメモリの使用量が非常に高い場合、その層のみでサーバーのサイズを変更できます。 サーバーサイズの選択に関するその他のアドバイスについては、Choosing the Right Droplet for Your Applicationに関するガイドを参照してください。
次のステップとして、web-serverにSSL証明書をインストールして、ユーザーからweb-serverへの接続を保護する必要があります。 手順については、Nginx Let’s Encrypt tutorialを確認してください。 また、SSHトンネルの使用について詳しく知りたい場合は、this guideを確認してください。