先日「ドクセル」というサービスをリリースしたので技術的な振り返りをQiitaにも投稿します。
追記:Qiitaにドクセルの埋め込み機能が対応しました!
モチベーション
- SlideShareが親会社をころころ変えるわりに中身が進化してなくてやる気ない
- SpeakerDeckが日本語のファイルをアップするとSlugを勝手に中国語読みにする
- なんか個人サービス作りたい
作ったもの
- https://www.docswell.com
- ドクセル と読ませるようにしている
- シンプルなスライド共有サービス
- Laravelベース
特徴
- 画質がいい(長辺1920px・Full HD相当のプロジェクターにも耐えうる)
- URL(Slug)をある程度自分で決めることができる
- マウスオーバーに頼らない(タッチデバイスを意識)
アーキテクチャ
アーキテクチャはこんな感じです。初期バージョンとしては、PHPなので共用サーバで済ませました。SMTPサーバもついてるし楽ちんですね。Deployerというものを教えてもらったので、Github Actions経由で自動デプロイできて、何かあったときのロールバックもコマンド一つでできます。
変換エンジンの悩み
PDFを画像にするまではいろいろ悩みました。まずOfficeファイルを対応するかですが、当初LibreOfficeをCloudRunでうごかしたりしていたのですが、なかなか良い変換結果が出なかったので本家MSのサービスを利用しました。
PDFから画像にするエンジンもいろいろあり、大きく分けてGhostscript系、Poppler系、PDFium系などがあり、当初Poppler系で実装していました。
ところが、内輪でテストしたときに、Google Slidesからエクスポートしたスライドでエラーをはくことがわかりました。そこでリリース直前にGhostScript系に変更しました。
💡 余談ですが、簡単にエンジンを変更できるのは、単純にCloud Runのnodejsからspawnでコマンドラインをたたいているからです。PDFの取り扱いは、セキュリティ界隈では有名ですが脆弱性のワンダーランド、脆弱性の大海原となっておるわけです。そのため、メインのアプリケーションからは分離して、コンテナ環境で都度変換する仕組みをとっています。
しかし、リリースしていろんな方にファイルをアップしていただくと、ことごとく変換に失敗してしまいました。また、変換ができているケースも、速度が6倍ほど遅く、タイムアウトになっているケースもありました。そのため、Poppler系に戻しつつ、エラーハンドリングを強化するという実装に着地しました。
いずれ引っ越し、商用プランに耐えうるように
(自分の本業はエンジニアくずれのPMなのですが)当初、この企画を作るにあたり勉強を兼ねてReact/Firebaseで開発する予定でした。しかし、B2Bプロダクトの特性上、将来的に企業利用が進む場合あのめんどくさいセキュリティチェックシートを書かなくてはなりません。そうでなくとも、お堅い企業から通信先としてホワイトリストに登録してもらうには、fqdnを限定する必要があります。
そのようなビジネス的な要件に対応するため(要はマネタイズのため)枯れた技術で作ることにしました。こうしておけば、アプリケーション本体も変換エンジンも基本はDockerコンテナがホストできれば動作するので、5000兆円払うからプライベートクラウド版作ってほしい!みたいなオファーをいただいた時にも対応できるようになりました。同様の理由で、InternetExplorer 11にもおおむね対応しています。なお本体部分は最初の実装と実装アドバイスを@mikkameさん、プレーヤ部分は自分の技術力では無理だったのでSplide.jsの作者様にカスタマイズ依頼をそれぞれ発注させていただきました。
みなさんのスライドをアップしてみてほしい
今後ドクセルでは、noteやZennのようにスライドを有償販売できたり、作成者を応援できる機能などを予定しています。でもその前に、安定したサービス運営のため、皆さんのスライドをどんどんアップいただきたいと思います。ぜひslideshareやspeakerdeckにアップしたスライドを転載いただけると嬉しいです!