- PHP 75.5%
- Blade 14.4%
- CSS 7.9%
- JavaScript 1.5%
- Shell 0.7%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
All checks were successful
Deploy public site / deploy (push) Successful in 12s
|
||
| .forgejo/workflows | ||
| app | ||
| bootstrap | ||
| config | ||
| database | ||
| public | ||
| resources | ||
| routes | ||
| scripts | ||
| storage | ||
| tests | ||
| .editorconfig | ||
| .env.example | ||
| .gitattributes | ||
| .gitignore | ||
| .npmrc | ||
| artisan | ||
| composer.json | ||
| composer.lock | ||
| Containerfile.dev | ||
| package-lock.json | ||
| package.json | ||
| phpunit.xml | ||
| README.md | ||
| vite.config.js | ||
Kannuki_sanの作業場 公開サイト
技術記事、趣味の記録、制作物を公開するLaravel 13製の公開フロントです。TekuTimeは制作物の一つとして掲載します。管理画面はこのリポジトリに含みません。
ローカル開発
前提はPodman、Node.js、npmです。管理画面リポジトリがDB migrationとダミーデータを所有します。既定では両リポジトリを同じ親ディレクトリへ置き、../runtime/content.sqliteと../runtime/mediaを共有します。
cd ../admin-panel
./scripts/reset-local-db.sh
cd ../public-site
npm install
npm run build
./scripts/dev.sh
リポジトリを別々の場所へcloneする場合は、両方のshellで同じ共有先を指定できます。ホスト側の配置やディレクトリ名は固定されていません。
export MYWEB_RUNTIME_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/myweb"
export MYWEB_MEDIA_DIR="$MYWEB_RUNTIME_DIR/media"
http://127.0.0.1:8000を開きます。テストは./scripts/test.shです。runtime、.env、本番データはGitに入りません。配色は未選択時にOSへ追従し、手動選択はCookieへ1年間保存します。
管理画面から登録した画像、MP4/WebM、添付・配布ファイルは、公開サイト自身の/media/... URLから配信されます。保存先のパスや内部ホストは公開せず、公開状態のレコードに実際に登録されたファイルだけをLaravelが読み取り専用ストレージから返します。YouTube・ニコニコ動画は検証済みの公式プレーヤーURLだけを埋め込みます。任意のHTML埋め込みコードは実行しません。
管理画面の動画欄に登録した順番を使い、本文中の任意位置へ複数配置できます。記法で参照しなかった動画は本文末尾へ表示されます。
[[video:1]]
[[video:2]]
[[uploaded-video:1]]
videoはYouTube/ニコニコURL、uploaded-videoはアップロード動画です。番号は1から始まります。本文画像はMarkdownエディタのカーソル位置へアップロード挿入できます。
本文はGitHub Flavored Markdownとして表示します。見出し、強調、リンク、引用、番号付き/番号なしリスト、タスクリスト、表、水平線、インラインコード、コードブロック、画像を利用できます。任意のHTMLやJavaScriptは実行せず、動画・配布物等は上記の専用記法で配置します。
各制作物には多段の子ページを追加できます。たとえば/works/tekutime/manual/exportのような階層URLになり、PCでは右側のページ一覧、狭い画面では本文上部の折り畳み一覧から移動できます。公開日時前・下書き・非公開の親を持つページは、ページ一覧、直接URL、サイトマップ、本文画像配信のすべてで公開されません。
本番デプロイの要点
LXCは現在の運用例であり、必須ではありません。通常のLinuxサーバー、VM、コンテナでも動作します。公開サイトと管理画面は、同じホストで動かす場合もWeb公開範囲、資格情報、実行ユーザーを分離してください。以下に登場するURL、配置先、socket、DB/S3接続先はすべて環境ごとに置き換える値です。
- Caddyまたは同等のWebサーバー、PHP 8.3以上、PHP-FPM、Composer、
php-mysql php-mbstring php-xml php-curl php-zip php-intl php-opcacheを導入する。 - 任意のアプリケーションルート配下へreleaseを配置し、
currentsymlink等で現在版を切り替える。 .envはGit外の永続領域に置き、APP_ENV=production、APP_DEBUG=false、APP_URL=https://example.com、本番専用APP_KEYを設定する。本番URLをHTTPにするとサイトマップ等の絶対URLがcanonicalと不一致になるため、HTTPSで固定する。- MariaDBには公開側専用ユーザーを作る。公開コンテンツ・公開コメント・制作物更新履歴・制作物ページへの
SELECTと、comments・content_reports・download_eventsへのINSERTだけを許可する。不具合報告やダウンロード集計の閲覧、既存データの更新、migration権限は渡さない。記事コメントは公開投稿、制作物の不具合報告は非公開として別々に扱う。 composer install --no-dev --classmap-authoritative、npm ci && npm run build、php artisan config:cache route:cache view:cacheを実行する。- Caddyのdocument rootは必ず
public/とし、.env、Git、storage、プロジェクトルートを公開しない。 - 公開reverse proxyやTunnelは公開サイトだけへ接続し、管理画面や非公開ストレージへ転送しない。Cloudflare Tunnelは選択肢の一つであり必須ではない。
- 非公開のS3互換ストレージへは公開サイト専用の読み取り専用資格情報で接続し、ストレージ自体を公開DNSへ接続しない。
.envへMEDIA_DISK=s3、内部endpoint、bucket、path-style設定を指定する。公開サイトへメディア書き込み権限を渡さない。
public/robots.txtのような静的ファイルは置かず、Laravelの/robots.txtルートを使用します。この応答がAPP_URLを基準にしたSitemap:行を含み、サイトマップ内のURLがすべてHTTPSであることをデプロイ後に確認してください。
次のCaddyfileはテンプレートです。example.com、/path/to/public-site、PHP-FPM socketを実環境へ合わせて置き換えてください。
example.com {
encode zstd gzip
root * /path/to/public-site/current/public
php_fastcgi unix//run/php/php-fpm.sock
file_server
@hidden path /.env /.git/* /storage/* /vendor/*
respond @hidden 404
}
管理パスはこのアプリ自体に存在しません。デプロイ後にphp artisan route:listとcurl -I https://example.com/admin(404)を確認してください。
添付・配布ファイルのGET開始時には、管理側が所有するdownload_eventsへ匿名の記録を1行追加します。IPアドレスとUser-Agentは保存せず、途中Rangeの再開要求と画像・動画のインライン表示はカウントしません。集計記録に失敗してもファイル配信は継続します。本番DBでは公開側ユーザーへdownload_eventsのINSERTだけを付与してください。
メディアストレージは公開DNSへ直接接続しません。公開URLは常に公開サイトの/media/...となり、LaravelがS3互換ストレージからストリーミングします。動画のRange応答にも対応します。大容量配布物はこの経路へ置かず、任意の外部共有サービスを制作物の「外部ダウンロードURL」に登録します。
MEDIA_DISK=s3
AWS_ACCESS_KEY_ID=PUBLIC_READ_ONLY_KEY
AWS_SECRET_ACCESS_KEY=PUBLIC_READ_ONLY_SECRET
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=site-media
AWS_URL=
AWS_ENDPOINT=http://storage.internal:8333
AWS_USE_PATH_STYLE_ENDPOINT=true
storage.internalは説明用hostnameです。実際の内部DNS名または非公開IPへ変更してください。SeaweedFS以外でも、Laravel Flysystem S3 adapterと互換性のあるストレージを利用できます。
デプロイ自動化の境界
同梱するForgejo Actions workflowは現在の管理者向けのデプロイ例であり、アプリケーションの動作要件ではありません。自動デプロイする場合は、公開環境専用のdeploy鍵を使い、限定されたdeployユーザーで新規release作成・依存導入・symlink切替だけを許可します。管理環境、配布リポジトリ、DB管理者、他サービスのcredentialへアクセスさせません。