Add production Dockerfile and release image pipeline #2
Labels
No labels
bug
ci
docs
enhancement
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Blocks
#3 Write README for self-hosters}
anagram-finder/web
Reference: anagram-finder/web#2
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
web/has no production image definition — onlyDockerfile.dev, which is a developmentenvironment (bind-mounts the source, installs dev dependencies, runs Vite in watch mode,
boots with Xdebug available). Nothing exists that a self-hoster could pull and run.
This blocks documenting installation at all: the conventional self-hosted README points at a
published image, and we have none.
Scope
1. Production
Dockerfiledunglas/frankenphp:1-php8.4-alpine(note
latest-php8.4-alpinedoes not exist — see.claude/PLATFORM.md)composer install --no-dev --optimize-autoloadernpm run buildfor Vite assets; no Vite dev server, nopublic/hotconfig:cache,route:cache,view:cache)2. Root
compose.yamlfor self-hostersapp+db(MariaDB 11), no dev-only services127.0.0.1rather than0.0.0.0— the convention incomparable projects (Vaultwarden, Uptime Kuma both do this deliberately)
/up(already wired inbootstrap/app.php:12)3. Forgejo workflow —
.forgejo/workflows/build.ymlMirror
ffr/.forgejo/workflows/build.yml:v*→forge.lvl0.xyz/anagram-finder/web:<tag>and:latestmain→:latestonlyforge.lvl0.xyzwithsecrets.REGISTRY_TOKENdocker/build-push-action@v5,context: .,file: Dockerfile4. Remove dead scaffolding
.github/workflows/tests.ymland.github/dependabot.ymlcame from the Laravel starter kit.This repo is hosted on Forgejo, so they will never run. Delete, or port
tests.ymlto.forgejo/workflows/ci.ymlif we want lint/test gates now.Prerequisites
REGISTRY_TOKENsecret must exist in the repo settingsanagram-finderorgAcceptance
Dockerfilebuilds a runnable production image locallypublic/hotv0.1.0publishesweb:v0.1.0andweb:latestcompose.yamlat the repo root brings the stack up from the published image alone.github/removed or portedNotes
Image tag comes from the git tag, not the release branch — so the release flow stays
release/<milestone>→ PR → merge tomain→ tagv*→ image builds.Done —
web:v0.1.0and:latestpublishedAll acceptance criteria verified:
assets, FrankenPHP runtime
public/hot— verified against arunning container: page 200, stylesheet 200 (265 KB, containing every
@lvl0/uiutility andthe
@font-face),/hot→ 404. End to end:POST /→ 302 →/find/eamstoxil→ 447matches from the dictionary in
anagram-finder/core.web:v0.1.0and:latest— run #14 on tagv0.1.0(f267bac),run #13 on the preceding push to main
compose.yamlbrings the stack up — verified locally against the built image.github/removedNot in the original scope
webhas two private dependencies —anagram-finder/core(composer) and@lvl0/ui(npm) —both previously
ssh://. A CI runner has no SSH key for Forgejo, so the build could not haveworked. Both repos allow anonymous read, so both manifests now use
https://and the buildneeds no secret beyond the registry push token.
Bugs found by running it
resources/css/app.cssimportsFlux's stylesheet from
vendor/and scans three vendor globs for class names. Reordered tovendor → assets → runtime.
dump-autoloadtriggered Laravel's post-autoload-dump hook, which runsartisanandneeds a runtime environment. Added
--no-scripts;package:discoverhappens at boot.bootstrap/cache/*.phpleaked in from the host, registeringlaravel/pail's provider —a dev dependency
--no-devnever installs, so every artisan call fatalled and the containercrash-looped. Excluded from the build context, and the boot script now rebuilds the manifest.
depends_on: condition: service_healthyhangs podman-compose 1.5.0 indefinitely, evenwith the database reporting healthy. Switched to a plain
depends_on; the start script pollsfor the database itself.
Notes for #3 (README)
forge.lvl0.xyz/anagram-finder/web:v0.1.0compose.yamlat the repo root is what the README should link rather than inline.env.examplegained the DB variables; it previously defaulted to sqlite, so a self-hostercopying it would have had nothing for compose to read
APP_KEY,APP_URL,DB_PASSWORD,DB_ROOT_PASSWORDLeftover
The stale
tests.yml #12run is queued forever — it was triggered by49fe4bf, before thisticket deleted
.github/. Forgejo has no runner matching itsruns-on. Harmless, and nothingwill queue again; cancel it in the Actions tab if the queued state is untidy.