adiaryをローカルで開発するための動かす環境構築のログ。
前提条件
- サーバー構成は前段にnginx、後段にapache2を配置し、adiaryはapache2側で動作させる
- 動作URLは
http://adiary.example.test/のようなサブドメイン付きURLとする- adiary.cgiなしでアクセス可能にする
- 開発を楽にするため、ホームディレクトリからシンボリックリンクを飛ばし、VSCodeで編集できるようにする
- nginxやapache2、perlは既にインストールされているものとする
- apache2はポート8080でListenしているものとする
確認環境
| Env | Ver |
|---|---|
| OS | Ubuntu 24.04.3 LTS |
| nginx | 1.26.1 |
| apache2 | 2.4.58 (Ubuntu) |
| adiary | 3.51a |
手順
この手順では手描きした内容をteeに書き直しており、正しくファイルが生やせるか見てないので注意。
/etc/nginx/nginx.confのhttpセクションのincludeの手前にapacheのupstream情報を追記するupstream apache { server [::1]:8080; }nginx→apache2のリバプロ設定の作成
cat <<'EOF' | sudo tee /etc/nginx/conf.d/adiary.conf server { listen [::]:80; client_max_body_size 100M; server_name adiary.example.local; access_log /var/log/nginx/adiary.example.access.log; error_log /var/log/nginx/adiary.example.error.log; location / { proxy_pass http://apache/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; } } EOF sudo service nginx restartApache2でadiaryをホスティングするバーチャルホスト設定の作成
cat <<'EOF' | sudo tee /etc/apache2/sites-enabled/001-adiary.conf <VirtualHost *:8080> # internal use only domain ServerName adiary.example.local ServerAdmin webmaster@localhost DocumentRoot /var/www/html/sites/adiary # Available loglevels: trace8, ..., trace1, debug, info, notice, warn, # error, crit, alert, emerg. # It is also possible to configure the loglevel for particular # modules, e.g. #LogLevel info ssl:warn ErrorLog ${APACHE_LOG_DIR}/adiary-error.log CustomLog ${APACHE_LOG_DIR}/adiary-access.log combined # For most configuration files from conf-available/, which are # enabled or disabled at a global level, it is possible to # include a line for only one particular virtual host. For example the # following line enables the CGI configuration for this host only # after it has been globally disabled with "a2disconf". #Include conf-available/serve-cgi-bin.conf </VirtualHost> EOF/etc/apache2/apache2.confを開き<Directory /var/www/>のセクションを次のように書き換えるOptions Indexes FollowSymLinks AllowOverride All Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch AddHandler cgi-script .cgi Require all grantedOptions +ExecCGI -MultiViews +SymLinksIfOwnerMatchの行は標準のserve-cgi-bin.confからパクってきたのでOptions +ExecCGIだけでも動く可能性があるAllowOverride Allはindex.htmlを残したまま表示させないために.htaccessを書くのに使う
mod_rewriteとmod_cgiを有効化し、apache2を再起動
sudo a2enmod rewrite sudo a2enmod cgi sudo service apache2 restart/var/www/html/sites/adiaryを作成し、adiaryの動作環境一式を配置- 開発し易いように権限を緩和
chmod 777 -R /var/www/html/sites/adiary sudo chown -R <your-user-name>:<your-user-name> /var/www/html/sites/adiary/ /var/www/html/sites/adiary/.htaccessにadiary用の.htaccessを書くDirectoryIndex RewriteEngine On # favicon RewriteRule ^favicon\.ico /path/to/icon.png [L] # 正規URLは通す RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*) adiary.cgi/$1 [L]
Apache2でadiaryを動かす理由
結論から書くとnginx + fcgiwrapだとtry_filesの仕様的にadiaryが行うパス解析が上手く行かずに正常に動作しないためだ。
元々ModRewrite前提のCGIとして設計されており、個人的なユースケースがCGIとしての動作であることから、Apacheで動かすことにした。
adiaryの作者がcgiラッパーを作っているため、これを使えばnginxでも動かせそうだが、adiary専用のデーモンを起動するのもなんか嫌というのも理由の一つとしてある。
何より現在このブログが動作している環境が、さくらのレンタルサーバーであり、構成的にnginx + Apacheであるため、この構成を作ることに興味があったというのもあるし、現状のローカル環境ではnginxをフロントに立たせて後ろで様々なものを動かしている都合で、フロントはnginxで捌いた方が管理がしやすいのもある。
書いてなさ過ぎて忘れるので備忘録として書き出しておく。必要最低限の設定なので要件が他にある場合は追加が必要。
React(SPA)
SPAなのでパスがなければ全部index.htmlに飛ばす。原理はどれも同じなのでVueやAngularなどのSPAもこれで行けると思う。ケツの=404がないと無限リダイレクトを起こす。
server {
listen 80;
location / {
root /path/to;
index index.html;
try_files $uri /index.html =404;
}
}
Next.js(SSR)
SSRなのでNext.jsのサーバープロセスにリバースプロキシする。別に直結してもいいが手前にルーティング機構があるほうが便利である。
mapステートメントがあるのは、これがないとiOS Safariでアクセスできないため
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://localhost:3000;
}
}
Next.js(SSG)
SPAではないのでパスがなければ同名のhtmlファイルに飛ばす。ケツの=404がないと無限リダイレクトを起こす。
server {
listen 80;
location / {
root /path/to;
index index.html;
try_files $uri $uri.html =404;
}
}
開発時に一々rootが持ってるフォルダを触るのが嫌でホームディレクトリ配下で作業したいというのは往々にしてあるので、それを楽にやる方法。
以下のようにnginxのルートディレクトリに適当なパスを切り、パーミッションを777にした上でシンボリックリンクを張ればよい。
sudo mkdir /usr/share/nginx/html/hoge
sudo chmod 777 /usr/share/nginx/html/hoge
ln -s /usr/share/nginx/html/hoge hoge
ホームディレクトリをnginx設定のrootとして指定すると上手く行かなかったので、そのアプローチは諦めた。(755指定してても読みに行けない、777ならいけると思うがそれは避けたい)
確認環境
| Env | Ver |
|---|---|
| OS | Ubuntu 20.04.4 LTS |
| PHP | 8.0.29 |
| nginx | 1.18.0 |
手順
php-fpmの導入
sudo apt install php8.0-fpm
sudo sed -i -e 's/;listen.mode = 0660/listen.mode = 0666/' /etc/php/8.0/fpm/pool.d/www.conf
sudo service php8.0-fpm start
nginxの設定
設定ファイルを開きPHPを動かす設定を書く
location ~ ^/.*$ {
root /path/to/www;
fastcgi_pass unix:/run/php/php8.0-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
Web開発をしていると取り敢えずHTTPリクエストが取れる雑なモックサーバーが欲しくなることがあるので、その作り方。
確認環境
| Env | Ver |
|---|---|
| OS | Windows 11 Pro |
| WSL2 | - |
| Distoribution | Ubuntu 20.04.4 LTS |
| PHP | 8.0.29 |
| nginx | 1.18.0 |
作り方
- Windows側の
hostsに127.0.0.1 mock-server.testを追加 /etc/nginx/conf.dに以下の設定ファイルを置く
server {
listen 80;
client_max_body_size 100m;
server_name mock-server.test;
access_log /var/log/nginx/mock-server.access.log;
error_log /var/log/nginx/mock-server.error.log;
location ~ ^/.*$ {
rewrite ^/.*$ / break;
# リクエストパスの確認用
proxy_set_header X-Request-Path $request_uri;
proxy_pass http://127.0.0.1:8888;
}
}
sudo service nginx restart- モックサーバーのコードを書いて適当な場所に置く
<?php
$server_json = json_encode($_SERVER);
file_put_contents('log', "$server_json\n", FILE_APPEND);
php -S localhost:8888http://localhost:8888/hogeにアクセスしログファイルに追記されることを確認- おわり
おまけ
$_SERVER の中身をフィルタしたい時
<?php
$ignoreKeys = [
'DOCUMENT_ROOT',
'REMOTE_ADDR',
'REMOTE_PORT',
'SERVER_SOFTWARE',
'SERVER_PROTOCOL',
'SERVER_NAME',
'SERVER_PORT',
'REQUEST_URI',
'SCRIPT_NAME',
'SCRIPT_FILENAME',
'PHP_SELF',
'HTTP_HOST',
'HTTP_CONNECTION',
'HTTP_UPGRADE_INSECURE_REQUESTS',
'HTTP_USER_AGENT',
'HTTP_ACCEPT',
'HTTP_ACCEPT_ENCODING',
'HTTP_ACCEPT_LANGUAGE',
'HTTP_CACHE_CONTROL',
'REQUEST_TIME_FLOAT',
'REQUEST_TIME'
];
$buff = array_filter($_SERVER, function($key) use($ignoreKeys) {
return !in_array($key, $ignoreKeys);
}, ARRAY_FILTER_USE_KEY);
$server_json = json_encode($buff);
file_put_contents('log', "$server_json\n", FILE_APPEND);