gnetwork-cp

Member
Mar 1, 2016
23
6
3
Australia
cPanel Access Level
Root Administrator
The brotli Apache module works fine for on-the-fly compression, but I want to use the Brotli Extension for PHP github.com/kjdev/php-ext-brotli to help serve brotli pre-compressed resources. It is not available in EasyApache 4. Is there a way to integrate it, or if I install the extension standalone, is there anything I need to be aware of?
 
Last edited by a moderator:

cPanelLauren

Product Owner
Staff member
Nov 14, 2017
13,298
1,279
313
Houston
  • Like
Reactions: LucasRolff

gnetwork-cp

Member
Mar 1, 2016
23
6
3
Australia
cPanel Access Level
Root Administrator
Hi @gnetwork-cp


It is not available in EasyApache for this kind of customization it'd probably be best to package it in your own RPM - we have some documentation on this here: How to Build and Install Custom RPMs - cPanel Knowledge Base - cPanel Documentation

As well as a tutorial here: Tutorial - Building Custom Packages For EasyApache 4


Thanks!

Thanks for your suggestions Lauren.
On consideration, with the probability that I would botch the job, or even if I succeeded would likely face future problems due to upgrades...
I decided to go an easy route, which hopefully can help others that are looking for a solution to brotli precompressed files.

The Apache mod_brotli being enabled also allows the use of the brotli executable, so I thought why can't I just use that to precompress what I want (CSS and JS files) with a simple command - it could even be automated for dynamically generated resources by adding the command to cPanel Cron.

Run this command by ssh terminal, and just set your /path-to-css-js-files/ - this will generate Brotli precompressed files in the same directory as the originals:

Code:
find /path-to-css-js-files/ \( -name "*.css" -o -name "*.js" \) -execdir /opt/cpanel/ea-brotli/bin/brotli --best '{}' \;
For cron, do the same command just add to the end >/dev/null 2>&1

Then the directives to make it work properly can be added to Apache configuration found at:
WHM: Home »Service Configuration »Apache Configuration »Include Editor
but I just added them to plain old htaccess in the document root. Here they are:

Code:
# ===== BEGIN BROTLI =====
# text/html removed to allow html cached gzip (supercache) - can add below if required.
# BROTLI Dynamic - Server Generated on-the-fly
<ifmodule mod_brotli.c>
    AddOutputFilterByType BROTLI_COMPRESS text/plain text/xml text/css text/javascript application/javascript
</ifmodule>
<IfModule mod_headers.c>
# BROTLI Static - Precompressed
# Serve brotli compressed CSS and JS files if they exist and the client accepts brotli.
    RewriteCond "%{HTTP:Accept-encoding}" "br"
    RewriteCond "%{REQUEST_FILENAME}\.br" "-s"
    RewriteRule "^(.*)\.(js|css)"              "$1\.$2\.br" [QSA]
# Serve correct content types, and prevent double compression.
    RewriteRule "\.css\.br$" "-" [T=text/css,E=no-brotli:1,E=no-gzip:1]
    RewriteRule "\.js\.br$"  "-" [T=text/javascript,E=no-brotli:1,E=no-gzip:1]
  <FilesMatch "(\.js\.br|\.css\.br)$">
# Serve correct encoding type.
    Header append Content-Encoding br
# Cache Control and Enable CORS
    ExpiresActive On
    ExpiresDefault  "access plus 1 month"
    Header set Cache-Control "public, immutable, max-age=2628000, s-maxage=2628000"
    Header set Access-Control-Allow-Origin "*"
    Header append Vary Accept-Encoding
  </FilesMatch>
</IfModule>
# ===== END BROTLI =====

# ===== BEGIN GZIP =====
# text/html removed to allow html cached gzip (supercache) - can add below if required.
# GZIP Dynamic - Server Generated on-the-fly
<ifmodule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/plain text/xml text/css text/javascript application/javascript
</ifmodule>
# GZIP Static - Precompressed
<IfModule mod_headers.c>
# Serve gzip compressed CSS and JS files if they exist and the client accepts gzip.
    RewriteCond "%{HTTP:Accept-encoding}" "gzip"
    RewriteCond "%{REQUEST_FILENAME}\.gz" -s
    RewriteRule "^(.*)\.(js|css)"              "$1\.$2\.gz" [QSA]
# Serve correct content types, and prevent double compression.
    RewriteRule "\.css\.gz$" "-" [T=text/css,E=no-gzip:1,E=no-brotli:1]
    RewriteRule "\.js\.gz$" "-" [T=text/javascript,E=no-gzip:1,E=no-brotli:1]
# Serve correct encoding type
    <FilesMatch "(\.js\.gz|\.css\.gz)$">
    Header append Content-Encoding gzip
# Cache Control and Enable CORS
    ExpiresActive On
    ExpiresDefault  "access plus 1 month"
    Header set Cache-Control "public, immutable, max-age=2628000, s-maxage=2628000"
    Header set Access-Control-Allow-Origin "*"
    Header append Vary Accept-Encoding
    </FilesMatch>
