Created
June 12, 2022 21:37
-
-
Save spaceemotion/01a9c94519eaf57fecba4279a8d83cc2 to your computer and use it in GitHub Desktop.
Browsershot on Vapor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace App\Services\Browsershot; | |
use RuntimeException; | |
use Spatie\Browsershot\Browsershot as SpatieBrowsershot; | |
use Spatie\TemporaryDirectory\TemporaryDirectory; | |
use function file_put_contents; | |
use function is_dir; | |
use function mkdir; | |
use function sprintf; | |
/** | |
* Custom overwrites for the base package: | |
* - Put all temporary files under a sub-folder inside /tmp | |
* - Configure user-data dir | |
* | |
* @internal | |
*/ | |
class BrowsershotExtended extends SpatieBrowsershot | |
{ | |
public function __construct(string $url = '', bool $deviceEmulate = false) | |
{ | |
parent::__construct($url, $deviceEmulate); | |
// Keep assets in cache between requests | |
if (!is_dir('/tmp/browsershot-user-data') && !mkdir('/tmp/browsershot-user-data')) { | |
throw new RuntimeException(sprintf('Directory "%s" was not created', '/tmp/browsershot-user-data')); | |
} | |
$this->setUserDataDir('/tmp/browsershot-user-data'); | |
} | |
protected function createTemporaryHtmlFile(): string | |
{ | |
$this->temporaryHtmlDirectory = $this->createTemporaryDirectory(); | |
file_put_contents($temporaryHtmlFile = $this->temporaryHtmlDirectory->path('index.html'), $this->html); | |
return "file://{$temporaryHtmlFile}"; | |
} | |
protected function createTemporaryOptionsFile(string $command): string | |
{ | |
$this->temporaryOptionsDirectory = $this->createTemporaryDirectory(); | |
file_put_contents($temporaryOptionsFile = $this->temporaryOptionsDirectory->path('command.js'), $command); | |
return "file://{$temporaryOptionsFile}"; | |
} | |
protected function createTemporaryDirectory(): TemporaryDirectory | |
{ | |
return (new TemporaryDirectory()) | |
->location('/tmp/browsershot') | |
->create(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace App\Services\Browsershot; | |
use App\Services\Pdf\Pdf; | |
use Spatie\Browsershot\Browsershot as SpatieBrowsershot; | |
class BrowsershotService | |
{ | |
public function forPdf(Pdf $pdf): SpatieBrowsershot | |
{ | |
$instance = new BrowsershotExtended(); | |
$instance->disableJavascript(); | |
$instance->dismissDialogs(); | |
$instance->ignoreHttpsErrors(); | |
$instance->setHtml($pdf->getContents()->render()); | |
$instance->landscape($pdf->landscape); | |
$instance->scale(1); | |
// Allow background colors | |
$instance->showBackground(); | |
$instance->hideBrowserHeaderAndFooter(); | |
// Set default page sizes | |
$instance->format('A4'); | |
$instance->setOption('preferCssPageSize', true); | |
$instance->margins( | |
$pdf->marginTop(), | |
$pdf->marginRight(), | |
$pdf->marginBottom(), | |
$pdf->marginLeft(), | |
); | |
// See https://github.com/alixaxel/chrome-aws-lambda/blob/master/source/index.ts#L94 | |
$instance->addChromiumArguments([ | |
'allow-running-insecure-content', // https://source.chromium.org/search?q=lang:cpp+symbol:kAllowRunningInsecureContent&ss=chromium | |
'autoplay-policy' => 'user-gesture-required', // https://source.chromium.org/search?q=lang:cpp+symbol:kAutoplayPolicy&ss=chromium | |
'disable-component-update', // https://source.chromium.org/search?q=lang:cpp+symbol:kDisableComponentUpdate&ss=chromium | |
'disable-domain-reliability', // https://source.chromium.org/search?q=lang:cpp+symbol:kDisableDomainReliability&ss=chromium | |
'disable-features' => 'AudioServiceOutOfProcess,IsolateOrigins,site-per-process', // https://source.chromium.org/search?q=file:content_features.cc&ss=chromium | |
'disable-print-preview', // https://source.chromium.org/search?q=lang:cpp+symbol:kDisablePrintPreview&ss=chromium | |
'disable-setuid-sandbox', // https://source.chromium.org/search?q=lang:cpp+symbol:kDisableSetuidSandbox&ss=chromium | |
'disable-site-isolation-trials', // https://source.chromium.org/search?q=lang:cpp+symbol:kDisableSiteIsolation&ss=chromium | |
'disable-speech-api', // https://source.chromium.org/search?q=lang:cpp+symbol:kDisableSpeechAPI&ss=chromium | |
'disable-web-security', // https://source.chromium.org/search?q=lang:cpp+symbol:kDisableWebSecurity&ss=chromium | |
'disk-cache-size' => 33554432, // https://source.chromium.org/search?q=lang:cpp+symbol:kDiskCacheSize&ss=chromium | |
'enable-features' => 'SharedArrayBuffer', // https://source.chromium.org/search?q=file:content_features.cc&ss=chromium | |
'hide-scrollbars', // https://source.chromium.org/search?q=lang:cpp+symbol:kHideScrollbars&ss=chromium | |
'ignore-gpu-blocklist', // https://source.chromium.org/search?q=lang:cpp+symbol:kIgnoreGpuBlocklist&ss=chromium | |
'in-process-gpu', // https://source.chromium.org/search?q=lang:cpp+symbol:kInProcessGPU&ss=chromium | |
'mute-audio', // https://source.chromium.org/search?q=lang:cpp+symbol:kMuteAudio&ss=chromium | |
'no-default-browser-check', // https://source.chromium.org/search?q=lang:cpp+symbol:kNoDefaultBrowserCheck&ss=chromium | |
'no-pings', // https://source.chromium.org/search?q=lang:cpp+symbol:kNoPings&ss=chromium | |
'no-sandbox', // https://source.chromium.org/search?q=lang:cpp+symbol:kNoSandbox&ss=chromium | |
'no-zygote', // https://source.chromium.org/search?q=lang:cpp+symbol:kNoZygote&ss=chromium | |
'use-gl' => 'swiftshader', // https://source.chromium.org/search?q=lang:cpp+symbol:kUseGl&ss=chromium | |
'window-size' => '1920,1080', // https://source.chromium.org/search?q=lang:cpp+symbol:kWindowSize&ss=chromium | |
'single-process', // https://source.chromium.org/search?q=lang:cpp+symbol:kSingleProcess&ss=chromium | |
// https://github.com/hiroppy/dynamic-rendering-sample/blob/98c40e730bc75ac076080ccd30f6f118414d48d5/rendertron/Dockerfile#L12 | |
'disable-2d-canvas-clip-aa', | |
'disable-accelerated-2d-canvas', | |
'disable-breakpad', | |
'disable-canvas-aa', | |
'disable-desktop-notifications', | |
'disable-extensions', | |
'disable-gl-drawing-for-tests', | |
'disable-permissions-api', | |
'disable-sync', | |
'no-first-run', | |
]); | |
// Hardcode module path to fix npm 8.6 $HOME path problem | |
// Coincidentally, this speeds up the warmup time by about 400ms | |
$instance->setNodeModulePath('/usr/local/lib/node_modules'); | |
return $instance; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# According to the docs, we should use the vapor-provided packages here, | |
# but they seem to be a bit out of date (we do want to have bugfixes asap) | |
# See: https://github.com/laravel/vapor-dockerfiles/blob/master/php81.Dockerfile | |
FROM php:8.1-fpm-alpine | |
# Add php extensions | |
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/ | |
RUN chmod +x /usr/local/bin/install-php-extensions && \ | |
install-php-extensions \ | |
mcrypt \ | |
redis \ | |
pdo_mysql \ | |
pcntl \ | |
bcmath \ | |
zip \ | |
opcache \ | |
intl | |
# Install dependencies | |
RUN apk add --no-cache nodejs-current npm | |
# Install chrome/chromium + Additional fonts | |
RUN apk add --no-cache chromium msttcorefonts-installer fontconfig && \ | |
update-ms-fonts && \ | |
fc-cache -f | |
# Install puppeteer | |
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true \ | |
PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser | |
RUN npm install -g puppeteer@^14 | |
# Prepare Vapor environment | |
RUN cp "/etc/ssl/cert.pem" /opt/cert.pem | |
COPY runtime/bootstrap /opt/bootstrap | |
COPY runtime/bootstrap.php /opt/bootstrap.php | |
COPY runtime/php.ini /usr/local/etc/php/php.ini | |
RUN chmod 755 /opt/bootstrap | |
RUN chmod 755 /opt/bootstrap.php | |
COPY . /var/task | |
RUN mkdir /.npm && chmod 777 /.npm | |
ENTRYPOINT [] | |
CMD /opt/bootstrap |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment