生活が破綻している(n年ぶりm回目)

生活が破綻している。夜眠れない。眠ろうという意思が起きない。どちらかと言えば眠りたくない。眠らずにしたいことがあるかと言われると、まあなくもないが、面倒なのでしない。つまり謎に意味なく起きている。

睡眠薬はこの状況で意味がない。睡眠薬を飲んだとて倒れるように眠れるわけではなく、結局布団に入っていなければ眠れない。眠りたくないので布団には入らない。だから眠れない。眠れるはずがない。

生活には明らかに影響が出ている。部屋は汚いし勉強会も出ていない。ジムも行ってない。かろうじて働いている。以前日記を書いていた頃は規則正しい生活に価値を認めていた。そう生活することが嬉しかったのでそうしていた。今は別に嬉しくない。そうしたいと思わない。なぜそうしていたのかわからない。改善の意思がない。面倒が勝る。ので改善しない。

こういう思考に行き着いていること自体が異常であり改善が必要であることは明白なのだが、改善しようという意思と活力が湧いてこない状態を改善することは、論理的に不可能だ。思えばこうしてずるずる夜中にずれこんでいく生活は大学院時代もそうだった。人生で一番嫌な時期だ。

困ったなあ。なんとかなってほしい。助かりたい。

20251006 ホームパイ


ようやくマイクラの世界から規則正しい生活に復帰しつつある。マイクラは5回くらい引退しました。

メンタルもかなり終わってたけどホームパイ1袋どか食いして復活しました。

苦しみながらマインクラフトをしている

最近、友人たちと一緒にマインクラフトをやっている。以前も少しやっていたことがあるが、このゲームは悪魔的に面白い。

最初マインクラフトの世界に降り立ったとき、僕たちを出迎えるのは美しい自然だ。ローポリではあるが、一貫性のあるアルゴリズムによって生成され、インタラクション可能でどこまでも広がるこの世界は、無限の可能性、ときめきを与えてくれる。僕はいつまでもその美しさを感じていたいと思い、自然と調和した生活、最小の介入での生活を試みる。

しかし次第に心は変わり始める。たまたま見つけた鉄で作った斧の切れ味を知ってしまったら、もう木の斧には戻れない。様々な先進的な道具が鉄で作れるとわかり、僕たちの中の暴力的なフロンティア精神が目を覚ます。鉄や希少鉱物を求めて岩盤に届くまで地面を掘り続ける。山を丸裸にする。そこには自然との調和という思いはもうない。

重要な位置づけの自動化装置としてゴーレムトラップがある。非常に用途が多い鉄を無限生産するただ一つの手段だ。アイアンゴーレムはNPCが敵対NPCに襲われたときに召喚する守護者で、死亡時に鉄を落とす。この性質を利用し、敵対するNPCたちを同じ部屋に閉じ込めて継続的にアイアンゴーレムを生み出させ、それを水流で捕えてマグマで焼き殺して鉄を得るのがアイアンゴーレムトラップだ。

ゲームの表現にとやかく言うつもりはないが(言います)、世界の原住民の感情を支配し、恐怖から生み出される自衛のためのゴーレムをシステマチックに殺して資源を手に入れる仕組みは、どの程度意識して作っていたのかわからないが、現実の搾取のあり方にも通じるものがありグロテスクだ。ゲームの世界だとわかっていても、生み出されて直後に焼き殺されるゴーレムがプレイヤー(僕)を見つめてくる感情のない目を見ていると、間違ったことをしているという気持ちになる。

僕はこのゲームを心底楽しんでいる。すごいゲームだと思う。何もやれと言われないのにやりたいことがなくならないゲームというのはそうそう作れるものじゃない。そしてまた、このゲームが教育にも役立つというのも間違いない。高度な自動化装置をYouTubeの解説動画やwikiで仕様を見ながら自分の手で組み立てていくことで技術の楽しさに目覚める子供は多いだろう(僕が『電子ブロック』でひたすら遊んでいたように)。説明を聞き、手を動かし、仕組みを理解し、さらに発展させる。これでどんどん上達していくし、抽象的な仕組みを考える力もつくだろう。

