カテゴリー: ガジェット Page 1 of 98

Nextcloud 32.xにClient Pushを導入して高速化させる(Mod_Security導入状況で躓いたこと)

Nextcloud32.0.2にアップデート後に表示された際に出てきた

Client Push
Client Push is not installed, this might lead to performance issue when using desktop clients.

と出てきたので、これを導入しました。筆者のようにIP/クローラー制限やMod_Securityを利用している方でもなんとかなる手順にしています。

Client Push (notify_push) とは?

正式名称は「High Performance Back-end / notify_push」。
一言でいうと、「ファイルの変更をクライアントに『瞬時に』知らせる機能」です。

導入前と導入後の違い

郵便受けの確認に例えるとわかりやすいでしょう。

  • Client Pushなし(ポーリング方式)
    • クライアントが、30秒おきに「ねえ、何か新しいファイルある?」「変更ない?」とサーバーへ聞きに行きます。
    • デメリット: サーバーはずっと質問攻めにされます。また、変更があってから聞きに行くまでにタイムラグ(遅延)が発生します。
  • Client Pushあり(プッシュ方式)
    • クライアント~サーバーが専用のホットライン(WebSocket)で繋がりっぱなしになります。
    • サーバー上のファイルが変更された瞬間、サーバーから「変更あったよ!」と通知(プッシュ)します。
    • メリット: 変更が即座に反映されます。無駄な問い合わせがなくなるため、サーバーの負荷も下がります。

Client Pushは導入すべきか?

「必須ではありませんが、導入すると劇的に快適になります」

  • 個人利用:
    • PCで保存した写真がスマホに「パッ」と出るようになるので非常に快適です。
  • 複数人/組織利用:
    • 強く推奨します。多数のユーザーによる「変更ある?」というアクセス集中を防げるため、サーバー安定化に寄与します。

環境

  • Nextcloud 32.0.2
  • Ubuntu 24.04
  • Apache 2.4
  • MySQL 8.0
  • PHP 8.3 (PHP-FPM 8.3)

(再掲)フェイズゼロ:政治交渉

このNextcloudを個人的に運用しているのならばそのまま行って構いません。しかし、これを組織で運用しているとなると話はまるで違います。

  • Nextcloudの高速化に寄与するnotify_pushをサーバに入れる。
  • Apacheの設定変更を行う
  • ついてはこの計画でサーバ設定を行う
  • そのため、追加で作業時間をいただきたい
  • 作業時間は○時頃、○分程度で終わる。その間、Nextcloudは使えなくなる

など、利用者への周知という名の政治交渉が必要になります。この運用者の政治的な立ち位置(担当者/担当部門が強権を振るえるか否か)でも言い方や手段が決まってきます。そこは状況に応じていきましょう。

※ 検証環境を用意できる程度には時間と予算と環境に余裕がある方は、その環境にいることを感謝しつつ、検証を重ねていきましょう。

もちろん、新サービス(Docker)の追加という文書管理も必要になっていきます。以下の手順は

  • 個人運用だからそもそも関係ない
  • フェイズゼロをクリアした

方向けの手順です。おそらく、組織でNextcloudを運用している方はここが一番のハードルだと思います。

さっくりとした手順

  1. 【Nextcloud Web画面】Client Pushをインストールします。
  2. 【コマンドライン】Nextcloudのメンテナンスモードを有効化します。
  3. 【コマンドライン】Apacheの設定ファイルを編集します。
  4. 【コマンドライン】Apacheの設定ファイルを反映させます。
  5. 【コマンドライン】Nextcloudのメンテナンスモードを無効化します。
  6. 【コマンドライン】notify_pushをサービス化します。
  7. 【コマンドライン】Nextcloudのconfigで、Trusted Proxyを有効化します。
  8. 【コマンドライン】Nextcloudのpushサービスを有効化します。
  9. 【Nextcloudクライアント】レスポンスの向上を確認します。

ClientPushのインストール

Nextcloudの管理者画面 >「アプリ」> 虫眼鏡アイコンで 「Client Push」を検索 > インストール・有効化します。

ここまでは単純です。

メンテナンスモードを有効化

  • Nextcloudのルートディレクトリ移動
cd /path/to/nextcloud/root/directory && pwd

自分の環境に合わせます。(筆者環境/home/www-data/nextcloud)

  • メンテナンスモード有効化
sudo -u www-data php occ maintenance:mode --on
  • メンテナンスモード確認

運用中のNextcloudのURLにアクセスし、メンテナンスモードであることを確認します。

Apache設定

Client Pushは「WebSocket」という特殊な通信を使用します。Apacheでこれを扱えるようにモジュールを有効化します。

sudo a2enmod proxy proxy_http proxy_wstunnel

念のため:apacheリスタート

  • apache再開前確認
systemctl status apache2.service

active(running)を確認します

  • apache再開
sudo systemctl restart apache2.service
  • apache再開確認
systemctl status apache2.service

active(runnning)を確認します

このタイミングでサービス再起動が必要なのは何故かというと、

  • proxy
  • proxy_http
  • proxy_wstunnel

を有効化していないと、この後のApache設定変更時に「これらのモジュールが無い」とサーバは判断するからです。

Nextcloudのバーチャルサイトの編集

  • バーチャルファイルのバックアップ
sudo cp -pi /etc/apache2/sites-available/nextcloud.conf /path/to/backup/directory/nextcloud.conf.$(date +%Y%m%d)

.confやバックアップディレクトリは自分の環境に合わせます。

  • バーチャルファイルのバックアップ確認
diff -u /path/to/backup/directory/nextcloud.conf.$(date +%Y%m%d) /etc/apache2/sites-available/nextcloud.conf

差分が無いことでバックアップを確認します。

※余談:執拗なまでのバックアップ

「責任範囲を明確にするため」です。

設定ファイルというものは、どこかのミスであっという間に破綻する「すぐそこにある破滅」です。「起きてしまった破滅」からすぐリカバリーできるため、「何かあったときの責任者は誰か(芋を引くのはどいつか?)」を決める絶好の証拠になります。

○自分の設定でミスが起きた:潔く諦め、原状回復に努めましょう。
○誰かの設定ミス:追求や晒し上げは後にして、原状回復に努めましょう。責任者は誰かと追求してもサーバは止まり続けます。

ここで重要なのは、サービスが止まった「この時点で」重要なのは、「誰がやったか」ではなく「いかに早く復旧させるか」です。

  • ファイル編集

/etc/apache2/sites-available/nextcloud.conf を、任意の方法で編集します。(エディタという宗教問題が絡むため)

他のリダイレクト設定やセキュリティ設定(RewriteRuleなど)に干渉されないよう、<VirtualHost *:443> ブロック内のなるべく上の方に記述するのがコツです。

<VirtualHost *:443>
    # (その他既存の設定...)

    # ====================================================
    # Nextcloud Client Push (notify_push) 設定
    # ====================================================
    <Location /push>
        ProxyPass ws://127.0.0.1:7867/ws
        ProxyPassReverse ws://127.0.0.1:7867/ws
    </Location>

    ProxyPass /push/ http://127.0.0.1:7867/
    ProxyPassReverse /push/ http://127.0.0.1:7867/
    # ====================================================

    # ... (これ以降にDocumentRootやセキュリティ設定が続く) ...
  • 編集後の差分確認
diff -u /path/to/backup/directory/nextcloud.conf.$(date +%Y%m%d) /etc/apache2/sites-available/nextcloud.conf

以下の差分を確認します。

+# ====================================================
+# Nextcloud Client Push (notify_push) 設定
+# ====================================================
+    <Location /push>
+        ProxyPass ws://127.0.0.1:7867/ws
+        ProxyPassReverse ws://127.0.0.1:7867/ws
+    </Location>
+    
+    ProxyPass /push/ http://127.0.0.1:7867/
+    ProxyPassReverse /push/ http://127.0.0.1:7867/
+# ====================================================
+

設定反映

  • 整合性確認
sudo apache2ctl configtest

Syntax OKを確認します。

  • apache再開前確認
systemctl status apache2.service

active(running)を確認します

  • apache再開
sudo systemctl restart apache2.service
  • apache再開確認
systemctl status apache2.service

active(runnning)を確認します

Notifyデーモン(サービス)を作成します。

Client Pushは、Webサーバーとは別に裏方で動くプログラムです。これを常駐させるための設定ファイルを作成します。

  • ファイル作成

