- 投稿日:2019-08-20T23:11:00+09:00
System specを使えるRuby on Rails開発環境をDockerで作る
Railsチュートリアルの2周目を、Docker環境でかつテストをRspecに代えて進めていたのですが、System specを導入しようとしたところで挫折…。
いろいろ調べたり、指導者の方に聞いたりして解決しましたので、同じように迷っている人の為になればと思い、書き残してみます。そもそもSystem specとはなんぞや?
System specについて知らない人はこちらの記事が参考になると思います。
rspec-rails 3.7の新機能!System Specを使ってみた簡単に説明すると、エンドツーエンド(E2E)テストを実行するための機能です。みなさんが実際にブラウザを利用するようにボタンやリンクを押してどの画面に遷移しただとか、その画面にはある特定のHTMLタグが含まれているかどうかなどをテストすることができます。
使ってみればわかると思いますが、とてもわかりやすく便利です。ちなみに、System specはrspec-rails 3.7以降から導入されたのですが、その前はFeature specというのが使われていました。実はほとんど同じなので、Feature specで進めても良いのですが、公式で推奨されているのでSystem specを使ってみたいと思います。
System(Feature) specで使えるいろいろな機能は以下の記事を参考にしてください。
使えるRSpec入門・その4「どんなブラウザ操作も自由自在!逆引きCapybara大辞典」さらにそもそもRSpecやDockerに詳しくない方へ
RSpec→使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」
Docker→【図解】Dockerの全体像を理解する -前編-
※ Dockerがインストールされていることを前提に話を進めますので、忘れずにインストールしておいてくだい。では、本題に入りましょう。
ちなみに、一から作成していくので、すでにRailsでDocker環境を持っている人は適宜置き換えて試してみてください。docker-composeを用いてRails Projectを作成する
完成版をおいておきます。
https://github.com/tegnike/system_specではまず、以下のファイルを作成しましょう。
- Dockerfile
- docker-compose.yml
- Gemfile
- Gemfile.lock
RailsのDocker環境作成に関しては以下の記事を参考にしています。
docker-compose で Rails の開発環境を作るDockerfileFROM ruby:2.4.2 RUN apt-get update -qq && apt-get install -y build-essential libpq-dev postgresql-client unzip RUN sh -c 'wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -' && \ sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list' && \ apt-get update && apt-get install -y google-chrome-stable RUN mkdir /app WORKDIR /tmp COPY Gemfile Gemfile COPY Gemfile.lock Gemfile.lock RUN bundle install ADD . /app WORKDIR /appSystem specではGoogle Chromをインストールしておく必要があるので、3行目のRUNでそれを実行しています。
docker-compose.ymldb: image: postgres expose: - "5432" web: build: . command: bundle exec rails s -p 3000 -b '0.0.0.0' volumes: - .:/app ports: - "3000:3000" links: - dbGemfilesource 'https://rubygems.org' gem 'rails', '~> 5.1.4'Gemfile.lockGemfile.lockは中身は空のまま、ファイルだけ作成ください。
ちなみに、Dockerfileの3行目のRUNでsystem specに必要なGoogle Chromeをwebコンテナにインストールしています。これらのファイルが用意できたら、それらがあるフォルダで以下のコマンドを実行してください。
$ docker-compose run web rails new . --force --database=postgresql --skip-testこのコマンドを実行することで、docker-compose.ymlに定義したwebコンテナを一時起動し、Rails Projectを作成することができます。
フォルダ下にRailsのファイルたちが追加されていますね。
では、更新されたGemfileにrspecでのテストに必要な下記のgemを追記しましょう。Gemfilegem 'therubyracer', platforms: :ruby # 先頭の"#"を消す ### 省略 ### group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console | gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] # 元から書いてあります gem 'rspec-rails' # 追記 end group :test do gem 'capybara' # 追記 gem 'selenium-webdriver' # 追記 gem 'webdrivers' # 追記 gem 'launchy', '~> 2.4.3' # 追記 endでは、更新したGemfileをimageに含めるためにbuildを実行しましょう。
$ docker-compose build次に、database.ymlを編集します。
今回はデータベースにpostgresqlを使用するので、以下のように設定してください。config/database.ymldefault: &default adapter: postgresql encoding: unicode username: postgres # 追記 host: db # 追記 password: # 追記以下のコマンドでデータベースを作成します。
$ docker-compose run web rake db:createこれで一通り準備が整いましたので、下記のコマンドでコンテナを立ち上げてから
localhost:3000
にアクセスすれば、お馴染みのYay! You're on Rails!を見ることができます。$ docker-compose up -dSystem specを導入する
では、System specを導入していきましょう。
まず、下記のコマンドを実行することでRSpecの設定ファイルであるspec_helper.rb
とrails_helper.rb
の2つのファイルが作成されます。$ docker-compose run web rails generate rspec:installそして
rails_helper.rb
は以下のように修正してください。spec/rails_helper.rb# This file is copied to spec/ when you run 'rails generate rspec:install' require 'spec_helper' ENV['RAILS_ENV'] = 'test' require File.expand_path('../../config/environment', __FILE__) # Prevent database truncation if the environment is production abort("The Rails environment is running in production mode!") if Rails.env.production? require 'rspec/rails' require 'capybara/rspec' # Add additional requires below this line. Rails is not loaded until this point! # Requires supporting ruby files with custom matchers and macros, etc, in # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are # run as spec files by default. This means that files in spec/support that end # in _spec.rb will both be required and run as specs, causing the specs to be # run twice. It is recommended that you do not name files matching this glob to # end with _spec.rb. You can configure this pattern with the --pattern # option on the command line or in ~/.rspec, .rspec or `.rspec-local`. # # The following line is provided for convenience purposes. It has the downside # of increasing the boot-up time by auto-requiring all files in the support # directory. Alternatively, in the individual `*_spec.rb` files, manually # require only the support files necessary. # Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f } # Checks for pending migrations and applies them before tests are run. # If you are not using ActiveRecord, you can remove these lines. begin ActiveRecord::Migration.maintain_test_schema! rescue ActiveRecord::PendingMigrationError => e puts e.to_s.strip exit 1 end RSpec.configure do |config| # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures config.fixture_path = "#{::Rails.root}/spec/fixtures" # If you're not using ActiveRecord, or you'd prefer not to run each of your # examples within a transaction, remove the following line or assign false # instead of true. config.use_transactional_fixtures = true # RSpec Rails can automatically mix in different behaviours to your tests # based on their file location, for example enabling you to call `get` and # `post` in specs under `spec/controllers`. # # You can disable this behaviour by removing the line below, and instead # explicitly tag your specs with their type, e.g.: # # RSpec.describe UsersController, :type => :controller do # # ... # end # # The different available types are documented in the features, such as in # https://relishapp.com/rspec/rspec-rails/docs config.infer_spec_type_from_file_location! # Filter lines from Rails gems in backtraces. config.filter_rails_from_backtrace! # arbitrary gems may also be filtered via: # config.filter_gems_from_backtrace("gem name") config.before(:each, type: :system) do driven_by :selenium_chrome end config.before(:each, type: :system, js: true) do driven_by :selenium_chrome end endもう1つ、
capybara.rb
というファイルを作ります。これはまだ作成されていないので、specフォルダの下にsupportファイルを作り、その下に配置しましょう。spec/support/capybara.rbCapybara.default_driver = :selenium_chrome Capybara.javascript_driver = :selenium_chrome Capybara.register_driver :selenium_chrome do |app| options = ::Selenium::WebDriver::Chrome::Options.new options.add_argument('--headless') options.add_argument('--no-sandbox') options.add_argument('--disable-gpu') options.add_argument('--window-size=1400,1400') Capybara::Selenium::Driver.new(app, browser: :chrome, options: options) endこれでSystem specの設定は完了です。
System specでテストしてみよう!
せっかく作ったので試してみたいのですが、今のままだとモデルがなくてテストができないので、
scaffold
コマンドでUserモデルを作成します。ついでにマイグレーションも実行しましょう。※ ちなみに今回はSystem specが動くかどうか確認することを目的としていますので、複雑なテストは書きません。
$ docker-compose run web bin/rails g scaffold User name:string $ docker-compose run web rake db:migratespecフォルダ下にSystem spec用のフォルダを作成し、そこに
users_spec.rb
を作成します。spec/system/users_spec.rbrequire 'rails_helper' RSpec.describe 'Users', type: :system, js: true do before do @user = User.create!(name: 'Test User') end it 'ユーザ名が表示されること' do visit user_path(@user) expect(page).to have_content @user.name end endでは、テストを実行してみましょう。
$ docker-compose up $ docker-compose run web rspec spec/system/users_spec.rb Starting system_spec_db_1 ... done . Finished in 5.18 seconds (files took 4.95 seconds to load) 1 example, 0 failuresはい、問題なく成功しました!
まとめ
この記事では、System Specを使えるDocker環境の構築を説明しました。
冒頭でも説明しましたが、Feature Specとほとんど一緒のSystem Specですが、確実に上位互換なので導入しておいて損はないでしょう(公式でも推奨されていますしね)。では、また。
参考
- 投稿日:2019-08-20T22:13:03+09:00
DockerでCPUの使用量制限をする(--cpus)
概要
Dockerには使えるCPUのコア(スレッド)数を制限する機能があります。
0.1コア分だけ使用するdocker update --cpus 0.1 container docker create -it --cpus 4.5 --storage-opt size=120G fedora /bin/bash最小単位が0.01から、最大で搭載しているコアの数まで上げられます。
これと言って特定のコアにやらせるわけではないので、OSが勝手に実際に使うコアを指定します。docker updateの場合には即座に制限が有効になるようです。
仕組み
例えば、
docker update --cpus 0.1 container
とした場合、
docker inspect container ・・・ "HostConfig": { "NanoCpus": 100000000, ・・・とされます。
NanoCPU つまり
100000000 NanoCPU = 0.1 CPUコアという等式が成り立ちます。
NanoCPUというのは
CPU quota in units of 10-9 CPUs.
1CPUを109区切りにした値のようです。
ところが、なぜこのような奇妙な分け方をするのは明らかではありません。
小数点を入れないようにするためでしょうか。関連記事
- Dockerコンテナで利用できるリソースや権限を制限する(Dockerの最新機能を使ってみよう:第3回)
- https://qiita.com/hoto17296/items/43d8c2d695c8724b99aa
参考文献
- 投稿日:2019-08-20T19:38:30+09:00
ローカルにDockerレジストリを建てる
レジストリのコンテナを起動
docker run -d -p 5000:5000 --restart=always --name registry registry:2タグをつけてpushする
$ docker tag sample:0.1.0 localhost:5000/sample $ docker push localhost:5000/sample
- 投稿日:2019-08-20T15:59:43+09:00
CircleCIで複数のイメージを利用する場合の注意点
発生した事象
CICDフローにおいて、CircleCi上でrspecを実行するために準備として
rails db:create
を実行した。
しかし、実行中にDB接続エラーが発生した。結論
CircleCIのジョブ実行において複数のイメージ指定する場合、DBの接続ホスト指定は
localhost
を指定ではなく127.0.0.1
を使おう。失敗時のエラーメッセージ
rails aborted! Mysql2::Error::ConnectionError: Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2 "No such file or directory")良くあるrailsからDBへの接続エラーですね。
ローカルのmysqlを参照しにいこうとしている様子。現状の設定見直し
接続エラーなので、DBの接続情報の設定を見直してみる。
Circleciの
config.yml
接続コマンドや環境変数や
RAILS_ENV
も適切で問題なさそう。Ruby on Railsで利用している
database.yml
設定ファイル上に、DB接続ホスト、ユーザ名、DB名が指定してあるため接続には問題なさそう。
調査
調査を進めると次の記事にヒットしました。
また、各コンテナ間の連携には localhost を使うことはできません。 127.0.0.1 を指定するようにすることと、Rails であれば config/database.yml で以下のような記述を追加することを忘れないようにしましょう。
https://tech.smarthr.jp/entry/2017/07/12/073000対応
上記の記事より、本件も同一事象と仮定しrailsで指定しているDBのhost指定を、
localhost
ではなく、127.0.0.1
に変更し動作確認。jobの確認
#!/bin/bash -eo pipefail bundle exec rails db:create bundle exec rails db:migrate bundle exec rspec Created database 'hoge' (中略) Finished in 0.00373 seconds (files took 0.87988 seconds to load)実行も完了し、ジョブも正常終了したのでOK!。
- 投稿日:2019-08-20T13:07:28+09:00
DockerでGitLab
古くなったGitLabサーバを刷新することになった。
折角なのでDockerでやってみた。Docker定義
web: image: 'gitlab/gitlab-ce:latest' restart: always container_name: 'gitlab' hostname: 'xxx.yyy.com' environment: GITLAB_OMNIBUS_CONFIG: | external_url 'http://xxx.yyy.com/gitlab' ports: - '10080:80' - '10443:443' - '10022:22' volumes: - '/srv/gitlab/config:/etc/gitlab' - '/srv/gitlab/logs:/var/log/gitlab' - '/srv/gitlab/data:/var/opt/gitlab'特に工夫はない。ポートを既存のものと被らないようにしただけ。
volumesはパスを変えたらうまく動作しなかった気がする?
メモリは4GBでやっと動いた。そこそこリソースは必要みたいです。起動まで時間がかかるので、起動しきったかを以下のコマンドで確認した。
docker-compose logs -f
- 投稿日:2019-08-20T12:48:18+09:00
Docker×Python×Oracle-CloudでLINE Botを作ってみた。 #2
はじめに
Flask×PythonでBotのアルゴリズムを作り、dockerの乗せてリモートサーバ稼働させる流れをまとめたものです。
第1回(前回)は、
python3の記述までの内容を扱いました。今回は、
Dockerfileの作成からリモートサーバでのデプロイまでの内容を扱います。目次
実装環境
環境
- MacOS X 10.13.6 (local)
- Docker 18.09.2
Docker
{$PWD}/Dockerfile
を作成します。Dockerfile# ベースとなるイメージを指定する FROM ubuntu:latest # コンテナ上のワーキングディレクトリを指定する WORKDIR /usr/src/ # ディレクトリやファイルをコピーする # 左側がホストのディレクトリ、右側がコンテナ上のディレクトリ COPY ./src /usr/src COPY ./startup.sh /startup.sh # "docker build"時に実行される処理 RUN apt-get update RUN apt-get install python3 python3-pip -y RUN pip3 install flask RUN pip3 install line-bot-sdk RUN pip3 install python-dotenv RUN chmod 744 /startup.sh RUN echo "building..." # "docker run"実行時に実行される処理 CMD /startup.shまた、docker runでstartup.shを実行しますが、内容はこんな感じです。
startup.sh# 日本語扱えるようにする export LC_CTYPE=C.UTF-8 # flask run!! python3 /usr/src/app.pyリモートサーバ
以下のコマンドを実行します。
これからはリモートサーバでの作業になります。$ scp . user@server:~/ $ ssh user@server:~/docker-bot $ (sudo) docker build -t bot . # 割と時間かかるこれで、dockerの準備は完了です。
あとはLINEサーバとの接続と docker run すればbotが動きそうです。Webhootの設定
LINEサーバとの接続をするためには、Webhookの設定をする必要がありますが、https通信以外は弾かれてしまいます。
その打開策として、今回はngrokを使います。
参考: ngrokが便利すぎるngrokを実行(
{ngrok directory}/ngrok http {port}
)すると以下のような画面が表示されます。
Forwardingのhttpsのアドレス(この場合はad19992.a.ngrok.io
)をあとで使います。
また、このアドレスはngrokを実行するたびにランダムで変更されます。ngrokngrok by @inconshreveable (Ctrl+C to quit) Session Status online Session Expires 7 hours, 59 minutes Version 2.3.34 Region United States (us) Web Interface http://127.0.0.1:4040 Forwarding http://ad19992a.ngrok.io -> http: Forwarding https://ad19992a.ngrok.io -> http Connections ttl opn rt1 rt5 p 0 0 0.00 0.00 0tmux
サーバ上ではdockerとngrokをマルチに開いておく必要があるので、今回はtmuxを採用します。
参考: tmuxを必要最低限で入門して使うtmuxで実現するイメージserver ├ docker-run └ ngrokserver$ tmux new -s docker-run $ (sudo) docker run -it --rm -p 8000:8000 bot # ウィンドウからデタッチ ctrl + b, d $ tmux new -s ngrok $ {ngrok directory}/ngrok http 8000 # line devloperの設定を行う ctrl + b, d # サーバからログアウトしてもdocker-run, ngrokは停止しない。 $ exitLINE Devloperの
「TOP > プロバイダーリスト > {プロバイダー名} > {botのアカウント名} > チャネル基本設定」
で、
メッセージ送受信設定の「Webhook送信」を「利用する」に変更した後、
Forwardingのhttpsのアドレスをコピーして、「Webhook URL」に貼り付けます。
最終的には Webhook URL がhttps://ad19992.a.ngrok.io/callback
になるようにします。以上で、botにラインを送った時の返信が変更されます。
おわりに
ngrokとflaskはdocker-composeでまとめられそうだけど、docker-compose分からないので、その辺りは追々学ぼうと思いました。
参考
- 投稿日:2019-08-20T09:16:12+09:00
Ubuntu18.04/Re:VIEW/docker-compose/zathuraを使って薄い本を書く手順
モチベーション
- 素早く薄い本を書くぞ!
- なるたけ楽するぞ!
使用するもの
- Docker(仮想環境を簡単/便利に扱えるツール)
- docker-compose(複数の仮想環境を簡単に扱えるツール)
- Re:VIEW(軽量マークアップ言語からpdf(latex), epubなどの書籍が簡単に作れるツール)
- zathura(vimのキーバインドが使える軽量PDFビューアー)
手順
1. Re:VIEWのDockerイメージをダウンロードする
bash$ sudo docker pull vvakame/review2. 薄い本の雛形を作成する
bash$ cd $ sudo docker run --rm -v `pwd`:/work vvakame/review /bin/sh -c "cd /work && review-init hello"3. docker-composeを使ってpdfファイルを作成する
bash$ cd # 所有権を変更する $ sudo chown -R solareenlo:solareenlo hello $ cd hello # Dockerfileを作成する $ echo FROM vvakame/review > Dockerfile # docker-compose.ymlを作成する $ cat <<EOF > docker-compose.yml version: '3' services: review: volumes: - .:/work build: . working_dir: /work EOF # pdfファイルを作成する $ sudo docker-compose run review rake pdf4. zathuraで作成したPDFを確認する
bash$ sudo apt install zathura $ zathura --fork book.pdf5. いろいろ削除する
bash# pdf作成過程で出来た不要なコンテナを削除する $ sudo docker container prune # Re:VIEWのDockerイメージを削除する $ sudo docker image rm vvakame/review:latest # zathuraを削除する $ sudo apt uninstall zathuraあとは好きなエディタとドキュメントを見ながら作成する
参考文献
- 投稿日:2019-08-20T09:16:12+09:00
Ubuntu18.04/Re:VIEW/docker-compose/zathuraを使った薄い本を書く手順
モチベーション
- なるたけ楽して$LaTeX$使って薄い本を書く.
- ホスト環境を変更せずに素早く薄い本を書く.
使用するもの
- Docker(仮想環境を簡単/便利に扱えるツール)
- docker-compose(複数の仮想環境を簡単に扱えるツール)
- Re:VIEW(軽量マークアップ言語からpdf(latex), epubなどの書籍が簡単に作れるツール)
- zathura(vimのキーバインドが使える軽量PDFビューアー)
手順
1. Re:VIEWのDockerイメージをダウンロードする
bash$ sudo docker pull vvakame/review2. 薄い本の雛形を作成する
bash$ cd $ sudo docker run --rm -v `pwd`:/work vvakame/review /bin/sh -c "cd /work && review-init hello"3. docker-composeを使ってpdfファイルを作成する
bash$ cd # 所有権を変更する $ sudo chown -R solareenlo:solareenlo hello $ cd hello # Dockerfileを作成する $ echo FROM vvakame/review > Dockerfile # docker-compose.ymlを作成する $ cat <<EOF > docker-compose.yml version: '3' services: review: volumes: - .:/work build: . working_dir: /work EOF # pdfファイルを作成する $ sudo docker-compose run review rake pdf4. zathuraで作成したPDFを確認する
bash$ sudo apt install zathura $ zathura --fork book.pdf5. いろいろ削除する
bash# pdf作成過程で出来た不要なコンテナを削除する $ sudo docker container prune # Re:VIEWのDockerイメージを削除する $ sudo docker image rm vvakame/review:latest # zathuraを削除する $ sudo apt uninstall zathuraあとは好きなエディタとドキュメントを見ながら作成する
参考文献