それでもなお、僕はこのゲームをプレイするのが苦しい。自分の中にある人間の欲望・向上心、それと表裏一体の調和を乱す性質に向き合うことを強制されるからだ。本当に優れたゲームは自分自身の人間性を浮き彫りにし、それと向き合わせてくれる。よくできたゲームだからこそ楽しく、そして苦しい。悪魔的というのはそういうことだ。

そしてこのゲームをプレイするまだ純粋(?)な子どもたちは、この世界に何を思うのだろう。

20250923 Ubuntu24.04+nerdctl+vscode devcontainers 研究2

コンテナからのインターネット制限(ドメインホワイトリスト)ですが、失敗しました。ホストのnftablesで開発コンテナからのリクエストであることを判別する方法が難しく、最後は開発コンテナを別のユーザーから立てることまでやったのだが、そうすると今度はファイルマウントの所有権がぐちゃぐちゃになってしまい、終わった。

ブラウザ上での動作確認を別の隔離コンテナに封じ込めることは簡単にできた。

# compose.yml
version: '3.8'

services:
  app:
    image: watch-duty-manager-app:latest
    build:
      context: .
      dockerfile: ./ContainerFile
    cap_drop:
      - ALL
    security_opt:
      - no-new-privileges
    pids_limit: 512
    tmpfs:
      - /tmp:rw,noexec,nosuid,nodev
      - /var/tmp:rw,noexec,nosuid,nodev
    environment:
      - TZ=Asia/Tokyo
      - NPM_CONFIG_IGNORE_SCRIPTS=true
      - SSH_AUTH_SOCK=""
      - SECRET=dummy
    networks:
      - dev-net
    command: sleep infinity
    volumes:
      - ..:/workspaces:cached

  browser:
    image: kasmweb/chrome:1.14.0
    ports:
      - "6901:6901" 
    shm_size: '512m'
    environment:
      - VNC_PW=password
    networks:
      - dev-net
  db:
    container_name: watch-duty-manager-db-with-app
    image: mysql:8.0.27
    ports:
      - "3307:3306"
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: watch-duty-manager
      MYSQL_USER: xxxx
      MYSQL_PASSWORD: xxxx
    volumes:
      - db-data:/var/lib/mysql
      - ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf
      - ./mysql/log:/var/log/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
    networks:
      - dev-net

networks:
  dev-net:
    driver: bridge

volumes:
  db-data:
# devcontainer.json
{
    "name": "Node.js & TypeScript with Secure Browser",
    "dockerComposeFile": "./compose.yml",
    "service": "app",
    "workspaceFolder": "/workspaces",
    "postCreateCommand": "rm -rf /tmp/vscode-ssh-auth-* && npm ci --ignore-scripts",
    "remoteUser": "node"
}
# vite.config.json
  server: {
    allowedHosts: ["app"],
    host: true,
    port: 5173,
    https: {
      key: fs.readFileSync("./.devcontainer/key.pem"),
      cert: fs.readFileSync("./.devcontainer/cert.pem"),
    },
    hmr: { host: "app", protocol: "wss", clientPort: 5137 }
  },

まず、devcontainerはcomposeもいける。それを使って開発用DBと動作確認用ブラウザコンテナを同時に立てる。動作確認用ブラウザコンテナはkasmweb/chromeを使うと、ホストからブラウザアクセスでコンテナ内でGUIでブラウザを操作でき、そのブラウザ内で https://app:5173 にアクセスすることで動作確認ができる。localhost以外からアプリケーションにアクセスするのでhost(0.0.0.0)が必要。httpsにしないとsecure付きcookieが死んでしまうので、鍵セットを自前で作ってappのvite.config.jsで読み込んでいる。

20250922 Ubuntu24.04+nerdctl+vscode devcontainers 研究

昨日今日は集中的にdevcontainerを研究していた。というのはnpmの汚染がなんかすごい感じになっていて(曖昧)とりあえずnpmからダウンロードしたパッケージに悪さをされることはもう避けられないっぽいので、それでも耐えられる環境づくりがテーマだ。

