docker-composeのスタック名で結構苦労した話

そんなにちゃんと調べた記事じゃないです…

docker-compose upすると適当なstackが作られ、stack名はデフォルトでdocker-compose.ymlがあるディレクトリの名前になる。僕は複数のリポジトリでdocker-compose.ymlをdockerディレクトリの下に入れているから、複数のstackの名前が docker になって被る。そうするとstack内のコンテナとかボリュームの名前も docker-app とか docker-db とかになり、他のstackとぶつかりまくる。特にボリュームの名前の衝突は最悪で、特にハッシュ化とかしてないので同じボリューム名だとホストマシンの同じ場所にマウントされてDBのスキーマ違いますと怒られたりする。

stack名をちゃんと指定するにはdocker-composeの-pオプションを使うのだが、そもそもdocker-composeというのはupとdownしか覚えられない人間が使うもので、アプリケーションによって適切なオプションをつけて運用するのは不可能だ。結局僕はコンテナやボリュームの名前にアプリケーション名のプレフィックスをつけることで問題を回避したのだが、docker-compose.ymlのトップレベルにnameを入れておけば解決するらしい?(未検証)docker-compose.ymlの仕様(というかdocker系のドキュメント)、ググってもどれが信用できる情報かわからなくていつも適当にしちゃう。

サーバーゼニ節約&kubernetes入門

ふと毎月のサブスク費用を確認したらAWSとさくらインターネットで月額5000円くらいかかっていて、いくらなんでも辛いのでこれを圧縮する。

原因は必要以上に多くのサーバーを稼働していること。現在稼働しているのは3つ。

さくらインターネット 2GB

  • 1738円/月
  • 2017年から借りており、中途半端な技術的挑戦の残骸が最も多い
  • 金額に対するスペックが良い

積載物

AWS EC2 t2.micro

  • 1544円/月

積載物

AWS EC2 t4g.micro

  • 1076円/月
  • AWS謹製のGravitonプロセッサなので安くて高性能。ただしArm。

積載物

  • gotosocialインスタンス

移行計画

どうしたものか…

とりあえずEC2は新世代ほど高コスパの原則があり、t2.microはt4g.microに移行すべき。自分の学習を考えるとさくらはやめてEC2に揃えたい。全部t4g.microに相乗りを狙ってみようか。

そしてどうせならkubernetesに全部載せてみたい。複数のアプリケーションを相乗りさせるときのトラフィック管理をこれまではjwilder/nginx-proxyでやっていたが、もうちょっとナウいやつに移行して監視とかも統一的にやりたい。

自分用ActivityPubインスタンスとしてGoToSocialを立てた

ツイッターがいよいよヤバそうなのでActivityPubのインスタンスを立てたくなった。まずMastodonを検討したが、リソースの要求が高いので諦めた。不慣れなRoRだしTypeScriptじゃないし構成も複雑なので個人で管理・改造するのは負担が大きいというのもある。

改めてActivityPub実装の中で軽量なものを探したところGoToSocialが良さそうだったので立てた。AWS EC2のt4g.microで現状問題なく稼働している。と言ってもまだフォローが少ないからかもしれない。ActivityPub、というか分散型SNSという仕組み上フォロー関係が増えると加速度的に通信が増大していくはず。

GoToSocial

GoToSocialはGoで書かれている。シングルバイナリで吐かれるアプリケーションとsqliteで動き、公式に提供されるdocker-compose.ymlを少し調整してリバースプロキシとしてnginxを立てるだけで動かすことができた。

現段階ではアルファリリースという位置づけであるが、大部分の基本的な機能に問題はない。今自分が把握している問題は以下の2つだ。

  • 動画が表示されない
  • notestockが利用できない
    • 利用を開始するためのnotestockのbotアカウントへのメッセージ送信がエラーで失敗する
    • mastodonには送れるのでnotestock側に何か問題があるのではと思っているが、notestockのソースコードは公開されていないので詳細不明

