tQuant / yii2-asset-combiner

Yii 2 extension to compress and concatenate assets
Other
4 stars 4 forks source link

use of shell_exec by www-data user in production #5

Closed dbd5 closed 5 years ago

dbd5 commented 5 years ago

Hi @tQuant ,

While trying to setup this combiner in production, I had the error "Failed to process JS files by UglifyJs with command: uglifyjs".

I have looked at the code, it seems to fail at public function process() in the filter in use perhaps due to permissions that the apache user (www-data:www-data) may not have in the destination directory, please correct me if am wrong.

Please advise me on the following questions

  1. Should www-data user be able to use shell_exec to write considering the risks if the server is hacked? Is it safe to grant www-data user such permission?

  2. If not, is there a safe work around for the filter to process and combine the files?

  3. If the files don't get regenerated unless changes are made, will it be ok to copy config/assets.php as well as everything in web/assets/ac to the production server and then somehow turn off the the filter->process() functions and use the locally combined files.

  4. If question 3 is a viable option, will the already combined files include external assets registered by other plugins?

I have included the stack trace at the end of this issue in the hope that it will help clarify the issue.

Thank you for your time

Adam


Failed to process JS files by UglifyJs with command: uglifyjs '/var/www/localservice/frontend/web/assets/49839e72/jquery.js' '/var/www/localservice/frontend/web/assets/335d1ca6/yii.js' '/var/www/localservice/frontend/web/libraries/owl.carousel/owl.carousel.min.js' ... '/var/www/localservice/frontend/web/js/app.js' '/var/www/localservice/frontend/web/js/custom.js' -o '/var/www/localservice/frontend/web/assets/ac/f194523b-eb949a0a.js' --compress

yii\base\Exception: Failed to process files with filter 'AssetCombiner\filters\UglifyJsFilter' in /var/www/localservice/vendor/tquant/yii2-asset-combiner/src/AssetCombinerTrait.php:186

Stack trace:

0 /var/www/localservice/vendor/tquant/yii2-asset-combiner/src/AssetCombinerBehavior.php(138): AssetCombiner\AssetCombinerBehavior->writeFiles(Array, 'js')

1 /var/www/localservice/vendor/tquant/yii2-asset-combiner/src/AssetCombinerBehavior.php(82): AssetCombiner\AssetCombinerBehavior->assembleMonolith(Array)

2 [internal function]: AssetCombiner\AssetCombinerBehavior->combineBundles(Object(yii\base\Event))

3 /var/www/localservice/vendor/yiisoft/yii2/base/Component.php(627): call_user_func(Array, Object(yii\base\Event))

4 /var/www/localservice/vendor/yiisoft/yii2/web/View.php(158): yii\base\Component->trigger('endBody')

5 /var/www/localservice/frontend/views/layouts/_clear.php(108): yii\web\View->endBody()

6 /var/www/localservice/vendor/yiisoft/yii2/base/View.php(348): require('/var/www/locals...')

7 /var/www/localservice/vendor/yiisoft/yii2/base/View.php(257): yii\base\View->renderPhpFile('/var/www/locals...', Array)

8 /var/www/localservice/vendor/yiisoft/yii2/widgets/ContentDecorator.php(79): yii\base\View->renderFile('/var/www/locals...', Array)

9 /var/www/localservice/vendor/yiisoft/yii2/base/Widget.php(109): yii\widgets\ContentDecorator->run()

10 /var/www/localservice/vendor/yiisoft/yii2/base/View.php(521): yii\base\Widget::end()

11 /var/www/localservice/frontend/views/layouts/base.php(48): yii\base\View->endContent()

12 /var/www/localservice/vendor/yiisoft/yii2/base/View.php(348): require('/var/www/locals...')

13 /var/www/localservice/vendor/yiisoft/yii2/base/View.php(257): yii\base\View->renderPhpFile('/var/www/locals...', Array)

14 /var/www/localservice/vendor/yiisoft/yii2/widgets/ContentDecorator.php(79): yii\base\View->renderFile('/var/www/locals...', Array)