</IfModule>
# ===== END GZIP =====
Kick back, and enjoy the Brotli...


PS: Only small problem I have found, is I can't stop images from being brotli compressed, even after using the suggested:
Code:
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-brotli
which is also present in the brotli config at:
/etc/apache2/conf.d/brotli.conf
Not sure why...
 
  • Like
Reactions: cPanelLauren

gnetwork-cp

Member
Mar 1, 2016
23
6
3
Australia
cPanel Access Level
Root Administrator
Thanks for your suggestions Lauren.
On consideration, with the probability that I would botch the job, or even if I succeeded would likely face future problems due to upgrades...
I decided to go an easy route, which hopefully can help others that are looking for a solution to brotli precompressed files.

The Apache mod_brotli being enabled also allows the use of the brotli executable, so I thought why can't I just use that to precompress what I want (CSS and JS files) with a simple command - it could even be automated for dynamically generated resources by adding the command to cPanel Cron.

Run this command by ssh terminal, and just set your /path-to-css-js-files/ - this will generate Brotli precompressed files in the same directory as the originals:

Code:
find /path-to-css-js-files/ \( -name "*.css" -o -name "*.js" \) -execdir /opt/cpanel/ea-brotli/bin/brotli --best '{}' \;
For cron, do the same command just add to the end >/dev/null 2>&1

Then the directives to make it work properly can be added to Apache configuration found at:
WHM: Home »Service Configuration »Apache Configuration »Include Editor
but I just added them to plain old htaccess in the document root. Here they are:

Code:
# ===== BEGIN BROTLI =====
# text/html removed to allow html cached gzip (supercache) - can add below if required.
# BROTLI Dynamic - Server Generated on-the-fly
<ifmodule mod_brotli.c>
    AddOutputFilterByType BROTLI_COMPRESS text/plain text/xml text/css text/javascript application/javascript
</ifmodule>
<IfModule mod_headers.c>
# BROTLI Static - Precompressed
# Serve brotli compressed CSS and JS files if they exist and the client accepts brotli.
    RewriteCond "%{HTTP:Accept-encoding}" "br"
    RewriteCond "%{REQUEST_FILENAME}\.br" "-s"
    RewriteRule "^(.*)\.(js|css)"              "$1\.$2\.br" [QSA]
# Serve correct content types, and prevent double compression.
    RewriteRule "\.css\.br$" "-" [T=text/css,E=no-brotli:1,E=no-gzip:1]
    RewriteRule "\.js\.br$"  "-" [T=text/javascript,E=no-brotli:1,E=no-gzip:1]
  <FilesMatch "(\.js\.br|\.css\.br)$">
# Serve correct encoding type.
    Header append Content-Encoding br
# Cache Control and Enable CORS
    ExpiresActive On
    ExpiresDefault  "access plus 1 month"
    Header set Cache-Control "public, immutable, max-age=2628000, s-maxage=2628000"
    Header set Access-Control-Allow-Origin "*"
    Header append Vary Accept-Encoding
  </FilesMatch>
</IfModule>
# ===== END BROTLI =====

# ===== BEGIN GZIP =====
# text/html removed to allow html cached gzip (supercache) - can add below if required.
# GZIP Dynamic - Server Generated on-the-fly
<ifmodule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/plain text/xml text/css text/javascript application/javascript
</ifmodule>
# GZIP Static - Precompressed
<IfModule mod_headers.c>
# Serve gzip compressed CSS and JS files if they exist and the client accepts gzip.
    RewriteCond "%{HTTP:Accept-encoding}" "gzip"
    RewriteCond "%{REQUEST_FILENAME}\.gz" -s
    RewriteRule "^(.*)\.(js|css)"              "$1\.$2\.gz" [QSA]
# Serve correct content types, and prevent double compression.
    RewriteRule "\.css\.gz$" "-" [T=text/css,E=no-gzip:1,E=no-brotli:1]
    RewriteRule "\.js\.gz$" "-" [T=text/javascript,E=no-gzip:1,E=no-brotli:1]
# Serve correct encoding type
    <FilesMatch "(\.js\.gz|\.css\.gz)$">
    Header append Content-Encoding gzip
# Cache Control and Enable CORS
    ExpiresActive On
    ExpiresDefault  "access plus 1 month"
    Header set Cache-Control "public, immutable, max-age=2628000, s-maxage=2628000"
    Header set Access-Control-Allow-Origin "*"
    Header append Vary Accept-Encoding
    </FilesMatch>
</IfModule>
# ===== END GZIP =====
Kick back, and enjoy the Brotli...


PS: Only small problem I have found, is I can't stop images from being brotli compressed, even after using the suggested:
Code:
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-brotli
which is also present in the brotli config at:
/etc/apache2/conf.d/brotli.conf
Not sure why...
The compressed images problem was solved too. Just remove from the directive the section for:
AddOutputFilterByType BROTLI_COMPRESS

The filters that are set by brotli.conf have a higher priority, so no further mention of brotli_compress filter is required.
 
  • Like
Reactions: cPanelLauren