What is it, naokirin?

バッチ実行をcronから移行する 〜Dockerコンテナにdigdagを添えて〜

最近の悩みは、ブラックフライデーに乗せられてまた本を買ってしまったので、積み本消化と仕事の両立です。。。

今回は、正直サーバーレスではなくちょっと古い感じの手法ですが、クラウドサービスの制限によらずに使えるのと、比較的簡単に移行できるということで、個人サービスで導入した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の記事で紹介しています。

naokirin.hatenablog.com

まとめ

上記を準備していくだけで簡単に複数の複雑な手順のバッチ実行ができるようになり、またPostgreSQLなどにすることで複数ワーカーでの実行なども可能になります。digdagでは、起動していない時間の分をさかのぼって実行などの機能もある点も魅力的です。

とはいえ、Lambda上で簡単にできる機能や、少数の定期バッチを実行するだけであれば、クラウドの機能を活用してサーバーレスを目指して行くほうが良いかと思います。ECS + EC2の環境などでこれまでのcronからとりあえず移行したい場合などには、こうした手段も使えるということで、簡単にですが記事として記載しました。