15 /var/www/localservice/vendor/yiisoft/yii2/base/Widget.php(109): yii\widgets\ContentDecorator->run()

16 /var/www/localservice/vendor/yiisoft/yii2/base/View.php(521): yii\base\Widget::end()

17 /var/www/localservice/frontend/views/layouts/main-wp-slider-horizontal.php(57): yii\base\View->endContent()

18 /var/www/localservice/vendor/yiisoft/yii2/base/View.php(348): require('/var/www/locals...')

19 /var/www/localservice/vendor/yiisoft/yii2/base/View.php(257): yii\base\View->renderPhpFile('/var/www/locals...', Array)

20 /var/www/localservice/vendor/yiisoft/yii2/base/Controller.php(399): yii\base\View->renderFile('/var/www/locals...', Array, Object(frontend\controllers\SiteController))

21 /var/www/localservice/vendor/yiisoft/yii2/base/Controller.php(385): yii\base\Controller->renderContent('\n<div style="mi...')

22 /var/www/localservice/frontend/controllers/SiteController.php(435): yii\base\Controller->render('index', Array)

23 [internal function]: frontend\controllers\SiteController->actionIndex('map-vertical-se...')

24 /var/www/localservice/vendor/yiisoft/yii2/base/InlineAction.php(57): call_user_func_array(Array, Array)

25 /var/www/localservice/vendor/yiisoft/yii2/base/Controller.php(157): yii\base\InlineAction->runWithParams(Array)

26 /var/www/localservice/vendor/yiisoft/yii2/base/Module.php(528): yii\base\Controller->runAction('index', Array)

27 /var/www/localservice/vendor/yiisoft/yii2/web/Application.php(103): yii\base\Module->runAction('site/index', Array)

28 /var/www/localservice/vendor/yiisoft/yii2/base/Application.php(386): yii\web\Application->handleRequest(Object(yii\web\Request))

29 /var/www/localservice/frontend/web/index.php(19): yii\base\Application->run()

30 {main}

tQuant commented 5 years ago

Hi, The best option for production server is "Combined compilation" https://github.com/tQuant/yii2-asset-combiner/blob/master/README.md#combined-compilation

You can set trigger on git pull or other ways, that will run the command "php yii asset-combiner config/assets.php" under a user with sufficient rights That command will minify the assets. Afterwards web application under the "www-data" user will combine minified assets without need to use shell_exec

This option will work faster than compilation on the fly, because each asset will by minified only once, when you upload chenges on production. All further work will go with minified assets and will consist only of concatenation of different combinations of files for different pages.

dbd5 commented 5 years ago

I've tested that on localhost and it works, thanks.

Please help me with an idea to push for better performance because really, the user waiting for the concatenation of different combinations with each page reload makes for a poor experience, caching doesn't appear to be helping in my testing.

What if the first time assets are concatenated for a combination, the CSS and JS bundles created are saved to a name matching the route so next time that route is selected by the user, the previously concatenated bundles matching the route are loaded and returned without any delay from asset concatenation?

Do you think this will improve performance?

tQuant commented 5 years ago

Simple concatination is pretty fast and its caching 10-15 ms - for the first time 1-2 ms - for the rest

Are you sure that you disable minifying in the web application

You can see execution time in the performance log

23:05:35.847 1.3 ms AssetCombiner\AssetCombinerBehavior::combineBundles →Combine bundles for page
dbd5 commented 5 years ago

These times are impressive! Perhaps my VM is slowing things down.

Yes I disabled minifying by commenting out filterJs and filterCss in $app/main.php/components/view/as assetCombiner.

dbd5 commented 5 years ago

Sorry to bother you once again;

"...You can see execution time in the performance log";

I'd like to reproduce these performance after tweaking my environment. Which performance log is this?

Thanks

tQuant commented 5 years ago

Yii debug panel https://c2n.me/40O6kRk Section "Profiling"

dbd5 commented 5 years ago

Thanks