Ubuntuで定刻にコマンドを実行する方法
UbuntuでWindowsのタスクスケジューラのように定刻でコマンドを実行するには、cronやsystemd timerを利用します。本記事では、毎日9:00にDockerコンテナを自動停止するジョブを例に、定期実行の手順を解説します。
cronで設定する
- cron設定を開く
ターミナルで以下のコマンドを実行します。Dockerをsudoで動かしている場合はsudoをつけてください。crontab -e -
スケジュールを追記する
ファイルの末尾にスケジュールを書き込みます。
記述例
0 9 * * * /usr/bin/docker container stop コンテナスケジュール指定部分の内容項目 記述 意味 指定できる範囲 第1項目 (分) 00分に 0 ~ 59 第2項目 (時) 99時に 0 ~ 23 第3項目 (日) *毎日 1 ~ 31 第4項目 (月) *毎月 1 ~ 12 第5項目 (曜日) *すべての曜日 0 ~ 7(※0と7が日曜日) *は 「すべて(条件を問わない)」 という意味です。
*/nは指定間隔ごとに実行で、*/10 * * * *とすると10分おきに実行という意味になります。 - 保存して閉じれば設定完了です
/usr/bin/docker のように「フルパス」で記述するのがポイントです。
うまく動かない場合はログを確認します。ログの出力はcronの設定を以下のように書き換えます。
0 9 * * * /usr/bin/docker container stop コンテナ名 >> /tmp/cron_docker.log 2>&1
systemd timerを使う
最近のUbuntu環境ではcronよりもsystemd timerの方が推奨されることが多いです。
cronでよく起きる「環境変数が足りない」「ログが見えない」「改行の落とし穴」といった問題が起きにくく、失敗した場合の原因(ログ)も圧倒的に調べやすいのが特徴です。
systemd timer を使って「毎日 9:00 にコンテナを停止する」設定手順を解説します。
systemd timer の仕組み
systemd では、以下の2つのファイルをペアで作ります。
.serviceファイル(何をやるか:docker container stop を実行する).timerファイル(いつやるか:9:00 に起動する)
設定手順
今回は例として、設定名を stop-my-container とします。
1. Serviceファイル(実行するコマンド)を作成する
ターミナルから任意のエディタでファイルを作成します。
sudo vi /etc/systemd/system/stop-my-container.service
以下の内容を記述します。(コンテナ名 はご自身の環境に合わせてください)
[Unit]
Description=Stop Docker Container
[Service]
Type=oneshot
# 実行したいコマンドを書く
ExecStart=/usr/bin/docker container stop コンテナ名
2. Timerファイル(スケジュール)を作成する
次に、時間を指定するファイルを作ります。
sudo vi /etc/systemd/system/stop-my-container.timer
以下の内容を記述します。
[Unit]
Description=Timer to stop Docker Container daily at 9:00
[Timer]
# 毎日 9:00 に実行する(年-月-日 時:分:秒)
OnCalendar=*-*-* 9:00:00
# もし9:00にPCの電源が落ちていて実行できなかった場合、次回起動時にすぐ実行するかどうか
Persistent=true
[Install]
WantedBy=timers.target
3. 設定を反映して、タイマーを有効化する
作成したファイルをシステムに認識させ、タイマーをスタートさせます。以下の3つのコマンドを順番に実行してください。
# ① systemdに新しいファイルを読み込ませる
sudo systemctl daemon-reload
# ② タイマーを自動起動(PC再起動後も有効)に設定し、今すぐ開始する
sudo systemctl enable --now stop-my-container.timer
# ③ タイマーが正しく登録されたか確認する
systemctl list-timers | grep stop-my-container
③のコマンドを実行したとき、次に実行される予定時刻(NEXT列)が 9:00:00 になっていれば成功です。
systemd timer のメリット(cronとの違い)
systemd timer に乗り換えると、以下の大きなメリットがあります。
1. ログがめちゃくちゃ見やすい
もし動かなかった場合、以下のコマンドを打つだけで「なぜ失敗したか」の詳細なエラーログが確認できます。cronのようにわざわざログ出力の設定を書く必要がありません。
journalctl -u stop-my-container.service
2. 手動テストが簡単
「とりあえず今すぐ動くかテストしたい」という時は、タイマーを待たずに以下のコマンドで .service だけを実行してテストできます。(これでコンテナが止まれば設定は完璧です)
sudo systemctl start stop-my-container.service
3. 時間の指定が分かりやすい
cronの 0 9 * * * よりも、OnCalendar=*-*-* 9:00:00 の方が直感的で間違いが起こりにくいです。
cronで上手く動かなかった場合はsystemd timerdを試してみてください。
