【Redmine】Railsアプリケーションを実行するためのApacheモジュール導入

Redmine等のRuby on Railsアプリケーションを
実行するためのApacheモジュールを導入します。

導入することのメリットは以下の通りです。

  1. Apache単独でRailsアプリケーションを実行可能。
    Apacheのモジュールとして実装されており、
    別途デーモンを起動する必要がなく、TCPポートも使わない。
  2. Railsアプリケーションのデプロイが簡単になる。
    ファイルをアップロードするだけなので、PHPのような感覚。
  3. サーバのメモリを節約できる。
    Railsインスタンスは必要なタイミングで生成し、
    一定時間アクセスがなければインスタンスを終了させる。
  • Passenger導入

    gem install passenger --no-rdoc --no-ri
    passenger-install-apache2-module
    

    以下の警告は無視しました。

    /usr/include/features.h:330:4: warning: #warning _FORTIFY_SOURCE requires compiling with optimization (-O) [-Wcpp]
    #  warning _FORTIFY_SOURCE requires compiling with optimization (-O)
    

    以下の設定依頼が表示されるので、メモしておきます。

    Please edit your Apache configuration file, and add these lines:
    
    LoadModule passenger_module /usr/local/share/ruby/gems/2.0/gems/passenger-5.0.27/buildout/apache2/mod_passenger.so
    <IfModule mod_passenger.c>
      PassengerRoot /usr/local/share/ruby/gems/2.0/gems/passenger-5.0.27
      PassengerDefaultRuby /usr/bin/ruby2.0
    </IfModule>
    
    After you restart Apache, you are ready to deploy any number of web
    applications on Apache, with a minimum amount of configuration!
    

    ここで別のTeraTermを立ち上げ、
    Apache2の設定ファイルを作成し、メモしたものを書き込みます。

    vi /etc/httpd/conf.d/redmine.conf
    
    # Passengerの基本設定。
    LoadModule passenger_module /usr/local/share/ruby/gems/2.0/gems/passenger-5.0.27/buildout/apache2/mod_passenger.so
    <IfModule mod_passenger.c>
      PassengerRoot /usr/local/share/ruby/gems/2.0/gems/passenger-5.0.27
      PassengerDefaultRuby /usr/bin/ruby2.0
    </IfModule>
    
    # サブディレクトリでRedmineを実行するための設定
    RackBaseURI /redmine
    
    # Passengerが追加するHTTPヘッダを削除するための設定(任意)
    Header always unset "X-Powered-By"
    Header always unset "X-Rack-Cache"
    Header always unset "X-Content-Digest"
    Header always unset "X-Runtime"
    
    # Passengerのチューニングのための設定(任意)
    PassengerMaxPoolSize 20
    PassengerMaxInstancesPerApp 4
    PassengerPoolIdleTime 3600
    PassengerHighPerformance on
    PassengerStatThrottleRate 10
    PassengerSpawnMethod smart
    RailsAppSpawnerIdleTime 86400
    PassengerMaxPreloaderIdleTime 0
    
    # RedmineのCSSや画像へのアクセスを許可
    <Directory "/var/lib/redmine/public">
      Require all granted
    </Directory>
    

    保存後、Apache2を再起動し、元のTeraTermでエンターを押下します。

    /etc/rc.d/init.d/httpd restart
    

    Apache上のPassengerでRedmineを実行するため、
    Redmineのオーナーを変更します。
    今回、AWSではApacheはrootユーザで実行しているため、
    変更前のオーナーでも実行は可能です。

    chown -R apache:apache /var/lib/redmine
    

    Apacheのドキュメントルートに指定されているディレクトリに
    Redmineのpublicディレクトリに対するシンボリックリンクを作成します。

    ln -s /var/lib/redmine/public /var/www/html/redmine
    

    再度、Apache2を再起動します。
    これにより、全てのRailsアプリケーションも再起動されるようになります。

    /etc/rc.d/init.d/httpd restart
    
  • Redmine動作確認
    以下のURLでRedmineにアクセスできれば成功です。
    https://xxx.xxx.xxx.xxx/redmine/

    コマンド以外のRedmineの初期設定については、
    以下のURLを確認しながら画面上で行います。
    http://redmine.jp/tech_note/first-step/admin/

