【LINE通知機能】Docker+Redis+Sidekiq+Active Jobを使いチャットを送信。Renderへのデプロイをする
はじめに
こんにちは! プログラミング初学者のyukimuraです!
今回は私自身の個人開発したアプリで実装した、LINE通知機能についてのRenderへのデプロイ方法を記述します。
間違いなどありましたら、優しくご指摘いただけましたら幸いです
LINE通知機能の実装自体は前回で既に終わっているので、前回の記事をご覧になってない方は先にそちらをご覧ください
始める前に
今回の実装とは別にRenderへのデプロイ方法に、render.ymlファイルを作成して行う方法があります
こちらは公式にも記載されております
よければこちらの方法も参考にどうぞ
実装手順
- RenderでRedisを作成する
- 環境変数を設定する
- Dockerfile.sidekiqを作成する
- RenderでBackground Worker(sidekiq)を作成する
- 実行を確認できたら、時間を調整する
RenderでRedisを作成する
1. 実装を開始します
Render.comのDashboardからRedisを作成してください
- 作成されたRedisのInternal Redis URLを使用します
環境変数を設定する
1. gem 'dotenv-rails'のインストール
Gemfile
gem 'dotenv-rails'
2. bundle install
bundle install
3. .envファイルをルートディレクトリに作成し、環境変数を設定する
## ローカルのURL
REDIS_URL_DEVELOPMENT = "redis://redis:6379"
## 作成されたRedisのInternal Redis URLを使用
REDIS_URL_PRODUCTION = "redis://your-production-redis-url:6379"
4. config/initializers/sidekiq.rbを修正する
Sidekiq.configure_server do |config|
config.redis = { url: Rails.env.production? ? ENV.fetch('REDIS_URL_PRODUCTION', nil) : ENV['REDIS_URL_DEVELOPMENT'] }
end
Sidekiq.configure_client do |config|
config.redis = { url: Rails.env.production? ? ENV.fetch('REDIS_URL_PRODUCTION', nil) : ENV['REDIS_URL_DEVELOPMENT'] }
end
5. .gitignoreファイルに下記を記述しないと、git hubに挙げられてしまうので注意
.gitignore
/.env
6. 設定の確認
- rails コンソールで下記コマンドを実行して、設定した値が返ってきたら成功です
> ENV['REDIS_URL_PRODUCTION']
参考記事
7. Web Serviceに接続する
- 作ったRedisのinternal-Redis-urlをWeb ServiceのEnvironmentから追加してください
Dockerfile.sidekiqを作成する
1. Web Serviceとは別にBackground Worker(sidekiq)を動かすために、Dockerfile.sidekiqを作成します
Dockerfile.sidekiq
ARG RUBY_VERSION=3.2.3
FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base
WORKDIR /rails
ENV RAILS_ENV="production" \
BUNDLE_DEPLOYMENT="1" \
BUNDLE_PATH="/usr/local/bundle" \
BUNDLE_WITHOUT="development"
FROM base as build
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y build-essential curl git libpq-dev libvips node-gyp pkg-config python-is-python3
ARG NODE_VERSION=20.13.1
ARG YARN_VERSION=1.22.22
ENV PATH=/usr/local/node/bin:$PATH
RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \
/tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \
npm install -g yarn@$YARN_VERSION && \
rm -rf /tmp/node-build-master
COPY Gemfile Gemfile.lock ./
RUN bundle install && \
rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \
bundle exec bootsnap precompile --gemfile
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile
COPY . .
RUN bundle exec bootsnap precompile app/ lib/
FROM base
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y curl libvips postgresql-client && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives
COPY --from=build /usr/local/bundle /usr/local/bundle
COPY --from=build /rails /rails
RUN useradd rails --create-home --shell /bin/bash && \
chown -R rails:rails db log storage tmp
USER rails:rails
CMD ["bundle", "exec", "sidekiq"]
Dockerfileとの違い
Dockerfile
# syntax = docker/dockerfile:1
ARG RUBY_VERSION=3.2.3
FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base
WORKDIR /rails
ENV RAILS_ENV="production" \
BUNDLE_DEPLOYMENT="1" \
BUNDLE_PATH="/usr/local/bundle" \
BUNDLE_WITHOUT="development"
FROM base as build
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y build-essential curl git libpq-dev libvips node-gyp pkg-config python-is-python3
ARG NODE_VERSION=20.13.1
ARG YARN_VERSION=1.22.22
ENV PATH=/usr/local/node/bin:$PATH
RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \
/tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \
npm install -g yarn@$YARN_VERSION && \
rm -rf /tmp/node-build-master
COPY Gemfile Gemfile.lock ./
RUN bundle install && \
rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \
bundle exec bootsnap precompile --gemfile
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile
COPY . .
RUN bundle exec bootsnap precompile app/ lib/
ENV SECRET_KEY_BASE=Rails.application.config.secret_key_base=ENV['SECRET_KEY_BASE']
RUN ./bin/rails assets:precompile
FROM base
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y curl libvips postgresql-client imagemagick && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives
COPY --from=build /usr/local/bundle /usr/local/bundle
COPY --from=build /rails /rails
RUN useradd rails --create-home --shell /bin/bash && \
chown -R rails:rails db log storage tmp
USER rails:rails
ENTRYPOINT ["/rails/bin/docker-entrypoint"]
EXPOSE 3000
CMD ["./bin/rails", "server", "-b", "0.0.0.0", "-p", "3000"]
- dockerfileではコンテナができたらこのコマンドが最後に実行されることによってサーバーが立ち上がる
ENTRYPOINT ["/rails/bin/docker-entrypoint"]
EXPOSE 3000
CMD ["./bin/rails", "server", "-b", "0.0.0.0", "-p", "3000"]
- sidekiqfileだと下記のコマンド。Dockerfileとの差異はここだけ
CMD ["bundle", "exec", "sidekiq"]
2. procfileにコードを記述
web: env RUBY_DEBUG_OPEN=true bin/rails server -b 0.0.0.0 -p 3000
js: yarn build --watch
css: yarn build:css --watch
worker: bundle exec sidekiq #追加
- Procfile(プロックファイル)
HerokuなどのPaaS(Platform as a Service)環境でアプリケーションを動かす際に、どのプロセスをどのように実行するかを定義するファイルです。主に、アプリケーションのWebサーバーの起動方法やバックグラウンドジョブの実行方法を指定します。
- Procfileの役割
Procfileは、アプリケーションで実行するプロセス(仕事の流れ)をHerokuや他のサービスに伝えるために使われます。これがあることで、HerokuがどのコマンドでWebサーバーや他のタスクを実行するのかを理解できるようになります。
3. 再buildとupを行う
docker compose build
docker compose up
4. ローカルでは新しいターミナルでsidekiqサーバーを動かす必要がなくなる
- 前回の記事では、sidekiqを動かすために、新しいターミナルからコンテナに入って
budle exec sidekiq
を実行して行っていたが、Dockerfile.sidekiq
の作成と
procfile
にコードを記述したことで、docker compose up
だけでsidekiqも立ち上がると思います(redisも同様に) - upした時に、4つのコンテナの起動が確認
- procfileで設定したコマンドが実行されていることも確認できます
RenderでBackground Worker(sidekiq)を作成する
1. Render.comのDashboardからBackground Worker(sidekiq)を作成してください
- この部分で課金が必要になります
2. 作成ができたら、読み込むDockerfile Pathを変更する
- Background Workerのsettingで読み込むdocker fileをDockerfile.sidekiqにする
3. Environmentを設定する
4. 確認
時間の確認
Regionに東京がないことから、シンガポールに設定していると思われます
シンガポールからは時差が9時間あるために、もし朝7時に送信されて欲しいのであればscheduleでは
22時に送信される設定にしてください
例
:scheduler:
:schedule:
send_line_message_job:
cron: "0 22 * * *" # 毎朝7時に実行するためにシンガポールの9時間前に設定
class: "SendLineMessageJob"
queue: default
最後に
実装は以上になります
Dockerなどのインフラ知識がまだまだ足りてないことが実感させられた実装でした
きっと他にもっと良い方法があると思いますので、一つの方法として受け止めてもらえたら幸いです
Dokcerについて
- Dockerfile.sidekiqについて
図から、composeは一個一個イメージを作成してbuildするのが面倒だからそのコンテナ作成を,一つのコマンドでまとめてやってくれるもの。。
でもrenderではwebサービスとbaskgroundサーバーをわけてしまっているから、一個一個イメージが必要だったという理解を自分はしています。
最後までご覧いただきありがとうございました
参考記事一覧
Discussion