フロントエンドをほとんど持たず、サードパーティのクライアントから叩かれるAPIサーバーに専念している。推奨されているクライアントはpinaforeだが、pinaforeは2023年1月に開発の停止が発表された。webクライアントに限ればこれが最も盛んに開発されていたので先行きが不安だ(しかし作者自身が述べているようにpinaforeもだいぶ技術スタックが尖っていて将来性は怪しかった…)。ActivityPubデビューする人は最初にサーバーに登録してからクライアントを導入するだろうが、GoToSocialはユーザー登録用のフロントエンドも持っていないので一般に公開するにはハードルが高めかなと思う。自分はdockerコンテナに入ってCLIからアカウントを作成した。

自分でちょっとした改造を試みたときにdocker buildが大量のメモリを食ってEC2が落ちた(2GBでは足りなかった)。Dockerfileからswagger関連の処理をゴリッと消してやると直る。

20200426

食事

朝なし昼スパゲッティ夜カレー

住居とは

外出をしない土日だった。自宅にこもっていても生存できる、それはつまり、この狭い部屋に人間が生きるために必要な機能を密集させ、さらにそのために必要なリソースを逐一引いてきているということだ。想像するだけですごい手間だ。共通化が禁じられたプログラミングのようなものだ。

そこまでやらなくてもいいんじゃないかと思う。たとえば風呂とトイレを集約するだけで配管と掃除の手間は激減するのではないか。その代わり排泄と入浴のタイミングが完全に自由ではなくなるが、それほど重大なこととは思わない。家賃が安くなるのならばそうしてほしい。

ScalaでDBを使いたい

温度管理サーバーは現状データをCSVに保存しているが、ダサいのと勉強のためにちゃんとDBを使いたい。ということでslickを導入しようとしている。今はチュートリアルをやっている。

たぶんapplication.confのurlを適切に設定すれば自分が用意したDBに接続できるはずで、docker-composeとかで用意すればいいかな。

同時に開発環境も整備した。これまではdockerコンテナの中で動かしていたが、それをやめてマシン上にJavaとsbtを入れた。このとき両者のバージョンを正確にこれまでのものと合わせないと依存関係が解決できずvscodeのmetals拡張が壊れる。sdkmanを使うと楽。

iceiceiceのDota2

今日はBTS Pro Series: Southeast AsiaというDota2の大会の決勝があった。名前の通り東南アジアのプロチームが参加する大会だ。決勝戦はFnatic vs TNC。僕はFnaticのiceiceiceのプレーを見ていた。

決勝戦第3試合の彼のNature's Prophetの動きが素晴らしかった。Nature's Prophetは一切の下準備なしにマップの任意の場所にテレポートするスキルを持つ、ある意味Dota2のルールを逸脱したヒーローだ。iceiceiceはこのヒーローの性能をフル活用してマップを縦横無尽に移動して支配し、チームを勝利に導いた。

人間性能も凄い。攻撃動作によって透明状態を解除しようとしたときに敵が視界に入り、瞬時に反応して攻撃動作をキャンセルするシーンがあった。iceiceiceは29歳、プロゲーマーとしてはかなり年長なのだがすごい反応速度だ。

Scala+Playのproduction buildは速い

https://github.com/chao7150/house-temperature-core の話。

以前droneで自動テスト(sbt test)を試みたときはScalaやsbtのダウンロードでとんでもない時間(30分以上)がかかってしまって実用的ではなかったのだが、今回Github Actionsでsbt distを実行したところ1分くらいで終わった。何も調べてはいないが、とりあえず経験知の共有として。

2/18~2/24 在宅勤務/過剰な健康への不安

在宅勤務

すでに発表されている通り弊社は在宅勤務期間中だ。僕はソフトウェアエンジニアの一般社員なので仕事に占めるコミュニケーションの割合が低く、在宅勤務でもそこまで不便を感じていない。エンジニア職以外の事情はよくわからないし、エンジニアでもリーダー級以上になるとミーティングが多くあるのでなかなか大変なところがあるのではと思う。

あえて不便なところを挙げると、オフィスが使えない分自宅の環境に左右されるところか。自宅のPCデスクはかなりリソースを投じて強化してきたので問題ないどころか会社以上に快適。だがネット回線は時間帯によって不安定でイライラする。自宅の周りに飲食店がないので食事に変化がなくなるし(自炊のレパートリーが少ない)、運動不足にもなる。通勤が不要なぶん1日あたり80分くらい時間が浮いてるので、その時間を使って散歩でもすればいいのか。でも花粉のシーズンだからなあ。

