cronの失敗をGoogle Apps Scriptで通知する
はじめに
cronが面倒くさい。特に失敗を通知するのが。
そもそも標準エラー出力があった時だけ通知されるようにするのも面倒なんですが、
AWSを使ってると迷惑メール扱いされないようにAmazon SES使うなり、DNS逆引き設定するなりしないといけないわけです。
こんなのサーバ毎にやってられんわけです。
ということで、そんな面倒なcronの失敗通知をGoogle Apps Scriptを使うことで楽にします。
スプレッドシート
まずは以下のようなスプレッドシートを作ります。
Google Apps Script
スプレッドシートの [ ツール ] > [ スクリプトエディタ ] を開き、以下の関数を登録します。
function doPost(e) { var sheet = SpreadsheetApp.getActive().getSheetByName('メーリングリスト'); var to_emails = sheet.getRange(1, 1, sheet.getLastRow()).getValues(); var subject = 'エラー通知'; var body = "以下の処理でエラーが発生しました。\n\n"; body += "タスク名: " + e.parameter.task_name; GmailApp.sendEmail(to_emails.join(','), subject, body); }
続いて、作成した関数を公開します。
スクリプトエディタの [ 公開 ] > [ ウェブアプリケーションとして導入... ] を選択します。
GASを初めて公開する場合、Googleの認証が出るので許可してください。
公開の設定は以下になります。
ここで表示される「現在のウェブアプリケーションのURL」にリクエストを送ることでメールが送信されるようになります。
スクリプトを更新する場合
再度、 [ 公開 ] > [ ウェブアプリケーションとして導入... ] が必要になります。
この時にプロジェクトバージョンを上げないと反映されないので注意してください。
自分も毎回やり忘れます。
cron
cronの処理は何でもいいんですが、
例としてLet's Encriptの更新処理をcronに登録します。
/etc/crontab
# エラーはGASで通知するので、全ての出力をリダイレクト 0 6 * * mon root /opt/cron/certbot_renew.sh >> /var/log/certbot_renew.log 2>&1
certbot_renew .sh
#!/usr/bin/env bash /opt/certbot/certbot-auto renew --no-self-upgrade --deploy-hook "systemctl restart nginx" # 証明書の更新に失敗したらGAS経由でメール通知 if [ $? != 0 ]; then TASK_NAME="certbot_renew.sh" curl -X POST -d task_name=$TASK_NAME https://script.google.com/macros/s/${APP_ID}/exec fi
最後に
メールにこだわらなくていいなら、Slackとかに通知した方が楽。
以上、現場からでした。
ポートマッピングを使わずにDockerコンテナにアクセスする方法
この記事はDocker Advent Calendar 2018の16日目になります。
はじめに
記事書いといてアレなんですが
基本的にはポートマッピングを使ったほうがいいと思うので、あんまり使い所はないかもしれません。
自分の場合は、とあるライブラリでWebSocketのコネクションがどうしても上手くいかず
今回の方法に行き着いた感じです。
どこかで誰かの参考になれば幸いなので記事にしたいと思います。
Linuxの場合
コンテナ起動
例として、apacheコンテナを使用していきます。
以下のdocker-compose.ymlを用意して、コンテナを起動します。
$ vi docker-compose.yml version: '3' services: web: image: httpd:2.4-alpine expose: - "80" network_mode: host # ホストのネットワークでコンテナを実行 $ docker-compose up -d
network_mode: host
とすることで、ホストのネットワークに対してポート番号をexposeするため、マッピング無しでアクセス可能となります。
この設定はLinux環境限定のようです。
確認
$ docker ps --format "table {{.Image}}\t{{.Ports}}\t{{.Names}}" IMAGE PORTS NAMES httpd:2.4-alpine test_web_1 $ curl http://localhost <html><body><h1>It works!</h1></body></html>
ポートマッピングしていませんが、アクセスできました。
Docker for Windowsの場合
Hyper-VでDockerデーモンが動いている都合上、仕方ないのかもしれませんが、
network_mode: host
は使えないのでネットワークの設定が必要になります。
コンテナ起動
以下のdocker-compose.ymlを用意して、apacheコンテナを起動します。
$ vi docker-compose.yml version: '3' services: web: image: httpd:2.4-alpine expose: - "80" networks: my_network: ipv4_address: 172.99.0.2 # コンテナのIPを指定 networks: my_network: driver: bridge ipam: driver: default config: - subnet: 172.99.0.0/24 # ネットワークアドレスを指定 $ docker-compose up -d
ネットワークアドレスは172以外は自由に設定できます。
他のdocker networkで使われていないものを指定してください。
ルーティングテーブル設定
Docker for Windowsでは、デフォルトで以下の構成になっているようです。
- 仮想スイッチ:10.0.75.0/24
- DockerNAT:10.0.75.1
- MobyLinuxVM:10.0.75.2
この内のMobyLinuxVMに、先ほどのネットワークアドレスをルーティングします。
$ route -p add 172.99.0.0/24 10.0.75.2 ※管理者権限のコマンドプロンプトで実行
ルーティングテーブルを確認
$ route print
設定を削除する時はこちら
$ route delete 172.99.0.0
この設定については、以下の記事が大変参考になりました。 qiita.com
確認
$ docker ps --format "table {{.Image}}\t{{.Ports}}\t{{.Names}}" IMAGE PORTS NAMES httpd:2.4-alpine 80/tcp test_web_1 $ curl http://172.99.0.2 <html><body><h1>It works!</h1></body></html>
アクセスできました。
Docker for Macの場合
すいません。分かりませんでした。
ただ、Macの場合はWndowsと違ってDocker for MacとVirtualBoxが共存できるので
VirtualBox上のDockerで network_mode: host
を使えば良いかなと思います。
最後に
Macについては思いっきり手抜きとなってしまいましたが、
そもそも今回の記事はDocker for WindowsとVirtualBoxが共存できないことがきっかけになっています。
前述のWebSocketの件で最初は仕方なくVagrantで環境構築したんですが
DockerとVagrantを切り替えるために毎回PCを再起動する状況にノイローゼ寸前だったので、必死に調べた結果となります。
*1
何卒ご容赦ください。
以上、現場からでした。
プライベートDockerHubをゆるく使う
Dockerを使ってるとDockerHubも使いたくなることがあると思いますが、
業務だとimageをパブリックな所に置けなかったりしますよね。
Docker Registryを使えばプライベートなDockerHubを割と簡単に構築できるので、
作り方や使い方などを備忘録も兼ねて公開したいと思います。
imageを共有できれば良いや程度のゆるい感じでやっていきます。
使用マシン
- registry-host(Registryコンテナを起動するマシン)
- my-pc(自分の作業PC)
自分の場合、社内の空きPCをregistry-hostとして使いました。
構築
registry-hostに以下のdocker-compose.ymlを用意してコンテナを起動します。
[registry-host]$ mkdir ~/docker_hub && cd ~/docker_hub [registry-host]$ vi docker-compose.yml version: '2' services: registry: image: registry:2 volumes: - ./registry:/var/lib/registry ports: - "5000:5000" restart: always [registry-host]$ docker-compose up -d
volumesの指定は登録したリポジトリデータを永続化するためのものです。
初回構築時にはdocker-compose.ymlだけあれば良いです。
登録
事前設定
httpで通信する場合、my-pcのDockerでregistry-hostを許可する設定が必要です。
registry-hostの部分はご自身の環境のIPやホスト名に置き換えてください。
これでmy-pcからregistry-hostへimageをpushできます。
例としてalpine linuxを登録してみます。
[my-pc]$ docker pull alpine:latest [my-pc]$ docker tag alpine:latest registry-host:5000/my-alpine:latest [my-pc]$ docker push registry-host:5000/my-alpine:latest
登録の確認
リポジトリ一覧
[my-pc]$ curl http://registry-host:5000/v2/_catalog {"repositories":["my-alpine"]}
タグ一覧
repositoriy名を指定して、タグ一覧を取得します。
この例ではmy-alpineを指定しています。
[my-pc]$ curl http://registry-host:5000/v2/my-alpine/tags/list {"name":"my-alpine","tags":["latest"]}
Pull
[my-pc]$ docker pull registry-host:5000/my-alpine:latest
削除
リポジトリの削除
[registry-host]$ cd ~/docker_hub/registry/docker/registry/v2/repositories [registry-host]$ rm -rf <repositoriy-name>
タグの削除
[registry-host]$ cd ~/docker_hub/registry/docker/registry/v2/repositories [registry-host]$ rm -rf <repositoriy-name>/_manifests/tags/<tag-name>
たぶん削除用のAPIとかあると思うんですが、今のところディレクトリ削除で何とかなってます。
削除自体あまりしないですし、壊れたらまたPushすればいいやってノリです。
今回はゆるく使うということでimageの管理は適当ですが、
ちゃんと管理したい人はPortusというのを使うと色々出来そうです。
まぁ自分だったら、これ以上は面倒なので素直にaws ECRとかを使いますが。
以上、現場からでした。
vscodeで効率良くコードレビューする小技
コードレビューする時の変更箇所を比較する方法って色々あると思うんですが、
自分的にvscodeのGitLensを使ったやり方がいい感じなのでご紹介します。
手順
レビューするブランチをコミットせずにマージします。
マージ後、resetでステージからも外します。
$ git checkout ${baseブランチ} $ git merge --no-commit --no-ff ${レビューするブランチ} $ git reset
vscodeで変更ファイルに色がつくので、
右クリックで[Compare File with Previous Revision]を選択します。
すると、こんな感じで差分が表示されます。
全体のコードを見つつ、差分は色付きで表示してくれるのでレビューしやすくなると思います。
定義へ移動とかも使えますし。
サイドバーの[ソース管理]でも同じように表示されますが
自分としては[エクスプローラー]でツリーを見ながらレビューしたいのでこの方法を使ってます。
コードレビューでお困りでしたら一度お試しください。
レビュー後は、マージした差分を取り消すのをお忘れなく
$ git reset --hard HEAD $ git clean -fd
vscodeは知れば知るほど便利なエディタですね。
vscodeのextension(プラグイン)を過去のバージョンに戻す
vscodeのextensionを自動更新のままにしていたら、rubyのextensionが更新されて定義へ移動が効かなくなりました。
とりあえずダウングレードしたら直ったので、バージョンの戻し方を備忘録として書いておきます。
パッケージファイルのダウンロード
マーケットからは最新バージョンしかダウンロードできないので、
以下のURLを組み立ててダウンロードします。
https://${publisher}.gallery.vsassets.io/_apis/public/gallery/publisher/${publisher}/extension/${extension_name}/${version}/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage
publisherやextension_nameはマーケットURLのitemNameパラメータで確認できます。
https://marketplace.visualstudio.com/items?itemName=rebornix.Ruby
マーケットのChangelogから戻したいバージョンも確認します。
${publisher} -> rebornix ${extension_name} -> Ruby ${version} -> 0.16.0
今回の場合は以下のURLでダウンロードしました。
https://rebornix.gallery.vsassets.io/_apis/public/gallery/publisher/rebornix/extension/Ruby/0.16.0/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage
ダウンロード後にファイルの拡張子を.vsixに変更します。
インストール
vscodeですべてのコマンドの表示(F1)-> vsix
と入力。
[拡張機能: VSIXからのインストール]でダウンロードしたファイルを選択すれば完了です。
思った以上に面倒だった。
最後にextensionの自動更新をオフにしておくことを忘れずに。
setting.json
"extensions.autoUpdate": false
以上、現場からでした。
参考
https://tpodolak.com/blog/2017/04/09/downgrading-visual-studio-code-extension/