もうひとつ、nerdctl(rootless)でやるというのも裏テーマ。僕の私物PCにはdockerの代わりにnerdctlしか入ってないからだ。特に深い理由はないが、なんかdockerはそろそろ標準じゃなくなるっぽいという話を数年前に聞いて以降そうしている。

AIに手伝わせながら作ったのがこんな感じだ。

{
    "name": "Node.js & TypeScript",
    "build": {
        "dockerfile": "ContainerFile"
    },
    "postCreateCommand": "rm -rf /tmp/vscode-ssh-auth-* && npm ci --ignore-scripts",
    "containerEnv": {
        "TZ": "Asia/Tokyo",
        "NPM_CONFIG_IGNORE_SCRIPTS": "true",
        "SSH_AUTH_SOCK": "",
        "SECRET": "dummy"
    },
    "runArgs": [
        "--cap-drop=ALL",
        "--security-opt", "no-new-privileges",
        "--pids-limit", "512",
        "--tmpfs", "/tmp:rw,noexec,nosuid,nodev",
        "--tmpfs", "/var/tmp:rw,noexec,nosuid,nodev",
    ]
}
FROM mcr.microsoft.com/devcontainers/typescript-node:1-22-bookworm

RUN usermod -aG root node

--cap-drop=ALLとかno-new-privileges、--pids-limit、/tmp潰しとかは基本らしいのだがSSH_AUTH_SOCKの周りは結構調査が必要だった。vscodeが作るdevcontainerはデフォルトでホストのssh-agentのソケットをコンテナ内にマウントして露出してしまい、これを止めるオプションはない。コンテナ内のsshはSSH_AUTH_SOCK経由でソケットファイルの場所を知るので、それを上書きしてしまえば良い…とAIは言うが、ソケットの置き場は/tmpで名前も明らかにそれとわかる感じなので名前だけ隠してもコンテナ内で悪意あるプログラムが動きうるという前提なら何も隠せてない。なのでpostCreateCommandでrmしている。

ContainerFileでusermodしているのはこうしておかないとホストとコンテナ内のファイルパーミッションが合わず、コンテナ内からファイルに書き込めないから。

nerdctlが正式サポートされていないのである程度コツが必要だった。AppArmorがユーザー名前空間の利用を制限している問題は、エラーログに解決法が書いてあり、その通りにこれを実行したら直った。

cat <<EOT | sudo tee "/etc/apparmor.d/usr.local.bin.rootlesskit"
# ref: https://ubuntu.com/blog/ubuntu-23-10-restricted-unprivileged-user-namespaces
abi <abi/4.0>,
include <tunables/global>

/usr/local/bin/rootlesskit flags=(unconfined) {
  userns,

  # Site-specific additions and overrides. See local/README for details.
  include if exists <local/usr.local.bin.rootlesskit>
}
EOT
sudo systemctl restart apparmor.service

rootlesskitとbuildkitは必要。runコマンドの--sig-proxyオプションも必要なのでnerdctlのバージョンはv2.0.0以上。

以下のように、ローカルのイメージをベースにして更にイメージをビルドしようとすると失敗することがある。devcontainerも何らかの差分ビルドをやっているのか、こういうエラーが起きることがあった。これはbuildkitをcontainerdを使うように設定すると直った

chao@chao-home:~/nerdctl-test$ nerdctl build -f Dockerfile.B .
[+] Building 1.1s (2/2) FINISHED                                                                                                                        
 => [internal] load build definition from Dockerfile.B                                                                                             0.0s
 => => transferring dockerfile: 107B                                                                                                               0.0s
 => ERROR [internal] load metadata for docker.io/library/my-test-image:latest                                                                      1.1s
------
 > [internal] load metadata for docker.io/library/my-test-image:latest:
------
Dockerfile.B:1
--------------------
   1 | >>> FROM my-test-image:latest
   2 |     RUN echo "This is image B" > /image-b.txt
   3 |     
--------------------