過剰な健康への不安

先週の虫歯の処置以降、なんでもない歯の感覚がどれも虫歯の兆候なのではと思えてしまって不安だ。歯医者では処置した歯以外は問題ないと言われているが、それもあまり信用できない気分。一般論として医者は信用すべきなんだが。

もともと僕は健康を損ないたくない、特に永続的にダメージが残るような病気にはなりたくないという心配が強すぎる。年齢的に考えればこれから健康は失っていく一方だというのに、バカバカしい。

ちゃおネイキッドプロジェクトの進展

自動デプロイ

Spotify機能のためにredisを立ててdocker-composeで連携するようにした。これに伴いデプロイの手順が変わったので.drone.ymlを調整した。docker runに複雑なオプションを載せまくるよりもdocker-compose.ymlに書いてしまう方が楽だし1コンテナでもdocker-composeを使うべきなのかもしれない。

CSSレイアウトのお勉強

Spotifyで聴いている曲を表示できるようになったので、画像・タイトル・アーティストをいい感じにレイアウトしたくてCSSのお勉強をした。MDNのドキュメントが大変参考になった。というかCSS系の情報はググってもノイズが多すぎる。

勉強のためにstyled-componentsでCSSをTSの中で記述してみた。ファイルの中身がカオスになる感覚は否めないが、コンポーネントとスタイルの結びつきが強くなるのは使いどころによっては便利なのだろう。特にwebpackを弄らずとも導入できるのはよい。

bundleサイズ削減

bundle analyzerで見てみるとmomentのタイムゾーンとかlocaleのファイルがすごい容量食っててビビったのでググって削減した。効果が数字で見えるのは楽しいのだが、webpack.config.jsがどんどん複雑になっていくのはつらい。

今後の野望

  • 監視・ロギングの強化
  • 様々な自動投稿機能がついたTwitterタイムラインのようなサービスにしていきたい

droneで自動デプロイする

12/22(日)

masterにマージするだけでデプロイされてほしかったので。

結論

  • Docker Pipelineでビルドが通るか確認し、OKならSSH PipelineでサーバーにSSH接続してgit clone→docker build→docker runしている。
  • SSH Pipelineはデフォルトでは/tmp下に適当なディレクトリを作ってcloneしてstepを実行していくのだが、サーバーに置いている設定ファイルを使いたい都合でそのデフォルトの挙動を無効にし、cd /home/satoru/workして手動でcloneしている。
  • SSH認証関連の情報はdroneのsecretsに保存してある
    • セキュリティ上の理由で、デフォルトではPRをトリガーにPipelineが実行されるときはsecretsを読み込めないので注意

VPS上でdroneを動かした

12/21(土)

CI環境ほしいので作った。基本的にはこれを読みながら進めるだけ。

結論

  • 単純にドキュメンテーションのdocker runのオプションをdocker-compose.ymlの形式に落とし込んだだけ
  • .env.sampleを.envにコピーして中身を埋める
  • common_linkはVPS上で動かしているnginx-proxyに接続するためのものなので気にしなくていい

TI9観戦/ナウいScala開発環境/口内炎の予感

日曜なので意識的に在宅していた。

TI9観戦

Dota2のTI9がアツい。FnaticがVPに勝つ番狂わせが起きるかと思いきや起きなかった。Dota2の試合時間はだいたい30分から40分くらいだ。ヒーローは大まかにスキルで戦うヒーローと通常攻撃で戦うヒーローに分類される。前者の方が早熟だが、金を稼いでアイテムが揃うにつれて後者の方が強くなる(基本的に時間が経てば金は貯まる)。金を横軸・強さを縦軸に取ると当然右上がりのグラフになるが、グラフの形はヒーローごとに様々だ。たとえば特定のアイテムを持つことで格段に強くなるということがある。プロレベルの試合では味方のヒーローに重要アイテムが入り、かつ敵のヒーローがまだ重要アイテムを手に入れていない絶妙なタイミングで戦いを仕掛けに行くということもある。そこで勝てば金が手に入り、また有利になる。

しかしこうして有利を拡大していっても決めきれなければ大器晩成型のヒーローによって逆転されることもある。たとえばMedusaは通常攻撃が4体攻撃になるスキルを持つ。単純に考えて通常攻撃を強化するアイテムのもたらす恩恵は4倍だ。だから強力なアイテムを揃える前に勝ちきらなければならない。

