oinume journal

Scratchpad of what I learned

VPSにDokkuをインストールする

VPS上にDokkuというものをインストールして、Dokku上でHello WorldするRailsアプリを動かすまでのメモ。

Why Dokku?

DokkuのWebサイトに書いてあるように、Dokkuはオープンソース版のHerokuという立ち位置のソフトウェア。かれこれ7年ぐらいHerokuを使い続けていてとても便利だと思っているのだけど、アプリケーションを1つ動かすのに$5かかるようになってしまった。昨今の円安で750円ぐらいかかるし、アプリを複数作るとなるとそれなりにお金がかかるので、VPSでDokkuを動かしその上でアプリケーションを稼働させるようにしたいと思った。

また、WebARENA IndigoのVPSだと、2vCPUでメモリ2GBで税込814円 / 月という安さなので、これを使うとかなりコスト抑えられそうだなと思ったからだった。

インストール

以下の環境にDokku 0.32.3をインストールする。

  • WebARENA IndigoのVPS(4vCPU, MEM 4GB, SSD 80GB)
  • OS: Ubuntu 22.04

インストール自体はDokkuのドキュメントの通り、aptを使ってインストールすれば特にハマることはないはず。

SSHの公開鍵の登録

アプリケーションのデプロイ時にgit push dokku ...とやる場合、sshの公開鍵が登録されていないと失敗するので、以下のコマンドで登録しておく。

$ echo 'CONTENTS_OF_ID_RSA_PUB_FILE' | sudo dokku ssh-keys:add admin

ドメインの設定

インターネット上にDokkuを使ってアプリケーションを公開するためには、当然ながらドメインが必要なので用意しておく。自分は dokku.lampetty.net をベースドメインにして、これのサブドメインでアプリケーションを公開していくつもりなので、必要な設定をした。

まず、 domains:report コマンドで現状のドメインを確認する。

$ dokku domains:report --global

=====> Global domains information
       Domains global enabled:        true
       Domains global vhosts:         i-xxxxxxxxx

Domains global vhostsはデフォルトではホストマシンのホスト名になっているので、これを以下のコマンドで変更する。

dokku domains:set-global dokku.lampetty.net

次に、dokku.lampetty.net サブドメインがこのVPSのIPアドレスになるようにDNSレコードを定義する。Aレコードの方は別になくてもいいけど、IPとのマッピングは1箇所にしたいのでこうしている。

dokku.lampetty.net A <VPSのIP>
*.dokku.lampetty.net CNAME dokku.lampetty.net

digコマンドでDNSレコードを確認して、以下のように返ってくればOK。

$ dig example.dokku.lampetty.net

example.dokku.lampetty.net. 300 IN      CNAME   dokku.lampetty.net.

これでドメインの設定は完了したので、サンプルアプリケーションをデプロイする。

アプリケーションのデプロイ

サンプルアプリケーションのデプロイはドキュメント通りにやって、最後にgit remote add dokku ...のところだけ、自分の環境に合わせて以下のようにやった。

$ cd ruby-getting-started
$ git remote add dokku dokku@dokku.lampetty.net:ruby-getting-started
$ git push dokku main

動作確認

http://ruby-getting-started.dokku.lampetty.net/ にアクセスして、以下の画面が表示されればアプリケーションがデプロイされている。(ruby-getting-started 以降のドメインは先ほど設定したドメイン)

あとはアプリケーションを https でアクセスできるようにする対応なども必要だけど、いったんこれでVPS上にアプリケーションをデプロイできるようになりましたとさ。

ししまるとしろ

最近、新しい猫を我が家に迎え入れた。名前は「しろ」。保護猫で年齢は5~6歳。岡山で多頭飼育の崩壊後ゴミ屋敷となった民家から保護された。その後、地元の預かりボランティアのお宅では他の猫と折り合いが悪く、ほぼケージ生活となったため、他に猫のいない家庭に譲渡したいということで東京に移動してきたところで、我が家で迎え入れることになった。

ウチに来て間もない頃のしろ

しろの話をする前に、このブログやTwitterにも登場していたししまるの話をしなければ、と思っている。ししまるは昨年の12月に虹の橋を渡ってしまった。昨年の夏から肺炎の症状があり投薬などで治療を続けていたが、(おそらく)間質性肺炎という難治性の病気で治ることなく他界してしまった。自分にとってはペットを飼うことが初めてで、当然その死に立ち会うのも初めてだったのでとてつもなく悲しかった。3ヶ月間は毎日ししまるの写真や動画を見ては泣いてしまうという状態が続いていたし、今でも病気で辛そうだったししまるのことを思い出すと泣いてしまう。

ししまる

その悲しさに一区切りつけられたのは、今年の4月に近所のお寺でペットの合同供養祭に参加したことだと思う。ペットを亡くした飼い主たちがお寺に集まり、お坊さんが供養のお経を唱えて線香をあげるという葬儀。人間と同じように葬儀を行うことで気持ちも少し整理された気がして、その後から「また猫を迎え入れる?」という話を妻とするようになった。そんな中で妻が保護猫のサイトで見つけたのがしろだった。色が白いところや雰囲気がなんとなくししまるに似ている...! ということで、本物を見に行ったところ、体重6.5kgの大きさがししまるっぽく、とてもビビりだけど人懐っこいということで、譲渡の申請+トライアルで2週間ほどわが家に来てもらうことになった。

