Rails6とSidekiqのアプリをDockerで作ってHerokuでリリース
Ruby3.0、Rails6でSidekiqを使ったアプリをDocker上に作る際に引っかかったので、備忘録を書いておきます。
Herokuにリリースします。
参考にしたURL:https://blog.u6k.me/2018/04/29/sample-sidekiq.html
$ mkdir myapp
$ cd myapp
GemfileとGemfile.lock、Dockerfile、docker-compose.ymlを作成して、Gemfileを編集してgem 'sidekiq'とgem 'sidekiq-cron'を追加
$ touch Gemfile Gemfile.lock Dockerfile docker-compose.yml
$ cat Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby '3.0.1'
gem 'rails', '~> 6'
railsコマンドをDockerコンテナ化する。Dockerfileを作って以下のように編集
FROM ruby:3.0.1
RUN apt-get update && \
apt-get install -y \
nodejs postgresql-client && \
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 && \
apt-get update && apt-get install -y yarn && \
apt-get clean
VOLUME /myapp
WORKDIR /myapp
COPY Gemfile .
COPY Gemfile.lock .
RUN bundle install
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
docker-compose.ymlを作って以下のように編集
version: '3'
services:
web:
build: .
environment:
- "RAILS_ENV=development"
- "REDIS_URL=redis://redis:6379"
volumes:
- ".:/myapp"
ports:
- "3000:3000"
depends_on:
- db
- redis
worker:
build: .
environment:
- "RAILS_ENV=development"
- "REDIS_URL=redis://redis:6379"
volumes:
- ".:/myapp"
depends_on:
- "redis"
command: sidekiq
redis:
image: redis:4.0
volumes:
- "redis:/data"
command: redis-server --appendonly yes
db:
image: postgres
ports:
- '5432:5432'
volumes:
- postgresql-data:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=password
volumes:
redis:
driver: local
postgresql-data:
driver: local
Docker上でrails new
$ docker-compose run web rails new . --force --no-deps --database=postgresql --skip-bundle
Gemfileを編集してsidekiqを追加
# sidekiq
gem 'sidekiq'
gem 'sidekiq-cron'
イメージをビルドしてwebpackerをインストール
$ docker-compose build
$ docker-compose run web yarn install --check-files
$ docker-compose run web bundle exec rails webpacker:install
トップページをwelcomeページから変えて、config/routes.rbでrequireやmountをしておきます。
$ docker-compose exec web rails g controller home top
require 'sidekiq/web'
require 'sidekiq/cron/web'
Rails.application.routes.draw do
mount Sidekiq::Web, at: '/sidekiq'
get "/" => "home#top"
end
config/database.ymlを編集
default: &default
adapter: postgresql
encoding: unicode
host: db
username: postgres
password: password
pool: 5
development:
<<: *default
database: myapp_development
test:
<<: *default
database: myapp_test
production:
<<: *default
database: myapp_production
username: myapp
password: <%= ENV['MYAPP_DATABASE_PASSWORD'] %>
コンテナを起動
$ docker-compose up -d
dbを作ってマイグレート
$ docker-compose run web rake db:create
$ docker-compose run web rails db:migrate
これでlocalhost:3000を開けば表示されます。
Hello ワーカーを作成します
$ docker-compose exec web rails g sidekiq:worker Hello
app/worker/hello_worker.rbにputs "hello"を追加
class HelloWorker
include Sidekiq::Worker
def perform(*args)
puts "hello"
end
end
コンテナを再起動してrailsコンソールを開きます
$ docker-compose down -v
$ docker-compose up -d
$ docker-compose exec web rails c
ワーカーをキューに登録します。
> HelloWorker.perform_async
正常に登録された場合、文字列が表示されます。
キューに登録したワーカーはすぐに実行されたことをworkerコンテナのログを確認します
$ docker-compose logs worker
worker_1 | hello
という行があれば実行されています。
sidekiqのcron化をしていきます。
コンテナを再起動してRailsコンソールを開き、
$ docker-compose down -v
$ docker-compose up -d --build
$ docker-compose exec web rails c
sidekiqでクーロンを登録します
Sidekiq::Cron::Job.create name: "Hello Job", cron: "* * * * *", class: "HelloWorker"
ログを確認すると、約1分ごとにジョブが実行されていることがわかります。
docker-compose logs worker
orker_1 | 2021-06-14T21:07:33.930Z pid=1 tid=641 INFO: Booted Rails 6.1.3.2 application in development environment
worker_1 | 2021-06-14T21:07:33.931Z pid=1 tid=641 INFO: Running in ruby 3.0.1p64 (2021-04-05 revision 0fb782ee38) [x86_64-linux]
worker_1 | 2021-06-14T21:07:33.932Z pid=1 tid=641 INFO: See LICENSE and the LGPL-3.0 for licensing details.
worker_1 | 2021-06-14T21:07:33.932Z pid=1 tid=641 INFO: Upgrade to Sidekiq Pro for more features and support: https://sidekiq.org
worker_1 | 2021-06-14T21:07:33.933Z pid=1 tid=641 INFO: Booting Sidekiq 6.2.1 with redis options {:url=>"redis://redis:6379"}
worker_1 | 2021-06-14T21:10:10.749Z pid=1 tid=eox class=HelloWorker jid=4b94056a98e35c24d72cf61c INFO: start
worker_1 | hello
worker_1 | 2021-06-14T21:10:11.100Z pid=1 tid=eox class=HelloWorker jid=4b94056a98e35c24d72cf61c elapsed=0.348 INFO: done
worker_1 | 2021-06-14T21:11:03.202Z pid=1 tid=euh class=HelloWorker jid=1e975d07184b6d8b5cd52b45 INFO: start
worker_1 | hello
worker_1 | 2021-06-14T21:11:03.206Z pid=1 tid=euh class=HelloWorker jid=1e975d07184b6d8b5cd52b45 elapsed=0.003 INFO: done
worker_1 | 2021-06-14T21:12:08.061Z pid=1 tid=ev1 class=HelloWorker jid=188bc7a35b13bef271afb3c0 INFO: start
worker_1 | hello
worker_1 | 2021-06-14T21:12:08.065Z pid=1 tid=ev1 class=HelloWorker jid=188bc7a35b13bef271afb3c0 elapsed=0.004 INFO: done
worker_1 | 2021-06-14T21:13:22.170Z pid=1 tid=evl class=HelloWorker jid=6d5f82a01ae29804c9663749 INFO: start
worker_1 | hello
worker_1 | 2021-06-14T21:13:22.173Z pid=1 tid=evl class=HelloWorker jid=6d5f82a01ae29804c9663749 elapsed=0.003 INFO: done
Herokuでリリース
# ログイン
$ heroku login
# herokuのコンテナレジストリにログイン
$ heroku container:login
# アプリ作成
$ heroku create アプリ名
$ heroku config:set HOST=0.0.0.0
$ rm tmp/pids/server.pid
# イメージを作成してコンテナレジストリにpush
$ heroku container:push web
# postgresqlアドオンの無料プランを追加
$ heroku addons:create heroku-postgresql:hobby-dev
# イメージをherokuへデプロイ
$ heroku container:release web
# DBセットアップ
$ heroku run rails db:migrate
# アクセス
$ heroku open