プロジェクト

全般

プロフィール

Redmineプラグイン開発環境

CentOS 7 開発者のホームディレクトリ下に展開

RedmineをCentOS 7の個人領域にインストールして開発用に使用する構築手順です。
注)tarボールをダウンロードする方法を記載していますが、Redmineのリポジトリからクローンしてくる方がよいかと思います。

redmineの展開

tarボールをダウンロードして展開

~$ mkdir work
~$ cd work
work$ tar xzf ~/redmine-3.3.0.tar.gz
  :
work$ cd redmine-3.3.0
redmine-3.3.0$ 

リポジトリからクローン

Redmine自体のコードはSubversionリポジトリで管理されています。git利用が増えたので、gitミラーリポジトリが用意されています。

  • 開発版(trunk)のgitミラー(master)
    ~$ git clone https://github.com/redmine/redmine.git 
    

ブランチを指定してクローンするときは、gitコマンドのオプションを指定します。

  • 安定版(3.4-stable)のgitミラー
    ~$ git clone -b 3.4-stable https://github.com/redmine/redmine.git
    

データベース設定ファイルの作成

開発用の環境なので、sqliteをデータベースに使用します。
Redmineインストールディレクトリの下で、config/database.yml.example を参考に、database.ymlファイルを作成します。

production:
  adapter: sqlite3
  database: db/redmine.sqlite3

development:
  adapter: sqlite3
  database: db/redmine.sqlite3
  • 上述の内容は、製品モード・開発モードとも同じデータベース(SQLite3)を使う設定です。

Linuxにsqlite開発パッケージのインストール

$ sudo yum install sqlite-devel
  :

設定ファイルの作成

redmine-3.3.0$ cd config
config$ cp -p configuration.yml.example configuration.yml

必要なRubyモジュールの取得

データベース設定に基づき必要なデータベースコネクションモジュールを読み込むので、データベースの設定ファイルの作成が終わってから実行します。

redmine-3.3.0$ bundle install --path vendor/bundler

セッション秘密鍵の生成

redmine-3.3.0$ bundle exec rake generate_secret_token
  • Redmine 4以降は、rakeをrailsと指定しても実行可能です。

データベースの初期化(テーブル作成)

redmine-3.3.0$ bundle exec rake db:migrate
redmine-3.3.0$ REDMINE_LANG=ja bundle exec rake redmine:load_default_data
Default configuration data loaded.

ファイアウォールにポート3000を設定

CentOS 7の場合次の設定をします。

~$ sudo firewall-cmd --zone=public --add-port=3000/tcp --permanent
success
~$ sudo firewall-cmd --reload
success
~$ sudo firewall-cmd --zone=public --list-port
21/tcp 3000/tcp 8008/tcp
~$

Redmineの実行

Redmineに標準で搭載されているWEBrickサーバーを使って実行します。

redmine-3.3.0$ ruby bin/rails server -b 0.0.0.0
=> Booting WEBrick
=> Rails 4.2.6 application starting in development on http://0.0.0.0:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
[2016-10-07 22:24:03] INFO  WEBrick 1.3.1
[2016-10-07 22:24:03] INFO  ruby 2.3.1 (2016-04-26) [x86_64-linux]
[2016-10-07 22:24:03] INFO  WEBrick::HTTPServer#start: pid=23239 port=3000

ブラウザからポート3000へアクセスするとRedmine画面が表示されます。

  • -b 0.0.0.0 について
    WEBrickサーバーは、デフォルトでは、localhost(127.0.0.1)にbindするため、別マシンからのアクセスを受け付けません。そこで、0.0.0.0(どのアドレスからも接続可)を指定します。

エラーになる場合、bundleで実行

以下は、Redmine 4.0.0リリース前のtrunkでの実行例です。