うちに来た当初はずっと机の下に隠れていたけど、2,3日で家の中を探検するようになり、息子含めた全員になでなでをお願いするぐらい懐いていった。ししまるは息子にはあまり甘えなかったので、息子もとても嬉しかったらしい。

ただ、ここで一つ問題が発生。ししまるの時は全然問題なかったのに、妻と息子の猫アレルギーが発動して、薬を飲まないとアレルギーの症状が抑えられず、「これだと迎え入れるのは厳しいかも」という状況になっていた。ひとまずトライアルを延長して、猫のアレルゲンを減らすキャットフードを試したり、体をまめにふく&ブラッシングしたりして、なんとか薬を飲まなくても大丈夫な状態にまでなった。一緒に生活していると慣れてきてアレルギーがおさまったりすることもあるそうで、何が効いたのかはいまでもよくわかってないけど、問題が解決したので一旦良しとしている。

というわけで、無事に9月にしろを正式に迎え入れることができて、また家に猫がいる生活が始まった。白猫のため、黒いシャツを着ているとしろの抜け毛が目立ってしまい頻繁にコロコロをかけないといけないあの生活がまた戻ってきたと思うと、面倒くさいながらちょっとニヤニヤしてしまう。ししまるは家に知らない人がきても興味を持って挨拶していたりしたけど、しろはビビりで引きこもってしまうところなど、さまざまな違いを発見できて面白い。

ししまる、今まで本当に本当にありがとう。しろ、これからよろしくね。

Next.js + Auth0でLogin handler failedのエラーを解消する

Next.js + Auth0で認証機能を実装しようとして、nextjs-auth0をセットアップしつつ、このドキュメント通りにやっていたら、AUTH0_ISSUER_BASE_URL の設定を間違えていて以下のエラーが出ていた。

LoginHandlerError: Login handler failed. CAUSE: Discovery requests failing for http://localhost:3000, expected 200 OK, got: 404 Not Found

上のauth0のドキュメントでは AUTH0_ISSUER_BASE_URL='https://{yourDomain}' との記述だったので、http://localhost:3000を指定したのだけど、どうやらこれはhttps://YOUR_AUTH0_DOMAIN.auth0.comを記述するのが正しいらしい。というわけでAuth0の該当アプリケーションのページからDomainの部分をコピーしてきてhttps://oinume.us.auth0.comのように指定すればOK。というかnextjs-auth0にはそのように記載されていたのではじめからこっちを読んでおけばよかった...

multipassでAnsibleの動作確認用のVMを作る

モチベーション

趣味で開発しているプロダクトのためにVPSを立てていて、Ansibleで各種ミドルウェアの設定をしているんだけど、VirtualBoxのApple Silicon への対応が微妙なのでmultipassを使ってVMを立てる+Ansible Playbookを流してセットアップするということをやってみたのでそのメモ。

multipassでVMを立ち上げる

まず初めにssh用の秘密鍵と公開鍵を生成する。multipassでVMを立ち上げるときはデフォルトでSSH用の鍵を生成してくれるけど、Ansibleでsshするときの鍵を作っておく。

ssh-keygen -t rsa -b 4096 -C multipass -f multipass

次に、以下のようなcloud-init.ymlを作成する。

users:
  - default
  - name: multipass
    sudo: ALL=(ALL) NOPASSWD:ALL
    ssh_authorized_keys:
      - "ssh-rsa <上で生成した公開鍵>"

multipass launchでVMを立ち上げる時に、--cloud-init オプションで先ほどのcloud-init.ymlを指定する。これを行うことでmultipassユーザーの authorized_keys に上で作成したSSHの公開鍵がセットされる。

multipass launch -n vps -c=1 -m=1G -d=5G --cloud-init=cloud-init.yml

次にVMのIPアドレスを確認する。

multipass info vps

Name:           vps
State:          Running
IPv4:           192.168.64.13
Release:        Ubuntu 22.04.2 LTS
Image hash:     f6b5b3a980f2 (Ubuntu 22.04 LTS)
CPU(s):         1
Load:           0.20 0.11 0.04
Disk usage:     1.4GiB out of 4.7GiB
Memory usage:   151.3MiB out of 962.5MiB
Mounts:         --

Ansibleのinventoryファイルを以下のようにする。

[local]
default ansible_host=<上で調べたIP> ansible_port=22 ansible_user='multipass' ansible_ssh_private_key_file='multipass'

最後にansible-playbookを実行する。

ANSIBLE_SSH_ARGS='-o IdentitiesOnly=yes -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook  --inventory-file=ansible/inventory/multipass  --timeout=30 -v -D ./ansible/hoge.yml

