背景
サービス運用の課題管理とタスク管理をRedmineで行っている。
このうち、タスク管理において、継続的に発生するタスクを定期タスクとして登録したいと考えたが、Redmineには該当する機能がなかった。
手動でチケットを登録していると作業漏れの要因にもなるし、なにより面倒くさいので、自動化しようと考えた。
前提条件
- 複数メンバで運用するサービスであるため、定期タスクとして登録している事項が容易に共有できる
- 各定期タスクについて、備考などのメモ書きを一元管理できる
=別の管理台帳を作成するようなことはしない。
アプローチ
同様の要望は多いようで、プラグインもいくつか見つかったが、上記前提条件に当てはまると思えるものは見つけられなかった。
また、開発が止まっているプラグインも少なくなかった。
そこで、紹介されていたcron+shellで登録する方法を参考に、cronではなくRundeckでshellを実行することにした。
Rundeckでジョブを管理することで、各ジョブの注釈にメモ書きを残すこともできるため、一元管理もできると考える。
構築するコンテナの構成
- RedmineとRundeckのそれぞれについて、バックエンドDBをMySQLで構成する
- Docker(Docker-Compose)を用いて、コンテナを作成する際、引数(環境変数)の指定で作成できるデータベースは1つ1なので、コンテナを分けて2つのDBを構築する
- Redmine APIを実行する際、チケットを作成する対象のプロジェクトやトラッカーをIDで指定する必要がある
- APIで参照/取得することもできるが、各情報を取得するためのAPIコマンドを実行する必要があるため、Adminer(データベース管理ツール)のコンテナを立てて、直接DBを参照できるようにする
構築
フォルダ構成
redmine
├─ redmine
│ └─ files : 各チケットに添付したファイルや画像データ
├─ db_redmine
│ ├─ db : dbデータを格納
├─ rundeck
│ ├─ data : rundeckのデータを格納
│ ├─ logs : rundeckで実行したジョブの実行結果を格納
│ └─ Dockerfile : Rundeckのコンテナをビルドするための定義ファイル
├─ db_rundeck
│ └─ db : dbデータを格納
└─ docker-compose.yaml
adminerは永続化するデータが存在しないので、フォルダを作成しない。
ただし、表示テーマを変更する際は、フォルダを作成してCSSを格納しておく。
Redmineの構築に関しては以下を参照
Rundeckの構築に関しては以下を参照
ここでは、作成したdocker-composeを記載する。
docker-compose.yaml
version: '3.8'
services:
redmine:
image: redmine:5.1.3
ports:
- 8888:3000
volumes:
- ./redmine/plugins:/usr/src/redmine/plugins
- ./redmine/themes:/usr/src/redmine/public/themes
environment:
REDMINE_DB_MYSQL: db_redmine
REDMINE_DB_PASSWORD: example
REDMINE_SECRET_KEY_BASE: supersecretkey
db_redmine:
image: mysql:5.7
volumes:
- ./db_redmine/db:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: example
MYSQL_DATABASE: redmine
command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
rundeck:
build: rundeck/.
environment:
RUNDECK_DATABASE_DRIVER: org.mariadb.jdbc.Driver
RUNDECK_DATABASE_USERNAME: rundeck
RUNDECK_DATABASE_PASSWORD: rundeck
RUNDECK_DATABASE_URL: jdbc:mysql://db_rundeck/rundeck?autoReconnect=true&useSSL=false
RUNDECK_GRAILS_URL: http://<ホストサーバのIPアドレス|ホスト名称>:4440
volumes:
- ./rundeck/data:/home/rundeck/server/data
- ./rundeck/logs:/home/rundeck/var/logs
- /etc/localtime:/etc/localtime:ro
ports:
- 4440:4440
db_rundeck:
image: mysql:5.7
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=rundeck
- MYSQL_USER=rundeck
- MYSQL_PASSWORD=rundeck
- TZ=Asia/Tokyo
volumes:
- ./db_rundeck/db:/var/lib/mysql
command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
adminer:
image: adminer
ports:
- 8080:8080
RundeckのDockerfile
FROM rundeck/rundeck:5.9.0
# RedmineのAPIから返されるJSONを解析するためにjqをインストール
USER root
RUN apt-get update && apt-get install -y \
jq && \
rm -rf /var/lib/apt/lists/*
起動
user@server:/home/com/rundeck$ docker-compose up -d
RundeckでRedmine APIを実行
1. Redmineの初期設定
Redmineにログインしてプロジェクトを作成し、チケットの作成に必要な設定を行う。
- <共通設定>
- プロジェクト情報
プロジェクト名:プロジェクト1、プロジェクト識別子:project1 - チケットのステータス
名称:新規、対応中、完了 - トラッカー情報
名称:トラッカー1、デフォルトのステータス:新規 - ロール
名称:管理者 - 選択肢の値
チケットの優先度: 高、中、低
- プロジェクト情報
- <プロジェクト設定>
- メンバ
Redmine Admin: 管理者 - チケットトラッキング
トラッカー1
- メンバ
2. Redmine APIの有効化
3. Redmine API実行の必要情報を取得
3-1. アクセスキーの取得
「個人設定」を開き、表示されているAPIアクセスキーを記録する。

3-2. プロジェクトID、トラッカーIDの取得
3-2-1. Adminerにアクセスして、RedmineのDBにログインする。

※パスワードは、docker-composeで設定した"example"
3-2-2. "project"テーブルを参照してプロジェクトIDを取得する。

id列の値がプロジェクトID
3-2-3. "tracker"テーブルを参照してトラッカーIDを取得する。

id列の値がトラッカーID
4. RundeckでRedmine APIコマンド実行
Rundeckでのプロジェクトの作成やコマンドの実行設定に関しては以下を参照
ジョブを作成して、Workflowのステップ1にScriptを選択し、Redmine APIコマンドを呼び出すコマンドを入力

Scriptに記載したコマンドを以下にも記載
#!/bin/sh
# Redmine APIのエンドポイントとAPIキー
REDMINE_API_URL="http://192.168.2.10:8888/issues.json"
API_KEY="<3-1で取得したAPIアクセスキー>"
# POSTデータ
POST_DATA='{
"issue": {
"project_id": 1,
"tracker_id": 1,
"subject": "テストチケット1",
"description": "これはテストチケット1です",
"assigned_to_id": 1
}
}'
# RedmineにPOSTリクエストを送信
response=$(curl -s -X POST "$REDMINE_API_URL" \
-H "Content-Type: application/json" \
-H "X-Redmine-API-Key: $API_KEY" \
-d "$POST_DATA")
# jqでerrors配列の長さを取得
errors_count=$(echo "$response" | jq '.errors | length')
# エラーがある場合に、エラーコード99で終了
if [ $errors_count -gt 0 ]; then
echo "Errors count: $errors_count"
echo $response
exit 99
fi
echo "$response" | jq '.'
exit 0
5 動作確認
ジョブの実行結果

ジョブは正常に完了していて、作成されたチケットの情報がログに出力されている。
5-2. 作成されたチケットをRedmineで確認

無事にチケットを登録することができました!!
あとはRundeckのジョブの設定で任意のタイミングで繰り返し実行することで、
自動的に定期タスクのチケットが作成されます。
5-3. 不正なチケットを作成しようとした場合にエラーとなることを確認
チケットの担当者IDに実在しない値を指定して、ジョブを実行してみる。
# POSTデータ
POST_DATA='{
"issue": {
"project_id": 1,
"tracker_id": 1,
"subject": "テストチケット1",
"description": "これはテストチケット1です",
"assigned_to_id": 2
}
}'
実行結果

ジョブは失敗と判定されていて、ログにエラーメッセージも表示されている。
更新
- 2025/02/24
- シェルを作成せずにジョブのScriptにコマンドを記載しても実行できたので記載を変更
- RedmineのAPIからエラーが返された場合に、検知できるようにスクリプトを修正
スクリプトが長くなったので、リファクタリングを実施 - Redmineから返されるJSONテキストを解析するためにjqをインストールする手順(dockerfileを作成)を追加
- Redmine APIからエラーが返される場合に、ジョブが失敗することを確認する手順を追加
-
【Docker】MySQLで複数database環境を構築する
https://qiita.com/piggydev/items/2096258dc45a6bbe2a19 ↩