redmine$ bundle exec rails server -b 0.0.0.0
=> Booting Puma
=> Rails 5.1.6 application starting in development
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.11.4 (ruby 2.4.1-p111), codename: Love Song
* Min threads: 0, max threads: 16
* Environment: development
* Listening on tcp://0.0.0.0:3000
Use Ctrl-C to stop

Fedora 26 の開発者アカウント下に展開

先のCentOS 7への展開との差分だけ記述します。
Redmineのソースコードは、redmineのレポジトリからチェックアウトします。Fedoraは、yumではなくdnfでRPMパッケージをインストールするのでそのコマンドを記載しています。

redmine自身のソースコード一式をチェックアウト

~$ cd Documents
Documents$ mkdir redmine
Documents$ cd redmine
redmine$ svn co http://svn.redmine.org/redmine/branches/3.4-stable
  :
redmine$ ls
3.4-stable
redmine$

データベースの設定

database.ymlの記述は先のものと同一

Linuxにsqlite開発パッケージのインストール

$ sudo dnf install sqlite-devel
  :

Linux Subsystem for WindowsのopenSUSE上へのインストール

先のCentOS 7への展開との差分だけ記述します。

Windows 10(2017-10に更新が提供された Fall Creators Update以降で正式搭載)のLinux Subsystem for Windows で、openSUSEを使用した環境でのRedmineのプラグイン開発環境の構築をします。

2017-11-10現在、openSUSE Leap 42です。
rubyはデフォルトでは2.1ですが、openSUSEのパッケージリポジトリにはruby2.4も存在しています。Redmine 4.0以降はruby 2.2以降を要求するので、動かすRedmineのバージョンによって必要なrubyバージョンを使います。

GitでRedmine自体を取得

Subversionは標準では入っていなかったので、Redmineのリポジトリをミラー(?)しているGithubから取得しました。

~/redmine$ git clone -b 3.4-stable https://github.com/redmine/redmine.git
Cloning into 'redmine'...
remote: Counting objects: 144588, done.
remote: Compressing objects: 100% (34/34), done.
remote: Total 144588 (delta 27), reused 26 (delta 17), pack-reused 144537
Receiving objects: 100% (144588/144588), 49.38 MiB | 4.08 MiB/s, done.
Resolving deltas: 100% (113230/113230), done.
~/redmine$

必要なOSパッケージの追加

ruby 2.4(Redmine 4以降を動かすとき)

openSUSE Leap 42.3 標準のRubyは2.1です。Redmine 4.0以降(Rails 5.x)はRuby 2.2以降を必要とするので、より新しいRubyを入れます。
$ zypper search ruby で検索すると、ruby2.4が見つかります。

$ sudo zypper install ruby2.4-devel
  :

ZLib、ImageMagick、SQLite3

$ sudo zypper install zlib-devel ImageMagick-devel sqlite3-devel

ruby gem bundler

Leap42.3標準のruby 2.1使用の時
$ sudo zypper install ruby2.1-rubygem-bundler
ruby2.4の時
$ sudo zypper install ruby2.4-rubygem-bundler

gemのインストール・ネイティブビルド・実行に必要なパッケージ

bundle exec rake generate_secret_token実行時にnokogiriが吐くlibexslt.soがないとエラー

  • libxslt1
    libexslt.soを含むパッケージはlibxslt1ですが、ネイティブビルド時にdevelパッケージも必要ではないか?と思い、libxml2-devel と libxslt-devel を入れています。

bundle exec rake db:migrate実行時にZoneInfoDirectoryNotFound といったエラー

  • timezone
    OSのパッケージの方です。

gemのインストール

3.4-stable$ bundle install --path vendor/bundler

環境変数の設定

NAMEとVERSIONの問題

Windows Subsystem for Linux上にOpenSUSE Leap 42を入れた際、デフォルトで環境変数NAMEとVERSIONが定義されていました。

~$ echo $NAME
openSUSE Leap
~$ echo $VERSION
42.3

この状態でプラグインのmigrateを実行するとエラーとなります。

