LoginSignup
70
11

docker環境からcronを定期実行させるのに苦戦した話

Last updated at Posted at 2023-12-11

概要

はじめまして。アドベントカレンダーの13日を担当します。
今回は件名にあるとおり、ローカルのdocker環境で処理を定期実行するためにcronを使用した話をまとめようと思います。
少々長くなりますがお付き合いください。

要件

今回実装したい処理の要件は以下になります。

  • WEBサイトの稼働サーバーに月1回作成されるレポートファイルをローカルに取得する(踏み台サーバーを経由する必要あり)
  • ファイルの中身を取得し、その内容をbacklogAPIを用いて新規登録させる。担当者を報告先のアカウントに設定する。
  • 新規登録した課題は「未対応」となるため「処理済み」とステータスを変える。

というのが要件です。
「稼働サーバーから直接API投げればよくない?」と思われそうですがセキュリティの関係上ローカルのPCからAPIを実行する必要があり、この要件で実装をしていきます。

実装内容

今回はdocker内PHPコンテナ内に実装した処理をホストのubuntu環境で定期実行設定するようにします。

稼働サーバーのレポートファイルを取得する

まず稼働サーバーへの接続設定をおこないます。
実行ユーザーのディレクトリ内に.sshディレクトリを作成し、configファイルを以下のように記述します。

Host {踏み台サーバー名}
 HostName {踏み台サーバーのIP}
 User {実行ユーザー}
 IdentityFile {秘密鍵ファイルの場所}

Host {稼働サーバー名}
 HostName {稼働サーバーのIP}
 User {実行ユーザー}
 IdentityFile {稼働サーバーへの接続鍵}
 ProxyJump {踏み台サーバーのHost}

このように設定すると、ssh {稼働サーバー名}でローカルから踏み台サーバー経由で稼働サーバーへログインすることができました。

コンテナ内に直接ディレクトリを作成するとdockerの起動時に毎回ディレクトリが削除されてしまうため、永続ボリューム等に上記のディレクトリを設定をおこない、起動時に実行ユーザーディレクトリにコピーすると毎回自動でディレクトリを作成してくれます。

注意点としてはコピー時に.sshディレクトリの権限を700、その他のファイル(config,鍵ファイル等)は権限を600にする必要があります。chmod ◯◯◯ {ファイルorディレクトリ}で権限を変えましょう。

これで稼働サーバーのファイルを取得できるようになりました。

scp {稼働サーバーのファイル} {ローカルの置き場所}

でレポートファイルをローカルに置いてしまいましょう。

レポートファイルをbacklogAPIで課題登録する

backlogはAPIドキュメントを用意してくれているのでこれを参考にします。
https://developer.nulab.com/ja/docs/backlog/#

今回は新規課題登録のAPIを実行します。

backlog.php
$host = 'backlogホスト';
$apiKey = 'ユーザー設定から取得したAPIキー';

$params = array(
    'projectId' => '課題を登録するプロジェクトのID',
    'summary' => '課題のタイトル',
    'issueTypeId' => '課題の種別ID',
    'assigneeId' => '担当者のID'
    'description' => '課題詳細、取得したレポートをここに添付する'
);

$headers = array('Content-Type:application/x-www-form-urlencoded');
$context = array(
    'http' => array(
        'method' => 'POST',
        'header' => $headers,
        'ignore_errors' => true
    )
);

$url = 'https://' . $host . '/api/v2/issues?apiKey=' . $apiKey . '&' . http_build_query($params, '', '&');
$response = json_decode(@file_get_contents($url, false, stream_context_create($context)));

このようにすると新規で課題が登録され、課題の情報がresponseに格納されます。

登録した課題を処理済みに変更する

今回は報告用のチケットを提出する際、チケットを「処理済み」にする必要があります。
課題情報の更新のAPIはbacklog.phpの処理に以下を追記します。

backlog.php
$id = $response->id; // idに登録した課題のキーが格納されている
$params = array(
    'statusId' => 3 // 1:未対応 2:処理中 3:処理済み 4:完了
);

$headers = array('Content-Type:application/x-www-form-urlencoded');
$context = array(
    'http' => array(
        'method' => 'PATCH',
        'header' => $headers,
        'ignore_errors' => true
    )
);

$url = 'https://' . $host . '/api/v2/issues/' . $id .  '?apiKey=' . $apiKey . '&' . http_build_query($params, '', '&');
$response = json_decode(@file_get_contents($url, false, stream_context_create($context)));

これで登録した課題のステータスを変更することができました。
要件を満たすPHPファイルの作成完了です。

作成した処理をcronにて定期実行させる

docker環境のcrontabに下記を記述することで定期実行ができました。
今回は月初の報告になるので毎月1日9時に実行する設定とします。
docker環境のディレクトリでないとdocker-composeが動かないためPHPファイル実行前にcdで場所を変える必要があります。(今回一番つまづいた・・)

SHELL=$SHELL
PATH=$PATH

0 9 1 * * cd {dockerディレクトリ}; /usr/local/bin/docker-compose exec -T php /bin/bash -c "php {上記で作成したPHPファイルの場所}" > {ログを出す場合は出力先} 2>&1

これで無事毎月のレポート提出を自動化することができました。

まとめ

最後までみていただきありがとうございます。
dockerの仕様の勉強、backlogAPIの勉強、crontabの勉強ができ、為になる作業だったと思います。
つまづく箇所って意外と小さなことだったりしますよね。
今後の誰かのつまづきの助けになればと思います。

70
11
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
70
11