yuw27b’s blog

技術メモと雑記

INSIDE FRONTEND #3に行ってきました

INSIDE FRONTEND #3に行ってきました。

#1以来、2回目の参加でした。

タイトル見て興味を持っていたのは、

  • 大規模なフロントエンド開発の話
  • BFF・TypeScriptあたりの現場の話

あたりでした。

Webサービス(主にフロントエンド開発)の機能の取捨選択や技術選定について、実際の現場でのお話を聞くのはとても勉強になりました。
ユーザー層や開発体制、納期などによって何が最適かは変わってきますが、その思考プロセスを知れたのはとても有意義でした。

メモしながら聞いてたので、備忘録に貼っておこう…と思ったのですが、モダモダしていたら動画が公開されておりましたので、そちらを。
www.youtube.com

時間が重なって聞けなかったものも見られるのでありがたいです!



その他。
会場がAbema Towersだったので、最新のオフィスビルはこんなのか…!というだけでも興味深かったです。
廊下のホワイトボードがJob boardになっていたり、Q&AにSlidoが使われていたりもしました。

Let's Encryptの証明書更新コマンドは、月1回実行ではダメ

TL;DR

  • Let's Encryptが発行するSSL証明書の有効期間は90日
  • ただし時計のずれを考慮して発行(更新)手続きの1時間前を"issue date"として発行される(つまり有効期間は発行時点からだと90*24-1時間)
  • なので、cronで「毎月x日」の設定で月に1回更新コマンドを実行している場合、暦によっては更新が間に合わず失効する可能性がある


深く考えずに月に1回更新コマンドを実行していたら、危うく失効しかけたのでメモ。

業務上の都合で、(クラウドではなく)自前のサーバにNginxをインストールして、いくつかのWebサービスホスティングしています。
SSL証明書Let's Encryptから取得し、HTTPSのサービスをしています。
そして、毎月1日のAM7時に証明書の更新コマンド(certbot-auto renew)が作動するようにcronを設定していました。
このコマンドは、有効期限が30日未満(less than 30 days)であればその証明書を更新する、という動作をします。

例えば1月1日のAM7時に取得された証明書がありました。

f:id:yuw27b:20190312120019p:plain
ファイルの生成日時を確認すると、1月1日の7:06です。

f:id:yuw27b:20190312120121p:plain
ブラウザでこの証明書の有効期限を確認すると、4月1日の6:06です。

今後のcronの作動タイミングは、
2月1日AM7時
3月1日AM7時
4月1日AM7時
・・・
ということになりますが、

2月1日AM7時・・・証明書の有効期限まで30日以上あるので更新かからず
3月1日AM7時・・・証明書の有効期限まで30日以上あるので更新かからず(3月は31日まである!)
4月1日AM6時6分・・・証明書失効(!)
(約1時間の証明書期限切れ状態)
4月1日AM7時・・・ここでやっと更新がかかる

約1時間とはいえ、これでは証明書の更新が間に合っていません。

ここで、証明書の有効期限は4月1日の7:06ではないのか、という疑問がわいたのですが、
ブラウザで証明書の詳細を見ると、1月1日の6:06に有効になって、4月1日の6:06に無効になる、と表示されます。
f:id:yuw27b:20190312163250p:plain

なぜ1時間ずれているのか。
同じ疑問を持った人がいるようで、Let's Encryptのコミュニティに質問と回答がありました。
Certificate Not Valid Before dated 1 hour prior to generation - Help - Let's Encrypt Community Support

回答者の中にLet's Encryptのエンジニアさんもいますが、時計のずれを許容できるように、という理由だそうです。

結論

月に2回とか25日に1回とかの設定で更新コマンドを実行するのが安全。

蛇足な補足

実は何度か「あと20日で失効しますよ」という警告のメールが届いて、不思議に思いつつも「とりあえず」で手動で更新したことがありました。月に2回更新コマンドを実行するように変更してからはそういう「不思議な」事態は起こっていません。

RMagickでよく使う画像処理

準備

Rubyで画像を編集するのにRMagickというgemを使う。
ImageMagickという画像操作ソフトウェアをRubyから使えるようにするものなので、そもそもOSにImageMagickをインストールしておく必要がある。OSごとの詳細はRMagickのGitHubリポジトリにある:
GitHub - rmagick/rmagick: Ruby bindings for ImageMagick

gemがインストールできたら、

require 'rmagick'
include Magick

で使えるようになる。

よく使う処理

PDFをpngにする
(RからPDFで出力→pngやjpgに変換→Webで表示、とか、PDFでサムネイル作るとか)

画像読み込み

image = ImageList.new(file_path)

サイズが知りたい(縦横のピクセル数)

image.columns
image.rows

任意の部分を切り出して保存

 slice = image.crop(50, 50, 200, 200) #左上が座標(0, 0)で、(50, 50)の位置から(250, 250)までを切り出し

画像を結合

image_list = Magick::ImageList.new("pic1.jpg", "pic2.jpg") { self.quality = 100 }
new_img = image_list.append(true) #true: pic1->pic2(top->bottom), false: pic1->pic2(left->right)
new_img.write("joined.jpg") { self.quality = 100 }

回転

rotated = img.rotate(45) #degree

保存時の画質設定

slice.format = 'JPEG'
slice.write("pic.jpg") {
  self.quality = 100
}