plugins$ bundle exec rake redmine:plugins:migrate

Plugin openSUSE Leap was not found.

Redmineのrake redmine:plugins:migrate コマンドでは、環境変数NAMEとVERSIONをプラグイン名とバージョン名として扱っているためです。

.bashrc にunsetで環境変数NAMEとVERSIONを未定義にしておきます。
unset NAME VERSION

RUBYOPT

rubyコマンド実行時にInsecure world writable dir /mnt/c in PATH, mode 040777の警告が出るのを抑制するのに設定します。
~/.bashrc に次を追記します。

export RUBYOPT=-W0

WSLでは、Windows側のコマンドを実行できるよう、/mnt/cを含むパスが環境変数PATHに設定されています。rubyはPATHに含まれるディレクトリに制限なく書き込み可能なものがあるとこの警告を表示します。WSLでは個人使用のPC上で開発者が作業するのが主な用途なので、この処置としています。

PS1

bashプロンプトを短くかつ使い勝手のよい設定にします。デフォルトでは「ユーザー名@ホスト名:カレントディレクトリのフルパス」となっているので、開発作業で深いディレクトリを扱うとプロンプトだけでコマンドウィンドウの端まで占めてしまうこともあります。
次に、開発作業ではgitをバシバシ使うので、プロンプトにgitのブランチ名を表示します。

  • プロンプトにはユーザー名、ホスト名は表示せず、カレントディレクトリは末端のディレクトリ名だけ表示
  • プロンプトにはgit作業ディレクトリであればブランチ名を表示
PS1="\W\[\033[36m\]\$(__git_ps1)\[\033[00m\]\$ " 
if [ -f ~/.git-completion.bash ]; then
        . ~/.git-completion.bash
fi
if [ -f ~/.git-prompt.sh ]; then
        . ~/.git-prompt.sh
fi
export GIT_PS1_SHOWDIRTYSTATE=1
export GIT_PS1_SHOWSTASHSTATE=1
export GIT_PS1_SHOWUNTRACKEDFILES=1
export GIT_PS1_SHOWUPSTREAM="auto" 
  • GIT_PS1_SHOWDIRTYSTATE=1 は、作業ツリーに変更があれば*を表示
  • GIT_PS1_SHOWSTASHSTATE=1 は、作業ツリーにスタッシュがあれば$を表示
  • GIT_PS1_SHOWUNTRACKEDFILES=1 は、作業ツリーにステージングされていない新規ファイルがあれば%を表示
  • GIT_PS1_SHOWUPSTREAM="auto"は、作業ツリーのリポジトリが追跡ブランチより進んでいるか遅れているかを<または>で表示

git-completion.bashとgit-promt.shはダウンロードして$HOMEに隠しファイル(ファイル名の先頭にピリオドを付けて)保存します。

Redmineの実行

エラー

次のコマンドでエラーになりました。

$ ruby bin/rails server -b 0.0.0.0
Could not find rake-12.3.1 in any of the sources
Run `bundle install` to install missing gems.

次で実行できました。rakeはbundleコマンドでRedmineディレクトリ下(vendor/bundler)に入れています。そのため、gemのrakeがシステムにインストールされていないとエラーになります。bundleで実行する必要がありました。

$ bundle exec rails server -b 0.0.0.0

性能面

Windows OS上にHyper-Vを使った仮想マシンにFedora 27を入れた環境と、WSLを使ったOpenSUSEを入れた環境と双方を構築しています。
例えば、PUMAサーバーの起動にかかる時間は、仮想マシンでは3秒、WSLでは34秒と10倍の開きがありました。

少し調べてみると、VM(仮想マシン)とWSL(Windows Subsystem for Linux)との性能比較を紹介しているブログがありました。

WSL vs VM for 開発作業

ブログによれば、ファイルI/OがVMに比べて相当に遅いですね。

/mntディレクトリ以外で実行する