error: failed to solve: my-test-image:latest: failed to resolve source metadata for docker.io/library/my-test-image:latest: pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed

FATA[0001] no image was built

秘密鍵はコンテナにマウントしたくないのでgit pushはdevcontainerの外で行うことにするが、git commitは悩みどころだ。commit hookで様々なnpmスクリプトが動くことを考えるとコンテナ内にしたいが、CIを勝手に回されるリスクを避けるためにはcommit署名を使うべきで、署名鍵はコンテナ内に入れたくないので、commitはコンテナ外ですることになる。結局commitをコンテナ内でやりつつ署名用gpg鍵のパスフレーズをホスト側で毎回要求することで解決した。

# ~/.gnupg/gpg-agent.conf
default-cache-ttl 1
max-cache-ttl 5

この設定だと、コンテナ内でgpg鍵を使おうとしたときに、毎回ホストマシン側にパスフレーズ入力ダイアログが現れる。vscodeはgpg-agentも勝手にコンテナ内にフォワーディングしているのでこれ以外の設定は不要。

次の段階としてインターネットアクセスもドメインで制限したいのだが、--cap-drop=ALLをつけているためコンテナからiptablesを操作できず、かなり面倒な形になりそうだ。そこまでしなくてもいいかなあ。でもここまで来たならやりたいよな。あとはnodeのpolicyとか、ビルド成果物のチェック、動作確認用のブラウザもサンドボックス内で実行とかもやっていきたい。

20250920 友人と自動車移動

友人と会う予定があり、せっかくだからとレンタカーを発動した。が、これはなかなかハードだった(開幕)。

土産を上野で買っていこうと考えたのだが、これが大きな間違い。都心部の道路が激混み。途中で諦めたのに想定の3倍以上かかってしまった。

混んでるだけじゃなく、都心の運転は難しい。まず人間が多い。単純に交通ルールを守って右左折で歩行者を持つ機会が多いだけではなく、異常な場所を歩いている人間も多く、人を殺さない難易度が高い。自転車も多い。自転車は合法的かつ危険に車道を走行するので、どうにもならない。この国の法律と道路事情では自転車は「無理」だ。諦めてくれ。道も難しい。右左折車線が複雑だし、路上駐車が多すぎて基本的に第一通行帯が死んでいる。基本死んでいる。だから左折のほうが右折より難しい。車が多いため運転技術の下限が低い。平均レベルはわからないが、俺より下手な人間がいたりするので本当に危ない。曖昧に白線を跨いで曖昧に進んだり止まったりしている。

23区内の運転は教習所以来かもしれない。23区内の運転はダメだ。別物。もうやりたくない。この経験を経て都心部の電車網がいかに偉大かよくわかった。

さて、友人の家を見せてもらい、車で移動してかつて暮らしたエリアを見たり、なんとも言えない公園を見たりして、もつ焼きを食べて解散した。もつ良かったですね。肉・油・塩・食感、全てがあり、「満ち」た。

20250915 志木ドライブ

また発作が出て、レンタカーを発動してしまった。と言っても今回は16時~20時。適当にスパジャポなる施設に行ってみたんだけど、入場待ちの行列があまりにも長く、諦めて別の場所に行くことにした。と言っても特に行きたい場所もなく、適当に志木駅に行った。

時間制駐車場に停めて、1分くらい歩いたところに良さそうな寿司屋があったので入ってみた。早めだったので客は僕だけ。並寿司とシメサバを注文(本当はバッテラが食べたいのだが、大抵無いので妥協)。寿司の良し悪しはあまりわからないが、間違いなく美味い寿司だった。不思議だよねえ。シンプルな料理に見えるけど、温度や硬さでネタの味が活きるかどうか変わってくる。いつも何も思わずに食べるかっぱ巻きですら海苔の豊かな香りがぶわっと広がって驚き。食材にもこだわっているのだろう。大将と話もしたのだが、三連休最後で…なんかいきなり出かけたくなって…川口から来ました…みたいな完全に意味不明なことしか言わなかったので意味不明な客だと思われてると思う。

