TermuxでLaravel
上記の記事の詳細記事です。
WordPressのような本格的なCMSもちゃんとTermuxで動くことは分かったので、次はLaravelでPHPの開発をしてみます。
なお、本記事ではすでに(Pythonと)JavaScriptを習得されてる段階の人を想定しているので、別の言語習得もそう苦ではないと考えており、PHPやLaravel自体の説明はしません。以下に示した本家の文書で確認しつつAIに聞いたり検索したりしてください。
composerのインストール
今どきのphpではまずはcomposerをインストールします。
~ $ pkg install composer
Laravel 10までの標準的なプロジェクト作成
次にLaravelプロジェクトlaravel_testを作って、そのまま開発サーバーで動かしてみます。ちなみにLaravelの開発サーバーを動かすのにnginxやphp-fpmの起動は不要です。もちろん本番環境への設置時はnginx+php-fpmのようなサーバー環境が必要です。
~ $ mkdir -p php
~ $ cd php
~/php $ composer create laravel/laravel laravel_test
~/php $ cd laravel_test
~/php/laravel_test $ php artisan serve # --host=0.0.0.0 を付けるとPCからもIPでアクセスできます。
ブラウザから http://localhost:8000/ を開くと以下の画面が表示されます。
Ctrl+Cで開発サーバーは停止します。このまま開発してもいいのですが、今回は別のプロジェクトの作り方から開発します。
Laravel11以降での標準的なプロジェクト作成
この方法ではJavaScriptとより連携して開発しやすくなっています。ただし、node.jsが必要になります。今回は本番環境ではnode.jsが不要な形(SSRがない形)を目指します。
laravelコマンドのインストール
最初にcomposerを使ってlaravelコマンドをインストールします。
~ $ cd
~ $ composer global require laravel/installer
プロジェクト作成
laravelコマンドを使ってプロジェクトを作成します。Starter Kitsといういくつかの開発パターンの雛形が用意されてます。ここではVueとLaravel組み込みの認証を使う方法を選択しています。
~ $ mkdir -p php
~ $ cd php
~/php $ ~/.composer/vendor/bin/laravel new example-app
_ _
| | | |
| | __ _ _ __ __ ___ _____| |
| | / _` | __/ _` \ \ / / _ \ |
| |___| (_| | | | (_| |\ V / __/ |
|______\__,_|_| \__,_| \_/ \___|_|
┌ Which starter kit would you like to install? ────────────────┐
│ Vue │
└──────────────────────────────────────────────────────────────┘
┌ Which authentication provider do you prefer? ────────────────┐
│ Laravel's built-in authentication │
└──────────────────────────────────────────────────────────────┘
┌ Which testing framework do you prefer? ──────────────────────┐
│ PHPUnit │
└──────────────────────────────────────────────────────────────┘
...
┌ Would you like to run npm install and npm run build? ────────┐
│ Yes │
└──────────────────────────────────────────────────────────────┘
...
(ビルドは失敗してます)
~/php $ cd example-app/
~/php/example-app $
今回はJavaScript側にVueを選択しています。以前見たnode.jsを使ったVueの開発環境がここにも同時に構築されているということです。
ビルドが失敗しているのはLaravelが使っているtailwind がAndroid用のarm64バイナリを用意してないlightningcssを使っていたからでした。ここではこちらの回避策を取り入れ以下のようにします。
~/php/example-app $ npm install --save-dev lightningcss.android-arm64.node
個人ビルドのやや信頼度の低いパッケージなのですが、そもそもrustで開発されていて、開発元がnpmで配布するのを諦めるとこうなるのかもしれません(調べたところ、testにブラウザが必要だったりしてtermuxでは色々問題が多い)。代替案としてはtailwindを他のpostcssなどに置き換えるなどが可能です。ただ最初の画面も崩れてしまうので、他と違いすぎる結果があまり好ましくありません。なので個人ビルドを選びました。調べたところGithub Actionでビルドされたもので、元のコード自体もいじってないようなので、こちらにしてみました。ただ普通はしない手順ではあるので、子供に言いたくないのですが)自己責任でどうぞ。
ここまででビルドは出来るのですが、開発サーバーを立ち上げると…
g/php/example-app $ composer run dev
...
[vite] Error: ENOSPC: System limit for number of file watchers reached, watch '/data/data/com.termux/files/home/php/example-app/vendor/laravel/framework/src/Illuminate/Auth/Console/stubs/make/views/layouts'
...
エラーが出て動きません。これはファイルの更新監視数が上限を超えたというものです(inotify)。
残念ながらroot権限がないとこの上限を増やすことが出来ず、JailbreakしたAndroidでないとどうにもできません。これは正規な手段ではなく、一度でもしてしまうとメーカーのサポートが受けられないなどのペナルティがあります。私の環境では8190個程度でこの上限に届くようなので、Laravelのような大きめのフレームだと初期状態で超えてしまうようです。
このファイルの更新監視はviteでHot Reload(Hot Module Replacement)を実現するために利用しているようなので、Hot Reloadを不完全にすることでどうにか動かしてみます。
方法は汚らしくviteのソースコードを直接書き換えるというものです。
function createFsWatchInstance(path, options, listener, errHandler, emitRaw) {
const handleEvent = (rawEvent, evPath) => {
listener(path);
emitRaw(rawEvent, evPath, {watchedPath: path});
// emit based on events occurring for files from a directory's watcher in
// case the file's watcher misses it (and rely on throttling to de-dupe)
if (evPath && path !== evPath) {
fsWatchBroadcast(
sysPath$2.resolve(path, evPath), KEY_LISTENERS, sysPath$2.join(path, evPath)
);
}
};
try {
return fs$4.watch(path, options, handleEvent);
} catch (error) {
errHandler(error);
}
}
これをこうするだけです。
function createFsWatchInstance(path, options, listener, errHandler, emitRaw) {
const handleEvent = (rawEvent, evPath) => {
listener(path);
emitRaw(rawEvent, evPath, {watchedPath: path});
// emit based on events occurring for files from a directory's watcher in
// case the file's watcher misses it (and rely on throttling to de-dupe)
if (evPath && path !== evPath) {
fsWatchBroadcast(
sysPath$2.resolve(path, evPath), KEY_LISTENERS, sysPath$2.join(path, evPath)
);
}
};
try {
return fs$4.watch(path, options, handleEvent);
} catch (error) {
console.error(error);
return;
//errHandler(error);
}
}
とりあえず処理を続行できるようになり、ブラウザで確認できる状態になりました。皆さんの環境で全く同じコードになるかどうかは分かりません。ただエラーを追っていけば同じような箇所がどこかにあり、同じような対処が出来ると思います。
起動後にブラウザから http://localhost:8000/ を開いて以前と同じような画面が出れば成功です(ログイン関連のボタンなどが追加されてますが)。
ホットリロードがうまく効いてないなと思ったら、サーバーを再起動(Ctrl+C
してcomposer run dev
)してください。
データベースの変更
なんとか起動したので、次はデータベースをデフォルトのsqliteからMariaDB(MySQL系)に変えてみます。
DB_CONNECTION=sqlite
# DB_HOST=127.0.0.1
# DB_PORT=3306
# DB_DATABASE=laravel
# DB_USERNAME=root
# DB_PASSWORD=
この部分をこう変えます。
#DB_CONNECTION=sqlite
# DB_HOST=127.0.0.1
# DB_PORT=3306
# DB_DATABASE=laravel
# DB_USERNAME=root
# DB_PASSWORD=
DB_CONNECTION=mariadb
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=
DB_SOCKET=/data/data/com.termux/files/usr/var/run/mysqld.sock
あとは実際の移行処理を指示します(その前にMariaDBを起動しておいてください)。
~/php/example-app $ php artisan migrate
WARN The database 'laravel' does not exist on the 'mysql' connection.
┌ Would you like to create it? ────────────────────────────────┐
│ Yes │
└──────────────────────────────────────────────────────────────┘
INFO Preparing database.
Creating migration table .................................................. 53.55ms DONE
INFO Running migrations.
0001_01_01_000000_create_users_table ...................................... 62.03ms DONE
0001_01_01_000001_create_cache_table ...................................... 23.09ms DONE
0001_01_01_000002_create_jobs_table ....................................... 63.74ms DONE
~/php/example-app $ composer run dev
...
これでデータベースがMariaDBに移行しました。
Laravelの開発用サーバーが稼働中の場合は一旦落としてから起動しなおしてください。
詳細記事
次はアプリ開発を予定していたのですが、今回は開発環境構築という意味で一旦ココまでです。
次回以降はココに詳細記事(というより続き)へのリンクを追加していきます。
Discussion