⏰
Fly.ioで運用しているRails 8のアプリでタスクを定期的に実行
はじめに
Fly.ioで運用しているRailsアプリで定期的にタスクを実行したいことがありました。Supercronicを使えばできるようなので、開発中のアプリに導入してみました。
タスクの作成
まずはrakeコマンドで実行するタスクを作成します。
rails g task scheduled_jobs deliver_daily_activities
lib/tasks/scheduled_jobs.rb
namespace :scheduled_jobs do
desc "Deliver daily activities"
task deliver_daily_activities: :environment do
# task
end
end
タスクを実行するスケジュールの設定
Railsアプリのルートにcrontabを作成します。Fly.ioにデプロイしたマシンの時刻はUTCなので、時差の9時間を考慮して設定します。
日本時間の23:58に実行する場合、UTCで14:58を指定します。
crontab
58 14 * * * bundle exec rake scheduled_jobs:deliver_daily_activities
Supercronicのインストール
Dockerfileの最終ステージの部分を編集してSupercronicをインストールします。
Dockerfile
# Final stage for app image
FROM base
# Copy built artifacts: gems, application
COPY "${BUNDLE_PATH}" "${BUNDLE_PATH}"
COPY /rails /rails
# Latest releases available at https://github.com/aptible/supercronic/releases
ENV SUPERCRONIC_URL=https://github.com/aptible/supercronic/releases/download/v0.2.33/supercronic-linux-amd64 \
SUPERCRONIC_SHA1SUM=71b0d58cc53f6bd72cf2f293e09e294b79c666d8 \
SUPERCRONIC=supercronic-linux-amd64
RUN curl -fsSLO "$SUPERCRONIC_URL" \
&& echo "${SUPERCRONIC_SHA1SUM} ${SUPERCRONIC}" | sha1sum -c - \
&& chmod +x "$SUPERCRONIC" \
&& mv "$SUPERCRONIC" "/usr/local/bin/${SUPERCRONIC}" \
&& ln -s "/usr/local/bin/${SUPERCRONIC}" /usr/local/bin/supercronic
COPY crontab crontab
# Run and own only the runtime files as a non-root user for security
RUN groupadd --system --gid 1000 rails && \
useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \
chown -R rails:rails db log storage tmp
USER 1000:1000
# Entrypoint prepares the database.
ENTRYPOINT ["/rails/bin/docker-entrypoint"]
# Start server via Thruster by default, this can be overwritten at runtime
EXPOSE 80
CMD ["./bin/thrust", "./bin/rails", "server"]
Supercronicの起動
fly.tomlの[processes]
セクションを以下のように追加します。
fly.toml
app = 'sampleapp'
primary_region = 'nrt'
console_command = '/rails/bin/rails console'
[build]
[deploy]
release_command = "./bin/rails db:prepare"
[processes]
app = "./bin/rails server -p 8080"
cron = "supercronic /rails/crontab"
[env]
HTTP_PORT = '8080'
Fly.ioにアプリをデプロイします。
fly deploy
タスクを実行するマシン数を設定
自分の場合はタスクを実行するマシンが1台でよかったので、flyコマンドでスケールするマシンを1に設定しました。
fly scale count cron=1
参考
Discussion