最近の悩みは、ブラックフライデーに乗せられてまた本を買ってしまったので、積み本消化と仕事の両立です。。。
今回は、正直サーバーレスではなくちょっと古い感じの手法ですが、クラウドサービスの制限によらずに使えるのと、比較的簡単に移行できるということで、個人サービスで導入したDockerコンテナ上でバッチ実行をするためにdigdagを使ったときのことを書いておきます。
ちなみに、今風にやると、CloudWatch Eventsでイベントを設定して、LambdaやBatch、ECS Fargateを実行するなどになるかと思います。
コンテナイメージを作成する
まずはdigdagを実行できるコンテナイメージを作成します。
本当は外部のPostgreSQLにプロジェクトやタスク情報など保存することで、複数ワーカーでの実行や、Fargateでの実行なども簡単になりますが、今回はh2dbで実行することを想定しています。
FROM alpine:3.12 ENV DIGDAG_VERSION 0.10.0 ENV JAVA_VERSION 8 RUN apk --no-cache add \ libc6-compat \ openjdk${JAVA_VERSION} \ logrotate \ curl RUN apk add --no-cache --virtual \ build-dependencies && \ curl -o /usr/local/bin/digdag --create-dirs -L "https://dl.digdag.io/digdag-${DIGDAG_VERSION}" && \ chmod +x /usr/local/bin/digdag && \ apk del build-dependencies RUN mkdir -p /digdag/logs /digdag/h2db /logs RUN chmod 755 /logs/* WORKDIR /digdag COPY ./digdag.conf /digdag/digdag.conf COPY ./workflow /digdag/workflow CMD ["/usr/local/bin/digdag", "scheduler", "-c", "digdag.conf", "--task-log", "log/digdag.log", "--project workflow/"]
基本的には、alpine linuxをベースに、digdagをインストールしているだけです。
digdagの設定(主にDBに接続情報など)は ./digdag.conf
、実行する各種ワークフローは ./workflow
ディレクトリにあるものとしています。
とりあえず、logrotateをdigdagで実行する
cronで動いているものとして、EC2インスタンスなどの環境では、logrotateがあると思います。
今回は、これをdigdagで実行してみます。
Fargateなどになると、そもそもlogrotateを実行することがないので、そのままは役に立ちませんが、わかりやすいということで…
まずはdigdag.confです。今回は、インメモリのh2dbなので以下のように設定します。
database.type = h2 database.path = ./h2db/digdag.db
つぎに、logrotateを実行する、digdagのワークフローを実装します。
timezone: Asia/Tokyo schedule: daily>: 03:00:00 skip_delayed_by: 15m +logrotate: sh>: logrotate -v -f /etc/logrotate.d/logrotate.conf
毎日日本時間の3時に実行するようにしていますが、 skip_delayed_by
で遅延した複数回のワークフローが実行されることを防いでいます。
あとは、logrotateを実行しているだけです。
ちなみにこのあたり設定については過去のEmbulkとdigdagの記事で紹介しています。
まとめ
上記を準備していくだけで簡単に複数の複雑な手順のバッチ実行ができるようになり、またPostgreSQLなどにすることで複数ワーカーでの実行なども可能になります。digdagでは、起動していない時間の分をさかのぼって実行などの機能もある点も魅力的です。
とはいえ、Lambda上で簡単にできる機能や、少数の定期バッチを実行するだけであれば、クラウドの機能を活用してサーバーレスを目指して行くほうが良いかと思います。ECS + EC2の環境などでこれまでのcronからとりあえず移行したい場合などには、こうした手段も使えるということで、簡単にですが記事として記載しました。