PR feedback

This commit is contained in:
Nabeel Shahzad 2026-05-28 10:03:15 -05:00
parent ad31e642f2
commit 736102eccd
No known key found for this signature in database
GPG Key ID: 08C44114D2BF3047
9 changed files with 25 additions and 249 deletions

View File

@ -49,6 +49,14 @@ APP_FALLBACK_LOCALE=en
# Locale used by Faker when generating fake data.
APP_FAKER_LOCALE=en_US
# =============================================================================
# OCTANE AND PRODUCTION CONFIGURATION
# =============================================================================
# If you're using the docker-compose or Railpack to serve directly
# to the internet, instead of a server in front of it, set this to true
OCTANE_HTTPS=false
# =============================================================================
# DATABASE
# =============================================================================

View File

@ -1,206 +0,0 @@
name: Docker image smoke
on:
pull_request:
paths:
- "Dockerfile"
- "compose.deploy.yml"
- "resources/docker/**"
- "composer.json"
- "composer.lock"
- "config/octane.php"
- ".github/workflows/docker-smoke.yml"
# Exercises the production image in both runtime modes:
# - Classic (image default — Serversideup's FrankenPHP entrypoint).
# - Octane worker mode (compose.deploy.yml's command: override).
#
# Checks for:
# - The image actually builds.
# - The container reaches a healthy state and serves /.
# - Sequential requests on the same container return stable response
# sizes (a quick heuristic for nav-list accumulation or other
# per-request state leaks under Octane worker mode).
#
# Not a full integration test — the database is SQLite in-memory, no
# migrations are run, and any route that requires DB will fail. The bar
# here is "the entrypoint hook doesn't crash and FrankenPHP serves
# something."
concurrency:
group: docker-smoke-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
name: Build image
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build image
uses: docker/build-push-action@v6
with:
context: .
push: false
load: true
tags: phpvms-smoke:latest
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Export image
run: docker save phpvms-smoke:latest -o /tmp/phpvms-smoke.tar
- name: Upload image artifact
uses: actions/upload-artifact@v4
with:
name: phpvms-smoke-image
path: /tmp/phpvms-smoke.tar
retention-days: 1
smoke-classic:
name: Smoke (image default — classic FrankenPHP)
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/checkout@v4
- name: Download image artifact
uses: actions/download-artifact@v4
with:
name: phpvms-smoke-image
path: /tmp
- name: Load image
run: docker load -i /tmp/phpvms-smoke.tar
- name: Run container (classic FrankenPHP, image default)
run: |
APP_KEY="base64:$(openssl rand -base64 32)"
docker run -d --name phpvms-smoke-classic \
-p 8080:8080 \
-e APP_KEY="$APP_KEY" \
-e APP_ENV=production \
-e APP_DEBUG=false \
-e DB_CONNECTION=sqlite \
-e DB_DATABASE=:memory: \
phpvms-smoke:latest
- name: Wait for HTTP
run: |
for i in $(seq 1 60); do
if curl -fsS -o /dev/null -w "%{http_code}" http://localhost:8080/ | grep -Eq "^[23]"; then
echo "Container responsive after ${i} attempts"
exit 0
fi
sleep 2
done
echo "Container did not become responsive"
docker logs phpvms-smoke-classic
exit 1
- name: Sequential request stability (3 hits, response sizes must match)
run: |
set -e
sizes=""
for i in 1 2 3; do
sz=$(curl -fsS http://localhost:8080/ | wc -c)
sizes="$sizes $sz"
done
echo "Response sizes:$sizes"
uniq_count=$(echo $sizes | tr ' ' '\n' | sort -u | wc -l)
if [ "$uniq_count" -ne 1 ]; then
echo "Response sizes differed across sequential requests."
docker logs phpvms-smoke-classic
exit 1
fi
- name: Verify Octane is NOT running (classic mode is image default)
run: |
if docker exec phpvms-smoke-classic sh -c 'ps -ef | grep -v grep | grep -q "octane:start\|octane:frankenphp"'; then
echo "octane is running but no command: override was passed — image default leaked Octane"
docker exec phpvms-smoke-classic ps -ef
exit 1
fi
- name: Container logs (on failure)
if: failure()
run: docker logs phpvms-smoke-classic
- name: Tear down
if: always()
run: docker rm -f phpvms-smoke-classic || true
smoke-octane:
name: Smoke (Octane via command override — compose.deploy.yml mode)
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/checkout@v4
- name: Download image artifact
uses: actions/download-artifact@v4
with:
name: phpvms-smoke-image
path: /tmp
- name: Load image
run: docker load -i /tmp/phpvms-smoke.tar
- name: Run container (Octane via command override)
run: |
APP_KEY="base64:$(openssl rand -base64 32)"
docker run -d --name phpvms-smoke-octane \
-p 8081:8080 \
-e APP_KEY="$APP_KEY" \
-e APP_ENV=production \
-e APP_DEBUG=false \
-e DB_CONNECTION=sqlite \
-e DB_DATABASE=:memory: \
phpvms-smoke:latest \
php /var/www/html/artisan octane:start --server=frankenphp --host=0.0.0.0 --port=8080 --workers=2 --max-requests=500
- name: Wait for HTTP
run: |
for i in $(seq 1 60); do
if curl -fsS -o /dev/null -w "%{http_code}" http://localhost:8081/ | grep -Eq "^[23]"; then
echo "Container responsive after ${i} attempts"
exit 0
fi
sleep 2
done
echo "Container did not become responsive"
docker logs phpvms-smoke-octane
exit 1
- name: Sequential request stability (3 hits, response sizes must match)
run: |
set -e
sizes=""
for i in 1 2 3; do
sz=$(curl -fsS http://localhost:8081/ | wc -c)
sizes="$sizes $sz"
done
echo "Response sizes:$sizes"
uniq_count=$(echo $sizes | tr ' ' '\n' | sort -u | wc -l)
if [ "$uniq_count" -ne 1 ]; then
echo "Response sizes differed across sequential requests — possible state leak."
docker logs phpvms-smoke-octane
exit 1
fi
- name: Verify Octane is the foreground process
run: |
docker exec phpvms-smoke-octane sh -c 'ps -ef | grep -v grep | grep -q "octane:start"' \
|| { echo "octane:start not running"; docker exec phpvms-smoke-octane ps -ef; exit 1; }
- name: Container logs (on failure)
if: failure()
run: docker logs phpvms-smoke-octane
- name: Tear down
if: always()
run: docker rm -f phpvms-smoke-octane || true

View File

@ -1,12 +1,14 @@
# This Dockerfile is used to create the base phpVMS image for Docker in production.
# It is based on https://serversideup.net/open-source/docker-php/.
#
# I highly recommend using the Railpack instead!
FROM serversideup/php:8.5-cli AS build
LABEL org.opencontainers.image.description="The official phpvms image"
USER root
COPY --from=node:lts-slim /usr/local/bin /usr/local/bin
COPY --from=node:lts-slim /usr/local/lib/node_modules /usr/local/lib/node_modules
COPY --from=oven/bun:latest /usr/local/bin/bun /usr/local/bin/bun
RUN install-php-extensions intl bcmath
@ -20,22 +22,7 @@ RUN composer install \
--no-dev \
--optimize-autoloader
RUN npm install && npm run build
# -----------------------------------------------------------------------------
#
# Run the npm build
#
#FROM node:lts AS npm
#
#WORKDIR /app
#
#COPY --chown=www-data:www-data --from=compose /build/ .
#
## Build assets directly into their final location (public/build). No
## separate web container means no asset-handoff step.
#RUN npm install && npm run build
RUN bun install && bun run build
# -----------------------------------------------------------------------------
#
@ -59,10 +46,7 @@ RUN apt-get update; \
apt-get install -yqq --no-install-recommends --show-progress \
mariadb-client
# Install nodejs
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
&& apt-get install -y nodejs \
&& rm -rf /var/lib/apt/lists/*
COPY --from=oven/bun:latest /usr/local/bin/bun /usr/local/bin/bun
# Deal with permissions
RUN usermod -ou $WWWUSER www-data \

View File

@ -59,16 +59,16 @@ class SetActiveTheme implements Middleware
}
if (empty($theme)) {
$theme = 'seven';
$theme = config('themes.default');
}
if ($request->is(self::$skip)) {
/*if ($request->is(self::$skip)) {
// Skipped paths don't pick a per-request theme but still need a
// deterministic baseline under Octane (see method PHPDoc).
Theme::set($theme);
return;
}
}*/
Theme::set($theme);
}

View File

@ -31,7 +31,7 @@ services:
pull_policy: build
# Build from the local repository
image: phpvms/phpvms:latest
image: ${PHPVMS_IMAGE_NAME:-phpvms/phpvms}:latest
# Build from the local repository
build:
@ -80,14 +80,13 @@ services:
"octane:start",
"--server=frankenphp",
"--host=0.0.0.0",
"--port=${FORWARD_HTTP_PORT:-80}",
"--workers=auto",
"--max-requests=500",
]
ports:
# The image binds to 8080/8443 internally (unprivileged); host ports
# The image binds to 8000/8443 internally (unprivileged); host ports
# 80/443 are mapped at the Compose layer.
- "${FORWARD_HTTP_PORT:-80}:8080"
- "${FORWARD_HTTP_PORT:-80}:8000"
- "${FORWARD_HTTPS_PORT:-443}:8443"
user: "${WWWUSER:-1000}:${WWWGROUP:-1000}"

