さくらのレンタルサーバーにRailsを入れてブログを作ってみた


リメイクしました

数年ほど当ブログのアクセスランキングの上位をだいたい保ち続けていた「さくらのスタンダードサーバーにRailsをインストールしてみる。」という記事がありまして、今回はその内容のリメイクです。この記事を書いてからの数年間はほぼ独占状態だった。ような気がします。
今となっては何故にさくらのスタンダードサーバーというなんか名称がおかしい感じで書いたのかの理由はもはや分からないのですが、数年が経過した今でも上位10〜20番目くらいには居座り続けておられるくらいのアクセスを日々いただいており嬉しい限りです。

今のところはPythonやC言語の記事の方が圧倒的にアクセスが多かったり、他の理由としてもっといい記事がないということもあるかもしれないけれどそこは穏便に。

ついでに言うとこの記事は本番運用を推奨するものではなく、アプリ開発ってなんだか楽しそうやなとかを感じてもらえると嬉しいです。

ハマりどころもそこそこあるわりに内容がサックリとしているのは上に書いたような理由からもそのままコピペしてたら気付いたらできていました。という内容になって欲しくはなくて、一応はどうやって進めるかのヒント程度のようにしており、決して手抜きではないのです。

今回は過去の記事を書いた頃とは具合がいろいろと違っていて、「なにげに気が向いて試してみたら今でもすんなり動いた〜!」なものでありますけれども、過去の記憶を辿ってみるとなんだかんだと色々調べたりしてすんごい苦労した感がありますので、以前よりも楽にできるのかもしれません。

Railsは相変わらず触る機会がないので(爆)、Rails界隈の状況などなどは全く把握していないのですけれど、前回と同様に様々なものをインストールする必要があり、今ではフロントエンドにWebpackが使われているようでして、そのためにNodeと、あとYarnも必要になってきました。なものですから、Railsに限らず他の言語のフレームワークも使える可能性は大いにあります。

まずは下準備

今回はRailsをインストールしてブログの投稿と閲覧までということだけを試しています。

ブログ機能はこちらを参考に作ってみました。余談ですがNodeのコンパイルに数時間かかる(コア数指定なしの場合)のでRailsの準備ができてから10分ということになります。ただこの辺りは流石にRailsだなと思いました。とRails使ったことないわたしが言うのもなんだけれど。

参考
ゼロから10分でブログが作れる!Rails 6の新機能「Action Text」を試してみた

Nodeに限らずですが、コンパイルするために途中でPythonだったりC++だったりの言語なども使われていて、画面を眺めていると、それはそれは呪文のようなものが滝のように流れます。そして、それはそれは途方もない時間がかかったりします。

今日日YumとかAptにGitなどでスッとインストールできてしまいますから、なにかしらの刺激にはなるのではないかなと思います。makeコマンドにオプションをつけて並列処理させることもできますが共用サーバなのであまり酷使しない方が良いかもしれません。

時は流れてRubyのバージョンも変わりました。Nodeはありません。

% ruby -v
ruby 2.5.5p157 (2019-03-15 revision 67260) [amd64-freebsd11]

% node
node: Command not found.

FreeBSD11です。

$ uname -a
FreeBSD www1918.sakura.ne.jp 11.2-RELEASE-p14 FreeBSD 11.2-RELEASE-p14 #0: Mon Aug 19 22:38:50 UTC 2019     root@amd64-builder.daemonology.net:/usr/obj/usr/src/sys/GENERIC  amd64

グローバルでgemも使えますが、パッケージ等は自分で管理できた方が楽だし簡単に扱えるのでユーザ権限で使えるようにしました。
自分での管理をするというのが若干レンタルサーバを使おうという気持ちに反しているような気もするけれど、、むぐぐ。

参考
さくらのレンタルサーバでRubyを使う

$ gem environment
RubyGems Environment:
  - RUBYGEMS VERSION: 3.0.3
  - RUBY VERSION: 2.6.5 (2019-10-01 patchlevel 114) [x86_64-freebsd11.2]

 中略

  - RUBYGEMS PLATFORMS:
    - ruby
    - x86_64-freebsd-11
  - GEM PATHS:
     - /home/USER/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0
     - /home/USER/.gem/ruby/2.6.0

 中略

rbenvなのでBashにします。

% chsh -s bash
Password:
chsh: user information updated
%
$ ruby -v
ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-freebsd11.2]

何はともあれのBundler

$ gem install bundler
Fetching bundler-2.0.2.gem
Successfully installed bundler-2.0.2
Parsing documentation for bundler-2.0.2
Installing ri documentation for bundler-2.0.2
Done installing documentation for bundler after 4 seconds
1 gem installed

$ bundler -v

Bundler version 2.0.2

これから何をするかというとPortsを入れて、ソースファイルの塊からNodeをコンパイルして利用しようというものです。なのでやっていることは過去記事と同じです。コケるところはあとでまとめてみました。違うのはググった結果で出てくるものもやはり違うのですね。もし環境によって違うところが出たとしても、ググりスキルで普通に対処できるのではないかと思います。