multipassのコマンドメモ

  • multipass transfer : VMからファイルをコピーする or ホストからVMにファイルをコピーする
  • multipass shell : VM内にシェルでログインする

whisper.cppで文字起こしをやってみた

自分の備忘録としてのやってみた系の話。OpenAIが提供するモデルを使って文字起こしをするC++実装のwhisper.cppを試してみた。

環境

Apple M1 MacBook Air 2020 (Memory 16GB)

uname -a

Darwin hogehoge.local 22.3.0 Darwin Kernel Version 22.3.0: Mon Jan 30 20:39:35 PST 2023; root:xnu-8792.81.3~2/RELEASE_ARM64_T8103 x86_64

whisper.cppのビルド

以下のコマンドを実行してビルドする。

git clone https://github.com/ggerganov/whisper.cpp.git
cd whisper.cpp
make

ビルドが成功すると、カレントディレクトリに main という名前のバイナリが出来上がる。

モデルのダウンロード

次にモデルのダウンロードをしておく。

./models/download-ggml-model.sh large

文字起こしする音声ファイルのwavファイルを用意

  • whisper.cppはwavファイルしか受け付けないので、ffmpegで動画ファイルをwavにする。
  • ちょうど手元に会社で公開している勉強会の動画があったので、これを使ってみる
  • あと長いので最初の2分間だけを抽出。
ffmpeg -i ~/Downloads/2023-02-13.mp4  -ar 16000 -to 120 2023-02-13.wav

whisper.cppで文字起こし

先ほど出力したwavファイルからwhisper.cppを使って文字起こしする。

./main -m models/ggml-large.bin -f 2023-02-13.wav -l auto

注意点

  • -m でダウンロードしたモデルファイルを使う。largeだと精度が高い
  • -l auto を指定しないと日本語の文字起こししてくれないので指定する。もしくは-l jaでもOK

文字起こしの結果。ちなみに2分の音声ファイルを文字起こしするのに82秒ぐらいかかっている。

[00:00:00.000 --> 00:00:01.000]  お願いします
[00:00:01.000 --> 00:00:02.000]  お願いします
[00:00:02.000 --> 00:00:11.120]  はい 本日 Dpエンジニアリングまで 第60回始めていきたいと思います
[00:00:11.120 --> 00:00:12.120]  お願いします
[00:00:12.120 --> 00:00:13.120]  お願いします
[00:00:13.120 --> 00:00:14.120]  お願いします
[00:00:14.120 --> 00:00:21.840]  今日は React 18かな 18から新しく 出たディファードバリューっていう
[00:00:21.840 --> 00:00:28.440]  やつの紹介ですね もともとデバウンス とかスロットルみたいな感じで
[00:00:28.440 --> 00:00:33.840]  各種ライブラリーが似たような やつやってたんですけど そうじゃ
[00:00:33.840 --> 00:00:38.800]  なくて結構UIのアップデートで 最適化したやつが出ましたよっていう
[00:00:38.800 --> 00:00:44.320]  ので もともとデバウンスっていう 本当はスロットルも出したかったん
[00:00:44.320 --> 00:00:49.200]  ですけど React 18でスロットルのやつ がバグっていてとあるライブラリー
[00:00:49.200 --> 00:00:54.000]  でパッてデモが用意できなかったん ですけど 一応デバウンスだけ紹介
[00:00:54.000 --> 00:01:04.120]  しておくと 18入力した後に時間差 で18入力されるという 今これ1秒
[00:01:04.120 --> 00:01:09.680]  かな 1秒ってやってるので 最後に 入力した後1秒後に値が更新される
[00:01:09.680 --> 00:01:15.400]  ってやつですね 連続で入力してる 間はデバウンスバリューは変わん
[00:01:15.400 --> 00:01:20.840]  ないけれど 止めてから1秒すると デバウンスバリューは変わる これ
[00:01:20.840 --> 00:01:27.120]  何使いたいかっていうと インクリメンタル サーチとか オリジンのところを
[00:01:27.120 --> 00:01:31.600]  見てもらうと 一文字変わるごとに サーチ検索API叩きまくってると
[00:01:31.600 --> 00:01:38.320]  重すぎるし 重すぎるので デバウンス みたいにユーザーの操作が終わった
[00:01:38.320 --> 00:01:44.560]  後にAPI一回叩くみたいな感じで やってあげるっていう スロットル
[00:01:44.560 --> 00:01:50.280]  の場合は1秒ごとに発火される っていうイメージなので 例えば
[00:01:50.280 --> 00:01:55.240]  デバウンスバリューはこれ 最後 操作終わるまではデバウンスバリュー
[00:01:55.240 --> 00:02:00.040]  更新されないですけど スロットル だった場合は1秒ごとに発火されて

最後に会社の勉強会の宣伝

ドクターズプライムでは、DP Engineering Mondayという名前で毎週勉強会をやってます。月に1回、社外向けに開催したものをYouTubeで配信しているので、よかったらチャンネル登録してください。技術スタックはReact, TypeScript, ChakraUI, Go, GCP, Hasura, PostgreSQLなので、その周辺の話が多いです。

www.youtube.com