LoginSignup
6
3

More than 3 years have passed since last update.

【Docker】crond専用のコンテナからHTTPリクエストを送ったり他コンテナのコマンドを実行してみたりする【cron】

Posted at

こんにちは!
鍋が美味しくてごきげんな季節になってまいりました。おさむです。

Dockerコンテナでcronによる定期処理を実行したいなあと思いたち、
いろいろ試してみた結果をまとめてみます。

この記事のゴール

粛々と時を刻み続けるDockerコンテナを手に入れる

前提

  • Dockerがインストールされており、hello-worldが動作する状態になっていること

試したこと

①あるURLに対して定期的にリクエストを送ってみる

AlpineLinuxはapkというパッケージマネージャにより、コマンドを追加することが出来ます。
この項ではcurlコマンドを追加でインストールし、
それを用いてGoogleのトップページにリクエストを送ってみます。

Dockerfile
# 公式版でもたぶんOK
FROM gliderlabs/alpine:latest

# 必要パッケージの取得とタイムゾーンの変更処理(Asia/Tokyo)
RUN \
  apk add --no-cache curl tzdata && \
  cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
  apk del tzdata

# あらかじめ用意しておいたcrontabs用ファイルをコンテナへコピーする
RUN mkdir -p /var/spool/cron/crontabs
COPY ./resource/cron/crontabs/root /var/spool/cron/crontabs/root

CMD busybox crond -l 2 -L /dev/stderr -f
root
# GoogleへGETリクエストを送信し、帰ってきたレスポンスのヘッダをひたすら追記していく
* * * * * curl https://www.google.co.jp/ -I >> /root/header.txt

# POSTも出来る。JSONを特定のAPIに流し込んだり。
# * * * * * curl -X POST -H "Content-Type: application/json" -d '{"id":"114514", "num":"810"}' localhost:8080/api

②定期的に別コンテナのコマンドを実行してみる

コンテナの中にdockerのバイナリを配置し、ホストマシンにある/var/run/docker.sockをマウントすると、
Dockerコンテナの中からでも別コンテナの操作が可能になります。
これを利用して他のコンテナのコマンドを実行してみました。

ただし、ちょっとトリッキーな方法であるため、こちらで言及されている通りWebAPI化し、
①の方法でリクエストを発行したほうが良いかもしれません。お好みで。

今度は複数のコンテナで連携するため、docker-composeも使用していきます。

docker-compose.yml
version: '2'
services:
  app:
    build: ./app
  cron:
    build: ./cron
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
volumes:
  db-data:
Dockerfile
# 公式版でもたぶんOK
FROM gliderlabs/alpine:latest

# 必要パッケージの取得とタイムゾーンの変更処理(Asia/Tokyo)
RUN \
  apk add --no-cache tzdata && \
  cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
  apk del tzdata

# dockerのバイナリを取得し、クライアントのみを/usr/local/binへコピー
RUN apk add --no-cache ssl_client && \
  mkdir -p /usr/local/bin && \
  wget https://get.docker.com/builds/Linux/x86_64/docker-latest.tgz -O - | tar -xzC /usr/local/bin --strip=1 docker/docker

# あらかじめ用意しておいたcrontabs用ファイルをコンテナへコピーする
RUN mkdir -p /var/spool/cron/crontabs
COPY ./resource/cron/crontabs/root /var/spool/cron/crontabs/root

CMD busybox crond -l 2 -L /dev/stderr -f
root
# appコンテナにあるコマンドを実行する
* * * * * docker exec example_app_1 /root/example.sh

# ちなみに、Laravelのスケジュール実行も同じ要領で起動できる
# * * * * * docker exec example_app_1 php artisan schedule:run

余談

なんでこんな事してるかと言うと、↑の「Laravelのスケジュール実行」を実現したかったから。
php-fpmをFROMに書いたDockerfileの中で無理やりbusyboxを起動するというのもアリなんですが、
それをするとphp-fpmのプロセスが上がってこないという現象が発生したりで色々と難があったため。

参考

Dockerコンテナ上でCronを動かしたい
curlコマンドを実行するだけのDockerfile
Alpine Linux でタイムゾーンを変更する
Alpine LinuxでDockerコンテナ開発を加速する
Docker コンテナから別のコンテナへコマンドを実行し、返り値を得る

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3