Nginx を macOS で本番級に構築:launchd/ログローテーション/権限・署名のベストプラクティス

macOS 上で Nginx を開発環境だけでなく、本番環境として運用したいと考えたことはありませんか?実は、macOS には Linux とは異なる独自のサービス管理や権限設計が存在し、それらを理解しないと思わぬトラブルに遭遇してしまいます。
本記事では、macOS で Nginx を本番級に運用するための launchd 設定、ログローテーション、権限管理、そしてコード署名まで、実践的なステップを丁寧に解説いたします。これらの知識があれば、macOS 上でも安心して Nginx を稼働させられるようになるでしょう。
macOS で Nginx を本番運用する際の課題
開発環境と本番環境の違い
開発環境では、nginx
コマンドを手動で起動し、必要なときだけ使うという運用が一般的です。しかし本番環境では、システム再起動後も自動的に Nginx が起動し、ログが適切に管理され、セキュリティが保たれている必要があります。
Linux 環境であれば systemd や SysVinit といったサービス管理ツールが標準で用意されていますが、macOS では launchd という独自の仕組みを使います。また、ログローテーションも Linux の logrotate ではなく、macOS 標準の newsyslog を活用することになるのです。
以下の図は、開発環境と本番環境における Nginx 運用の違いを示しています。
mermaidflowchart LR
dev["開発環境"] -->|手動起動| nginx_dev["Nginx"]
nginx_dev -->|手動停止| dev
prod["本番環境"] -->|自動起動| launchd["launchd"]
launchd -->|プロセス管理| nginx_prod["Nginx"]
nginx_prod -->|ログ出力| logs["ログファイル"]
logs -->|自動ローテーション| newsyslog["newsyslog"]
本番環境では launchd がプロセスを管理し、ログは newsyslog が自動的にローテーションします。
macOS ならではの制約事項
macOS で Nginx を運用する際には、以下のような独自の制約に直面します。
# | 制約項目 | 内容 | 影響 |
---|---|---|---|
1 | サービス管理 | systemd が使えず launchd を使う必要がある | 設定ファイル形式が XML(plist)になる |
2 | ログローテーション | logrotate が標準搭載されていない | newsyslog を使った設定が必須 |
3 | 権限管理 | BSD 系の権限体系 | Linux とは微妙に挙動が異なる |
4 | ポート制限 | 1024 番未満のポートは root 権限が必要 | 80/443 番ポートのバインドに工夫が必要 |
5 | セキュリティポリシー | Gatekeeper による実行制限 | 未署名バイナリは警告が表示される |
特にポート 80 や 443 を使う場合、root 権限での実行が必要になりますが、セキュリティリスクを考慮すると可能な限り一般ユーザーで実行したいところです。この矛盾をどう解決するかが、macOS での Nginx 運用における最大のポイントとなるでしょう。
また、macOS Catalina 以降では Gatekeeper のセキュリティ強化により、インターネットからダウンロードしたバイナリや未署名のバイナリを実行しようとすると警告が表示されます。これらの制約を理解した上で、適切な設定を行う必要があるのです。
launchd による自動起動設定
launchd とは
launchd は macOS における標準的なサービス管理デーモンで、システム起動時やログイン時にプログラムを自動実行する役割を担っています。Linux の systemd に相当する存在ですが、設定方法や思想が大きく異なります。
launchd の主な特徴は以下の通りです。
- XML 形式の plist ファイルで設定を記述
- プロセスの監視と自動再起動機能
- 起動タイミングを柔軟に制御(システム起動時、ログイン時、時刻指定など)
- 環境変数や作業ディレクトリの設定が可能
以下の図は、launchd によるプロセス管理の流れを示しています。
mermaidflowchart TB
boot["macOS 起動"] --> launchd["launchd 起動"]
launchd --> plist["plist ファイル読み込み"]
plist --> check{KeepAlive<br/>設定?}
check -->|Yes| monitor["プロセス監視開始"]
check -->|No| start["プロセス起動"]
monitor --> nginx["Nginx 起動"]
nginx --> crash{プロセス<br/>異常終了?}
crash -->|Yes| restart["自動再起動"]
restart --> nginx
crash -->|No| running["正常稼働"]
launchd は plist ファイルの設定に従い、プロセスを起動・監視し、異常終了時には自動的に再起動を行います。
plist ファイルの作成
launchd で Nginx を管理するには、専用の plist ファイルを作成します。plist ファイルは /Library/LaunchDaemons/
(システム全体)または ~/Library/LaunchAgents/
(ユーザーごと)に配置しますが、Nginx のようなサーバープロセスはシステム全体で動かすのが一般的です。
まず、plist ファイルのベースとなる構造を見ていきましょう。
xml<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- この中に設定を記述 -->
</dict>
</plist>
plist ファイルは XML 形式で、必ず上記のヘッダーと <dict>
タグで囲む必要があります。
次に、Nginx 用の具体的な設定を追加します。
xml<key>Label</key>
<string>com.nginx.server</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/nginx</string>
<string>-g</string>
<string>daemon off;</string>
</array>
Label
は一意な識別子で、ProgramArguments
には実行するコマンドとオプションを配列形式で指定します。daemon off;
オプションは重要で、これにより Nginx がフォアグラウンドで実行され、launchd による監視が可能になるのです。
続いて、自動起動と再起動の設定を追加しましょう。
xml<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
RunAtLoad
を true
にすると、plist ファイルがロードされた時点で即座に起動します。KeepAlive
を true
にすると、プロセスが異常終了した場合に自動的に再起動されます。
ログ出力の設定も重要です。
xml<key>StandardOutPath</key>
<string>/usr/local/var/log/nginx/launchd.out.log</string>
<key>StandardErrorPath</key>
<string>/usr/local/var/log/nginx/launchd.error.log</string>
これにより、Nginx の標準出力とエラー出力が指定したファイルに記録されます。トラブルシューティング時に非常に役立つでしょう。
最後に、作業ディレクトリと環境変数を設定します。
xml<key>WorkingDirectory</key>
<string>/usr/local/var/www</string>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
</dict>
これで基本的な plist ファイルが完成しました。完全な設定ファイルは後述の「統合設定例」で紹介いたします。
起動スクリプトの設定
作成した plist ファイルを /Library/LaunchDaemons/
に配置し、適切な権限を設定します。
bash# plistファイルを配置
sudo cp com.nginx.server.plist /Library/LaunchDaemons/
ファイルを配置したら、オーナーとパーミッションを設定します。
bash# オーナーをrootに設定
sudo chown root:wheel /Library/LaunchDaemons/com.nginx.server.plist
# パーミッションを644に設定(所有者のみ書き込み可能)
sudo chmod 644 /Library/LaunchDaemons/com.nginx.server.plist
セキュリティ上、plist ファイルは root 所有で、一般ユーザーが書き込めないようにする必要があります。
次に、必要なログディレクトリを作成します。
bash# ログディレクトリを作成
sudo mkdir -p /usr/local/var/log/nginx
# 権限を設定
sudo chown -R nginx:staff /usr/local/var/log/nginx
sudo chmod 755 /usr/local/var/log/nginx
ログディレクトリは Nginx ユーザーが書き込めるように権限を設定しましょう。
launchd にサービスを登録して起動します。
bash# plistファイルをロード(登録)
sudo launchctl load /Library/LaunchDaemons/com.nginx.server.plist
# サービスを起動
sudo launchctl start com.nginx.server
launchctl load
コマンドで plist ファイルを launchd に登録し、start
コマンドで実際にサービスを起動します。
自動起動の確認とトラブルシューティング
サービスが正常に起動しているか確認します。
bash# 起動中のサービス一覧を確認
sudo launchctl list | grep nginx
正常に起動していれば、以下のような出力が表示されます。
diff- 0 com.nginx.server
左から順に、PID(-は launchd が管理中)、終了ステータス(0 は正常)、ラベル名を示しています。
プロセスの詳細情報を確認しましょう。
bash# プロセス詳細を確認
ps aux | grep nginx
Nginx のマスタープロセスとワーカープロセスが表示されれば成功です。
yamlnginx 1234 0.0 0.1 2468 1024 ?? Ss 9:00AM 0:00.01 nginx: master process
nginx 1235 0.0 0.2 2468 2048 ?? S 9:00AM 0:00.02 nginx: worker process
トラブルが発生した場合は、ログファイルを確認します。
bash# launchdのエラーログを確認
cat /usr/local/var/log/nginx/launchd.error.log
# macOSのシステムログを確認(Nginxに関する直近のログ)
log show --predicate 'processImagePath contains "nginx"' --last 1h
よくあるエラーとして、以下のようなケースがあります。
# | エラー内容 | 原因 | 解決方法 |
---|---|---|---|
1 | nginx: [emerg] bind() to 0.0.0.0:80 failed (13: Permission denied) | ポート 80 へのバインド権限がない | root 権限で起動するか、ポートフォワーディングを使用 |
2 | Path had bad ownership/permissions | plist ファイルの権限が不適切 | sudo chown root:wheel と sudo chmod 644 を実行 |
3 | Service is disabled | サービスが無効化されている | sudo launchctl enable system/com.nginx.server を実行 |
4 | Could not find specified service | Label が間違っている | plist ファイルの Label 名を確認 |
サービスを停止・削除する場合は、以下のコマンドを使用します。
bash# サービスを停止
sudo launchctl stop com.nginx.server
# plistをアンロード(登録解除)
sudo launchctl unload /Library/LaunchDaemons/com.nginx.server.plist
設定を変更した場合は、一度アンロードしてから再度ロードする必要があります。
ログローテーション戦略
macOS におけるログ管理の課題
Nginx を長期間運用すると、アクセスログやエラーログがどんどん肥大化していきます。特にアクセス数の多いサーバーでは、1 日で数百 MB から数 GB ものログが蓄積されることも珍しくありません。
ログファイルが大きくなりすぎると、以下のような問題が発生します。
- ディスク容量の圧迫: ログファイルがディスクを占有し、他の処理に影響
- 検索・分析の困難: 巨大なログファイルは grep や解析ツールでの処理が遅い
- バックアップの肥大化: ログを含めたバックアップサイズが膨大に
- パフォーマンス低下: ログ書き込みの I/O 負荷が増大
Linux 環境では logrotate という専用ツールがありますが、macOS には標準搭載されていません。代わりに macOS では newsyslog というツールが古くから使われており、こちらを活用することになります。
以下の図は、ログローテーションの仕組みを示しています。
mermaidflowchart LR
nginx["Nginx"] -->|書き込み| current["access.log"]
newsyslog["newsyslog"] -->|定期実行| check{サイズ/日時<br/>条件達成?}
check -->|Yes| rotate["ログローテーション"]
check -->|No| wait["待機"]
rotate --> rename["access.log<br/>→ access.log.0"]
rename --> compress["access.log.0<br/>→ access.log.0.gz"]
compress --> new["新規 access.log<br/>作成"]
new --> signal["Nginx へ<br/>SIGHUP 送信"]
signal --> reopen["ログファイル<br/>再オープン"]
newsyslog は定期的にログファイルをチェックし、条件を満たしたらローテーションを実行します。その後、Nginx にシグナルを送ってログファイルを再オープンさせるのです。
newsyslog を使った設定
newsyslog は macOS に標準搭載されており、/etc/newsyslog.conf
または /etc/newsyslog.d/
ディレクトリ内の設定ファイルで動作を制御します。独自の設定は /etc/newsyslog.d/
に配置するのがベストプラクティスです。
まず、newsyslog の設定ファイル形式を理解しましょう。
css# ログファイル [オーナー:グループ] モード 数 サイズ 間隔 フラグ [PIDファイル] [シグナル]
各フィールドの意味は以下の通りです。
# | フィールド | 説明 | 例 |
---|---|---|---|
1 | ログファイルパス | ローテーション対象のログファイル | /usr/local/var/log/nginx/access.log |
2 | オーナー:グループ | ローテーション後の所有者 | nginx:staff |
3 | モード | パーミッション(8 進数) | 644 |
4 | 数 | 保持する世代数 | 7 |
5 | サイズ | ローテーションするサイズ(KB 単位、*は無制限) | 102400 (100MB) |
6 | 間隔 | 時間ベースのローテーション | @T00 (毎日 0 時)、$D0 (日次) |
7 | フラグ | 動作オプション | GZN (圧縮、空でも作成、バイナリ) |
8 | PID ファイル | シグナル送信先の PID ファイル | /usr/local/var/run/nginx.pid |
9 | シグナル | 送信するシグナル | SIGHUP |
基本的な設定例を見てみましょう。
swift# アクセスログを100MBまたは日次でローテーション
/usr/local/var/log/nginx/access.log nginx:staff 644 7 102400 @T00 GZN /usr/local/var/run/nginx.pid SIGHUP
この設定では、access.log が 100MB に達するか、毎日 0 時になったらローテーションが実行されます。
より詳細な設定オプションについて説明します。
bash# フラグの詳細
# G: gzip圧縮を行う
# Z: bzip2圧縮を行う
# N: 空のログファイルでも新規作成する
# B: バイナリファイルとして扱う
# C: ログファイルが存在しなくても作成する
フラグは組み合わせて使用でき、GZN
なら「gzip 圧縮、空でも作成、バイナリ扱い」となります。
ログローテーション設定ファイルの作成
Nginx 専用の newsyslog 設定ファイルを作成しましょう。
bash# 設定ファイルを作成
sudo vi /etc/newsyslog.d/nginx.conf
以下の内容を記述します。
swift# Nginx アクセスログ(サイズベース + 日次ローテーション)
/usr/local/var/log/nginx/access.log nginx:staff 644 30 102400 @T00 GZN /usr/local/var/run/nginx.pid SIGHUP
アクセスログは 100MB または毎日 0 時にローテーションし、30 世代保持、gzip 圧縮を行う設定です。
次に、エラーログの設定を追加します。
swift# Nginx エラーログ(日次ローテーション、サイズ制限なし)
/usr/local/var/log/nginx/error.log nginx:staff 644 14 * $D0 GZN /usr/local/var/run/nginx.pid SIGHUP
エラーログはサイズに関係なく日次でローテーションし、14 世代(2 週間分)を保持します。
launchd のログも合わせて管理しましょう。
perl# launchd 標準出力ログ
/usr/local/var/log/nginx/launchd.out.log nginx:staff 644 7 10240 $D0 GZ
# launchd エラーログ
/usr/local/var/log/nginx/launchd.error.log nginx:staff 644 7 10240 $D0 GZ
launchd のログは Nginx のプロセスとは無関係なので、PID ファイルやシグナルの指定は不要です。
設定ファイルの構文チェックを行います。
bash# 構文チェック(実際にはローテーションしない)
sudo newsyslog -nvv
-n
オプションは dry-run(実際には実行しない)、-vv
は詳細出力を意味します。エラーがなければ、どのログがローテーション対象かが表示されるでしょう。
動作確認とテスト
実際にログローテーションを手動で実行してテストします。
bash# 強制的にローテーションを実行
sudo newsyslog -v
正常に動作すれば、以下のような処理が行われます。
lua/usr/local/var/log/nginx/access.log <nginx:staff>: size (Kb): 98765 [100MB] --> trimming log
ログファイルの状態を確認しましょう。
bash# ローテーション後のログファイル一覧
ls -lh /usr/local/var/log/nginx/
以下のようなファイルが生成されていれば成功です。
c-rw-r--r-- 1 nginx staff 0B 1 1 00:00 access.log
-rw-r--r-- 1 nginx staff 45M 1 1 00:00 access.log.0.gz
-rw-r--r-- 1 nginx staff 0B 1 1 00:00 error.log
-rw-r--r-- 1 nginx staff 1.2M 1 1 00:00 error.log.0.gz
新しい access.log
が作成され、古いログは .0.gz
という名前で圧縮保存されています。
Nginx がログファイルを正しく再オープンしているか確認します。
bash# Nginxのログファイルディスクリプタを確認
sudo lsof -p $(cat /usr/local/var/run/nginx.pid) | grep log
新しい access.log
と error.log
がオープンされていれば、SIGHUP シグナルが正しく処理されています。
newsyslog は cron によって自動実行されますが、実行タイミングを確認しておきましょう。
bash# newsyslogのcron設定を確認
cat /etc/periodic/daily/999.local
macOS では /etc/periodic/daily/
配下のスクリプトが毎日実行されます。newsyslog は通常 /etc/periodic/daily/500.daily
として登録されており、毎日深夜 3 時頃に実行されるのです。
トラブルシューティングのポイントをまとめます。
# | 問題 | 原因 | 解決方法 |
---|---|---|---|
1 | ログがローテーションされない | 設定ファイルの構文エラー | sudo newsyslog -nvv で確認 |
2 | 権限エラーが発生 | オーナーやモードが不適切 | 設定ファイルの 2・3 番目のフィールドを確認 |
3 | Nginx が新しいログに書き込まない | SIGHUP が送信されていない | PID ファイルパスとシグナル設定を確認 |
4 | 圧縮ファイルが作成されない | フラグに G または Z がない | フラグフィールドに G を追加 |
権限設定のベストプラクティス
実行ユーザーの選定
セキュリティの観点から、Nginx を root ユーザーで実行し続けるのは望ましくありません。万が一 Nginx に脆弱性があった場合、攻撃者にシステム全体を掌握されるリスクがあるためです。
理想的な構成は以下の通りです。
- マスタープロセス: root ユーザーで起動(ポート 80/443 へのバインドのため)
- ワーカープロセス: 専用の nginx ユーザーで実行(実際のリクエスト処理)
まず、Nginx 専用のユーザーを作成しましょう。
bash# システムユーザーIDを確認(既存の最大値を調べる)
dscl . -list /Users UniqueID | sort -k2 -n | tail -1
macOS では、ユーザー ID 200〜400 がシステムユーザー用に予約されています。
nginx ユーザーを作成します。
bash# nginxグループを作成(グループID: 250)
sudo dscl . -create /Groups/nginx
sudo dscl . -create /Groups/nginx PrimaryGroupID 250
グループを作成したら、ユーザーを作成します。
bash# nginxユーザーを作成(ユーザーID: 250)
sudo dscl . -create /Users/nginx
sudo dscl . -create /Users/nginx UniqueID 250
sudo dscl . -create /Users/nginx PrimaryGroupID 250
sudo dscl . -create /Users/nginx UserShell /usr/bin/false
sudo dscl . -create /Users/nginx NFSHomeDirectory /var/empty
sudo dscl . -create /Users/nginx RealName "Nginx User"
UserShell
を /usr/bin/false
に設定することで、このユーザーではログインできなくなります。セキュリティ上重要な設定です。
作成したユーザーを確認しましょう。
bash# ユーザー情報を確認
id nginx
正常に作成されていれば、以下のような出力が表示されます。
scssuid=250(nginx) gid=250(nginx) groups=250(nginx)
次に、Nginx の設定ファイルでワーカープロセスの実行ユーザーを指定します。
nginx# /usr/local/etc/nginx/nginx.conf の先頭に追加
user nginx staff;
user
ディレクティブで、ワーカープロセスを nginx ユーザー、staff グループで実行するよう指定します。macOS では staff グループがデフォルトのユーザーグループとして使われることが多いためです。
ディレクトリ権限の設計
Nginx が正常に動作するには、各種ディレクトリに適切な権限を設定する必要があります。セキュリティと機能性のバランスを考慮した権限設計を行いましょう。
以下は、Nginx で使用する主要なディレクトリと推奨権限の一覧です。
# | ディレクトリ | 用途 | 推奨権限 | オーナー | 理由 |
---|---|---|---|---|---|
1 | /usr/local/etc/nginx/ | 設定ファイル | 755 | root:wheel | 設定改ざん防止 |
2 | /usr/local/var/log/nginx/ | ログファイル | 755 | nginx:staff | Nginx が書き込み可能 |
3 | /usr/local/var/run/ | PID ファイル | 755 | root:wheel | ランタイム情報 |
4 | /usr/local/var/www/ | ドキュメントルート | 755 | nginx:staff | 静的ファイル配信 |
5 | /usr/local/var/cache/nginx/ | キャッシュ | 700 | nginx:staff | 他ユーザーアクセス不要 |
設定ファイルディレクトリの権限を設定します。
bash# 設定ディレクトリの権限設定
sudo chown -R root:wheel /usr/local/etc/nginx/
sudo chmod 755 /usr/local/etc/nginx/
sudo chmod 644 /usr/local/etc/nginx/*.conf
設定ファイルは root のみが編集可能にし、他のユーザーは読み取り専用とします。
ログディレクトリの権限を設定します。
bash# ログディレクトリの権限設定
sudo chown -R nginx:staff /usr/local/var/log/nginx/
sudo chmod 755 /usr/local/var/log/nginx/
sudo chmod 644 /usr/local/var/log/nginx/*.log
nginx ユーザーが書き込めるようにしつつ、他のユーザーは読み取り専用とします。
ドキュメントルートの権限を設定しましょう。
bash# ドキュメントルートの権限設定
sudo chown -R nginx:staff /usr/local/var/www/
sudo chmod 755 /usr/local/var/www/
sudo find /usr/local/var/www/ -type f -exec chmod 644 {} \;
sudo find /usr/local/var/www/ -type d -exec chmod 755 {} \;
ディレクトリは 755
(実行権限が必要)、ファイルは 644
(読み取り専用で十分)とします。
キャッシュディレクトリはより厳密な権限にします。
bash# キャッシュディレクトリの権限設定
sudo mkdir -p /usr/local/var/cache/nginx/
sudo chown -R nginx:staff /usr/local/var/cache/nginx/
sudo chmod 700 /usr/local/var/cache/nginx/
キャッシュは nginx ユーザー以外がアクセスする必要がないため、700
(所有者のみアクセス可)とします。
ポート 80/443 へのバインド対策
macOS では、1024 番未満のポート(いわゆる特権ポート)にバインドするには root 権限が必要です。しかし、root ユーザーで Nginx を実行し続けるのはセキュリティリスクが高いため、工夫が必要となります。
主な対策方法は以下の 3 つです。
mermaidflowchart TB
problem["ポート 80/443 へのバインド問題"] --> method1["方法1: マスタープロセスのみroot実行"]
problem --> method2["方法2: pfctl によるポートフォワーディング"]
problem --> method3["方法3: リバースプロキシの利用"]
method1 --> m1_result["ワーカープロセスは nginx ユーザー"]
method2 --> m2_result["nginx ユーザーで 8080 を Listen<br/>80 → 8080 へ転送"]
method3 --> m3_result["Caddy や Apache を前段に配置"]
各方法にはメリット・デメリットがありますので、環境に応じて選択しましょう。
方法 1: マスタープロセスのみ root 実行
最も一般的な方法で、Nginx の標準的な動作です。
nginx# nginx.conf
user nginx staff;
events {
worker_connections 1024;
}
http {
# 80番ポートでリッスン
server {
listen 80;
server_name localhost;
root /usr/local/var/www;
}
}
この設定で root ユーザーが Nginx を起動すると、マスタープロセスのみが root で実行され、実際のリクエスト処理を行うワーカープロセスは nginx ユーザーで実行されます。
起動方法は以下の通りです。
bash# rootユーザーで起動
sudo /usr/local/bin/nginx
launchd で自動起動する場合は、plist ファイルで UserName を指定しないことで root として起動されます。
方法 2: pfctl によるポートフォワーディング
nginx ユーザーで 8080 番ポートを Listen し、pfctl(Packet Filter)でポート 80 からの通信を 8080 へ転送する方法です。
まず、Nginx の設定を変更します。
nginx# nginx.conf(8080番ポートでリッスン)
server {
listen 8080;
server_name localhost;
root /usr/local/var/www;
}
次に、pfctl のルール設定ファイルを作成します。
bash# pfctl用のルールファイルを作成
sudo vi /etc/pf.anchors/nginx
以下の内容を記述します。
python# ポート80 → 8080へリダイレクト
rdr pass on lo0 inet proto tcp from any to any port 80 -> 127.0.0.1 port 8080
rdr pass on en0 inet proto tcp from any to any port 80 -> 127.0.0.1 port 8080
lo0
はループバックインターフェース、en0
はプライマリネットワークインターフェースです。
メインの pf.conf にアンカーを追加します。
bash# pf.confを編集
sudo vi /etc/pf.conf
以下の行を追加します。
csharp# rdrアンカーの読み込み
rdr-anchor "nginx"
load anchor "nginx" from "/etc/pf.anchors/nginx"
pfctl を有効化して、設定を反映させます。
bash# pfctlを有効化
sudo pfctl -e
# 設定を読み込み
sudo pfctl -f /etc/pf.conf
この方法なら、nginx ユーザーでプロセス全体を実行できるため、セキュリティリスクが低減されます。
方法 3: リバースプロキシの利用
Caddy や Apache など、特権ポートに対応した別のサーバーをフロントに配置し、Nginx をバックエンドとして利用する方法もあります。ただし、構成が複雑になるため、特別な理由がない限り方法 1 または方法 2 を推奨します。
セキュリティ強化設定
権限設定に加えて、Nginx 自体のセキュリティ設定も重要です。
まず、サーバートークンの非表示化を行います。
nginx# nginx.conf
http {
# バージョン情報を隠す
server_tokens off;
}
これにより、エラーページに表示される Nginx のバージョン情報が非表示になります。
不要な HTTP メソッドを制限しましょう。
nginx# 許可するHTTPメソッドを制限
location / {
limit_except GET HEAD POST {
deny all;
}
}
GET、HEAD、POST 以外のメソッドをすべて拒否します。
ファイルアップロードサイズの制限も重要です。
nginxhttp {
# アップロードサイズを制限(10MB)
client_max_body_size 10M;
# ボディバッファサイズ
client_body_buffer_size 128k;
}
これにより、巨大なリクエストによる DoS 攻撃を防ぎます。
タイムアウト設定を適切に行いましょう。
nginxhttp {
# クライアント接続タイムアウト
client_body_timeout 12;
client_header_timeout 12;
# レスポンス送信タイムアウト
send_timeout 10;
# キープアライブタイムアウト
keepalive_timeout 15;
}
短めのタイムアウトを設定することで、リソースの無駄遣いを防げます。
コード署名と公証
macOS のセキュリティポリシー
macOS Catalina(10.15)以降、Apple はセキュリティを大幅に強化し、Gatekeeper という仕組みで実行可能ファイルを厳格に管理しています。インターネットからダウンロードしたファイルや、未署名のバイナリを実行しようとすると、以下のような警告が表示されるのです。
「"nginx" は開発元が未確認のため開けません。」
この警告は、ユーザーを悪意あるソフトウェアから守るための仕組みですが、正規の用途であっても表示されてしまいます。特に企業内で Nginx を配布する場合、この警告は混乱を招くでしょう。
macOS のセキュリティレイヤーは以下のように階層化されています。
mermaidflowchart TB
download["バイナリのダウンロード/ビルド"] --> quarantine["Quarantine 属性の付与"]
quarantine --> first_run["初回実行時"]
first_run --> gatekeeper["Gatekeeper チェック"]
gatekeeper --> signature{コード署名<br/>あり?}
signature -->|No| warning1["警告表示:<br/>開発元未確認"]
signature -->|Yes| notarize{公証<br/>あり?}
notarize -->|No| warning2["警告表示:<br/>公証されていません"]
notarize -->|Yes| xprotect["XProtect スキャン"]
xprotect --> run["実行許可"]
Gatekeeper はコード署名と公証の 2 段階でチェックを行い、両方をパスして初めて警告なしで実行できます。
Quarantine(検疫)属性について理解しておきましょう。
bash# ダウンロードしたファイルのQuarantine属性を確認
xattr /usr/local/bin/nginx
以下のような出力があれば、Quarantine 属性が付いています。
com.apple.quarantine
この属性があると、初回実行時に Gatekeeper のチェックが入ります。
Gatekeeper 対応
Gatekeeper の警告を回避する方法は、主に以下の 3 つです。
# | 方法 | メリット | デメリット | 推奨度 |
---|---|---|---|---|
1 | Quarantine 属性の削除 | 即座に実行可能 | 一時的な対処、配布に不向き | ★☆☆ |
2 | コード署名の適用 | 開発元が明示される | Apple Developer 登録が必要 | ★★☆ |
3 | 公証(Notarization) | 最も安全、警告なし | 手続きが複雑、有料 | ★★★ |
方法 1: Quarantine 属性の削除
最も簡単な方法ですが、セキュリティリスクがあるため推奨されません。
bash# Quarantine属性を削除
sudo xattr -d com.apple.quarantine /usr/local/bin/nginx
この方法は、自分でビルドしたバイナリや、信頼できるソースから入手したファイルにのみ使用すべきです。
削除されたか確認します。
bash# 属性が削除されたか確認(何も表示されなければ成功)
xattr /usr/local/bin/nginx
方法 2: システム環境設定での許可
GUI から個別に実行を許可することもできます。
bash# システム環境設定のセキュリティ設定を開く
open "x-apple.systempreferences:com.apple.preference.security?General"
警告ダイアログが表示された後、「システム環境設定」→「セキュリティとプライバシー」→「一般」タブに「このまま開く」ボタンが表示されるので、これをクリックします。
ただし、この方法も一時的な対処であり、他のユーザーに配布する場合には適していません。
方法 3: spctl コマンドによる確認
システムポリシーコントロール(spctl)で Gatekeeper の判定を確認できます。
bash# Gatekeeperの判定を確認
spctl --assess --type execute /usr/local/bin/nginx
署名がない場合、以下のようなエラーが表示されます。
ini/usr/local/bin/nginx: rejected
source=no usable signature
署名付きバイナリの検証
コード署名を適用するには、Apple Developer Program への登録(年間 11,800 円)が必要です。登録後、以下の手順で署名を行います。
まず、証明書をキーチェーンにインストールします。
bash# 利用可能な署名用証明書を確認
security find-identity -v -p codesigning
以下のような証明書が表示されれば使用可能です。
arduino1) ABC123DEF456 "Developer ID Application: Your Name (TEAM123456)"
codesign コマンドで署名を適用します。
bash# バイナリに署名
codesign --sign "Developer ID Application: Your Name (TEAM123456)" \
--force \
--timestamp \
--options runtime \
/usr/local/bin/nginx
各オプションの意味は以下の通りです。
--sign
: 使用する証明書--force
: 既存の署名を上書き--timestamp
: タイムスタンプサーバーを使用(署名の有効期限延長)--options runtime
: Hardened Runtime を有効化(macOS 10.14 以降で必須)
署名が正しく適用されたか確認しましょう。
bash# 署名を検証
codesign --verify --deep --strict --verbose=2 /usr/local/bin/nginx
成功すれば以下のように表示されます。
swift/usr/local/bin/nginx: valid on disk
/usr/local/bin/nginx: satisfies its Designated Requirement
署名の詳細情報を確認します。
bash# 署名情報を表示
codesign --display --verbose=4 /usr/local/bin/nginx
以下のような情報が表示されます。
iniExecutable=/usr/local/bin/nginx
Identifier=nginx
Format=Mach-O thin (x86_64)
CodeDirectory v=20500 size=12345 flags=0x10000(runtime) hashes=123+5 location=embedded
Signature size=4567
Authority=Developer ID Application: Your Name (TEAM123456)
Authority=Developer ID Certification Authority
Authority=Apple Root CA
Timestamp=2025年1月1日 12:00:00
これで、開発元が明示された署名付きバイナリが完成しました。
企業内配布時の注意点
企業内で Nginx を複数の macOS 端末に配布する場合、以下の点に注意が必要です。
公証(Notarization)の実施
署名だけでは、初回実行時に「開発元は確認済みですが、Apple によるマルウェアスキャンが実施されていません」という警告が表示されることがあります。これを回避するには、Apple の公証サービスにバイナリを提出する必要があります。
公証の手順は以下の通りです。
bash# バイナリをZIPで圧縮
ditto -c -k --keepParent /usr/local/bin/nginx nginx.zip
公証サービスに提出します。
bash# 公証サービスに提出
xcrun notarytool submit nginx.zip \
--apple-id "your-email@example.com" \
--password "app-specific-password" \
--team-id "TEAM123456" \
--wait
--wait
オプションを付けると、公証が完了するまで待機します(通常数分)。
公証が完了したら、スタンプ(チケット)をバイナリに添付します。
bash# 公証チケットを添付
xcrun stapler staple /usr/local/bin/nginx
スタンプが正しく添付されたか確認しましょう。
bash# スタンプを検証
xcrun stapler validate /usr/local/bin/nginx
成功すれば以下のように表示されます。
rubyProcessing: /usr/local/bin/nginx
The validate action worked!
MDM(Mobile Device Management)による配布
大規模な企業環境では、Jamf Pro や Kandji などの MDM ソリューションを使って Nginx を配布することになるでしょう。MDM を使う場合、以下の設定が重要です。
xml<!-- MDM プロファイルの例 -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>PayloadType</key>
<string>com.apple.system.approved-apps</string>
<key>TeamIdentifier</key>
<string>TEAM123456</string>
</dict>
</array>
</dict>
</plist>
MDM プロファイルで Team Identifier を指定することで、該当する開発者の署名付きアプリを自動的に許可できます。
バージョン管理とアップデート
署名付きバイナリを配布する際は、バージョン管理も重要です。
bash# バイナリのバージョン情報を確認
/usr/local/bin/nginx -v
バージョン情報をログに記録しておくと、トラブルシューティング時に役立ちます。
bash# バージョン情報をログに記録
/usr/local/bin/nginx -v 2>&1 | tee /usr/local/var/log/nginx/version.log
アップデート時は、必ず新しいバイナリに署名し直してから配布しましょう。古い署名のままでは、整合性チェックでエラーが発生する可能性があります。
統合設定例
完全な設定ファイル一式
ここまで説明してきた設定を統合した、本番環境で使える完全な設定ファイル一式を紹介します。
launchd plist ファイル(/Library/LaunchDaemons/com.nginx.server.plist
)
xml<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- サービスの一意な識別子 -->
<key>Label</key>
<string>com.nginx.server</string>
<!-- 実行するプログラムと引数 -->
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/nginx</string>
<string>-g</string>
<string>daemon off;</string>
</array>
<!-- システム起動時に自動実行 -->
<key>RunAtLoad</key>
<true/>
<!-- プロセス監視と自動再起動 -->
<key>KeepAlive</key>
<dict>
<key>SuccessfulExit</key>
<false/>
</dict>
<!-- 標準出力ログ -->
<key>StandardOutPath</key>
<string>/usr/local/var/log/nginx/launchd.out.log</string>
<!-- エラー出力ログ -->
<key>StandardErrorPath</key>
<string>/usr/local/var/log/nginx/launchd.error.log</string>
<!-- 作業ディレクトリ -->
<key>WorkingDirectory</key>
<string>/usr/local/var/www</string>
<!-- 環境変数 -->
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
</dict>
<!-- プロセス制限 -->
<key>SoftResourceLimits</key>
<dict>
<key>NumberOfFiles</key>
<integer>4096</integer>
</dict>
<key>HardResourceLimits</key>
<dict>
<key>NumberOfFiles</key>
<integer>8192</integer>
</dict>
<!-- スロットリング(再起動の間隔、秒単位) -->
<key>ThrottleInterval</key>
<integer>60</integer>
</dict>
</plist>
newsyslog 設定ファイル(/etc/newsyslog.d/nginx.conf
)
perl# logfilename [owner:group] mode count size when flags [/pid_file] [sig_num]
# Nginxアクセスログ - 100MBまたは毎日0時にローテーション、30世代保持
/usr/local/var/log/nginx/access.log nginx:staff 644 30 102400 @T00 GZN /usr/local/var/run/nginx.pid SIGHUP
# Nginxエラーログ - 日次ローテーション、14世代保持
/usr/local/var/log/nginx/error.log nginx:staff 644 14 * $D0 GZN /usr/local/var/run/nginx.pid SIGHUP
# launchd標準出力ログ - 10MBで日次ローテーション、7世代保持
/usr/local/var/log/nginx/launchd.out.log nginx:staff 644 7 10240 $D0 GZ
# launchdエラーログ - 10MBで日次ローテーション、7世代保持
/usr/local/var/log/nginx/launchd.error.log nginx:staff 644 7 10240 $D0 GZ
Nginx メイン設定ファイル(/usr/local/etc/nginx/nginx.conf
)
nginx# ワーカープロセスの実行ユーザー
user nginx staff;
# ワーカープロセス数(CPUコア数に合わせる)
worker_processes auto;
# エラーログの設定
error_log /usr/local/var/log/nginx/error.log warn;
# PIDファイルの場所
pid /usr/local/var/run/nginx.pid;
events {
# 1ワーカーあたりの最大同時接続数
worker_connections 1024;
# 複数の接続を同時に受け付ける
multi_accept on;
# 効率的なイベント処理モデル(macOSではkqueue)
use kqueue;
}
http {
# MIMEタイプ設定
include mime.types;
default_type application/octet-stream;
# ログフォーマット
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# アクセスログ
access_log /usr/local/var/log/nginx/access.log main;
# バージョン情報を非表示
server_tokens off;
# ファイル送信の最適化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# タイムアウト設定
keepalive_timeout 15;
client_body_timeout 12;
client_header_timeout 12;
send_timeout 10;
# バッファサイズ制限
client_body_buffer_size 128k;
client_max_body_size 10m;
client_header_buffer_size 1k;
large_client_header_buffers 4 8k;
# gzip圧縮
gzip on;
gzip_vary on;
gzip_min_length 1000;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# 追加の設定ファイルを読み込み
include /usr/local/etc/nginx/conf.d/*.conf;
include /usr/local/etc/nginx/sites-enabled/*;
}
サーバー設定ファイル(/usr/local/etc/nginx/conf.d/default.conf
)
nginxserver {
# ポート80でリッスン
listen 80;
server_name localhost;
# ドキュメントルート
root /usr/local/var/www;
index index.html index.htm;
# 文字コード
charset utf-8;
# メインロケーション
location / {
try_files $uri $uri/ =404;
# HTTPメソッド制限
limit_except GET HEAD POST {
deny all;
}
}
# 静的ファイルのキャッシュ設定
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# .htaccessや隠しファイルへのアクセス拒否
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# エラーページ
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/local/var/www;
}
}
起動から運用までの流れ
設定ファイルを配置したら、以下の手順で Nginx を起動し、運用を開始します。
mermaidflowchart TB
start["設定準備"] --> user["nginxユーザー作成"]
user --> dir["ディレクトリ構築"]
dir --> perm["権限設定"]
perm --> conf["設定ファイル配置"]
conf --> test["設定テスト"]
test --> plist["plist配置"]
plist --> load["launchdロード"]
load --> verify["起動確認"]
verify --> monitor["監視開始"]
ステップ 1: nginx ユーザーの作成
bash# nginxグループとユーザーを作成
sudo dscl . -create /Groups/nginx
sudo dscl . -create /Groups/nginx PrimaryGroupID 250
sudo dscl . -create /Users/nginx
sudo dscl . -create /Users/nginx UniqueID 250
sudo dscl . -create /Users/nginx PrimaryGroupID 250
sudo dscl . -create /Users/nginx UserShell /usr/bin/false
sudo dscl . -create /Users/nginx NFSHomeDirectory /var/empty
sudo dscl . -create /Users/nginx RealName "Nginx User"
ステップ 2: ディレクトリ構築
bash# 必要なディレクトリを作成
sudo mkdir -p /usr/local/etc/nginx/conf.d
sudo mkdir -p /usr/local/etc/nginx/sites-enabled
sudo mkdir -p /usr/local/var/log/nginx
sudo mkdir -p /usr/local/var/run
sudo mkdir -p /usr/local/var/www
sudo mkdir -p /usr/local/var/cache/nginx
ステップ 3: 権限設定
bash# 設定ディレクトリ
sudo chown -R root:wheel /usr/local/etc/nginx/
sudo chmod 755 /usr/local/etc/nginx/
sudo chmod 644 /usr/local/etc/nginx/nginx.conf
# ログディレクトリ
sudo chown -R nginx:staff /usr/local/var/log/nginx/
sudo chmod 755 /usr/local/var/log/nginx/
# ドキュメントルート
sudo chown -R nginx:staff /usr/local/var/www/
sudo chmod 755 /usr/local/var/www/
# キャッシュディレクトリ
sudo chown -R nginx:staff /usr/local/var/cache/nginx/
sudo chmod 700 /usr/local/var/cache/nginx/
ステップ 4: 設定テスト
bash# 設定ファイルの構文チェック
sudo /usr/local/bin/nginx -t
成功すれば以下のように表示されます。
swiftnginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful
ステップ 5: launchd 設定
bash# plistファイルを配置
sudo cp com.nginx.server.plist /Library/LaunchDaemons/
sudo chown root:wheel /Library/LaunchDaemons/com.nginx.server.plist
sudo chmod 644 /Library/LaunchDaemons/com.nginx.server.plist
# newsyslog設定を配置
sudo cp nginx.conf /etc/newsyslog.d/
sudo chown root:wheel /etc/newsyslog.d/nginx.conf
sudo chmod 644 /etc/newsyslog.d/nginx.conf
ステップ 6: サービス起動
bash# launchdにロード
sudo launchctl load /Library/LaunchDaemons/com.nginx.server.plist
# サービス起動
sudo launchctl start com.nginx.server
ステップ 7: 起動確認
bash# サービス状態を確認
sudo launchctl list | grep nginx
# プロセスを確認
ps aux | grep nginx
# ポート80がリッスンされているか確認
sudo lsof -iTCP:80 -sTCP:LISTEN
正常に起動していれば、以下のような出力が得られます。
yamlnginx 1234 0.0 0.1 2468 1024 ?? Ss 9:00AM 0:00.01 nginx: master process
nginx 1235 0.0 0.2 2468 2048 ?? S 9:00AM 0:00.02 nginx: worker process
ステップ 8: 動作テスト
bash# ローカルアクセステスト
curl -I http://localhost
# レスポンスヘッダーを確認
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 01 Jan 2025 09:00:00 GMT
Content-Type: text/html
サーバートークンが非表示になっており、バージョン情報が表示されていないことを確認しましょう。
監視とメンテナンス
本番環境では、Nginx の状態を継続的に監視し、問題が発生したら即座に対応する必要があります。
ヘルスチェックスクリプト(/usr/local/bin/nginx-healthcheck.sh
)
bash#!/bin/bash
# ヘルスチェックスクリプト
LOG_FILE="/usr/local/var/log/nginx/healthcheck.log"
ALERT_EMAIL="admin@example.com"
# プロセスチェック
if ! pgrep -x nginx > /dev/null; then
echo "[$(date)] CRITICAL: Nginx process not running" >> "$LOG_FILE"
# launchdが自動的に再起動するので、ログ記録のみ
fi
# ポートチェック
if ! lsof -iTCP:80 -sTCP:LISTEN > /dev/null; then
echo "[$(date)] CRITICAL: Port 80 not listening" >> "$LOG_FILE"
fi
# HTTPレスポンスチェック
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost)
if [ "$HTTP_CODE" != "200" ]; then
echo "[$(date)] WARNING: HTTP response code is $HTTP_CODE" >> "$LOG_FILE"
fi
# ログファイルサイズチェック(100MB以上で警告)
ACCESS_LOG_SIZE=$(stat -f%z /usr/local/var/log/nginx/access.log)
if [ "$ACCESS_LOG_SIZE" -gt 104857600 ]; then
echo "[$(date)] WARNING: access.log size is over 100MB" >> "$LOG_FILE"
fi
スクリプトに実行権限を付与します。
bashsudo chmod 755 /usr/local/bin/nginx-healthcheck.sh
cron で定期実行します。
bash# crontabを編集
sudo crontab -e
以下の行を追加して、5 分ごとにヘルスチェックを実行します。
perl# Nginxヘルスチェック(5分ごと)
*/5 * * * * /usr/local/bin/nginx-healthcheck.sh
ログ監視スクリプト(/usr/local/bin/nginx-log-monitor.sh
)
bash#!/bin/bash
# エラーログ監視スクリプト
ERROR_LOG="/usr/local/var/log/nginx/error.log"
ALERT_LOG="/usr/local/var/log/nginx/alert.log"
# 直近1分間のエラーを検索
ERRORS=$(tail -n 1000 "$ERROR_LOG" | \
grep "$(date -v-1M '+%Y/%m/%d %H:%M')" | \
grep -E "\[error\]|\[crit\]|\[alert\]|\[emerg\]")
if [ -n "$ERRORS" ]; then
echo "[$(date)] Errors detected in the last minute:" >> "$ALERT_LOG"
echo "$ERRORS" >> "$ALERT_LOG"
fi
このスクリプトも cron で定期実行しましょう。
bash# crontabに追加(1分ごと)
* * * * * /usr/local/bin/nginx-log-monitor.sh
メンテナンスコマンド一覧
日常的なメンテナンスで使用するコマンドをまとめます。
# | 操作 | コマンド | 説明 |
---|---|---|---|
1 | 設定再読み込み | sudo nginx -s reload | ダウンタイムなしで設定を反映 |
2 | 設定テスト | sudo nginx -t | 構文チェック |
3 | サービス停止 | sudo launchctl stop com.nginx.server | プロセスを停止 |
4 | サービス開始 | sudo launchctl start com.nginx.server | プロセスを起動 |
5 | ログローテーション | sudo newsyslog -v | 手動でログをローテーション |
6 | ログ確認 | tail -f /usr/local/var/log/nginx/access.log | リアルタイムでログを監視 |
7 | プロセス確認 | ps aux | grep nginx | 実行中のプロセスを確認 |
8 | ポート確認 | sudo lsof -iTCP:80 -sTCP:LISTEN | ポート 80 の使用状況を確認 |
設定変更後は、必ず以下の手順を踏みましょう。
bash# 1. 設定ファイルをバックアップ
sudo cp /usr/local/etc/nginx/nginx.conf /usr/local/etc/nginx/nginx.conf.bak
# 2. 設定を編集
sudo vi /usr/local/etc/nginx/nginx.conf
# 3. 構文チェック
sudo nginx -t
# 4. 問題なければリロード
sudo nginx -s reload
構文エラーがあった場合は、バックアップから復元します。
bash# バックアップから復元
sudo cp /usr/local/etc/nginx/nginx.conf.bak /usr/local/etc/nginx/nginx.conf
sudo nginx -s reload
まとめ
macOS で Nginx を本番級に運用するための設定方法を、launchd によるサービス管理、newsyslog によるログローテーション、適切な権限設計、そしてコード署名まで、実践的に解説してまいりました。
Linux とは異なる macOS 独自の仕組みを理解することで、安定した Nginx 運用が実現できます。特に重要なポイントを振り返りましょう。
- launchd: plist ファイルで自動起動とプロセス監視を設定
- newsyslog:
/etc/newsyslog.d/
に設定ファイルを配置し、自動ログローテーションを実現 - 権限設計: nginx 専用ユーザーを作成し、最小権限の原則でセキュリティを強化
- ポート対応: マスタープロセスを root で起動するか、pfctl でポートフォワーディング
- コード署名: Gatekeeper 対応のため、可能であれば署名と公証を実施
これらの設定を適切に行うことで、macOS 上でも Linux 環境と同等の信頼性で Nginx を運用できるようになります。本記事の設定例を参考に、ぜひご自身の環境に合わせてカスタマイズしてみてください。
関連リンク
- article
Nginx を macOS で本番級に構築:launchd/ログローテーション/権限・署名のベストプラクティス
- article
Nginx Unit と Node(+ PM2)/Passenger を比較:再読み込み・可用性・性能の実測
- article
Nginx 499/444/408 の謎を解く:クライアント切断と各種タイムアウトの実態
- article
Nginx リクエスト処理の舞台裏:フェーズ/ハンドラ/モジュール連携を図解で理解
- article
Nginx vs Apache 徹底比較:速度・メモリ・機能で最適解を選ぶ
- article
Nginx インストール完全ガイド:Linux・macOS・Windows・Docker 対応
- article
【2025 年 10 月版】 Claude Sonnet 4.5 登場! Claude Pro でも使える!Claude Code のアップデート手順まで紹介
- article
Turborepo で Zustand スライスをパッケージ化:Monorepo 運用の初期設定
- article
Nuxt を macOS + yarn で最短構築:ESLint/Prettier/TS 設定まで一気通貫
- article
キャッシュ比較:WordPress で WP Rocket/LiteSpeed/W3TC を検証
- article
Nginx を macOS で本番級に構築:launchd/ログローテーション/権限・署名のベストプラクティス
- article
WebSocket を NGINX/HAProxy で終端する設定例:アップグレードヘッダーとタイムアウト完全ガイド
- blog
iPhone 17シリーズの発表!全モデルiPhone 16から進化したポイントを見やすく整理
- blog
Googleストアから訂正案内!Pixel 10ポイント有効期限「1年」表示は誤りだった
- blog
【2025年8月】Googleストア「ストアポイント」は1年表記はミス?2年ルールとの整合性を検証
- blog
Googleストアの注文キャンセルはなぜ起きる?Pixel 10購入前に知るべき注意点
- blog
Pixcel 10シリーズの発表!全モデル Pixcel 9 から進化したポイントを見やすく整理
- blog
フロントエンドエンジニアの成長戦略:コーチングで最速スキルアップする方法
- review
今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
- review
ついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
- review
愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
- review
週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
- review
新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
- review
科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来