ナウいScala開発環境

以前vscodeでScala開発を試みたときはまともに使える拡張機能がなく補完が効かなかったのだが、今はMetalsを入れるだけでいい。補完があるとプログラミングは楽だ。ミスに気づくのは早ければ早いほどいい。

今はActivityPubの実装に挑戦している。仕様が固まっているものなのでTDDしている。ActivityPubではObjectはTypeという属性を持つことを定めているが、これは予約語なので`type`と表現する必要がありややこしい。ScalaTestの機能と思っていたmatcherが実はPlayの機能だったりして難しい。フレームワーク周りの知識がない。

素人丸出しのアレだが、package hogeはそのファイルの内容をhogeに所属させるために使うことを知った。つまり他のファイルからhoge.fugaという呼び出しができるようになる。ファイルでもオブジェクトでもクラスでもなく「パッケージに所属させる」という操作の感覚が新しかった。

今日はもうひとつ、droneのデプロイもした。droneはCIの一種でgitリポジトリにpushしたときに.drone.ymlを読んで自動でテストやビルドを行う。1回毎にdockerコンテナを作って捨てることでクリーンな環境でテストできるのがdroneの特徴だが、1回毎にsbtの初期化を行うせいで(貧弱なサーバーでは)1時間以上かかってしまい、タイムアウトしてしまった。

口内炎の予感

口内の傷が嫌な感じに痛み出していて口内炎になりそうで嫌だ。口内炎は食事が楽しめないのが辛い。ただ、火曜に右上の親知らずを抜くのでどうせ1週間くらいはろくな食事ができない。

houseTemperatureプロジェクトの大詰め

自分の家の天気(気温・湿度・気圧)をRaspberry Piから5分ごとにサーバに送り、それを使っていろいろ遊ぶプロジェクト(github)もそろそろ大詰めだ。使用技術はScala + Play Framework。開発環境にもデプロイにもDockerを利用している。サーバはこのブログと同じさくらのVPSで、nginx-proxyによってサブドメインgyokuroへのアクセスを振り分けている。

ドキュメント

ベースURLはhttps://gyokuro.chao.tokyoで、現状公開しているリソースは以下のとおりだ。

例:
{"status":"200","data":{"time":"00:25:00","temperature":27.7,"humidity":76.7,"pressure":1001.6}}
例:
{"status":"200","data":[{"time":"00:00:00","temperature":27.6,"humidity":76.8,"pressure":1001.7},{"time":"00:05:00","temperature":27.6,"humidity":77,"pressure":1002},{"time":"00:10:00","temperature":27.8,"humidity":76.3,"pressure":1001.9},{"time":"00:20:00","temperature":27.8,"humidity":76.5,"pressure":1001.7},{"time":"00:25:00","temperature":27.7,"humidity":76.7,"pressure":1001.6}]}

iframe化の苦労

WordPressは自由なhtmlをウィジェットに追加できるので、iframeを使って/temperature/nowを常に表示しようと思った。しかしPlay FrameworkはデフォルトでX-Frame-Options: denyが設定されているのでiframeに表示されない。これはクリックジャッキング防止のためだ。クリックジャッキングというのは僕のサイトを透明なiframeにして他のサイトの上に重ねて表示させることで、僕のサイトの任意の箇所を不正にクリックさせる手口だ。

MDNにしたがってX-Frame-Options: allow-from https://example.com/を登録しようと思ったのだが、なんとChromeは対応していない。ブチギレてる。対応してないということで無視されているのでとりあえず動いてはいる。ユーザーがクリックできる箇所はないのでたぶんオッケー(ホンマか?)。

iframeが表示されるようになったはいいが、黒背景に黒文字で表示されていて読めなかった。WordPress側からiframe内のstyleを操作するのは無理っぽかったので上記の通りクエリパラメータで白文字化できるようにして対応した。

頑張って作ったので適当にAPIで遊んでみてください。グラフ化するやつ作ってほしい。

ちなみに現在の状況は27.8 ℃、76.1 %、1001.4 hPa。肌がべたつきやや不快だ。今夜から明朝にかけてすごい降るらしい。通勤はできるかな?