diff --git a/app/Commands/GenerateCommand.php b/app/Commands/GenerateCommand.php index e5e310a..80393c9 100644 --- a/app/Commands/GenerateCommand.php +++ b/app/Commands/GenerateCommand.php @@ -18,7 +18,8 @@ class GenerateCommand extends Command {--force : Overwrite existing files} {--skip : Keep existing files} {--dev : Include dev dependencies like the local .env file} - {--laravel-version= : Set the laravel version}'; + {--laravel-version= : Set the laravel version} + {--path=. : Set the directory to check files in.}'; /** * The description of the command. @@ -48,13 +49,13 @@ public function handle() // Define the options available to the templates. $options = [ - 'octane' => $this->option('octane'), 'build_assets' => ! $this->option('no-assets'), 'dev' => $this->option('dev'), 'laravel_version' => $scan->laravelVersion( $this->options() ), 'fly' => $scan->isForFly(), - ]; - + 'octane' => $scan->octaneFlavor( $this->options() ) + ]; + // Define the list of templates to render. // The key is the template name, and the value is the output file name. $templates = $scan->templates( $options ); diff --git a/app/Services/File.php b/app/Services/File.php index f6d4b1b..a07e1ab 100644 --- a/app/Services/File.php +++ b/app/Services/File.php @@ -26,4 +26,13 @@ public function createFile( $output, $result ) // Create the file, finally! return file_put_contents($output, implode("\n", $result) . "\n"); } + + public function composerJsonContent( $directory ) + { + $path = $directory.'/composer.json'; + + if( !file_exists( $path ) ) return []; + + return json_decode( file_get_contents( $path ), 1 ); + } } \ No newline at end of file diff --git a/app/Services/Scanner.php b/app/Services/Scanner.php index 7a3443c..52ed8ac 100644 --- a/app/Services/Scanner.php +++ b/app/Services/Scanner.php @@ -13,21 +13,47 @@ class Scanner */ public function laravelVersion( $options ) { - $run = Process::run( 'php artisan --version' ); - $version = $run->output(); - $version = explode('Laravel Framework', $version); - if( count($version) >1 ){ - // From artisan command - return trim($version[1]); - }else if( isset( $options['laravel-version']) && !empty($options['laravel-version']) ){ + if( isset( $options['laravel-version']) && !empty($options['laravel-version']) ){ // From options return trim( $options['laravel-version'], '^' ); + }else{ + // From detection + $run = Process::run( 'php artisan --version' ); + $version = $run->output(); + $version = explode('Laravel Framework', $version); + if( count($version) >1 ){ + // From artisan command + return trim($version[1]); + } } - + // Default Latest Version return "11.0.0"; } + /** + * Detect octane setup and flavor + */ + public function octaneFlavor( array $options ) + { + $composerContent = (new \App\Services\File())->composerJsonContent( $options['path'] ); + $octane = false; + + // Detect octane from composer.json + if( isset($composerContent['require']) && isset( $composerContent['require']['laravel/octane'] ) ){ + + // Determine flavor + if( file_exists( $options['path'].'/frankenphp') ){ + return 'frankenphp'; + }else if( file_exists( $options['path'].'/rr' ) && file_exists( $options['path'].'/.rr.yaml') ){ + return 'roadrunner'; + }else{ + return 'swoole'; + } + } + return $options['octane']; + } + /** * Scan directory and check if applicable for Fly.io deployment */ diff --git a/builds/dockerfile-laravel b/builds/dockerfile-laravel index f510886..81bfd8b 100755 Binary files a/builds/dockerfile-laravel and b/builds/dockerfile-laravel differ diff --git a/storage/logs/laravel.log b/storage/logs/laravel.log new file mode 100644 index 0000000..78bb062 --- /dev/null +++ b/storage/logs/laravel.log @@ -0,0 +1,4 @@ +[2024-04-01 17:29:21] development.ERROR: Declaration of LaravelZero\Framework\Commands\BuildCommand::handleSignal(int $signal): int|false must be compatible with Symfony\Component\Console\Command\SignalableCommandInterface::handleSignal(int $signal, int|false $previousExitCode = 0): int|false {"exception":"[object] (Symfony\\Component\\ErrorHandler\\Error\\FatalError(code: 0): Declaration of LaravelZero\\Framework\\Commands\\BuildCommand::handleSignal(int $signal): int|false must be compatible with Symfony\\Component\\Console\\Command\\SignalableCommandInterface::handleSignal(int $signal, int|false $previousExitCode = 0): int|false at /home/admin_kath/development/projects/dockerfile-laravel/vendor/laravel-zero/framework/src/Commands/BuildCommand.php:84) +[stacktrace] +#0 {main} +"} diff --git a/tests/Feature/GenerateCommandTest.php b/tests/Feature/GenerateCommandTest.php index 7f58f15..225bcdc 100644 --- a/tests/Feature/GenerateCommandTest.php +++ b/tests/Feature/GenerateCommandTest.php @@ -1,13 +1,18 @@ composerJsonContent( $directory ); $composerConfig = $composerContent['require']; // Matches with options for in App\Commands\GenerateCommand::generate() command $optionsToCheck = [ - 'laravel/framework' => 'laravel-version' + 'laravel/framework' => 'laravel-version', ]; // Gather options @@ -17,6 +22,10 @@ function getTestOptions( string $directory ): string $optionsFound .= '--'.$option.'="'.$composerConfig[$key].'" '; } } + + // Set directory to check files in + $optionsFound .= '--path="'.$directory.'"'; + return $optionsFound; } @@ -37,7 +46,7 @@ function getTestOptions( string $directory ): string foreach( $referenceFiles as $reference ){ $failedForMsg = 'Failed for: "'.$reference->getPathName().'"'; - if( $reference->getFileName() == 'composer.json' ) continue; + if( in_array( $reference->getFileName(), ignoreFiles()) ) continue; // Second assert: a new file with the reference file's name was created-it should exist! $this->assertFileExists( $reference->getFileName(), $failedForMsg ); @@ -46,12 +55,13 @@ function getTestOptions( string $directory ): string $expected = file_get_contents( $reference->getPathName() ); // expected content from reference file $generated = file_get_contents( $reference->getFileName() ); // new file content - // Clean UP: Delete generated file, no longer needed - unlink( $reference->getFileName() ); - // Third assert: contents are the same // TODO: ignore different ARG VALUES $this->assertEquals( $expected, $generated, $failedForMsg); + + // Clean UP: Delete generated file, no longer needed + unlink( $reference->getFileName() ); + } } }); diff --git a/tests/Feature/Supported/10_octane_frankenphp/Dockerfile b/tests/Feature/Supported/10_octane_frankenphp/Dockerfile new file mode 100644 index 0000000..bc95692 --- /dev/null +++ b/tests/Feature/Supported/10_octane_frankenphp/Dockerfile @@ -0,0 +1,79 @@ +# syntax = docker/dockerfile:experimental + +ARG PHP_VERSION=8.2 +ARG NODE_VERSION=18 +FROM fideloper/fly-laravel:${PHP_VERSION} as base + +# PHP_VERSION needs to be repeated here +# See https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact +ARG PHP_VERSION + +LABEL fly_launch_runtime="laravel" + +# copy application code, skipping files based on .dockerignore +COPY . /var/www/html + +RUN composer install --optimize-autoloader --no-dev \ + && mkdir -p storage/logs \ + && php artisan optimize:clear \ + && chown -R www-data:www-data /var/www/html \ + && echo "MAILTO=\"\"\n* * * * * www-data /usr/bin/php /var/www/html/artisan schedule:run" > /etc/cron.d/laravel \ + && sed -i 's/protected \$proxies/protected \$proxies = "*"/g' app/Http/Middleware/TrustProxies.php;\ + if [ -d .fly ]; then cp .fly/entrypoint.sh /entrypoint; chmod +x /entrypoint; fi; + +RUN rm -rf /etc/supervisor/conf.d/fpm.conf; \ + mv /etc/supervisor/octane-franken.conf /etc/supervisor/conf.d/octane-franken.conf; \ + rm -f frankenphp; \ + php artisan octane:install --no-interaction --server=frankenphp; \ + rm /etc/nginx/sites-enabled/default; \ + ln -sf /etc/nginx/sites-available/default-octane /etc/nginx/sites-enabled/default; + +# Multi-stage build: Build static assets +# This allows us to not include Node within the final container +FROM node:${NODE_VERSION} as node_modules_go_brrr + +RUN mkdir /app + +RUN mkdir -p /app +WORKDIR /app +COPY . . +COPY --from=base /var/www/html/vendor /app/vendor + +# Use yarn or npm depending on what type of +# lock file we might find. Defaults to +# NPM if no lock file is found. +# Note: We run "production" for Mix and "build" for Vite +RUN if [ -f "vite.config.js" ]; then \ + ASSET_CMD="build"; \ + else \ + ASSET_CMD="production"; \ + fi; \ + if [ -f "yarn.lock" ]; then \ + yarn install --frozen-lockfile; \ + yarn $ASSET_CMD; \ + elif [ -f "pnpm-lock.yaml" ]; then \ + corepack enable && corepack prepare pnpm@latest-8 --activate; \ + pnpm install --frozen-lockfile; \ + pnpm run $ASSET_CMD; \ + elif [ -f "package-lock.json" ]; then \ + npm ci --no-audit; \ + npm run $ASSET_CMD; \ + else \ + npm install; \ + npm run $ASSET_CMD; \ + fi; + +# From our base container created above, we +# create our final image, adding in static +# assets that we generated above +FROM base + +# Packages like Laravel Nova may have added assets to the public directory +# or maybe some custom assets were added manually! Either way, we merge +# in the assets we generated above rather than overwrite them +COPY --from=node_modules_go_brrr /app/public /var/www/html/public-npm +RUN rsync -ar /var/www/html/public-npm/ /var/www/html/public/ \ + && rm -rf /var/www/html/public-npm \ + && chown -R www-data:www-data /var/www/html/public + +EXPOSE 8080 diff --git a/tests/Feature/Supported/10_octane_frankenphp/composer.json b/tests/Feature/Supported/10_octane_frankenphp/composer.json new file mode 100644 index 0000000..fe8cfff --- /dev/null +++ b/tests/Feature/Supported/10_octane_frankenphp/composer.json @@ -0,0 +1,6 @@ +{ + "require": { + "laravel/framework": "^10.0.0", + "laravel/octane" : "*" + } +} \ No newline at end of file diff --git a/tests/Feature/Supported/10_octane_frankenphp/frankenphp b/tests/Feature/Supported/10_octane_frankenphp/frankenphp new file mode 100644 index 0000000..30d74d2 --- /dev/null +++ b/tests/Feature/Supported/10_octane_frankenphp/frankenphp @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/tests/Feature/Supported/10_octane_rr/.rr.yaml b/tests/Feature/Supported/10_octane_rr/.rr.yaml new file mode 100644 index 0000000..474e5c7 --- /dev/null +++ b/tests/Feature/Supported/10_octane_rr/.rr.yaml @@ -0,0 +1 @@ +rryaml \ No newline at end of file diff --git a/tests/Feature/Supported/10_octane_rr/Dockerfile b/tests/Feature/Supported/10_octane_rr/Dockerfile new file mode 100644 index 0000000..84fc57e --- /dev/null +++ b/tests/Feature/Supported/10_octane_rr/Dockerfile @@ -0,0 +1,79 @@ +# syntax = docker/dockerfile:experimental + +ARG PHP_VERSION=8.2 +ARG NODE_VERSION=18 +FROM fideloper/fly-laravel:${PHP_VERSION} as base + +# PHP_VERSION needs to be repeated here +# See https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact +ARG PHP_VERSION + +LABEL fly_launch_runtime="laravel" + +# copy application code, skipping files based on .dockerignore +COPY . /var/www/html + +RUN composer install --optimize-autoloader --no-dev \ + && mkdir -p storage/logs \ + && php artisan optimize:clear \ + && chown -R www-data:www-data /var/www/html \ + && echo "MAILTO=\"\"\n* * * * * www-data /usr/bin/php /var/www/html/artisan schedule:run" > /etc/cron.d/laravel \ + && sed -i 's/protected \$proxies/protected \$proxies = "*"/g' app/Http/Middleware/TrustProxies.php;\ + if [ -d .fly ]; then cp .fly/entrypoint.sh /entrypoint; chmod +x /entrypoint; fi; + +RUN rm -rf /etc/supervisor/conf.d/fpm.conf; \ + mv /etc/supervisor/octane-rr.conf /etc/supervisor/conf.d/octane-rr.conf; \ + if [ -f ./vendor/bin/rr ]; then ./vendor/bin/rr get-binary; fi; \ + rm -f .rr.yaml; \ + rm /etc/nginx/sites-enabled/default; \ + ln -sf /etc/nginx/sites-available/default-octane /etc/nginx/sites-enabled/default; + +# Multi-stage build: Build static assets +# This allows us to not include Node within the final container +FROM node:${NODE_VERSION} as node_modules_go_brrr + +RUN mkdir /app + +RUN mkdir -p /app +WORKDIR /app +COPY . . +COPY --from=base /var/www/html/vendor /app/vendor + +# Use yarn or npm depending on what type of +# lock file we might find. Defaults to +# NPM if no lock file is found. +# Note: We run "production" for Mix and "build" for Vite +RUN if [ -f "vite.config.js" ]; then \ + ASSET_CMD="build"; \ + else \ + ASSET_CMD="production"; \ + fi; \ + if [ -f "yarn.lock" ]; then \ + yarn install --frozen-lockfile; \ + yarn $ASSET_CMD; \ + elif [ -f "pnpm-lock.yaml" ]; then \ + corepack enable && corepack prepare pnpm@latest-8 --activate; \ + pnpm install --frozen-lockfile; \ + pnpm run $ASSET_CMD; \ + elif [ -f "package-lock.json" ]; then \ + npm ci --no-audit; \ + npm run $ASSET_CMD; \ + else \ + npm install; \ + npm run $ASSET_CMD; \ + fi; + +# From our base container created above, we +# create our final image, adding in static +# assets that we generated above +FROM base + +# Packages like Laravel Nova may have added assets to the public directory +# or maybe some custom assets were added manually! Either way, we merge +# in the assets we generated above rather than overwrite them +COPY --from=node_modules_go_brrr /app/public /var/www/html/public-npm +RUN rsync -ar /var/www/html/public-npm/ /var/www/html/public/ \ + && rm -rf /var/www/html/public-npm \ + && chown -R www-data:www-data /var/www/html/public + +EXPOSE 8080 diff --git a/tests/Feature/Supported/10_octane_rr/composer.json b/tests/Feature/Supported/10_octane_rr/composer.json new file mode 100644 index 0000000..fe8cfff --- /dev/null +++ b/tests/Feature/Supported/10_octane_rr/composer.json @@ -0,0 +1,6 @@ +{ + "require": { + "laravel/framework": "^10.0.0", + "laravel/octane" : "*" + } +} \ No newline at end of file diff --git a/tests/Feature/Supported/10_octane_rr/rr b/tests/Feature/Supported/10_octane_rr/rr new file mode 100644 index 0000000..7481d32 --- /dev/null +++ b/tests/Feature/Supported/10_octane_rr/rr @@ -0,0 +1 @@ +rr \ No newline at end of file diff --git a/tests/Feature/Supported/10_octane_swoole/Dockerfile b/tests/Feature/Supported/10_octane_swoole/Dockerfile new file mode 100644 index 0000000..9a6c73b --- /dev/null +++ b/tests/Feature/Supported/10_octane_swoole/Dockerfile @@ -0,0 +1,77 @@ +# syntax = docker/dockerfile:experimental + +ARG PHP_VERSION=8.2 +ARG NODE_VERSION=18 +FROM fideloper/fly-laravel:${PHP_VERSION} as base + +# PHP_VERSION needs to be repeated here +# See https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact +ARG PHP_VERSION + +LABEL fly_launch_runtime="laravel" + +# copy application code, skipping files based on .dockerignore +COPY . /var/www/html + +RUN composer install --optimize-autoloader --no-dev \ + && mkdir -p storage/logs \ + && php artisan optimize:clear \ + && chown -R www-data:www-data /var/www/html \ + && echo "MAILTO=\"\"\n* * * * * www-data /usr/bin/php /var/www/html/artisan schedule:run" > /etc/cron.d/laravel \ + && sed -i 's/protected \$proxies/protected \$proxies = "*"/g' app/Http/Middleware/TrustProxies.php;\ + if [ -d .fly ]; then cp .fly/entrypoint.sh /entrypoint; chmod +x /entrypoint; fi; + +RUN rm -rf /etc/supervisor/conf.d/fpm.conf; \ + mv /etc/supervisor/octane-swoole.conf /etc/supervisor/conf.d/octane-swoole.conf; \ + rm /etc/nginx/sites-enabled/default; \ + ln -sf /etc/nginx/sites-available/default-octane /etc/nginx/sites-enabled/default; + +# Multi-stage build: Build static assets +# This allows us to not include Node within the final container +FROM node:${NODE_VERSION} as node_modules_go_brrr + +RUN mkdir /app + +RUN mkdir -p /app +WORKDIR /app +COPY . . +COPY --from=base /var/www/html/vendor /app/vendor + +# Use yarn or npm depending on what type of +# lock file we might find. Defaults to +# NPM if no lock file is found. +# Note: We run "production" for Mix and "build" for Vite +RUN if [ -f "vite.config.js" ]; then \ + ASSET_CMD="build"; \ + else \ + ASSET_CMD="production"; \ + fi; \ + if [ -f "yarn.lock" ]; then \ + yarn install --frozen-lockfile; \ + yarn $ASSET_CMD; \ + elif [ -f "pnpm-lock.yaml" ]; then \ + corepack enable && corepack prepare pnpm@latest-8 --activate; \ + pnpm install --frozen-lockfile; \ + pnpm run $ASSET_CMD; \ + elif [ -f "package-lock.json" ]; then \ + npm ci --no-audit; \ + npm run $ASSET_CMD; \ + else \ + npm install; \ + npm run $ASSET_CMD; \ + fi; + +# From our base container created above, we +# create our final image, adding in static +# assets that we generated above +FROM base + +# Packages like Laravel Nova may have added assets to the public directory +# or maybe some custom assets were added manually! Either way, we merge +# in the assets we generated above rather than overwrite them +COPY --from=node_modules_go_brrr /app/public /var/www/html/public-npm +RUN rsync -ar /var/www/html/public-npm/ /var/www/html/public/ \ + && rm -rf /var/www/html/public-npm \ + && chown -R www-data:www-data /var/www/html/public + +EXPOSE 8080 diff --git a/tests/Feature/Supported/10_octane_swoole/composer.json b/tests/Feature/Supported/10_octane_swoole/composer.json new file mode 100644 index 0000000..fe8cfff --- /dev/null +++ b/tests/Feature/Supported/10_octane_swoole/composer.json @@ -0,0 +1,6 @@ +{ + "require": { + "laravel/framework": "^10.0.0", + "laravel/octane" : "*" + } +} \ No newline at end of file diff --git a/tests/Feature/Supported/11_octane_frankenphp/Dockerfile b/tests/Feature/Supported/11_octane_frankenphp/Dockerfile new file mode 100644 index 0000000..80f2307 --- /dev/null +++ b/tests/Feature/Supported/11_octane_frankenphp/Dockerfile @@ -0,0 +1,81 @@ +# syntax = docker/dockerfile:experimental + +ARG PHP_VERSION=8.2 +ARG NODE_VERSION=18 +FROM fideloper/fly-laravel:${PHP_VERSION} as base + +# PHP_VERSION needs to be repeated here +# See https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact +ARG PHP_VERSION + +LABEL fly_launch_runtime="laravel" + +# copy application code, skipping files based on .dockerignore +COPY . /var/www/html + +RUN composer install --optimize-autoloader --no-dev \ + && mkdir -p storage/logs \ + && php artisan optimize:clear \ + && chown -R www-data:www-data /var/www/html \ + && echo "MAILTO=\"\"\n* * * * * www-data /usr/bin/php /var/www/html/artisan schedule:run" > /etc/cron.d/laravel \ + && sed -i='' '/->withMiddleware(function (Middleware \$middleware) {/a\ + \$middleware->trustProxies(at: "*");\ + ' bootstrap/app.php; \ + if [ -d .fly ]; then cp .fly/entrypoint.sh /entrypoint; chmod +x /entrypoint; fi; + +RUN rm -rf /etc/supervisor/conf.d/fpm.conf; \ + mv /etc/supervisor/octane-franken.conf /etc/supervisor/conf.d/octane-franken.conf; \ + rm -f frankenphp; \ + php artisan octane:install --no-interaction --server=frankenphp; \ + rm /etc/nginx/sites-enabled/default; \ + ln -sf /etc/nginx/sites-available/default-octane /etc/nginx/sites-enabled/default; + +# Multi-stage build: Build static assets +# This allows us to not include Node within the final container +FROM node:${NODE_VERSION} as node_modules_go_brrr + +RUN mkdir /app + +RUN mkdir -p /app +WORKDIR /app +COPY . . +COPY --from=base /var/www/html/vendor /app/vendor + +# Use yarn or npm depending on what type of +# lock file we might find. Defaults to +# NPM if no lock file is found. +# Note: We run "production" for Mix and "build" for Vite +RUN if [ -f "vite.config.js" ]; then \ + ASSET_CMD="build"; \ + else \ + ASSET_CMD="production"; \ + fi; \ + if [ -f "yarn.lock" ]; then \ + yarn install --frozen-lockfile; \ + yarn $ASSET_CMD; \ + elif [ -f "pnpm-lock.yaml" ]; then \ + corepack enable && corepack prepare pnpm@latest-8 --activate; \ + pnpm install --frozen-lockfile; \ + pnpm run $ASSET_CMD; \ + elif [ -f "package-lock.json" ]; then \ + npm ci --no-audit; \ + npm run $ASSET_CMD; \ + else \ + npm install; \ + npm run $ASSET_CMD; \ + fi; + +# From our base container created above, we +# create our final image, adding in static +# assets that we generated above +FROM base + +# Packages like Laravel Nova may have added assets to the public directory +# or maybe some custom assets were added manually! Either way, we merge +# in the assets we generated above rather than overwrite them +COPY --from=node_modules_go_brrr /app/public /var/www/html/public-npm +RUN rsync -ar /var/www/html/public-npm/ /var/www/html/public/ \ + && rm -rf /var/www/html/public-npm \ + && chown -R www-data:www-data /var/www/html/public + +EXPOSE 8080 diff --git a/tests/Feature/Supported/11_octane_frankenphp/composer.json b/tests/Feature/Supported/11_octane_frankenphp/composer.json new file mode 100644 index 0000000..1c0265b --- /dev/null +++ b/tests/Feature/Supported/11_octane_frankenphp/composer.json @@ -0,0 +1,6 @@ +{ + "require": { + "laravel/framework": "^11.0.0", + "laravel/octane" : "*" + } +} \ No newline at end of file diff --git a/tests/Feature/Supported/11_octane_frankenphp/frankenphp b/tests/Feature/Supported/11_octane_frankenphp/frankenphp new file mode 100644 index 0000000..30d74d2 --- /dev/null +++ b/tests/Feature/Supported/11_octane_frankenphp/frankenphp @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/tests/Feature/Supported/11_octane_rr/.rr.yaml b/tests/Feature/Supported/11_octane_rr/.rr.yaml new file mode 100644 index 0000000..30d74d2 --- /dev/null +++ b/tests/Feature/Supported/11_octane_rr/.rr.yaml @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/tests/Feature/Supported/11_octane_rr/Dockerfile b/tests/Feature/Supported/11_octane_rr/Dockerfile new file mode 100644 index 0000000..d273b7a --- /dev/null +++ b/tests/Feature/Supported/11_octane_rr/Dockerfile @@ -0,0 +1,81 @@ +# syntax = docker/dockerfile:experimental + +ARG PHP_VERSION=8.2 +ARG NODE_VERSION=18 +FROM fideloper/fly-laravel:${PHP_VERSION} as base + +# PHP_VERSION needs to be repeated here +# See https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact +ARG PHP_VERSION + +LABEL fly_launch_runtime="laravel" + +# copy application code, skipping files based on .dockerignore +COPY . /var/www/html + +RUN composer install --optimize-autoloader --no-dev \ + && mkdir -p storage/logs \ + && php artisan optimize:clear \ + && chown -R www-data:www-data /var/www/html \ + && echo "MAILTO=\"\"\n* * * * * www-data /usr/bin/php /var/www/html/artisan schedule:run" > /etc/cron.d/laravel \ + && sed -i='' '/->withMiddleware(function (Middleware \$middleware) {/a\ + \$middleware->trustProxies(at: "*");\ + ' bootstrap/app.php; \ + if [ -d .fly ]; then cp .fly/entrypoint.sh /entrypoint; chmod +x /entrypoint; fi; + +RUN rm -rf /etc/supervisor/conf.d/fpm.conf; \ + mv /etc/supervisor/octane-rr.conf /etc/supervisor/conf.d/octane-rr.conf; \ + if [ -f ./vendor/bin/rr ]; then ./vendor/bin/rr get-binary; fi; \ + rm -f .rr.yaml; \ + rm /etc/nginx/sites-enabled/default; \ + ln -sf /etc/nginx/sites-available/default-octane /etc/nginx/sites-enabled/default; + +# Multi-stage build: Build static assets +# This allows us to not include Node within the final container +FROM node:${NODE_VERSION} as node_modules_go_brrr + +RUN mkdir /app + +RUN mkdir -p /app +WORKDIR /app +COPY . . +COPY --from=base /var/www/html/vendor /app/vendor + +# Use yarn or npm depending on what type of +# lock file we might find. Defaults to +# NPM if no lock file is found. +# Note: We run "production" for Mix and "build" for Vite +RUN if [ -f "vite.config.js" ]; then \ + ASSET_CMD="build"; \ + else \ + ASSET_CMD="production"; \ + fi; \ + if [ -f "yarn.lock" ]; then \ + yarn install --frozen-lockfile; \ + yarn $ASSET_CMD; \ + elif [ -f "pnpm-lock.yaml" ]; then \ + corepack enable && corepack prepare pnpm@latest-8 --activate; \ + pnpm install --frozen-lockfile; \ + pnpm run $ASSET_CMD; \ + elif [ -f "package-lock.json" ]; then \ + npm ci --no-audit; \ + npm run $ASSET_CMD; \ + else \ + npm install; \ + npm run $ASSET_CMD; \ + fi; + +# From our base container created above, we +# create our final image, adding in static +# assets that we generated above +FROM base + +# Packages like Laravel Nova may have added assets to the public directory +# or maybe some custom assets were added manually! Either way, we merge +# in the assets we generated above rather than overwrite them +COPY --from=node_modules_go_brrr /app/public /var/www/html/public-npm +RUN rsync -ar /var/www/html/public-npm/ /var/www/html/public/ \ + && rm -rf /var/www/html/public-npm \ + && chown -R www-data:www-data /var/www/html/public + +EXPOSE 8080 diff --git a/tests/Feature/Supported/11_octane_rr/composer.json b/tests/Feature/Supported/11_octane_rr/composer.json new file mode 100644 index 0000000..1c0265b --- /dev/null +++ b/tests/Feature/Supported/11_octane_rr/composer.json @@ -0,0 +1,6 @@ +{ + "require": { + "laravel/framework": "^11.0.0", + "laravel/octane" : "*" + } +} \ No newline at end of file diff --git a/tests/Feature/Supported/11_octane_rr/rr b/tests/Feature/Supported/11_octane_rr/rr new file mode 100644 index 0000000..30d74d2 --- /dev/null +++ b/tests/Feature/Supported/11_octane_rr/rr @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/tests/Feature/Supported/11_octane_swoole/Dockerfile b/tests/Feature/Supported/11_octane_swoole/Dockerfile new file mode 100644 index 0000000..ef0d507 --- /dev/null +++ b/tests/Feature/Supported/11_octane_swoole/Dockerfile @@ -0,0 +1,79 @@ +# syntax = docker/dockerfile:experimental + +ARG PHP_VERSION=8.2 +ARG NODE_VERSION=18 +FROM fideloper/fly-laravel:${PHP_VERSION} as base + +# PHP_VERSION needs to be repeated here +# See https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact +ARG PHP_VERSION + +LABEL fly_launch_runtime="laravel" + +# copy application code, skipping files based on .dockerignore +COPY . /var/www/html + +RUN composer install --optimize-autoloader --no-dev \ + && mkdir -p storage/logs \ + && php artisan optimize:clear \ + && chown -R www-data:www-data /var/www/html \ + && echo "MAILTO=\"\"\n* * * * * www-data /usr/bin/php /var/www/html/artisan schedule:run" > /etc/cron.d/laravel \ + && sed -i='' '/->withMiddleware(function (Middleware \$middleware) {/a\ + \$middleware->trustProxies(at: "*");\ + ' bootstrap/app.php; \ + if [ -d .fly ]; then cp .fly/entrypoint.sh /entrypoint; chmod +x /entrypoint; fi; + +RUN rm -rf /etc/supervisor/conf.d/fpm.conf; \ + mv /etc/supervisor/octane-swoole.conf /etc/supervisor/conf.d/octane-swoole.conf; \ + rm /etc/nginx/sites-enabled/default; \ + ln -sf /etc/nginx/sites-available/default-octane /etc/nginx/sites-enabled/default; + +# Multi-stage build: Build static assets +# This allows us to not include Node within the final container +FROM node:${NODE_VERSION} as node_modules_go_brrr + +RUN mkdir /app + +RUN mkdir -p /app +WORKDIR /app +COPY . . +COPY --from=base /var/www/html/vendor /app/vendor + +# Use yarn or npm depending on what type of +# lock file we might find. Defaults to +# NPM if no lock file is found. +# Note: We run "production" for Mix and "build" for Vite +RUN if [ -f "vite.config.js" ]; then \ + ASSET_CMD="build"; \ + else \ + ASSET_CMD="production"; \ + fi; \ + if [ -f "yarn.lock" ]; then \ + yarn install --frozen-lockfile; \ + yarn $ASSET_CMD; \ + elif [ -f "pnpm-lock.yaml" ]; then \ + corepack enable && corepack prepare pnpm@latest-8 --activate; \ + pnpm install --frozen-lockfile; \ + pnpm run $ASSET_CMD; \ + elif [ -f "package-lock.json" ]; then \ + npm ci --no-audit; \ + npm run $ASSET_CMD; \ + else \ + npm install; \ + npm run $ASSET_CMD; \ + fi; + +# From our base container created above, we +# create our final image, adding in static +# assets that we generated above +FROM base + +# Packages like Laravel Nova may have added assets to the public directory +# or maybe some custom assets were added manually! Either way, we merge +# in the assets we generated above rather than overwrite them +COPY --from=node_modules_go_brrr /app/public /var/www/html/public-npm +RUN rsync -ar /var/www/html/public-npm/ /var/www/html/public/ \ + && rm -rf /var/www/html/public-npm \ + && chown -R www-data:www-data /var/www/html/public + +EXPOSE 8080 diff --git a/tests/Feature/Supported/11_octane_swoole/composer.json b/tests/Feature/Supported/11_octane_swoole/composer.json new file mode 100644 index 0000000..1c0265b --- /dev/null +++ b/tests/Feature/Supported/11_octane_swoole/composer.json @@ -0,0 +1,6 @@ +{ + "require": { + "laravel/framework": "^11.0.0", + "laravel/octane" : "*" + } +} \ No newline at end of file