ImageMagickは、JPEG/MIFF*1/PNG保存時のデフォルトのqualityが「75」なので、できるだけきれいに保存したい場合は明示的に「100」を指定する。



ImageMagickは、過去に脆弱性が発覚したこともあるので*2、外部からアクセス可能なサーバにインストールする場合は注意する必要がありそうです。

※私が使っているケースは、

  • Dockerに閉じ込めてサーバーレス+アクセス元を制限
  • 処理する画像の生成元がサーバ内部
  • 機械学習の前処理Python使うのが主流では、と言われればそれはそうなのですが)

などです。

*1:MIFFって何?と思ったらImageMagickの独自フォーマットのようです。

*2:参考: ImageMagickの脆弱性(CVE-2016-3714他)についてまとめてみた - piyolog

HighchartsをReactで使う

ReactなWebアプリケーション内に、Hightchartsでグラフを描画するときのメモ。

基本的には、Hightcharts公式のReact用ラッパーライブラリを使えば良い。
GitHub - highcharts/highcharts-react: The official Highcharts supported wrapper for React

npmにあるので、Highcharts本体とこのライブラリを入れる。

npm install highcharts highcharts-react-official
  • ミニマムなexampleは上記の公式GitHubリポジトリにあるとおり
  • 実際は、チャートだけを独立したコンポーネントにすることがほとんど
  • チャートのoptionパラメータが多いので、別のファイルに書いたり、サーバからJSONで取ってきたりする
  • グラフデータのフォーマットが想定されているものと合っていないと、コンソールに Uncaught ReferenceError: Highcharts is not definedエラーが出る
  • 開発時に、とりあえずで空配列を渡してもこのエラーが出るので、最初から描画可能なモックデータを渡すのが良さそう
  • テンプレートにしてるコード:GitHub - yuw27b/react-highcharts-template (2020/07/05更新)

f:id:yuw27b:20200705155907p:plain

NDS第59回勉強会に行ってきたよ

参加&発表して来ました!

nagaoka.techtalk.jp

・・・次でちょうど60回なんですね!
いつもどおりいろいろな発表が聞けて、良いインプットになりました。
テーマが「学習・AI・入学」ということで、機械学習について発表もさせてもらいました。
私の働く研究室での取り組みについて話せる範囲でお話したのですが、絶賛試行錯誤中なのでスライドの公開ができません、ごめんなさい。成果として早めに公表できるようがんばります。

以下、印象に残った発表などを(発表者の敬称略)。
※メモを取るのをすっかり忘れて聞いていたので、記憶が間違っていたらごめんなさい!!



「TensorFlow.jsで遊ぶ」(kasacchiful)

TensorFlow.jsを使って、ブラウザでの機械学習のデモを見せてくださいました。
モデルさえロードされていればオフラインでも画像の判定などができるはずなので、おもしろいですね!
あとで「他の人がやっているのを見てささっと作った」みたいなことをおっしゃていましたが、手を動かすのが早くて見習いたい・・・。

「趣味がはかどる趣味プログラミングの話」(yyasuyuki)

AS番号の観察がご趣味とのことで、番号の取得と返却を自動で監視してTweetするbotを作りました、というお話でした。
AS番号というものは知らなかったのですが、通信事業者の歴史まで分かって興味深かったです。
botをフォローしたらさっそくいろいろ発生しているのですが、ぜひ背景について解説していただきたいところ・・・


「Angularでコンポーネント間のデータ受け渡し」(gatabutsu)

Angularのコンポーネント間でデータの受け渡しをする場合の最適解は何だろう、というお話でした。
私は普段、主にReactを書いているので、最近のAngularのコードを見られて良かったし、コンポーネント間のデータの受け渡し、という問題はReactでも同様に発生するので、とても興味深く聞きました。
データの受け渡し方法がいくつかあるわけですが、それを(コンポーネント同士の)結合強度によって整理して、不必要に結合を強くしないようにする、という考え方はとても良さそうだと感じました。

「GHELIAグループとAIUEOの取り組み MakersのためのAI」(清水 亮)

清水さんのことは存じていて、前述のように私も最近は機械学習に関わっているので、とても楽しみにしていました。
スケールが大きく力強いお話で圧倒されていたのですが、何より、AIが社会インフラとなる時が来ることを確信して、そのために着実に事業を進めていらっしゃる、という印象を受けました。
実験的なAIの話はよく聞きますが(私が研究寄りの仕事だからかもしれませんが)、実際に社会で活用するための”出口”をこんなにしっかりと見据えたお話は初めてで、とてもおもしろかったです。

C#で、安眠装置の開発」(ailight)

安眠装置、というか「降雪量によって自動的に水量をコントロールできる融雪パイプがあれば雪が降っても安心して寝てられる」装置です。
インターネットから降雪情報を取得→イーサーネットリレーで電圧を制御→融雪パイプから水が出たり止まったりする、
という仕組みです。これ本当に動いてるそうです・・・すごい・・・。
悲しいことに(?)今年は雪が少なかったので、効果の検証は次の冬まで持ち越しの部分もあるようですが、どうなるか気になります。
技術を使って身の回りの問題を解決するのは、まさにエンジニアのあるべき姿でかっこいいですね!


最後に、主催のcivicさん今回もありがとうございました&お疲れさまでした!
次回は6月22日の予定だそうです。