下記のサイトを参考にNodeを入れました。
結構古い記事ですが、だいたいそのままでいけるけれど、「さらに、以下の設定.zshrcにする」のコード内にあるPerlの部分は削除しました。対話的にガンガン進めていきます。

Sakura共用サーバにportsをインストール

ではこけたところを紹介していきます。

  • texinfo
  • /usr/local/include/libintl.hがあるのでこれをコピペします。

  • m4
  • これはサーバーにあるものが使えませんでしたので下記からおとしてきたものを使います。
    wget http://ftp.gnu.org/gnu/m4/m4-1.4.15.tar.gz

  • autoreconf
  • これもサーバーのものをコピペです。
    /usr/local/bin/autoreconf

  • Try to set MAKE_JOBS_UNSAFE=yes
  • MakefileにMAKE_JOBS_UNSAFE=yesを追記します。

コケて治してコケて治してでまた時間がかかって、おおよそここまで済ませれば完走できる(と思います)。
でもここからが本番で、コンパイルの完了までは数時間ほどかかるのでTmuxやScreenを利用して落としておくのが良いと思います。Makeにオプションをつけてコア数指定もできるけれども、共用サーバーなものですから全力で回してKillになっては元も子もないし程よいところを見つけるかもう指定なしで

な感じで良いと思います。

これが出ればゴールです。

====> Compressing man pages (compress-man)
===>  Installing for node10-10.16.3_1
===>  Checking if node10 is already installed
===>   Registering installation for node10-10.16.3_1
Installing node10-10.16.3_1...
Note: If you need npm (Node Package Manager), please install www/npm.

===> SECURITY REPORT:
      This port has installed the following files which may act as network
      servers and may therefore pose a remote security risk to the system.

      If there are vulnerabilities in these programs there may be a security
      risk to the system. FreeBSD makes no guarantee about the security of
      ports included in the Ports Collection. Please type 'make deinstall'
      to deinstall the port if this is a concern.

      For more information, and contact details about the security
      status of this software, see the following webpage:

あとはPortsからYarnをインストールすれば準備完了。

Railsの起動テスト

ブログを作ろう

新しいRailsはPUMAというウェブサーバがデフォルトで使われているようで、開発環境と本番環境もいずれもいけるようで、今時なサービスってそんな感じですね。
あとサーバーの方はサービスに不要なポートしか空いてないので外からアクセスするのでプロキシを用意します。

参考サイト
@tadsan
PHPでプロキシサーバーを作る

「著作権とかは特に気にしないで勝手にコピペして良いです。」

ということで使わせていただいています。

著者が書かれているとおりに必要最低限の実装となっていて、Getメソッド以外は通りません。今回はどうしてもどうしても記事の投稿がしたかったのでPOSTを追加しました。どうしてもそこだけというのが味噌で編集と削除は作っておりませんゆえEDITとDELETEをしてもなにも起こりません。
ソースもメソッドがPOSTのときPOSTしてリダイレクト処理してという処理を付け足しただけなのでぶさいくだけどそこはご乱心。

cat www/index.php
<?php

require_once(dirname(__FILE__).'/../vendor/autoload.php');

use GuzzleHttp\Client as HttpClient;
use GuzzleHttp\Psr7;

$host_table = [
    'localhost' => [
        'host' => 'localhost',
        'port' => 30001,
        'scheme' => 'http',
    ],
    '__DOMAIN__.sakura.ne.jp' => [
        'host' => 'localhost',
        'port' => 30001,
        'scheme' => 'http',
    ]
];

$request = Psr7\ServerRequest::fromGlobals();
$new_uri = $request->getUri()->withPort(80);

$key = $new_uri->getHost();
$port = $new_uri->getPort();

if (isset($host_table[$key])) {
    if (isset($host_table[$key]['host'])) {
        $new_uri = $new_uri->withHost($host_table[$key]['host']);
    }
    if (isset($host_table[$key]['port'])) {
        $new_uri = $new_uri->withPort($host_table[$key]['port']);
    }
    if (isset($host_table[$key]['scheme'])) {
        $new_uri = $new_uri->withScheme($host_table[$key]['scheme']);
    }
}

$client = new HttpClient;

if ((((array)$request->getServerParams()['REQUEST_METHOD'])[0]) === 'POST') {

  $method = "POST";
  $uri = $new_uri;

  $options = [
    'json' => $request->getParsedBody(),
    'http_errors' => false,
    'headers' => [
        'Accept' => 'application/json',
        'Content-Type' => 'application/json'
    ]
  ];

  $response = $client->request($method, $uri, $options);


  header( "Location: https://__DOMAIN__.sakura.ne.jp/articles/");
  exit;
}