WSLの遅さの主要因は、Windows OSのファイルシステムをWSLからアクセスするときのファイルI/O性能の遅さです。
そこで、Redmineの展開先を/mnt以下ではなくWSLのLinuxを入れた場所の下にする(例:ホームディレクトリ下)とかなり速度が改善されます。
PUMAサーバーの起動は13秒となりました。それでもHyper-V上での3秒に比べると重いです。

問題回避・解決

デバッグ

Rack用エラー表示 better_errors

Webブラウザからアクセスしてエラーが発生したときに、エラー発生個所のコンテキストでブラウザ上でREPL環境(コマンドライン)が利用可能になります。

RedmineルートディレクトリのGemfile.localファイルに次を記述し、bundle実行します。

group :development do
  gem 'better_errors'
  gem 'binding_of_caller'
end

エラーが発生すると画面にエラーに至るメソッド呼び出しツリー(Application Frames)と該当コードおよびREPLのコマンドプロンプトが表示されるので、エラー時点での各変数の値などが確認できます。

ステップ実行 pry-byebug

Webブラウザからのアクセステストでは上述のbetter_errorsが有用ですが、テストコードを実行するなどコンソールからWebを介さずに実行しデバッグするときは、このpry-byebugが有用です。

ブレークポイントを置くには直接コードにbinding.pryを記述します。その上でコードを実行すると、REPLでステップ実行が可能になります。

RedmineルートディレクトリのGemfile.localに次を記述し、bundleを実行します。

  gem 'pry-byebug'

ツールの使い方

Puma(rails server)

Ruby on Rails 5以降で標準搭載のアプリケーションサーバーです。

起動方法

$ bundle exec rails server

デフォルトでは、localhostからのアクセスのみ受け入れます。別サーバーからアクセスできるようにするには次のようにオプションを指定します。

$ bundle exec rails server -b 0.0.0.0

  • -bオプションは、--bindの省略形

再起動要否の判断

  • モデルクラス、コントローラークラス、ビューのファイルを変更した場合再起動せずに反映
  • ルーティング設定(routes.rb)を変えたら再起動要

SQLite3

次のコマンドで、Redmineのデータベースを開き対話モードに入ります。

3.4-stable$ sqlite3 db/redmine.sqlite3
sqlite>

テーブル一覧

sqlite> .tables
attachments                          members
auth_sources                         messages
boards                               news
  :

テーブルの構造(スキーマ)

sqlite> .schema wikis
CREATE TABLE IF NOT EXISTS "wikis" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "project_id" integer NOT NULL, "start_page" varchar(255) NOT NULL, "status" integer DEFAULT 1 NOT NULL);
CREATE INDEX "wikis_project_id" ON "wikis" ("project_id");
sqlite>

コマンドの実行結果を見やすくする

  • sqlite> .explain on
    カラムが多い場合は折り返しが発生するのでケースバイケース
  • sqlite> .nullvalue NULL
    デフォルトでNULLの値は空文字列表示なのでNULLかどうか調べるにはこの指定必要

Railsコンソール

redmine$ bundle exec rails console
irb(main):001:0> 

Emacs

web-mode の設定

主に erb(埋め込みruby)ファイルを扱うために設定します。
http://web-mode.org/

  • web-mode.el をダウンロードし、site-lispに配置
  • init.el等に設定を記述
    ;; web-mode
    (autoload 'web-mode "web-mode" nil t)
    (add-to-list 'auto-mode-alist '("\\.erb\\'" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.css\\'" . web-mode))
    (defun my-web-mode-hook ()
      "Hooks for Web mode." 
      (setq web-mode-markup-indent-offset 2) ; HTML element
      (setq web-mode-css-indent-offset 2) ; CSS
      (setq web-mode-code-indent-offset 2) ; misc script/code
      )
    (add-hook 'web-mode-hook 'my-web-mode-hook)
    

RubyMine


5年以上前に更新