概要
redmineのソースコードを読むための環境をDockerで構築します。以下の状態をゴールとします。
- redmineのmasterブランチのコードがDocker上で動作する
- Debug用のツールが使える
モチベーション
動作環境を構築するのは実際のアプリケーションの挙動とコード内容を頭の中で紐付けながらコードリーディングしたいからです。
なぜコードリーディングしたいのか?
人が書いたコードを読むことは新たな発見や学びに繋がると考えています。
私の場合は、クラスの分け方、命名、テストコードの書き方、エラーハンドリングの仕方などに悩むことが最近多いので、そのあたりの引き出しを増やしたいというモチベーションがあります。
なぜRedmineか?
Redmineを選んだのは以下の理由です。
- 普段からRedmineを使っているため馴染みがあり、画面や外部仕様をある程度知っている。
- 長年メンテナンスされており、世界中で使用されている。
- 普段はPHPをつかっているため、あえて別の言語やFWに触れてみる。
環境構築
以下を参考にすすめていきます。
リポジトリの用意
- redmineのレポジトリをフォーク
- フォークしたリポジトリをクローン
-
redmine
ディレクトリに移動 - masterブランチから別ブランチを切る(自分は
code_reading
にしました)
Docker関連ファイルの作成
redmine
ディレクトリ直下に以下のファイルを作成します。
- Dockerfile
- docker-compose.yml
- entrypoint.sh
ファイルの内容は以下の通りにします。
Dockerfile
RedmineのGemfileがconfig/database.yml
を参照しているため、COPY . /redmine
をした後にbundle install
をする必要があります。
ちなみに参照して何をしているかというと、使用するDBにあわせてインストールするGemを変えています。例えばconfig/database.yml
にpostgresの接続情報が書いてあると、postgresに接続するためのGemがインストールされます。
Gemfileで指定するgemを動的に変えるという発想があまりなかったので既に学びがあったと感じています。
FROM ruby:2.5
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
&& echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client yarn
RUN mkdir /redmine
WORKDIR /redmine
COPY Gemfile /redmine/Gemfile
COPY Gemfile.lock /redmine/Gemfile.lock
COPY . /redmine
RUN bundle install
# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]
#!/bin/bash
set -e
# Remove a potentially pre-existing server.pid for Rails.
rm -f /redmine/tmp/pids/server.pid
# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
docker-compose.yml
コメントアウトしているのはruby-debug/ruby-debug-ide用の設定です。
導入しましたが自分の環境では動作が安定しなかったので一旦使わないようにしています。
version: '3'
services:
db:
image: postgres
volumes:
- ./tmp/db:/var/lib/postgresql/data
ports:
- "5433:5432"
environment:
POSTGRES_PASSWORD: password
web:
build: .
# command: bash -c "rm -f tmp/pids/server.pid && bundle exec rdebug-ide --host 0.0.0.0 --port 1234 -- bin/rails s -p 3000 -b 0.0.0.0"
command: bash -c "rm -f tmp/pids/server.pid && bin/rails s -p 3000 -b 0.0.0.0"
volumes:
- .:/redmine
ports:
- "3003:3000"
# - "1234:1234"
# - "26162:26162"
stdin_open: true
tty: true
depends_on:
- db
デバッグ用のGemの追記
- 【Rails】better_errorsとbinding_of_callerで自分でエラーを解決できるようになろう【初心者向け】 - Qiita
- pry-byebugでrubyをデバッグする - Qiita
などの記事を参考にGemfile.に以下を追加します。
- better_errors
- binding_of_caller
- pry-rails
- pry-byebug
group :development do
gem "yard" #この下に追記する
gem "better_errors"
gem "binding_of_caller"
gem "pry-rails"
gem "pry-byebug"
# 安定動作しなかったのでコメントアウト
# gem "ruby-debug-ide"
# gem "debase"
end
また、better_errosをDocker上の環境で使えるようにするため、development.rb
に以下を追記します。
BetterErrors::Middleware.allow_ip! "0.0.0.0/0"
database.ymlの設定
config/database.yml
を作成し以下の内容にします。
default: &default
adapter: postgresql
encoding: unicode
host: db
# For details on connection pooling, see Rails configuration guide
# https://guides.rubyonrails.org/configuring.html#database-pooling
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: postgres
password: password
development:
<<: *default
database: redmine_development
test:
<<: *default
database: redmine_test
production:
<<: *default
database: redmine
環境の立ち上げ
ファイルの用意が完了したのでコンテナを起動し、アプリケーションを動かします。
# 空のGemfile.lockを作る
$ touch Gemfile.lock
# コンテナイメージのビルド
$ docker-compose build
# コンテナの起動
$ docker-compose up -d
# DBの作成
$ docker-compose run --rm web rake db:create
# マイグレーションの実行
$ docker-compose run --rm web bin/bundle exec rake db:migrate
# Redmineのデフォルトデータ投入タスク
$ docker-compose run --rm web bin/bundle exec rake redmine:load_default_data
起動が成功していればdocker-compse ps
で以下のようにStatusがUpになります。
$ dcom ps
Name Command State Ports
--------------------------------------------------------------------------------
redmine_db_1 docker-entrypoint.sh postgres Up 0.0.0.0:5433->5432/tcp
redmine_web_1 entrypoint.sh bash -c rm - ... Up 0.0.0.0:3003->3000/tcp
この後にhttp://localhost:3003
にアクセスするとRedmineの画面が表示されます。
また、最初はIDとパスワード共にadmin
でログインすることができます。
これで環境構築は完了です。
pry-byebugによるデバッグ
docker-compose up
でコンテナが起動している状態でコンテナにアタッチします。
$ docker attach redmine_web_1
確認したいコードの該当箇所にbinding.pry
を追記します。以下の例はRedmineのルートパスにアクセスした時に実行されるwellcome#index
に追加しています。
def index
binding.pry #調べたいところに追加する
@news = News.latest User.current
end
この状態でhttp://localhost:3003
にアクセスするとターミナルに以下の内容が表示されステップ実行などができるようになります。
From: /redmine/app/controllers/welcome_controller.rb:25 WelcomeController#index:
23: def index
24: binding.pry
=> 25: @news = News.latest User.current
26: end
[1] pry(#<WelcomeController>)> Started GET "/" for 172.18.0.1 at 2020-09-27 07:41:34 +0000
[1] pry(#<WelcomeController>)>
[1] pry(#<WelcomeController>)>
の箇所にコマンドを打つことでステップ実行などができます。
- next
- ステップイン
- step
- ステップオーバー
- continue
- プログラムの実行を続行しpryを終了
以上