SVX日記

2004|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|

2021-08-12(Thu) dockerでcronを使わずに周期実行

  諸君、私はdockerが好きだ。諸君、私はdockerが好きだ。諸君、私はdockerが大好きだ。KubernetesやOpenShiftも便利には違いないが、個人で使うにはアレは重すぎるものだ。では、どんなコンテナ管理を望むか? よろしい、ならばdocker-composeだ。

  自分は長らく自宅サーバを運用しているが、過去記事によれば立ち上げたのは2002年の4月頃らしいから、もうすぐ20年というところ。当然、何度もサーバの移行を繰り返してきたが、この作業が面倒で仕方なかった。

  昔はPCのアプリの導入も「実行ファイルをコピーするだけ」だったが、いつのまにか「インストーラ」なるものを使うのが普通になった。まぁ、構成ファイルが一定数以上になれば仕方ないのだが、それは「システムに永続的な変更をもたらすにも関わらず、何をしでかすかを知りえないプログラム」であるから、いまだ実行するには抵抗がある。

  Linuxの場合、RPMを使う限り安心して導入できるが、データや設定の引き継ぎや、バージョンで仕様に差異があるなど、どうしても細々とした作業が必要となってしまう。長らくどうにかならないものかと思っていたが、ある日、そんな解決方法があったのかと目からウロコが落ちた。それがdockerだ。

  データや設定を分離し、OS環境とアプリと構築手順をまとめてカートリッジ化してしまう。一度、そうしてしまえば、docker/docker-composeが使える環境でありさえすれば、どのカートリッジだろうが、ほぼ共通の僅かなコマンドだけでサービスが起動できてしまう。想像もできなかった解決方法だ。しかし、欲しかったのはまさにこれなのだ。

  そして、意外と楽しいのが、Dockerfileとdocker-compose.ymlを書く作業だ。できるだけ無駄なく、美しく、構築手順を詰めていく。つまり、最低限のコマンド以外の全てを削ぎ落として箱詰めしてカートリッジ化する……おやおや、おやおやおやおや、なんと……なんと素晴らしい……。

  <かきかけ>

# Dockerfile 中の設定スクリプトを抽出するスクリプトを出力、実行
COPY Dockerfile .
RUN echo $'\
cat Dockerfile | sed -n \'/^##__BEGIN0/,/^##__END0/p\' | sed \'s/^#//\' > startup.sh\n\
' > extract.sh && bash extract.sh
  
# docker-compose up の最後に実行される設定スクリプト
##__BEGIN0__startup.sh__
#
#   # easy cron
#   now=`date +%s`
#   target0=$((now - now % ${CYCLE0:=86400}   + ${SCHED0:=$(( 5 * 60 +  4 * 3600 - 32400))}))               # day
#   while [ $target0 -lt $now ]; do
#       ((target0 += CYCLE0))
#   done
#   target1=$((now - now % ${CYCLE1:=604800}  + ${SCHED1:=$(( 5 * 60 +  2 * 3600 + 0 * 86400 - 378000))}))  # week
#   while [ $target1 -lt $now ]; do
#       ((target1 += CYCLE1))
#   done
#   target2=$((now - now % ${CYCLE2:=2419200} + ${SCHED2:=$(( 5 * 60 +  3 * 3600 + 0 * 86400 - 378000))}))  # 4weeks
#   while [ $target2 -lt $now ]; do
#       ((target2 += CYCLE2))
#   done
#
#   s=S
#   while true; do
#       pgrep -f httpd > /dev/null
#       if [ $? -ne 0 ]; then
#           echo "`date`: ${s}tart httpd."
#           /usr/sbin/httpd
#       fi
#       s=Res
#
#       # easy cron
#       if [ `date +%s` -ge $target0 ]; then
#           ((target0 += CYCLE0))
#           echo "`date`: Job easy cron 0 started."
#           (cd /var/lib/pv/hyperestraier; find documents/ -type f -name "*.$FILE_TYPE" | estcmd gather -cl $GATHER_OPTS -cm casket - | grep -v ' passed ')
#       fi
#       if [ `date +%s` -ge $target1 ]; then
#           ((target1 += CYCLE1))
#           echo "`date`: Job easy cron 1 started."
#           (cd /var/lib/pv/hyperestraier; estcmd purge -cl casket | grep -v ' passed')
#       fi
#       if [ `date +%s` -ge $target2 ]; then
#           ((target2 += CYCLE2))
#           echo "`date`: Job easy cron 2 started."
#           (cd /var/lib/pv/hyperestraier; estcmd optimize casket)
#       fi
#       sleep 5
#   done
#
##  target0=$((now - now % ${CYCLE0:=3600}    + ${SCHED0:=$(( 0 * 60))}))                                   # hour
##  target0=$((now - now % ${CYCLE0:=86400}   + ${SCHED0:=$(( 0 * 60 +  0 * 3600 - 32400))}))               # day
##  target0=$((now - now % ${CYCLE0:=604800}  + ${SCHED0:=$(( 0 * 60 +  0 * 3600 + 0 * 86400 - 378000))}))  # week
##  target0=$((now - now % ${CYCLE0:=2419200} + ${SCHED0:=$(( 0 * 60 +  0 * 3600 + 0 * 86400 - 378000))}))  # 4weeks
#
##__END0__startup.sh__
  
ENTRYPOINT ["bash", "startup.sh"]