FrankenPHPを laravel new
して最速で使う方法をメモ
とりあえず laravel new
laravel new frankenphp
フロントエンドは React
を選択
ローカル環境のDockerを整備
とりあえずDockerfileやcompose.ymlを作る
FROM dunglas/frankenphp:1-php8.4-bookworm
ENV COMPOSER_ALLOW_SUPERUSER=1
ENV DEBCONF_NOWARNINGS=yes
RUN ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
locales strace vim git less unzip
RUN install-php-extensions @composer xdebug
RUN curl -sLS https://deb.nodesource.com/setup_24.x | bash - \
&& apt-get install -y nodejs
RUN sed -i -e 's/# \(ja_JP.UTF-8\)/\1/' /etc/locale.gen \
&& locale-gen \
&& update-locale LANG=ja_JP.UTF-8
ENV LANG=ja_JP.UTF-8
RUN cp /usr/local/etc/php/php.ini-development /usr/local/etc/php/php.ini
必要に応じて pdo_mysql
とか intl
とかをインストールする。
compose.yml
services:
app:
build: .
volumes:
- .:/app
ports:
- 8080:80
environment:
SERVER_NAME: ':80'
SERVICE_NAME: ':80'
がポイント。
:80を指定するとauto https(自動で証明書発行したりする機能)が動かなくなる。
TLSを利用する場合
mkcert -install
mkcert {domain_name}
services:
app:
build: .
volumes:
- .:/app
ports:
- 443:443
environment:
SERVER_NAME: '{domain_name}:443'
CADDY_SERVER_EXTRA_DIRECTIVES: "tls /app/{domain_name}.pem /app/{domain_name}-key.pem"
DNSで{domain_name}を127.0.0.1に向ける
Google Cloud Runにデプロイしてみる
デプロイ用Docker
FROM dunglas/frankenphp:1-php8.4-bookworm
ENV COMPOSER_ALLOW_SUPERUSER=1
ENV DEBCONF_NOWARNINGS=yes
RUN ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
locales unzip
RUN install-php-extensions @composer
RUN curl -sLS https://deb.nodesource.com/setup_24.x | bash - \
&& apt-get install -y nodejs
RUN sed -i -e 's/# \(ja_JP.UTF-8\)/\1/' /etc/locale.gen \
&& locale-gen \
&& update-locale LANG=ja_JP.UTF-8
ENV LANG=ja_JP.UTF-8
RUN cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini
COPY . /app
WORKDIR /app
RUN composer install --no-dev --no-interaction --no-progress --no-scripts --optimize-autoloader
RUN npm ci
RUN npm run build
デプロイはこんな感じで
APP_NAME={app_name}
REGION=asia-northeast1
PROJECT_ID={project_id}
REPOSITORY=${REGION}-docker.pkg.dev/${PROJECT_ID}/{artifact_registry}/{repository}
docker build --platform linux/amd64 -f Dockerfile.prod . --tag ${REPOSITORY}
docker push ${REPOSITORY}
gcloud run deploy ${APP_NAME} --project ${PROJECT_ID} \
--image ${REPOSITORY}:latest \
--region ${REGION} \
--set-env-vars=SERVER_NAME=:80,APP_ENV=production \
--port=80
そのままだとassetの配信がhttpになるので、APP_ENV=productionのときはhttpsを強制するようにする
// app/Providers/AppServiceProvider.php
if (app()->isProduction()) {
\URL::forceScheme('https');
}
FrankenPHPとDockerfileとCaddyfile
FrankenPHPはCaddyというサーバーを使って動いている。CaddyはCaddyfileという設定ファイルがあり、FrankenPHPのCaddyfileはこんな感じになっている。{$xxx} の部分は環境変数で設定できる。
{
skip_install_trust
{$CADDY_GLOBAL_OPTIONS}
frankenphp {
{$FRANKENPHP_CONFIG}
}
}
{$CADDY_EXTRA_CONFIG}
{$SERVER_NAME:localhost} {
root {$SERVER_ROOT:public/}
encode zstd br gzip
{$CADDY_SERVER_EXTRA_DIRECTIVES}
php_server {
#worker /path/to/your/worker.php
}
}
import Caddyfile.d/*.caddyfile
SERVER_NAMEでホスティングするドメインやポートが決定される。そしてこれによってauto httpsという証明書の自動発行処理が動くかどうかも決まる。
https://caddyserver.com/docs/caddyfile/concepts#addresses
:80
という設定はホスト名のバリデーションは行わず、httpでホスティングする(証明書の自動発行は行わない)という設定。{domain_name}:443
はhttpsでホスティングするが証明書の自動発行は行わない、という設定。
php_server
がFrankenPHPが拡張している部分で、実体は以下のような設定と等価になる。
route {
# Add trailing slash for directory requests
@canonicalPath {
file {path}/index.php
not path */
}
redir @canonicalPath {path}/ 308
# If the requested file does not exist, try index files
@indexFiles file {
try_files {path} {path}/index.php index.php
split_path .php
}
rewrite @indexFiles {http.matchers.file.relative}
# FrankenPHP!
@phpFiles path *.php
php @phpFiles
file_server
}
よく見そうなapacheやnginxの設定みたいな感じになっている。ということで特に設定無くこのデフォ設定でLaravelなどは動くようになる。
ちなみにLaravel OctaneはOctane側に内包されているCaddyfileを使っていたりする。
https://github.com/laravel/octane/blob/7cbb80a0bd7ccfbf0615dd33de7907c5dad21171/src/Commands/stubs/Caddyfile