$response = $client->send($request->withUri($new_uri), [
    'http_errors' => false,
]);
foreach ($response->getHeaders() as $key => $values) {
    if($key !== 'Transfer-Encoding'){
        foreach ($values as $value) {
            header("{$key}:{$value}");
        }
    }
}

echo $response->getBody();

続いては参考URLを参考にブログを作ります。こちらではSqliteではなくMySQLを使いました。
ゼロから10分でブログが作れる!Rails 6の新機能「Action Text」を試してみた

追加修正した点を書いておきます。MySQLなのでconfig/database.ymlに以下の感じの情報を書いておきます。

host: __DBHOST__.sakura.ne.jp
username: __USERNAME__
password: __PASSWORD__
database: __DATABASE__

プロキシを通しているのでコントローラーに
protect_from_forgery with: :null_sessionを追加します。

$ head app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
  before_action :set_article, only: [:show, :edit, :update, :destroy]
  protect_from_forgery with: :null_session

  # GET /articles
  # GET /articles.json
  def index
    @articles = Article.all
  end

Action textは何故かViewにShowの記述がないのでShowしたときの追記をしました。
今回は触っていませんが、PUMAではpuma.rbでDaemonizeだったりスレッド数だったりと色々と設定することができるのでその辺りを調べて動作をみてみるのも面白いかもしれません。

だいたいこのような仕上がりです。かなりのミニマリストです。

投稿画面



ググるしていて、たまに「さくらレンタルサーバーではRuby on Railsは動作するけどレスポンスが糞遅いのでやめとけ」というブログがヒットしていたのでちょっと気になっていました。応答ログを載せてみますのでご参考ぬ。

Case1

Started POST "/articles" for 127.0.0.1 at 2019-10-31 22:30:13 +0900
Processing by ArticlesController#create as JSON
  Parameters: {"authenticity_token"=>"nAJpia+8utmIPa/YaixMe4xKIXHQ7MOmMQTDufQhYu2mvfERFxFYGuVGH0wC9nAOPzGQSLyhb2wOiTn5yijB9w==", "article"=>{"title"=>"はろーれいるず", "content"=>"
パワーは負けない
"}, "commit"=>"Create Article"} Can't verify CSRF token authenticity. 中略 Completed 200 OK in 25ms (Views: 21.8ms | ActiveRecord: 1.3ms | Allocations: 9566) Started GET "/articles" for 127.0.0.1 at 2019-10-31 22:36:07 +0900 Processing by ArticlesController#index as HTML Rendering articles/index.html.erb within layouts/application Article Load (1.4ms) SELECT articles.* FROM articles ↳ app/views/articles/index.html.erb:14 Rendered articles/index.html.erb within layouts/application (Duration: 5.5ms | Allocations: 1269) Completed 200 OK in 25ms (Views: 22.3ms | ActiveRecord: 1.4ms | Allocations: 10019)

Case2

Started POST "/articles" for 127.0.0.1 at 2019-10-31 22:46:25 +0900
Processing by ArticlesController#create as JSON
  Parameters: {"authenticity_token"=>"4TjT05yLHKKar0BrQP4YvKS8C9TtNw0+5Yk0L2hdIzvbh0tLJCb+YffU8P8oJCTJF8e67YF6ofTaBM5vVlSAIQ==", "article"=>{"title"=>"ぼんちあげ", "content"=>"
おいしい
"}, "commit"=>"Create Article"} Can't verify CSRF token authenticity. (1.1ms) BEGIN   中略 (1.1ms) COMMIT ↳ app/controllers/articles_controller.rb:31:in `block in create' Rendering articles/show.json.jbuilder Rendered articles/_article.json.jbuilder (Duration: 1.0ms | Allocations: 144) Rendered articles/show.json.jbuilder (Duration: 2.7ms | Allocations: 527) Completed 201 Created in 65ms (Views: 7.3ms | ActiveRecord: 8.2ms | Allocations: 16201) Started GET "/articles" for 127.0.0.1 at 2019-10-31 22:46:25 +0900 Processing by ArticlesController#index as HTML Rendering articles/index.html.erb within layouts/application Article Load (1.2ms) SELECT articles.* FROM articles ↳ app/views/articles/index.html.erb:14 Rendered articles/index.html.erb within layouts/application (Duration: 5.7ms | Allocations: 1511) Completed 200 OK in 25ms (Views: 21.8ms | ActiveRecord: 1.2ms | Allocations: 10264)

さいごに

自分のまわりではブログはアメブロばかりだけど、Wordpressが全盛期の今からどうなっていくのでしょうか。
最後にまたしつこく書いておくけれども、本番運用を推奨するものではなく、アプリ開発ってなんだか楽しそうやな〜な感じを感じてもらえると嬉しいです。

参考サイト

PHPでプロキシサーバーを作る

ゼロから10分でブログが作れる!Rails 6の新機能「Action Text」を試してみた

Rails4のCSRF対策で「Can't verify CSRF token authenticity」エラー

Similar Posts:


Leave a Reply

Your email address will not be published. Required fields are marked *