`/etc/systemd/system/notify_push.service`

を、任意の方法で作成します。

UserWorkingDirectoryExecStart のパスは、ご自身のNextcloudインストール環境(例: /var/www/nextcloudなど)に合わせて必ず修正してください。

[Unit]
Description = Nextcloud Client Push Node binary
After = network.target

[Service]
Type = simple
User = www-data
Group = www-data
# 【重要】環境に合わせて変更してください。特に、ExecStartは2カ所、修正箇所があります。
WorkingDirectory = /var/www/nextcloud
ExecStart = /var/www/nextcloud/apps/notify_push/bin/x86_64/notify_push /var/www/nextcloud/config/config.php
Restart = on-failure

[Install]
WantedBy = multi-user.target
  • サービス有効化
sudo systemctl daemon-reload
  • サービス起動
sudo systemctl enable --now notify_push
  • サービス起動確認
systemctl status notify_push.service 

active(running)を確認します

Trusted Proxiesの設定(どハマりした部分)

ここがつまずきポイントでした。

サーバーが自分自身のURL(https://your.domain.com)にアクセスした際、ネットワーク環境(ヘアピンNATなど)によっては一度外に出てグローバルIP経由で戻ってくる場合があります。

この場合、Nextcloudは「外部からのアクセス」とみなして通信を拒否してしまいます。これを防ぐため、config.php に自身のグローバルIPを信頼済みプロキシとして登録します。

  • configファイルのバックアップ
sudo cp -pi /path/to/nextcloud/root/config/config.php /path/to/backup/directory/config.php.$(date +%Y%m%d)

格納場所は自分の環境に合わせます。

  • 差分確認(※sudo付き)
sudo diff -u /path/to/backup/directory/config.php.$(date +%Y%m%d) /path/to/nextcloud/root/config/config.php

差分が無いことを確認します。

ここでsudoをつけるのは、NextcloudのファイルパーミッションがNextcloudの実行ユーザとrootしか読み取れないため(640)のためです。

Nextcloudの config/config.php を開き、trusted_proxies 配列に追記します。

  'trusted_proxies' => 
  array (
    0 => '127.0.0.1',
    1 => '::1',
    2 => '203.0.113.123',  // ← 【ここに追加】あなたのサーバーのグローバルIP
  ),
  • 差分確認(※sudo付き)
sudo diff -u /path/to/backup/directory/config.php.$(date +%Y%m%d) /path/to/nextcloud/root/config/config.php

以下を確認します。

+    2 => '203.0.113.123',

設定の手動登録

通常は occ notify_push:setup コマンドを使いますが、Bot検知やIP制限などのセキュリティ設定が厳しい環境では、接続テストで「403 Forbidden」や「404 Not Found」が出て失敗することがあります。

そのため、テストをスキップして強制的に設定値を登録するコマンドを使います。

sudo -u www-data php /var/www/nextcloud/occ config:app:set notify_push base_endpoint --value "https://your.domain.com/push"

URLはご自身のものに合わせてください。また、パス(/var/www/nextcloud)は環境に合わせて変更してください。

  • notify_pushサービス再起動
sudo systemctl restart notify_push
  • サービス起動確認
systemctl status notify_push.service 

active(running)を確認します。

確認

Nextcloudの管理画面(「概要」または「ログ」)を確認し、「Client Push」に関する警告が消えていれば導入成功です。

これでファイル同期が爆速になり、サーバー負荷も低減されているはずです。警告を消したいだけの場合でも、この手順を行っておけば「高セキュリティかつ高性能」な環境が手に入ります。

Nextcloud 32.xでAppAPIデプロイデーモンをDockerでインストール。

Nextcloudを32.0.2にアップデート後、以下のエラーを確認しました。

AppAPIデプロイデーモン
AppAPIデフォルトのデプロイデーモンが設定されていません。外部アプリ(Ex-Apps)をインストールするための設定で、デフォルトのデプロイデーモンを登録してください。

Mimetypeの移行が可能
1つ以上のmimetypeマイグレーションが利用できます。時折、特定のファイルタイプをよりよく扱うために新しいmimetypesが追加されます。大規模なインスタンスではmimetypesの移行に時間がかかるため、アップグレード時には自動的には行われません。移行を行うには occ maintenance:repair --include-expensive コマンドを使用してください。

データベースに存在しないインデックス
いくつかの欠落しているオプションのインデックスを検出しました。データベースのパフォーマンスを向上させるために、(Nextcloudまたはインストールされたアプリケーションによって)新しいインデックスが追加されることがあります。インデックスの追加には時間がかかり、一時的にパフォーマンスが低下することがあるため、アップグレード時には自動的には行われません。インデックスが追加されると、それらのテーブルへのクエリが速くなるはずです。インデックスを追加するには、occ db:add-missing-indices コマンドを使用してください。 インデックスが不足: "properties_name_path_user" テーブル内の "properties", "unique_category_per_user" テーブル内の "vcategory", "calobjects_by_uid_index" テーブル内の "calendarobjects"

これについて解消していきます。

環境

  • Nextcloud 32.0.2
  • Ubuntu 24.04
  • Apache 2.4
  • MySQL 8.0
  • PHP 8.3 (PHP-FPM 8.3)

フェイズゼロ:政治交渉

このNextcloudを個人的に運用しているのならばそのまま行って構いません。しかし、これを組織で運用しているとなると話はまるで違います。

  • NextcloudのアップデートによりDockerコンテナが必要になった。
  • ついてはこの計画でサーバ設定を行う
  • そのため、追加で作業時間をいただきたい
  • 作業時間は○時頃、○分程度で終わる。その間、Nextcloudは使えなくなる

など、利用者への周知という名の政治交渉が必要になります。この運用者の政治的な立ち位置(担当者/担当部門が強権を振るえるか否か)でも言い方や手段が決まってきます。そこは状況に応じていきましょう。

※ 検証環境を用意できる程度には時間と予算と環境に余裕がある方は、その環境にいることを感謝しつつ、検証を重ねていきましょう。

もちろん、新サービス(Docker)の追加という文書管理も必要になっていきます。以下の手順は

  • 個人運用だからそもそも関係ない
  • フェイズゼロをクリアした

方向けの手順です。おそらく、組織でNextcloudを運用している方はここが一番のハードルだと思います。

さっくりとした手順

  1. Nextcloudのメンテナンスモードを有効化します。
  2. Dcokerをインストールします。
  3. Dockerの起動と自動起動設定を行います。
  4. Docker Socket Proxyのコンテナを立ち上げます。
  5. Nextcloudのメンテナンスモードを無効化します。
  6. NextcloudでDockerデーモンを登録します。
  7. ついでに他のエラーも解消します。
  8. エラーの解消を確認します。

正直、筆者はDockerを信用していませんが「必要ならば入れるまで」です。

メンテナンスモードを有効化

  • Nextcloudのルートディレクトリ移動
cd /path/to/nextcloud/root/directory && pwd

自分の環境に合わせます。(筆者環境/home/www-data/nextcloud)

  • メンテナンスモード有効化
sudo -u www-data php occ maintenance:mode --on
  • メンテナンスモード確認

運用中のNextcloudのURLにアクセスし、メンテナンスモードであることを確認します。

Dockerのインストールを行います。

AppAPIは、背後でDockerコンテナを立ち上げてアプリケーションを実行します。まずはUbuntuサーバー自体にDockerが入っているか確認し、なければインストールします。

  • パッケージ全体のアップデート
sudo aptitude update

※筆者の好みでaptitudeを用いています。好みに応じてaptに読み替えてください。

  • Dockerのインストール
sudo aptitude install docker.io
  • Docker有効化
sudo systemctl start docker
  • Dockerの自動起動
sudo systemctl enable docker
  • Dockerのサービス状況確認
systemctl status docker.service docker.socket 

active(running)enabledを確認します。

Docker Socket Proxyのセットアップ

NextcloudはApacheユーザー(通常 www-data)で動作していますが、Dockerは roto 権限で動いています。NextcloudからDockerを安全に操作させるために、Docker Socket Proxy という中継役のコンテナを立ち上げるのが推奨される方法です。

  • Docker Socket Proxy (socat) を起動
sudo docker run -d \
  --name nextcloud_app_api_dsp \
  --restart always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -p 2375:2375 \
  alpine/socat \
  tcp-listen:2375,fork,reuseaddr unix-connect:/var/run/docker.sock
  • 稼働中のコンテナ一覧を見る
sudo docker ps

出力されたリストの中に、以下の特徴があれば成功です。

  1. NAMES: nextcloud_app_api_dsp という名前がある。
  2. STATUS: Up X secondsUp X minutes となっている。(ここが Exited だと停止しています)
  3. PORTS: 0.0.0.0:2375->2375/tcp のようにポートが表示されている。

※出力例:

CONTAINER ID   IMAGE          STATUS          PORTS                    NAMES
a1b2c3d4e5f6   alpine/socat   Up 2 minutes    0.0.0.0:2375->2375/tcp   nextcloud_app_api_dsp

  • ポートが開いているか確認する

OS側から見て、ポート2375番が待受状態になっているか確認します。

ss -nlt | grep 2375

※成功時の表示例:

LISTEN 0      512          0.0.0.0:2375        0.0.0.0:

※注意: 2375ポートは内部アクセス専用とし、外部公開しないようFW設定を確認してください

これが出ていれば、Nextcloudからの接続を受け付ける準備が完了しています。

  • もし「動いていない(表示されない)」場合

sudo docker ps で何も表示されない場合は、起動に失敗して終了してしまった可能性があります。その場合は以下でエラー原因を確認します。

  • 停止したものも含めて表示
sudo docker ps -a
  • ログ(エラー内容)を表示
sudo docker logs nextcloud_app_api_dsp

※よくあるエラー:
もしログに permission denied と出る場合は、Docker自体へのアクセス権限の問題ですが、今回の sudo docker run で実行していればこの動作は置きにくいでしょう。

  • メンテナンスモード無効化
sudo -u www-data php occ maintenance:mode --off
  • メンテナンスモード確認

運用中のNextcloudのURLにアクセスし、管理画面に入ります。

NextcloudでDockerデーモンを登録します。

管理者権限でNextcloudにログインし、

管理 > AppAPI

に進みます。

Deploy Daemonsの項目の+デーモンを登録に進みます。

以下のように設定します。

  • Daemon configuration template
    • Docker Socket Proxy を選択。
  • 名前
    • docker_socket_proxy (デフォルトのままでOK)
  • 表示名
    • Docker Socket Proxy (デフォルトのままでOK)
  • Deployment method
    • docker-install (デフォルトのままでOK)
  • Daemon host
    • localhost:2375
    • → ここはデフォルトと異なります。せっかくDockerを自サーバ(localhost)に接続したのですから、localhostを入れましょう。
  • Haproxyパスワード
    • HaProxyパスワード」に入っている黒丸(……)をすべて消して空白にします。
    • 先ほどコマンドで立ち上げた alpine/socat というコンテナは、パスワード認証機能を持たないシンプルな「通信中継(土管)」です。そのため、「HaProxyパスワード」という項目は、今回の構成(Docker Socket Proxy)では無視されます。(HaRP Proxyなどもっと複雑な構成で使用します)
  • Nextcloud URL
    • 管理しているNextcloudのURLを入れます。

このあと、「Check connection」をクリックします。「Daemon connection successful」と出たら「Register」をクリックします。

他のエラーの解消

  • MymeTypeの登録

再びNextcloudがインストールされているWebサーバに接続します。

  • Nextcloudのルートディレクトリ移動
cd /path/to/nextcloud/root/directory && pwd

自分の環境に合わせます。(筆者環境/home/www-data/nextcloud)

sudo -u www-data php occ maintenance:repair --include-expensive
  • インデックスの追加

先ほどのNextcloudのルートディレクトリのまま実行します。

sudo -u www-data php occ db:add-missing-indices

念のため:apacheリスタート

  • apache再開前確認
systemctl status apache2.service

active(running)を確認します

  • apache再開
sudo systemctl restart apache2.service
  • apache再開確認
systemctl status apache2.service

active(runnning)を確認します

エラーの解消を確認します。

管理者権限でNextcloudにログインし、

AppAPIデフォルトのデプロイデーモンはHaRPを使用していません。パフォーマンス向上のため、アップグレードをご検討ください。

とメッセージが警告に変わっていればOKです。

この作業に関するFAQ

Dockerインストールによるメモリ消費量は大丈夫か?

全く問題ありません。誤差レベルです。

今回使用する alpine/socat というコンテナは、非常に軽量なことで有名な「Alpine Linux」というOSをベースに、socat という単純な転送プログラムだけが動いています。

  • 消費メモリ:
    • およそ 2MB ~ 6MB程度です。
  • CPU負荷:
    • 待機時はほぼ 0%です。

サーバー全体のメモリが数GBある環境であれば、このコンテナの存在に気づかないレベルの軽さですので、ご安心ください。

サーバ再起動時、Dockerの設定が消えるのではないか?

このコンテナに関しては、「データが消えても問題ない(そもそもデータを保存しない)」仕組みになっているため、大丈夫です。

なぜ消えても大丈夫なのか(仕組みの解説)

このコンテナ nextcloud_app_api_dsp は、「土管(パイプ)」のような役割しかしていません。

  • データの保存場所:
    -「どのデーモンを使うか」という設定情報は、このコンテナの中ではなく、Nextcloud本体のMySQLデータベースに保存されます。今後インストールする外部アプリ(AIなど)のデータも、Nextcloudのストレージ領域に保存されます。
  • このコンテナの役割:
    • Nextcloud(Webサーバー)からの命令を、Ubuntu本体のDockerシステムに「中継」するだけです。中継役なので、自分自身は何も記憶する必要がありません。
  • 再起動時の挙動:
    • Docker立ち上げ時、コマンド内の --restart always というオプションのおかげで、Ubuntuサーバーを再起動すると、このコンテナも自動的に「新品の状態」で立ち上がります。立ち上がった瞬間から、再び「中継役(土管)」としての仕事を再開します。前回の中身を覚えている必要がないため、これで正常に動作します。

まとめ

  • メモリ: スマートフォンの写真1枚分(数MB)しか使いません。
  • 保存: このコンテナは「ただの通信ケーブル」のようなものなので、記憶を保持する必要がなく、再起動してもNextcloud側の設定(DB)が残っている限り繋がり続けます。

色と差し色。

カメラの試し撮りを行った帰り、iPadを広げた途端に強烈な情報が目に入りました。

それは

  • No Time
  • No Choise
  • Without Thinking

と言えるものであり、その場で手続きを済ませ、翌日に到着。

ハリー・ポッターシリーズ、

  • スリザリン
  • レイブンクロー
  • ハッフルパフ
  • グリフィンドール

それぞれのLAMY AL-Star。そもそもLAMY万年筆は愛用品。しかも、それぞれの寮の色。ペン先も使いやすいEF。

それぞれ、プレミア価格ではなく在庫ありという幸運にも助けられ、届きました。

さて、ここまでの逸品。量産品を愛用する身ではありますが「それはそれ」です。これを最大限に活かすため、まずはインクを決めるところからです。

それぞれの寮に合わせ

はワンパターンです。かといって別の色というのも何か合いません。そこで、新たなインクを買い求めました。

そこで決めたのは、「寮のサブカラー」です。

  • スリザリン:銀
    • 冬将軍。この冷徹な野心を「冬」に込めました。
  • ハッフルパフ:黒
    • 竹炭。最も多用する色は、彼等の調和、連帯力に一致。
  • グリフィンドール:金
    • 橙路。色合いが金に近かったためこちらに。「路は自分で切り開く」グリフィンドールの精神にも合います。
  • レイブンクロー:銅
    • 春暁。同じく銅の鈍さと明るさ。彼等の寮ならそれこそ暁まで研究や議論に明け暮れいるでしょう。

さらに、インクに寮のマステを貼り、更に迷いをなくします。

書き味などを確かめるのはこのあとで。

RHEL系Linux(Rocky Linux)でDockerのビルド領域変更

Dockerならではの問題に対処したのでメモを残します。

背景と課題

RHEL / Rocky Linux 9 環境のGPUサーバーにおいて、Dockerビルド(大規模LLMモデルの生成など)を実行した際、ルートパーティション(/)の使用率が100%に達する事象が発生しました。

  • 原因: Dockerはデフォルトで /var/lib/docker(ルート配下)にイメージやビルドキャッシュを保存します。
  • 環境: ルート領域は70GB程度ですが、/home 領域には数TBの空きがります。
  • 対策: パーティションリサイズ(LVM操作)はリスクが高いため、Dockerのデータ保存先(data-root)を /home 配下へ物理的に移行して解決します。

さっくりとした手順

  1. 現状を確認し、サービスを停止します。
  2. Dockerの移行ディレクトリを作成します。
  3. rsyncを用いて安全にデータを移行します。
  4. Dockerの設定ファイルを変更します。
  5. Dockerサービスの再起動を行います。
  6. 設定変更を確認します。

現状の確認とサービスの停止

まず、現在のDocker設定とディスク使用量を確認し、Dockerサービスを停止します。

  • Dockerの保存先確認
docker info | grep "Docker Root Dir"

(デフォルトは /var/lib/docker)

  • Dockerサービスを停止します。
sudo systemctl stop docker docker.socket
  • Dockerサービスの停止を確認します。
systemctl status docker

inactive(dead)を確認します。

移行先ディレクトリを作成します。

大容量領域(今回は /home 配下)に新しい保存用ディレクトリを作成します。

  • ディレクトリ作成
sudo mkdir -p /home/docker/data

データの移行(最重要)

既存のイメージやコンテナデータを保持するため、rsync を用いてデータを同期します。
cp コマンドよりも、権限やタイムスタンプを正確に保持できる rsync を推奨します。
rsyncはRocky9に最初から入っているコマンドです。

  • /var/lib/dockerの中身を、新ディレクトリへコピー
sudo rsync -aqxP /var/lib/docker/ /home/docker/data/

-a: アーカイブモード(権限等を保持)
-x: ファイルシステム境界を越えない
注意: コピー元のパス末尾に / を付けることで、ディレクトリそのものではなく「中身」を転送先に展開します。

設定ファイルの変更 (daemon.json)

  • ファイルのバックアップを取ります。(凄く重要)

何かあったときの切り戻しのため。特に、後述するjsonの編集をミスると地獄行きの通過駅無しの特急が待っています。

sudo cp -pi /etc/docker/daemon.json /path/to/backup/directory/daemon.json.$(date +%Y%m%d)
  • ファイルのバックアップをdiffで取ります。
sudo diff -u /path/to/backup/directory/daemon.json.$(date +%Y%m%d) /etc/docker/daemon.json

一般ユーザが読み取れないディレクトリ構造も考慮して、念のためsudoをつけます。

→ エラーがなければバックアップ成功。ここでコピー元とコピー先を逆にしているのは編集後のdiffを取るためです。

  • Dockerに新しい保存先を認識させるため、/etc/docker/daemon.json を編集します。(エディタは宗教問題のため、自分の教義・信仰に沿ったものを利用してください)

変更例:
data-root オプションを追記します。
JSON形式のため、行末のカンマ(,)の有無に注意してください。

{
    "runtimes": {
        "nvidia": {
            "path": "nvidia-container-runtime",
            "runtimeArgs": []
        }
    },
    "data-root": "/home/docker/data"
}
  • 編集後の差分をdiffで確認します。
sudo diff -u /path/to/backup/directory/daemon.json.$(date +%Y%m%d) /etc/docker/daemon.json

以下のようになっていることを確認します。

-     "data-root": "/var/lib/docker"
+     "data-root": "/home/docker/data"

サービスの起動と確認

Dockerを起動し、設定が反映されているか確認します。

  • Dockerサービスを起動します。
sudo systemctl start docker
  • Dockerサービスの起動を確認します。
systemctl status docker

active(running)を確認します。

  • 設定反映の確認
docker info | grep "Docker Root Dir"

=> Docker Root Dir: /home/docker/data となっていれば成功です。

不要データの削除(任意)

動作確認後、元の /var/lib/docker を削除または退避させて、ルートパーティションの空き容量を回復させます。

安全のため、バックアップを取るか慎重に削除してください。この作業を行うときは深呼吸を3回ほど行い、飲み物を飲むなどして落ち着いてから行いましょう。

sudo rm -rf /var/lib/docker

結果

本対応により、ルートパーティションの圧迫が解消されました。

Before:

Filesystem           Size  Used Avail Use% Mounted on
/dev/mapper/rl-root   70G   70G   20K 100% /

After:

Filesystem           Size  Used Avail Use% Mounted on
/dev/mapper/rl-root   70G  6.0G   65G   9% /
/dev/mapper/rl-home  6.9T  198G  6.7T   3% /home

トラブルシューティング

  • SELinux: 起動に失敗する場合、SELinuxが非標準ディレクトリへのアクセスをブロックしている可能性があります。一時的に setenforce 0 で切り分けを行うか、適切なコンテキストを設定してください。
  • JSON構文エラー: daemon.json の記述ミス(カンマ忘れなど)があるとDockerが起動しません。編集後は慎重に確認を行いましょう。

RHEL系LinuxサーバにRTX 6000を認識させる。

※昨今のトレンドである「GPU前提のLinuxサーバ」つまり、AI環境に必須の

  • データセンタークラスのGPU
  • それをRHEL系Linuxに認識させ
  • 更にDockerというトレンドでも動かす

という難易度が高く――そして、インフラ屋にとって極上の素材を得る経験がありました。

そのときのメモです。(氷見の本マグロを捌くことになった調理師のような気分でした)

“逸般”の誤家庭的な環境

まず、これを一般家屋に置くと言うことはないでしょう。

  • OS:
    • Rocky Linux 9.x (Minimal Install)
  • Kernel:
    • 5.14.0-x (RHEL 9 Standard)
  • GPU:
    • NVIDIA RTX 6000 Ada Generation x 1
      • →2025/12/06時点でもちょっとした軽自動車が買えるやつです
  • Driver:
    • NVIDIA Driver 590.xx (Open Kernel Module)
  • Container Runtime:
    • Docker CE 27.x + NVIDIA Container Toolkit

前提環境の整備

  1. OSインストールを行います。(Rocky Linux Minimal)
  2. ネットワークの設定を行います。
  3. dnf updateを済ませます。

NetworkManagerによるネットワーク設定

固定IP化および自動接続設定を行う。

  • 接続プロファイル名の正規化 (デバイス名と合わせる)
sudo nmcli connection modify "Wired connection 1" connection.id eno2
  • 固定IP設定
sudo nmcli connection modify eno2 ipv4.addresses xx.xx.x.x/16
sudo nmcli connection modify eno2 ipv4.gateway Gateway IP
sudo nmcli connection modify eno2 ipv4.dns "DNS1 DNS2"
sudo nmcli connection modify eno2 ipv4.method manual
sudo nmcli connection modify eno2 connection.autoconnect yes

→ これをやっておかないと、再起動したときにNW設定が消えます。

  • 設定反映
sudo nmcli connection up eno2

システム更新とリポジトリ適用

RHEL 9 系でサードパーティ製パッケージを入れるため、これは必須です。特に、CRB (CodeReady Builder) の有効化を忘れると依存解決ができず、高性能GPUを認識させることができません。

  • dnf全更新
sudo dnf update -y
  • サーバ再起動
sudo reboot

→ カーネルアップデートも含まれるため。

  • CRB有効化 (旧 PowerTools)
sudo dnf config-manager --set-enabled crb
  • EPEL導入
sudo dnf install epel-release -y

NVIDIA Driver の導入

ここまで来たらいよいよ本命。(先のマグロの例に例えると、いよいよマグロの身に刃を当てていきます)

【重要】 RTX 6000 Ada はプロプライエタリ版ドライバではなく、Open Kernel Module (open-dkms) を要求します。これに気づかずハマりかけました。

依存関係の解決とリポジトリの導入。

  • 開発ツールの導入
sudo dnf groupinstall "Development Tools" -y
  • カーネルヘッダの導入
sudo dnf install kernel-devel-$(uname -r) kernel-headers-$(uname -r) -y
  • NVIDIA公式リポジトリ (RHEL9用) 追加
sudo dnf config-manager --add-repo https://developer.download.nvidia.com/compute/cuda/repos/rhel9/x86_64/cuda-rhel9.repo

旧ドライバ/競合の排除

以前のインストール試行や(ハマったところ)、OSに入っているであろうGPUドライバを取り除かないと詰まります。

  • nvidia dkmsドライバのアンインストール
sudo dnf remove nvidia-driver kmod-nvidia-latest-dkms -y
  • nvidia dkmsドライバのリセット
sudo dnf module reset nvidia-driver -y

Open Kernel Module 版のインストール

  • dnf module機能を使って open-dkms ストリームを指定してインストール
sudo dnf module install nvidia-driver:open-dkms -y
  • サーバ全体を再起動してカーネルモジュールをロード
sudo reboot

ドライバ動作確認

nvidia-smi

-> `Driver Version: 590.xx / GPU Name: RTX 6000 Ada / VRAM: xxGB が表示されることを確認します。

コンテナ基盤の構築

筆者はコンテナが好みではないのですが、それはそれです。相手のオーダーに答えるのもまたお仕事。

Docker CE のインストール

ここではpodman ではなく Docker CE を採用しました。

  • Docker CEレポジトリ追加
sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
  • Docker CEインストール
sudo dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
  • Docker 自動起動有効化
sudo systemctl enable --now docker
  • 現在のユーザをDockerグループに加える
sudo usermod -aG docker $USER

NVIDIA Container Toolkit の導入

DockerコンテナでGPUが見えないと、せっかく「Dockerを入れろ」というオーダーが無になります。

  • Toolkitインストール
sudo dnf install nvidia-container-toolkit -y
  • Dockerランタイム設定 (daemon.jsonの更新)
sudo nvidia-ctk runtime configure --runtime=docker
  • Tookit/ランタイム反映
sudo systemctl restart docker

動作確認 (パススルーテスト)

コンテナ内部から GPU が見えるか確認します。

sudo docker run --rm --gpus all nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi

成功時、コンテナ内からホスト同様の nvidia-smi 結果が出力されれば動作完了です。

追加要素:最新トレンドに合わせた開発環境の用意。

言語ランタイム (Modern Runtime)の導入

OS標準を汚さず、最新の開発環境を整備する。

  • Node.js 22+:
    • NodeSourceリポジトリより導入。これは割愛です。(どっかしら探せば出てくるので)
  • Python 3.12:
    • Rocky Linuxは3.9。しかも、OSの核となっているプログラムなので、ソースコードを用いて altinstall (共存インストール) しないとサーバそのものが吹っ飛びます。

※実行例

  • 開発環境導入
sudo dnf install -y openssl-devel bzip2-devel libffi-devel zlib-devel readline-devel sqlite-devel tk-devel xz-devel
  • ソースコードダウンロード
wget https://www.python.org/ftp/python/3.12.8/Python-3.12.8.tgz
  • ソースコード展開
tar xzf Python-3.12.8.tgz && cd Python-3.12.8
  • ソースコードconfigure(最適化オプション)
./configure --enable-optimizations
  • CPUコアフルに用いての高速メイク
make -j $(nproc)
  • altinstall
sudo make altinstall

altinstallを入れないと上述したようにサーバが吹っ飛びます。

トラブルシューティング (Tips)

以下のエラーに出くわしたときの原因と対策です。

  • NVRM: requires use of the NVIDIA open kernel modules:
    • 原因: Ada世代のGPUに対し、従来のプロプライエタリドライバを入れたため。
    • 対策: dnf module install nvidia-driver:open-dkms を使用しました。
  • Secure Boot:
    • ドライバ導入前に BIOS/UEFI で Disabled になっていることを確認すること(署名周りのトラブル回避)。

RHEL系サーバ、実物環境下でのネットワーク設定

はじめに

GUIが多くなったとは言え、Linuxサーバは基本的にCLI(コマンドライン)・SSH接続によるリモート操作が基本です。この、CLIの環境下でのネットワーク設定という基本のメモです。

環境とやったこと

極めてよくあるユースケースです。即ち

「サーバ実機はこれである。ひとまず組織内(社内)ネットワークにつなげ」

という指令への対処。

  • 物理サーバ
    • 今回はVPSではありません。実機です。
    • その大きさ、重さを知るのもインフラ屋の醍醐味です。
  • Rocky Liunx 9.x
    • (RHEL系フォーク、ミニマルインストール)
  • ローカルNWにサーバのIPを割り当てる。
  • NW設定を有効化する。
    • 固定IP。クライアントならいざ知らず、サーバ運用は固定IPであるべきです。
    • IP: 172.xx.xx.xx/16 (/16はサブネットマスク255.255.0.0を意味します)
    • GW: 172.xx.254.254 (※これはあくまでも例です)
    • DNSサーバ/ドメイン:ローカルで定められているもの。

さっくりとした手順

ではありますが、かなり慎重に書いています。

  1. RockyLinuxサーバをMinimalでインストールします。
  2. サーバコンソールに直接ログインします。
  3. ネットワークインタフェースを確認します。
  4. nmcliによりネットワークを設定します。
  5. ネットワークインタフェースを有効化します。
  6. サーバを結線してリンクアップを確認します。
  7. 最初のdnf updateを行います。

RockyLinux 9.6インストール

インストール方法については割愛。GUI無しのMinimalをインストールします。というのも、多くのサービスが入ってしまうと、自分が管理しきれない部分が増えると共に、そこが脆弱性となるからです。

また、ここでは最初からネットワークにつなぎません。設置する組織によってはLAN接続も許可制になっているパターンが極めて多いです。(IPも指定されたものを使うというのが実情でしょう)

サーバコンソールにログイン

この段階ではrootでも構いません。何せ、物理的に言葉通りの意味で切断されているのですから。

物理ネットワークの確認

vpsと違い、最初からネットワークにつながっていません。当然、IPも振られていません。なので「どのLANポートを使うか?」から始まります。

nmcli

を実行します。これはNetwork Manager Command Line Interfaceの略であり、RHELサーバの肝と言えるネットワーク設定コマンドです。(普段Ubuntuサーバを使う筆者は少々混乱しました)

筆者環境では

  • eno2
  • eno3

がありました。ここではeno2を確認していきます。

ネットワーク設定

  • 現状確認
nmcli connection show

以下のような例が出てきます。

NAME     UUID                                  TYPE      DEVICE
eno2     UUID文字列                             ethernet  eno2
lo       UUID文字列                             loopback  lo
eno3     UUID文字列                             ethernet  eno3

この、eno2というポートを使います。

  • ※例外

もし、もし NAME 列に Wired connection 1 とあり、DEVICE 列が eno2 ならば、次の手順で名前を変更します。

  • ※例外時の実施- "Wired connection 1" を "eno2" にリネーム
sudo nmcli connection modify "Wired connection 1" connection.id eno2
  • IPとサブネット設定 (CIDR表記でスマートに)
sudo nmcli connection modify eno2 ipv4.addresses 172.xx.xx.xx/16

→ 実際に指定されたIPアドレスを入力します。このとき、二重チェックで「同一ネットワーク内にIPアドレスが無いか? / 打ち間違いがないか?」を確認しましょう。被ってしまうと単純な破滅が待っています。

  • ゲートウェイ設定
sudo nmcli connection modify eno2 ipv4.gateway 172.xx.254.254

こちらも同様。別のゲートウェイを設定していないかを確認。

  • DNS設定
sudo nmcli connection modify eno2 ipv4.dns "DNS1 IPアドレス DNS2 IPアドレス"

→ DHCPと異なり、固定IPはDNSサーバを指定します。組織内では冗長性のため複数あるケースがほとんどです。

  • ドメイン設定
sudo nmcli connection modify eno2 ipv4.dns-search "組織内ドメイン"

→ 組織内ドメインで、FQDNの名前解決を効率化するため。

  • メソッドを手動にしてIPアドレス固定
sudo nmcli connection modify eno2 ipv4.method manual
  • 【重要】自動接続をONにする (これを忘れると再起動後に死ぬ)
sudo nmcli connection modify eno2 connection.autoconnect yes

→ autoconnect no の状態だと、システムが再起動した後、NetworkManagerは設定ファイルは認識していますが、その接続を自発的に起動しません。つまり、何らかの事情でサーバそのものを再起動した場合、このネットワーク設定が断たれます。即ち、あらゆるネットワークから完全に切り離されます。

ネットワーク設定の有効化

ここまで来たらいよいよサーバにネットワークを認識させます。このコマンドの前に深呼吸をして落ち着きましょう。(サーバ室/データセンターからの離席を許されるならこの段階で)

  • 再起動して設定をロード
sudo nmcli connection up eno2
  • IPアドレスの確認
ip addr show eno2

→ インターフェース eno2 に正しいIPアドレス、ネットマスクが割り当てられたか。

eno2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
  • ルーティングの確認
ip route

→ デフォルトゲートウェイ(外部ネットワークへの出口)が正しく設定されたか。

IPアドレスが正しくても、どこへパケットを送るか(経路情報)がなければ、ローカルネットワーク外へは通信できません。

default via  172.xx.254.254 dev eno2

などの行がないと、外部環境は無意味です。初歩的ですが非常に詰まりやすいポイントです。

  • DNS設定の確認
cat /etc/resolv.conf

→ ネームサーバーと検索ドメインが設定ファイルに反映されたか。

nameserver: 設定した社内のDNSサーバーのIPアドレス(例: nameserver 192.168.1.53)が正しくリストアップされているか。
もしこれらが正しく反映されていなければ、名前解決ができず、Webサイトの閲覧やホスト名でのサーバーアクセスができなくなります。

サーバの結線

上記が確認できたら、サーバという鉄の箱を「ネットワークと通信ができる」状態へと落とし込みます。ここでも、単純ながら致命的なミスが待ち構えています。

以下を確認しましょう。

  • LANポートの接続先と接続元は合っているか?
    • 特に、LANポートの迷路とも言えるサーバ室やデータセンターではこれらを間違えると地獄が待っています。比喩的な意味では無く。
  • LANケーブルは断線が無いか?
    • 切り分けの手間を減らします。
  • ストレートとクロスを間違えていないか?
    • たまにありますが結構盲点です。

疎通確認

  1. Gatewayへの Ping:ping -c 4 172.xx.254.254
    • これが通れば、L2/L3(組織/社内ネットワークへの物理・論理接続)は成功しています。
  2. DNSサーバへの Ping:ping -c 4 [DNSサーバーのIP]
    • これが通れば、名前解決の準備OKです。
  3. 外の世界への Ping:ping -c 4 google.com
    • これで初めて「インターネット接続完了」です。

DNFアップデート

サーバ全体のLinuxシステムを「最新の状態にする」おまじないです。

sudo dnf update -y

ここでの注意点はトラフィック。大容量のデータがこのサーバに流れます。貧弱な回線ではたちまちパンクします。

Complete!と表示されたら、

sudo reboot

で物理的に再起動します。というのも、dnfアップデートはたいがいカーネルの更新も伴うからです。

この再起動後、「先ほどのネットワーク設定が活きているか? 失われていないか?」が伴い、初めてこのネットワーク設定という初歩的な設定が完了します。

BIOSビルトインのRAID設定メモ。

サーバ設定時、BIOSに備わっているRAID機能を有効化したときのメモです。

SATA接続、同容量、同じ型番のSSDを「RAID1」として、冗長化をしたハードウェアのフェイルセーフのメモです。

環境

  • ASU-PRO/WS/W790E-SAGE/SE

というワークステーション(サーバ)のMBをいじりました。

さっくりとした手順

  1. BIOSの画面に入ります。
  2. Sata ModeをRaidにします。
  3. Raid構成をセットします。
  4. Raidが見えるかを確認します。

BIOS画面のセッティング

  1. Platform Configuration > PCH Storage Configuration > Controllr SATA And RST Configuratioに進む。
  2. SATA Mode Selection > Raidに進む。

この段階ではまだ有効化されていないので、F10で情報を保存。サーバそのものを再起動します。

Raid構成

再起動後、再びBIOSに入ります。

  1. Advanced > Intel (R) VROC SATA Controllerに進みます。
  2. Create Raid Volumeを選択します。

以下の通りセッティングします。

  • Name:Raidのボリュームを探す
  • Raid LevelでMirroringがStripingを選択します。(Striping/Raid0はまず利用しないでしょう)
  • Select Diskでボリュームを選択します。
  • その他項目(ラベリングや容量など)を設定。

Create Volumeを実行します。

Raid構成確認

その後、BIOS画面で設定を確認します。
OSインストールで、ディスクそのものが1つ(ミラーリング)として見えていれば成功です。

BookStackのカスタム404ページを更に変更。

以前のこのページを更に差し替え。

/path/to/BookStack/resources/views/errors/

の`404.blade.php`の内容を、

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>404 Not Found: The Final Problem</title>
<style>
  @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700;900&display=swap');

  body {
    background-color: #000000;
    color: #d4d4d4;
    font-family: 'Noto Sans JP', sans-serif;
    margin: 0;
    padding: 20px;
    line-height: 1.6;
    overflow-x: hidden;
  }

  .container {
    max-width: 800px;
    margin: 0 auto;
    border: 2px solid #ff0055; /* Neon Pink Border */
    box-shadow: 0 0 15px #ff0055, inset 0 0 20px rgba(255, 0, 85, 0.2);
    padding: 40px;
    position: relative;
    background: repeating-linear-gradient(
      0deg,
      #0a0a0a,
      #0a0a0a 2px,
      #000000 2px,
      #000000 4px
    ); /* Scanline effect */
  }

  h1 {
    color: #ff0055;
    font-size: 3rem;
    text-align: center;
    text-transform: uppercase;
    text-shadow: 2px 2px 0px #ffffff;
    margin-bottom: 10px;
    letter-spacing: 0.1em;
    font-weight: 900;
  }
  
  .sub-header {
    color: #00ffcc; /* Cyber Green */
    text-align: center;
    font-size: 1.2rem;
    margin-bottom: 40px;
    font-family: monospace;
  }

  h2 {
    color: #ffff00; /* Warning Yellow */
    border-left: 5px solid #ff0055;
    padding-left: 15px;
    margin-top: 40px;
    margin-bottom: 20px;
    font-size: 1.5rem;
    text-shadow: 0 0 5px rgba(255, 255, 0, 0.5);
  }

  p {
    margin-bottom: 1.5em;
    font-size: 1.1rem;
  }

  .shout {
    color: #ff0055;
    font-weight: bold;
    font-size: 1.2rem;
  }

  .emphasis {
    color: #00ffcc;
    font-weight: bold;
  }

  .quote-box {
    border: 1px dashed #00ffcc;
    padding: 15px;
    margin: 20px 0;
    background-color: rgba(0, 255, 204, 0.05);
    font-style: italic;
  }

  .footer-nav {
    margin-top: 50px;
    text-align: center;
    border-top: 1px solid #333;
    padding-top: 20px;
  }

  .btn {
    display: inline-block;
    background-color: #ff0055;
    color: #000;
    padding: 10px 25px;
    text-decoration: none;
    font-weight: bold;
    font-size: 1.2rem;
    border: 2px solid #fff;
    transition: all 0.3s ease;
    box-shadow: 5px 5px 0px #00ffcc;
    transform: skew(-10deg);
  }

  .btn:hover {
    background-color: #000;
    color: #ff0055;
    border-color: #ff0055;
    box-shadow: 5px 5px 0px #fff;
    transform: skew(-10deg) translate(-2px, -2px);
  }

  hr {
    border: 0;
    height: 1px;
    background-image: linear-gradient(to right, rgba(0, 0, 0, 0), rgba(255, 0, 85, 0.75), rgba(0, 0, 0, 0));
    margin: 30px 0;
  }

  /* Glitch Effect Animation for H1 */
  @keyframes glitch {
    2%, 64% { transform: translate(2px,0) skew(0deg); }
    4%, 60% { transform: translate(-2px,0) skew(0deg); }
    62% { transform: translate(0,0) skew(5deg); }
  }
  h1:hover {
    animation: glitch 0.3s cubic-bezier(.25, .46, .45, .94) both infinite;
    color: #00ffcc;
  }

</style>
</head>
<body>

<div class="container">
  <h1>404 Not Found</h1>
  <div class="sub-header">ERROR: PAGE ANNIHILATED / ページはアナイアレーションされた</div>

  <h2>💀 第一章:クリエイターの恐怖、ドイル=サンの葛藤</h2>
  <p>時はマッポーの世、ヴィクトリア朝のヤミ。ドイル=サンは自らが生み出した、探偵という名の、知的なリアルニンジャ、シャーロック・ホームズ=サ
ンの存在に辟易していた。</p>
  
  <div class="quote-box">
    「アイエエエ! 私は医術というリアルなサイエンスを極めたいのに!ヘッズどもはホームズ=サンの狂気の物語しか求めない!」
  </div>

  <p>ドイル=サンにとってホームズ=サンは、ニューロンを支配し、創造性を吸い尽くす、邪悪なバイオ・ゴーストの如し! 彼は決断した。<span class="shout">「ホームズ=サンを殺す!完全に、そして、シメやかに、アナイアレーションする!」</span></p>
  
  <p>彼の脳内には既に、ホームズ=サンのデス・プランが構築されていた。ヘッズたちの熱狂、ストランズ・シンジケートの金と欲! これらを断ち切るには、究極のバイオレンス、すなわち、デスしかない!</p>
  <p>ドイル=サンは内心、自らが生み出した、巨大な、そして、熱狂的な読者層(ヘッズ)に恐れをなしていた。「アイエエエ! 彼らは私のロードではない!私が彼らのロードであるはずなのに!」</p>

  <hr>

  <h2>💥 第二章:ライヘンバッハのNRS! 滝壺のデス・ファイト</h2>
  <p>場所はスイス。ライヘンバッハの滝!</p>
  <p>ホームズ=サンの宿敵、モリアーティ=サンとの最終決戦。二人の、知的なリアルニンジャは激流の轟音の中で格闘!</p>
  
  <p class="shout">「イヤーッ!」「グワーッ!」</p>

  <p>ドイル=サンは冷静にペンを走らせる。二人の、そして、彼の分身の如き、ホームズ=サンは滝壺へと落ち、デス! 証拠は一切なし! 完全なアナイア
レーション!</p>
  <p>ストランズ・マガジンに掲載されたこの物語を目撃した読者、すなわち、ヘッズたちは一斉にNRSを発動!</p>
  
  <div class="quote-box">
    「アイエエエエ! ホームズ=サンが死んだナンデ!?」
  </div>

  <p>彼らのリアリティは滝壺へと引きずり込まれた! ホームズ=サンは架空の存在ではない! 彼らの日々の、そして、生きるための精神的な支えであった
のだ!</p>
  <p>ライヘンバッハの滝は単なる、景勝地ではなく、世界のニューロンが崩壊した地点となった。</p>

  <hr>

  <h2>🔥 第三章:IRCの大炎上! フジキドめいた絶望</h2>
  <p>ドイル=サンは勝利を確信! 「これで私は自由だ!」</p>
  <p>だが、彼の解放の喜びは一瞬で砕かれる! ヘッズたちの狂気がドイル=サンの私生活を襲ったのだ!</p>
  <p>電報、手紙、そして、ストランズ・シンジケートからの緊急のIRC通信がドイル=サンの屋敷を包囲! これぞIRCの大炎上!</p>
  
  <div class="quote-box">
    「貴様の殺意、許さん!」「ホームズを戻せ!」「私はドイルのロードをやめる!」
  </div>

  <p>女性のヘッズたちは喪章を付け、ストリートでデモ! マガジンの発行部数は暴落! ドイル=サンは現実のニンジャに襲われるが如く、四方八方からヘ
ッズの狂気に晒された!</p>
  <p>ドイル=サンは悟る。自らの手で生み出した、この物語の世界に囚われていることを!</p>
  <p>これはまるでニンジャスレイヤー、フジキド・ケンジ=サンの如し! 家族を殺され、復讐のソウルに憑依され、望まぬ、そして、終わりの見えない、デス・ファイトの世界に引きずり込まれた!</p>
  <p>ドイル=サンも同じ! 望まぬ、そして、辞めることの許されない、クリエイターとしてのデス・ゲームに囚われたのだ!</p>

  <hr>

  <h2>✨ 第四章:奇跡の生還! 読者の要求がニューロンを支配</h2>
  <p>ドイル=サンに選択肢はなかった。ホームズ=サンを殺すことで得た「自由」は幻想! 彼のリアリティはヘッズたちの狂気によって完全に、そして、シメやかに支配されていた。</p>
  
  <p class="emphasis">「奇跡の生還、これしか策なし!」</p>

  <p>10年の沈黙を経て、ドイル=サンは筆を執る。「空き家の冒険」!</p>
  <p><span class="shout">ゴウランガ!</span> ホームズ=サンは生存していた! モリアーティ=サンとの格闘の後、奇跡的に生還し、三年の間、世界のヤミで潜伏していたという狂気的な筋書き!</p>
  <p>読者、すなわち、ヘッズたちは歓喜! NRSは修復され、IRCの炎上は鎮火!</p>
  <p>ドイル=サンは再び、ホームズ=サンの物語を書き続けるという運命に逆戻り。フジキド=サンがニンジャをスレイする宿命から逃れられない如く、ド
イル=サンもホームズ=サンという知的なリアルニンジャの物語を書き続けるという宿命から逃れられなかったのだ!</p>
  <p>クリエイターとヘッズの関係が逆転した、アリエナイ・インシデント! これぞフィクションを超えた、リアルな、そして、ゴウランガな史実! <span class="shout">スゴイ!</span></p>

  <div class="footer-nav">
    <p>このリアル・ニンジャ・ゴトの文学的事件をさらに掘り下げるか? それとも、次の恐るべき史実を所望か?</p>
    <a href="/" class="btn">トップページへ戻る</a>
  </div>

</div>

</body>
</html>

に置き換え。

のような、マッポーめいた文章にしました。

この手の、遊び心を発揮できるというのは本当に自サイトの強みです。

「あなたにとっての“ナイフ”」とは?-3- (「私が量産品を選ぶ理由」)

前回、「万年筆」を

  • 格好良いから

という理由で使い始めました。その書き味や機能性に惹かれて言った結果、なぜLAMY Safari(AL-Star)を選択したかという部分について解説します。

自分の感覚という「Book」

『メリー・ポピンズ・リターンズ』の『本は表紙じゃ分からない/Cover is not the Book』に曰く

Cover is not the book / 心が目に見えないように本も
So open it up and take a look / 表紙の美しさに騙されちゃダメ
'Cause under the covers one discovers / 中身読んだらやさしい王様
That the king may be a crook / 詐欺師だとわかるかも

とあります。この、「きちんと中身を読んだ」結果として、今の自分はLAMY Safari(AL-Star)になったという形です。

LAMYを使って良かった点:重心

これが一番、自分が良かったと思うポイントです。LAMY万年筆最大の特徴と言えるクリップ付きのキャップ。筆記時、これを後ろにつけることで重心が後ろ寄りになります。これにより、必然的に重心は親指と人差し指の付け根にフィット。
軽く支えるだけでさらさらとした書き味を保証してくれます。

より重いアルミを用いたAL-Starはそれを更に補強。ひんやりとした金属の素材感と相まって「よりしっかりした書き味」を楽しめます。

LAMYを使って良かった点:フィット感

持ちやすさ、と言い換えてもいいでしょう。持ち手の上が自然にカット(三角形のカーブ)があることで、手になじむような形にフィット。

何よりも、この持ち手が明示されていることで万年筆にありがちな「どこがペン先の上か?」を一切気にする必要がありません。

LAMYを使って良かった点:速度

この場合の速度は

  1. 書こうとする
  2. ペンを取り出す
  3. キャップを取り外す
  4. 書き始める

のスタートです。多くの高級万年筆は(キャップレスでない場合は)ネジ式のキャップであるため「キャップを取り外す」がハードルになります。

ですが、LAMY万年筆はシンプルなキャップ式を採用。「取り外す」手間が秒単位で速くなります。

LAMYを使って良かった点:カラーバリエーション

『忍風戦隊ハリケンジャー』のカラーで揃えられるなどバリエーションは豊富

通常色、限定色、チャーム付きなど、多彩なカラーバリエーションがあります。

単に物欲を充たしてくれるのはもちろんのこと、ボディに沿った色のインクを詰めることで、インク補充時に「このライトグリーンには『翠玉』のインクを。黄色には『夕焼け』を選ぶ」と、直感に従ったインク補充が可能になります。

量産品であるという美徳

おおよそ道具というものは使ってなんぼ、壊れてなんぼという考えです。なので、「書く」という「思考を伝達する道具」の替えが効かないというのは、それ自体が単一障害点(SPOF: Single Point of Failure):その部分に障害が発生すると、システム全体が停止してしまうような、代替手段のない単一の要素になります。

しかし、LAMY Safariであれば

  • Amazon等のネットショップで2500円程度から買える(2025年11月現在)。
  • 大都市圏の文具店、量販店でも扱っている。

という、「替えが効く」理由としては十分です。紛失、破損などがあっても「ペンそのものを用意できる」という安心感は非常に有用です。

量産品のユーザーの多さ

これに落ち着く前、中華万年筆を使っていました。「安いに越したことはない」と。しかし、

  • インクの乾きが速く、キャップをしてもすぐにペン先が詰まる
  • ひどいのになるとインクがすべて飛び跳ねてしまった

という「安物買いの銭失い」を地で行く結果となりました。この「授業料」の結果、ある程度は出費を覚悟しても(それでも高級万年筆よりは安価です)それなりのものとして白羽の矢が立ったのがLAMY万年筆でした。

最初は「樹脂製のデザイン」等がハードルとなっていましたが

  • 古くからのデザインという普遍性は、それだけ使われる理由があるということ。
  • 工学的に優れたデザインのため飽きが来ないということ。
  • ファンが多いため世界各国のユーザーからの知見が山ほどあること。

という、量産品の強みが前面に打ち出されたのです。

まとめに代えて

以上、「格好良さ」から始めた万年筆は、

  • 合理的な機能
  • 量産品の強み

という筆者のプラグマティズムにより、これを求めたという結論。コレクションを手放すことになったとか、壊れたという話でない限り、他のブランドに手を出すのはまだまだ先となりそうです。何せ、前の記事でお話ししたとおり5年前のSafariが未だに現役なのですから。

ここで、「量産品の強み」を最も的確に表した『ガールズ&パンツァー』、サンダース大付属のアリサがM4シャーマン戦車を

「丈夫で壊れにくいし、おまけに居住性も高い!
  バカでも乗れるくらい操縦が簡単で、
 バカにも扱えるマニュアル付きよ!」

と評した言葉を以て、本稿を締めくくります。

「あなたにとっての“ナイフ”」とは?-2- (万年筆を選んだ理由)

基本的に筆者はプラグマティズムを以て道具を選びますが「それ以上の理由」。即ち

  • 伊達
  • 酔狂

の2つで使い始めた結果として、この万年筆というスタイルが確立されたという話です。

メインの万年筆一覧

まずこちらを。

LAMY Safari / AL-Starを中心に、一部は

  • Pilot ライティブ
  • カスタム ヘリテイジ

が一部混じっています。筆者が帰る範囲で諸々を試し、これに落ち着きました。これらは筆者のアナログの言葉通りの意味で屋台骨として支える道具。2025年現在、一番長く使って13年。短くても2年は愛用しています。

万年筆のデメリット

結論から言います。万年筆はデメリットが多い道具です。

値段の問題。

他の筆記具とベースの価格が違います。(全ての道具は天井知らずなので一般的に買えるものに絞ります)

これら3つは100均でも見かけるものでしょう。

  • シャープペンシル
    • 100円商品として1本は買える。替え芯を合わせても200円ほど。(+消費税)
  • 鉛筆:
    • 100円で4本程度。鉛筆削りを足しても200円。(+消費税)
  • ボールペン
    • これはもっと安く、100円で10本ほどセットで買えるでしょう。

ですが、万年筆は、入門用に限った上でも

おおよそ「500円台〜6,000円台」まで。(Copilot調べ)

価格帯特徴・用途例主なモデル例(参考)
〜500円超低価格帯。プラスチック製で軽量。試し書きや学生の練習用に最適。プラチナ プレピー、ダイソー製品など
1,000〜2,000円初心者向けの定番。カートリッジ式が多い。PILOT カクノ、セーラー ふでDEまんねん
2,000〜4,000円書き心地やデザイン性が向上。プラチナ プレジール PILOT ライティブ
4,000〜6,000円金属製や透明軸など、質感やインクの楽しみが広がる。長く使える1本に。ラミー サファリ、セーラー プロフィットJr.、パイロット コクーン
6,000円以上本格派の入門機。耐久性・筆記性能ともに高く、長期使用を前提とした設計。パイロット カスタム74(入門上級)

と、桁が違います。

消耗品の問題。

ここに「インク」が加わります。日本のボールペンの筆頭ブランドである『Jet Stream』シリーズとカートリッジ式、これら、一つでどこまで書けるのかを見てみます。

筆記具インク容量の目安書ける文字数(概算)原稿用紙(400字詰)換算備考
ジェットストリーム(0.5mm)約0.4〜0.5ml約20,000〜25,000字約50〜60枚油性・低粘度インクで長持ち
パイロット 万年筆カートリッジ約0.9ml約4,000〜5,000字約10〜12枚字幅や筆圧により変動
セーラー 万年筆カートリッジ約1.0ml約5,000〜6,000字約12〜15枚染料インクでやや多め
  • ジェットストリームのボールペンは約20,000〜25,000文字
  • パイロットやセーラーの万年筆カートリッジは約4,000〜6,000文字

この時点で、ボールペンのコストパフォーマンスは圧勝。

もっとわかりやすく言うと原稿用紙換算では

  • ボールペン:約50〜60枚
  • 万年筆:約10〜15枚分

というより、ボールペンのインク切れを体験するという方はかなり少ないのではないでしょうか。(書き味が怪しくなったら新しいボールペンを買うというのが基本的な運用だと思います)

また、カートリッジもインクも高額です。(インク沼という言葉を聞いたことがあるかと思います)

手間の問題。

万年筆のカートリッジ交換はボールペンとほぼ同じぐらいとは言え手間です。

インク補充式ともなると

  • インクがこぼれないように(倒れでもしたら大惨事です)
  • インクを間違えないように(複数本、色が違うものを用いている場合)
  • 吸入した後、確実に書けるかの確認

と、別次元の手間が加わります。

確実性の問題。

万年筆は、上記のシャープペンシルや鉛筆、ボールペンなどに比べて「誰でも使える」筆記具ではありません。断じて。

再掲しますが:

漫画『MASTERキートン』に以下のやりとりがあります。

「やめておけ」
「…………」
「拳銃の方が、ナイフよりも速いと思っているんだろう。
 だが、拳銃はデリケートな道具だ。
 弾が出ないかもしれないし、
思い通り的に当たるとは限らん。
おまけに拳銃は、
抜き、構え、引き金を引くまでに三動作(スリーアクション)……
その点ナイフは、一動作(ワンアクション)で終わる。
この距離なら、絶対に俺が勝つ!!
どうする? それでもやってみるかね?」

万年筆は

  • デリケートさ
  • 使うまでのアクション
  • 書き始めるまでの動作

全てが劣ります。特に、品質が悪いものともなると、使った瞬間にインクが漏れて服に付着するなんてこともあります。

この、一般的な筆記具ではなく万年筆を筆者が使い続ける理由を述べます。

使い始めた理由

「格好良いから」

これに尽きます。ハッキリ言って、これ以外の理由は全て『後付け』に過ぎません。

  • インクを補充する
  • あのペン先の格好良さ
  • ボールペンとも違う高級感

全てが「他の人と違う特別感」が、使い始めたきっかけでした。

インク補充の格好良さ

上記、述べたインク補充は、サーバのメンテナンスのごとき、手間をかけることで「自分のものである」という愛着を持つことができます。

自分で組み立てたものなど、自分の手で労力をかけたものに対して、本来の価値以上の価値を見出す心理的な傾向

いわゆる「イケア効果」の発露の表れです。

「書き味が違う」

これもまた別格でした。筆圧が強い方だったので、力を入れずにさらさらと書ける、滑るような書き心地は、一度慣れてしまうと他に戻れなくなった次第です。

それなりのものを使えば長持ちする。

上述した通り、手入れされた万年筆は圧倒的な強度を誇ります。

  • 未だに使えているヘリテイジ カスタムは2012年から愛用。
  • 限定版、丸の内Oazo10周年記念で買ったヘリテイジは2015年から愛用。
  • Lamy Safariも5年は使っているものがある。

「万年」の名は伊達ではありません。

まとめに代えて「合理性を超えるもの」

最終的に

  • この書き味があるならもっと試してみよう
  • これは自分のものだというもの
  • TCGプレイヤー特有のコレクション欲

が加わり、ちょっとした万年筆のコレクション群を持ち歩き、日々使い続けているという話でした。では、なぜLAMY Safariに落ち着いたかというのはまた次に機会を設けて記事を記します。

映画『Back to the Future』の

「If you're gonna build a time machine into a car, why not do it with some style?」
「タイムマシンを車にするなら、カッコよく作らなきゃだろ?」

という言葉を以て、本記事はひとまず区切りとします。

Page 1 of 98

Powered by WordPress & Theme by Anders Norén