帰り道は夜・雨の高難易度ステージ。ゲームの難易度上げるために視界塞ぐのはやめろってあれほど…。前回の水戸はほぼ高速道路だったが、今回は街。狭い道で通行人・自転車・バイクも多く、明らかに難易度が高かった。けれど前回以上に「必要ない情報を切る」ことが上手くできるようになっていて、速く正確な判断ができるようになっていた。

やっぱり車さえ所有していればこのノリで外出できるというのはとても夢がある。車の外出は楽しい。しかし、電車移動に比べて何が優れているのかと聞かれると、これは即答できない。難しい問題だ。まず僕は単純に運転が好きだ。機械の操作が楽しい。しかしそれを差し引くと、電車の方が優れている点は多々ある。電車は購入する必要がない。維持する必要もない。つまり安い。そして自分で運転する必要もない。つまり時間が有効活用できるし安全だ。

所要時間、これはケースバーケースだ。始点と終点が駅に近いかどうかに大きく左右される。電車は渋滞の影響を受けないが混雑は不快ではある。一方で常に車はプライベート空間で快適だ。

整理してみると、過程の快適性に大きな差がある気がする。駅まで歩く、駅で乗り換える、駅で待つ、駅から歩く。このように細かくプロセスを切らねばならない電車は快適性で劣る。車内は公共空間であり、座れる保証もなく、座れても席が狭い。スマホ見てられるというのはそうなのだが、スマホを見るのは精神に悪い。特に「他にできることもないのでとりあえずスマホ見るか」で見るコンテンツは激烈に精神に悪い。

自動車は電車よりは確実にドア・ツー・ドア移動に近い。乗っている間運転の作業は必要だが、シートは快適、空調も快適、ラジオも聞ける。切れ目がない。そして行程を自由に変更して寄り道もできる。

ああ、やはりどう生きたいのか、という魂の疑問になるんですよね。全ては。車好きだなあ。

20250909 高い肉まん


冷凍肉まん、高級なやつが半額になっていた(半額になったあと、いつも食べてるやつの1.5倍くらい)。食べたらめっちゃよかった。大きいしふっくらしてるし、肉がぽってりしている。

昼、松屋。

書くこと、無(な)!

困ったときの時事ネタ。天下一品にゴキブリが混入していたそうだが、あれは天下一品のこってりがちゃんとした不透明なラーメンだから起きたことだ。それがラーメンの精神性だ。スープが透明・麺が平行・チャーシューが赤いなどの非精神家賃ラーメンだったら混入にはすぐに気づいていただろう。

20250908 フラワーシャワー


ゴミ拾い、また雪見だいふくの刺すやつがあった。下を見て歩いていると首に水がかかって、雨!?と思ったら屋上のガーデニングの水やりだった。雅。

自分の体調なのか、季節なのか、やってるタスクなのかわからないが、久々に仕事が進んでいる感覚が得られている。

次のサラダは舞茸+ポン酢とする。

20250907 二度漬け

最近、天竜川ナコンの『現実チャンネル』に救われているっつってんの!。

昼にジムに行って、帰り道に薬局に処方箋だけ提出(受取は後日)、買い物をして帰ってきた。

しかししばらくしてジムに忘れ物をしていたのに気づいてもう一度ジムに行くことになった。それならばと、薬局で薬は受け取ったし、買い物も買い忘れがあったのでもう一度した。

夕方は神の昼寝。

最近はゴーヤがうまい。なんか新しい野菜に挑戦したい(挑戦したいとは、レンチンだけで料理したいという意味)と思ってゴーヤを買ってみた。まず、ゴーヤを切ったのは人生で初かもしれない。最初に輪切りにしちゃって、なんか中央部に変なのがあるな…と思った。そう言えば人生で食べてきたゴーヤは全部周縁部だった。調べてみるとまず縦に一刀両断して綿を除去するらしい。そうした。その後塩もみすると苦味が緩和されるらしい。そうした。レンジで4分、めんつゆと鰹節で食べてみるとかなりいい。かなりいいが、これってもうゴーヤチャンプルじゃね?

人生〜(鳴き声)