View File

@ -154,7 +154,8 @@
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi",
"@php artisan ide-helper:generate || true",
"@php artisan ide-helper:meta || true"
"@php artisan ide-helper:meta || true",
".hooks/setup-git-hooks.sh || true"
],
"post-update-cmd": [
"Illuminate\\Foundation\\ComposerScripts::postUpdate",

View File

@ -8,5 +8,4 @@ return [
'default' => env('DEFAULT_THEME', 'seven'),
'cache' => true,
'themes' => [],
];

View File

@ -1,14 +1,5 @@
[env]
BUILDKIT_HOST = "docker-container://buildkit"
APP_ENV = "local"
[tools]
php = "8.5"
node = "24"
[settings]
activate_aggressive = true
env_shell_expand = true
[tasks.setup]
run = ["mise install", "mise run run-buildkit-container || true"]

View File

@ -2,9 +2,9 @@
"private": true,
"type": "module",
"scripts": {
"dev": "bunx --bun vite",
"dev": "bun x --bun vite",
"dev:components": "bun bin/build.js --dev",
"build": "bunx --bun vite build && bun bin/build.js",
"build": "bun x --bun vite build && bun bin/build.js",
"build:components": "bun bin/build.js",
"clean": "rm -rf public/build resources/js/dist",
"lint": "oxlint",
@ -12,7 +12,7 @@
"fmt": "oxfmt",
"fmt:check": "oxfmt --check",
"typecheck": "tsc --noEmit",
"test": "bunx --bun vitest run"
"test": "bun x --bun vitest run"
},
"dependencies": {
"@date-fns/tz": "^1.5.0",