【Redmine】Redmine導入

  • Redmine導入
    Redmineのバージョンは以下のURLから最新版を調査します。
    http://www.redmine.org/projects/redmine/wiki/Download

    cd /var/lib
    curl -O http://www.redmine.org/releases/redmine-3.2.1.tar.gz
    tar xvf redmine-3.2.1.tar.gz
    mv redmine-3.2.1 /var/lib/redmine
    
  • RedmineからMySQLへの接続ファイル作成

    vi /var/lib/redmine/config/database.yml
    
    production:
      adapter: mysql2
      database: レッドマイン用DB名
      host: localhost
      username: レッドマイン用ユーザ名
      password: "レッドマイン用ユーザパスワード"
      encoding: utf8
    

    スペースは2つ空けること。
    パスワードはダブルクォートをつけること。
    この設定がおかしいと後続のbundle処理でハマリます。
    「/var/lib/redmine/config/database.yml.example」にサンプルファイルがあります。

  • Redmineからメールサーバへの接続ファイル作成

    vi /var/lib/redmine/config/configuration.yml
    

    今回はお試しで導入することもあり、作成しませんでした。
    日本語フォントファイルのパス、アップロードされたファイルの保管場所、
    データベースの暗号化等も設定できます。
    この設定ファイルも記述をミスると後続のbundle処理でハマリます。
    「/var/lib/redmine/config/configuration.yml.example」にサンプルファイルがあります。

  • gemパッケージ導入
    Rubyのパッケージ管理ツール「bundler」を使用して、
    Redmineが依存するgemパッケージを導入します。

    cd /var/lib/redmine
    bundle install --without development test
    

    通常はここで普通に上手くいくようですが、私の環境では以下のエラーが発生しました。

    [root@ip-xxx-xxx-xxx-xxx redmine]# bundle install --without development test
    /usr/share/ruby/vendor_ruby/2.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- io/console (LoadError)
    from /usr/share/ruby/vendor_ruby/2.0/rubygems/core_ext/kernel_require.rb:55:in `require'
    from /usr/local/share/ruby/gems/2.0/gems/bundler-1.11.2/lib/bundler/vendor/thor/lib/thor/shell/basic.rb:2:in `<top (required)>'
    from /usr/share/ruby/vendor_ruby/2.0/rubygems/core_ext/kernel_require.rb:55:in `require'
    from /usr/share/ruby/vendor_ruby/2.0/rubygems/core_ext/kernel_require.rb:55:in `require'
    from /usr/local/share/ruby/gems/2.0/gems/bundler-1.11.2/lib/bundler/vendor/thor/lib/thor/shell/color.rb:1:in `<top (required)>'
    from /usr/local/share/ruby/gems/2.0/gems/bundler-1.11.2/lib/bundler/vendor/thor/lib/thor/shell.rb:17:in `shell'
    from /usr/local/share/ruby/gems/2.0/gems/bundler-1.11.2/lib/bundler/ui/shell.rb:14:in `initialize'
    from /usr/local/share/ruby/gems/2.0/gems/bundler-1.11.2/lib/bundler/cli.rb:12:in `new'
    from /usr/local/share/ruby/gems/2.0/gems/bundler-1.11.2/lib/bundler/cli.rb:12:in `rescue in start'
    from /usr/local/share/ruby/gems/2.0/gems/bundler-1.11.2/lib/bundler/cli.rb:10:in `start'
    from /usr/local/share/ruby/gems/2.0/gems/bundler-1.11.2/exe/bundle:19:in `block in <top (required)>'
    from /usr/local/share/ruby/gems/2.0/gems/bundler-1.11.2/lib/bundler/friendly_errors.rb:7:in `with_friendly_errors'
    from /usr/local/share/ruby/gems/2.0/gems/bundler-1.11.2/exe/bundle:17:in `<top (required)>'
    from /usr/local/bin/bundle:23:in `load'
    from /usr/local/bin/bundle:23:in `<main>'
    

    「io/console (LoadError)」が存在しないと記載があるので、
    以下のコマンドで追加で導入しました。

    cd /var/lib/redmine
    gem install io-console
    

    その後、「/var/lib/redmine」を全部削除し、最初からやり直したところ、上手くいきました。

  • Redmineのセッション改ざん防止用秘密鍵の作成

    cd /var/lib/redmine
    rake generate_secret_token
    
  • Redmine用DBにテーブル作成

    cd /var/lib/redmine
    RAILS_ENV=production rake db:migrate
    
  • Redmine用DBのテーブルに初期データ登録
    初期データ登録はコマンドではなく、Redmine起動後に管理画面から実行することも可能。

    cd /var/lib/redmine
    RAILS_ENV=production rake redmine:load_default_data
    
  • Redmineのパーミッション設定

    cd /var/lib/redmine
    chown -R 755 files log tmp public/plugin_assets
    

【Redmine】Redmine導入前準備

RedmineをAWSのEC2の無料版であるAmazon Linuxに導入します。
導入の前提として、WEBサーバ、DBサーバの設定が済んでいること。
WEBサーバにはApache2、DBサーバにはMySQLを利用します。

導入前の準備として、各ツールを揃えます。

  • 開発ツール・ビルドに必要なヘッダファイルのインストール
    RubyやPassengerのビルドで必要なヘッダファイルです。

    yum -y groupinstall "Development Tools"
    yum -y install openssl-devel readline-devel zlib-devel curl-devel libyaml-devel libffi-devel
    
  • ImageMagickと日本語フォントのインストール
    ImageMagickと日本語フォントはガントチャートをPNG形式の画像にエクスポートする機能、
    添付ファイルのサムネイル画像を作成するのに利用するようです。
    インストールを行わなくてもRedmineの実行は可能ですが、入れておきます。

    yum -y install ImageMagick ImageMagick-devel ipa-pgothic-fonts
    
  • Rubyインストール
    Amazon Linuxでは既に導入済ですが、最新のものにしました。

    yum install ruby-devel
    
  • bundler導入
    Redmineが使用するGemを一括インストールするためのツールです。

    gem install bundler --no-rdoc --no-ri
    

    「–no-rdoc –no-ri」はドキュメントのインストールを省略するためのオプションです。

  • Redmine用のMySQLのユーザ作成

    mysql -uroot -pデータベースパスワード
    
    create database レッドマイン用DB名 default character set utf8;
    grant all on レッドマイン用DB名.* to レッドマイン用ユーザ名@localhost identified by 'レッドマイン用ユーザパスワード';
    flush privileges;
    exit
    

【DBサーバ】MySQL導入

  • MySQLインストール

    yum -y install mysql-server mysql-devel
    
  • MySQL設定

    vi /etc/my.cnf
    
    # 下記内容を追加([mysqld]に)
    # クライアントの文字コードに依存しない
    skip-character-set-client-handshake
    # 文字コード
    character-set-server=utf8
    
    下記内容を追加
    [mysql]
    default-character-set=utf8
    
    /etc/rc.d/init.d/mysqld start
    chkconfig mysqld on
    chkconfig --list mysqld
    

    ランレベルが2~5でonを確認する。

  • rootユーザのパスワード設定とUTF-8の確認

    mysql -u root
    
    SET PASSWORD FOR root@localhost=password('データベースパスワード');
    

    character_set_filesystemとcharacter_sets_dir以外がUTF-8であることを確認する。

    show variables like 'char%';
    
  • 初期ユーザと初期データベースの削除

    mysql -u root -pデータベースパスワード
    

    ユーザ名が空のユーザを確認し、削除する。

    SELECT user,host FROM mysql.user;
    
    DELETE FROM mysql.user WHERE user='';
    

    データベースを確認しデータベースtestを削除する。

    SHOW DATABASES;
    
    DROP DATABASE test;
    exit
    

【WEBサーバ】Apache2SSL導入

  • 秘密鍵作成

    cd /etc/pki/tls/certs
    openssl genrsa -aes256 1024 > server.key
    
    Generating RSA private key, 1024 bit long modulus
    ......................++++++
    ............++++++
    e is 65537 (0x10001)
    Enter pass phrase:パスワード入力
    Verifying - Enter pass phrase:パスワード再入力
    
  • 公開鍵作成

    openssl req -new -key server.key > server.csr
    
    Enter pass phrase for server.key:パスワード入力
    You are about to be asked to enter information that will be incorporated
    into your certificate request.
    略
    Country Name (2 letter code) [XX]:JP
    State or Province Name (full name) []:Tokyo
    Locality Name (eg, city) [Default City]:Akihabara
    Organization Name (eg, company) [Default Company Ltd]:OreOreCA
    Organizational Unit Name (eg, section) []:z-aws
    Common Name (eg, your name or your server's hostname) []:z-aws.net
    Email Address []:空欄
    A challenge password []:空欄
    An optional company name []:空欄
    
  • 証明書作成

    openssl x509 -in server.csr -days 36500 -req -signkey server.key > server.crt
    
    Enter pass phrase for server.key:パスワード入力
    
  • 秘密鍵パスワード解除
    現状のままだとApache2の再起動のたびにパスワードを求められるので、
    秘密鍵のパスワードを解除しておきます。

    mv server.key server.key.org
    openssl rsa -in server.key.org > server.key
    
    Enter pass phrase for server.key.org:パスワード入力
    writing RSA key
    
  • Apache2のSSL導入

    yum install mod_ssl
    
  • Apache2のSSL設定

    cp -pi /etc/httpd/conf.d/ssl.conf /etc/httpd/conf.d/ssl.conf.org
    vi /etc/httpd/conf.d/ssl.conf
    
    下記内容に変更
    #DocumentRoot "/var/www/html"
    ↓
    DocumentRoot "/var/www/html"
    
    ErrorLog logs/ssl_error_log
    ↓
    ErrorLog /var/log/httpd/ssl_error_log
    
    TransferLog logs/ssl_access_log
    ↓
    #TransferLog logs/ssl_access_log
    
    CustomLog logs/ssl_request_log \
              "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
    ↓
    CustomLog /var/log/httpd/ssl_access_log \
              "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
    
    
    # POODLE SSLv3.0 脆弱性問題対処
    SSLProtocol all -SSLv2
    ↓
    SSLProtocol all -SSLv2 -SSLv3
    
    SSLCertificateFile /etc/pki/tls/certs/localhost.crt
    ↓
    SSLCertificateFile /etc/pki/tls/certs/server.crt
    
    SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
    ↓
    SSLCertificateKeyFile /etc/pki/tls/certs/server.key
    
  • Apache2SSLの動作確認
    AWSコンソール画面から「セキュリティグループ」-「インバウンド」で
    以下を許可しておきます。

    プロトコル:TCP
    ポート:443
    
    echo '<h1>It works!</h1>' > /var/www/html/index.html
    /etc/rc.d/init.d/httpd restart
    

    https://xxx.xxx.xxx.xxx/

    証明書の確認が表示された後、「It works!」が表示されれば正常です。

    rm -f /var/www/html/index.html
    

【WEBサーバ】Apache2設定

  • Apache2のドキュメントルート設定
    基本的な設定は完了したので、次にドキュメントルートの設定を行います。

    vi /etc/httpd/conf/httpd.conf
    
    下記の設定となるように変更(変更部分または重要部分のみ記載)
    # ドキュメントルート
    DocumentRoot "/var/www/html"
    
    # 最上位の制御
    <Directory />
        Options FollowSymLinks
        AllowOverride None
    </Directory>
    
    # ドキュメントルートの制御
    <Directory "/var/www/html">
        Options -Indexes FollowSymLinks
        AllowOverride All
        Order allow,deny
        Allow from all
    </Directory>
    
    # アクセス制御ファイル名
    AccessFileName .htaccess
    
    # ファイル名を指定しない場合の検索優先順位(index.html)
    <Files ~ "^\.ht">
        Order allow,deny
        Deny from all
        Satisfy All
    </Files>
    
    # iconsルートの制御
    <Directory "/var/www/icons">
        Options -Indexes MultiViews FollowSymLinks
        AllowOverride None
        Order allow,deny
        Allow from all
    </Directory>
    
    # エラーログ出力先
    ErrorLog /var/log/httpd/error_log
    
  • welcome.confの無効化

    mv /etc/httpd/conf.d/welcome.conf /etc/httpd/conf.d/welcome.conf.org
    
  • Apache2の動作確認
    AWSコンソール画面から「セキュリティグループ」-「インバウンド」で
    以下を許可しておきます。

    プロトコル:TCP
    ポート:80
    
    echo '<h1>It works!</h1>' > /var/www/html/index.html
    /etc/rc.d/init.d/httpd start
    

    http://xxx.xxx.xxx.xxx/

    「It works!」が表示されれば正常です。

    rm -f /var/www/html/index.html
    
  • Apache2起動設定

    chkconfig httpd on
    chkconfig --list httpd
    

    ランレベルが2~5でonを確認する。

【WEBサーバ】Apache2導入

  • Apatch2インストール

    yum -y install httpd httpd-devel
    

    簡単な初期設定を行っておきます。

    cp -pi /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.org
    vi /etc/httpd/conf/httpd.conf
    
    下記内容を変更
    # サーバ情報表示内容
    ServerTokens OS
    ↓
    ServerTokens ProductOnly
    
    # サーバ署名表示内容
    ServerSignature On
    ↓
    ServerSignature Off
    

【AWS】iphoneからAWS接続

  • iphoneからAWS接続
    *pemを*pkkにPuTTYの鍵生成で変換。
    vsshアプリで鍵指定して接続可能。

  • iphoneからAWS起動
    AWSアプリで可能。
    IAMユーザーで作成したユーザーでログインする。

【APサーバ】Tomcat導入

  • Tomcat専用ユーザ作成

    useradd -s /sbin/nologin tomcat
    

    /sbin/nologinシェルを指定し、通常利用不可とする。

  • Tomcat導入

    バージョンは「apache-tomcat-7.0.50.tar.gz」にしました。
    サーバーに配置しておきます。

    tar xvzf apache-tomcat-7.0.50.tar.gz
    mv apache-tomcat-7.0.50 /usr/local
    cd /usr/local
    chown -R tomcat.tomcat apache-tomcat-7.0.50
    ln -s apache-tomcat-7.0.50 tomcat
    
  • 環境変数の設定

    下記3つのうちのどれかに記載します。

    【共通設定】
    /etc/profile
    「JAVA_HOME」や「CATALINA_HOME」の値を設定する。
    
    【環境変数設定】
    $CATALINA_HOME/bin/setenv.sh
    「JAVA_OPTS」や「CATALINA_OPTS」の値を設定する。
    
    【クラスパス設定】
    $CATALINA_HOME/bin/setclasspath.sh
    追加のjarファイル等を設定する。
    

    今回は共通設定に追加します。
    AWSの場合、JAVA_HOMEは設定済なので、CATALINA_HOMEだけ設定します。

    vi /etc/profile
    
    下記を最終行に追加
    export CATALINA_HOME=/usr/local/tomcat
    

    環境変数を適用しておきます。

    source /etc/profile
    
  • Tomcat起動確認

    AWSコンソール画面から「セキュリティグループ」-「インバウンド」で
    以下を許可しておきます。

    プロトコル:TCP
    ポート:8080
    

    Tomcatをtomcatユーザで起動します。

    sudo -u tomcat /usr/local/tomcat/bin/startup.sh
    

    http://xxx.xxx.xxx.xxx:8080/examples/servlets/

    「Servlet Examples with Code」の画面が出れば成功です。
    併せてrootユーザではなくtomcatユーザで動作していることを確認します。

    ps -ef | grep tomcat
    
    tomcat    プロセスID  親プロセスID プロセッサ使用率 プロセスの起動時刻  制御端末 累積時間 略
    

    startup.shはrootユーザで実行しないこと。
    初回でrootユーザで実行するとログファイルがrootユーザで作成されてしまい、
    tomcat専用ユーザでstartup.shを実行しても権限がないと言われてしまうので、
    そうなった場合、1度ログを削除すれば問題なし。

    sudo -u tomcat /usr/local/tomcat/bin/shutdown.sh
    

【APサーバ】Java導入

  • Java導入確認
    AWSでは初期状態でJavaが導入済の状態になっています。

    java -version
    
    java version "1.7.0_85"
    OpenJDK Runtime Environment (amzn-2.6.1.3.61.amzn1-x86_64 u85-b01)
    OpenJDK 64-Bit Server VM (build 24.85-b03, mixed mode)
    

    JAVA_HOMEも設定済のため、そのまま利用する。
    JAVA_HOMEは下記パスを参照している。

    /usr/lib/jvm/jre