community-forum icon indicating copy to clipboard operation
community-forum copied to clipboard

How to deploy Laravel+Backpack to Laravel Vapor

Open mwisner opened this issue 6 years ago • 20 comments

Bug report

I'm not really sure if this is a Larval Vapor, or Laraval Backpack issue... but I figured I would start here.

Problem 1 Build size

For Laravel Vapor, your application must be less than 45MB compressed. the packages provided by backpack take up a considerable amount of that.

Workaround solution: Delete the packages from the vendor file before uploading.

    build:
      - 'rm -rf vendor/backpack/crud/src/public/packages'

Docs: https://docs.vapor.build/1.0/projects/deployments.html#build-hooks

Problem 2: Exception during initialization

Looks like $_SERVER['REMOTE_ADDR'] isn't set at this point.

Caching Laravel configuration[2019-10-02 13:57:34] staging.ERROR: Undefined index: REMOTE_ADDR {"exception":"[object] (ErrorException(code: 0): Undefined index: REMOTE_ADDR at /var/task/vendor/backpack/crud/src/LicenseCheck.php:22)

17:57:34
[stacktrace]

17:57:34
#0 /var/task/vendor/backpack/crud/src/LicenseCheck.php(22): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleError(8, 'Undefined index...', '/var/task/vendo...', 22, Array)

17:57:34
Laravel-Backpack/CRUD#1 /var/task/vendor/backpack/crud/src/BackpackServiceProvider.php(45): Backpack\\CRUD\\BackpackServiceProvider->checkLicenseCodeExists()

17:57:34
Laravel-Backpack/CRUD#2 [internal function]: Backpack\\CRUD\\BackpackServiceProvider->boot(Object(Illuminate\\Routing\\Router))

17:57:34
Laravel-Backpack/CRUD#3 /var/task/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(32): call_user_func_array(Array, Array)

17:57:34
Laravel-Backpack/CRUD#4 /var/task/vendor/laravel/framework/src/Illuminate/Support/helpers.php(522): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()

17:57:34
Laravel-Backpack/CRUD#5 /var/task/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(90): value(Object(Closure))

17:57:34
Laravel-Backpack/CRUD#6 /var/task/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(34): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))

17:57:34
Laravel-Backpack/CRUD#7 /var/task/vendor/laravel/framework/src/Illuminate/Container/Container.php(591): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)

17:57:34
Laravel-Backpack/CRUD#8 /var/task/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(828): Illuminate\\Container\\Container->call(Array)

17:57:34
Laravel-Backpack/CRUD#9 /var/task/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(811): Illuminate\\Foundation\\Application->bootProvider(Object(Backpack\\CRUD\\BackpackServiceProvider))

17:57:34
Laravel-Backpack/CRUD#10 [internal function]: Illuminate\\Foundation\\Application->Illuminate\\Foundation\\{closure}(Object(Backpack\\CRUD\\BackpackServiceProvider), 15)

17:57:34
Laravel-Backpack/CRUD#11 /var/task/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(812): array_walk(Array, Object(Closure))

17:57:34
Laravel-Backpack/CRUD#12 /var/task/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/BootProviders.php(17): Illuminate\\Foundation\\Application->boot()

17:57:34
Laravel-Backpack/CRUD#13 /var/task/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(211): Illuminate\\Foundation\\Bootstrap\\BootProviders->bootstrap(Object(Illuminate\\Foundation\\Application))

17:57:34
Laravel-Backpack/CRUD#14 /var/task/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(320): Illuminate\\Foundation\\Application->bootstrapWith(Array)

17:57:34
Laravel-Backpack/CRUD#15 /var/task/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(271): Illuminate\\Foundation\\Console\\Kernel->bootstrap()

17:57:34
Laravel-Backpack/CRUD#16 /var/task/fpmRuntime.php(65): Illuminate\\Foundation\\Console\\Kernel->call('config:cache')

17:57:34
Laravel-Backpack/CRUD#17 /var/task/vendor/laravel/framework/src/Illuminate/Support/helpers.php(548): {closure}(Object(Illuminate\\Foundation\\Application))

17:57:34
Laravel-Backpack/CRUD#18 /var/task/fpmRuntime.php(66): with(Object(Illuminate\\Foundation\\Application), Object(Closure))

17:57:34
Laravel-Backpack/CRUD#19 /var/task/runtime.php(28): require('/var/task/fpmRu...')

17:57:34
Laravel-Backpack/CRUD#20 /opt/bootstrap.php(6): require('/var/task/runti...')

17:57:34
Laravel-Backpack/CRUD#21 {main}

Problem 3: Too many public assets

Due to the number of public package files published in the Laravel Backpack admin theme, (4191) (find packages -print | wc -l), Laravel Backpack cannot be deployed to https://vapor.laravel.com.

Laravel Vapor has a requirement of a max of 300 public assets.


Project built successfully. (0m24s)

==> Uploading Deployment Artifact (28.12MB)
 28792KB/28792KB [============================] 100% (< 1 sec remaining)


Whoops! There were some problems with your request.

    - Vapor applications may not have more than 300 public assets.

What I did

  • Attempt to deploy Backpack to our Laravel Vapor deployment.
  • Attempted to delete any of the packages I thought weren't necessary for our deployment... I was only able to get down to around 600 files.

Backpack, Laravel, PHP, DB version

When I run php artisan backpack:version the output is:

### PHP VERSION:
PHP 7.3.10 (cli) (built: Sep 30 2019 19:59:06) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.10, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.3.10, Copyright (c) 1999-2018, by Zend Technologies

### LARAVEL VERSION:
laravel/framework                      v6.0.4     The Laravel Framework.

### BACKPACK VERSION:
backpack/crud                          4.0.5      Quickly build an admin in...
backpack/generators                    2.0.4      Generate files for larave...
vapor --version
Laravel Vapor 1.3.0

mwisner avatar Oct 02 '19 17:10 mwisner

Hello there! Thanks for opening your first issue on this repo!

Just a heads-up: Here at Backpack we use Github Issues only for tracking bugs. Talk about new features is also acceptable. This helps a lot in keeping our focus on improving Backpack. If you issue is not a bug/feature, please help us out by closing the issue yourself and posting in the appropriate medium (see below). If you're not sure where it fits, it's ok, a community member will probably reply to help you with that.

Backpack communication mediums:

  • Bug Reports, Feature Requests - Github Issues (here);
  • Quick help (How do I do X) - Gitter Chatroom;
  • Long questions (I have done X and Y and it won't do Z wtf) - Stackoverflow, using the backpack-for-laravel tag;

Please keep in mind Backpack offers no official / paid support. Whatever help you receive here, on Gitter, Slack or Stackoverflow is thanks to our awesome awesome community members, who give up some of their time to help their peers. If you want to join our community, just start pitching in. We take pride in being a welcoming bunch.

Thank you!

-- Justin Case The Backpack Robot

welcome[bot] avatar Oct 02 '19 17:10 welcome[bot]

i didn't use vapor yet but with a little search i found that blog.laravel.com

iMokhles avatar Oct 02 '19 18:10 iMokhles

Hi @iMokhles, thanks for pointing that blog post out.

I added another issue that I forgot about solving the issue description. Basically, to work around this all I did was remove the packages from build during deployment.

https://docs.vapor.build/1.0/projects/deployments.html#build-hooks

mwisner avatar Oct 02 '19 20:10 mwisner

PR Added to solve problem 2. (https://github.com/Laravel-Backpack/CRUD/pull/2119)

Now working on some sort of asset solution

mwisner avatar Oct 02 '19 20:10 mwisner

So this only works if you use only the most basic of packages provided by Laravel backpack. If you're using something like CKE-editor I am not confident you'll be able to get below 300 assets.

What I did was write a janky script that removes all sorts of files during the Laravel Vapor build step.

You can find a rough idea of what I did here:

https://gist.github.com/mwisner/35b0088f9d4ae24911fc69452338d98a

using this I was able to go from 4k+ assets down to around 150.

Using this script + my fork that fixes the missing IP issue I am able to get Backpack running great using Larvel Vapor.

mwisner avatar Oct 16 '19 17:10 mwisner

Hi @mwisner ,

Thanks a lot for posting about your problems and progress with Vapor here. I'm 100% sure people will find this useful. And I do think it's important to be able support Vapor - so we definitely should make it seamless to deploy projects that use Backpack on Vapor. Let's see how we can best do that.

Problem 1. I think this will be solved by installing vendors separately in Vapor. Please correct me if I'm wrong.

Problem 2. I've just merged your PR for it. Thank you!

Problem 3. This one is painful 😄

You see, in v3 we were using CDNs to load CSS&JS assets, which would solve the public folder size problem. Most jQuery plugin assets weren't in the folder at all. However, in v4 we pulled in everything using npm, and published the assets in the public folder, so Backpack can be used on intranets with no internet connection. Plus, it's a security/privacy improvement - nothing's as safe&private as hosting the assets yourself. Now, the trick is to find a solution that solves both problems (use on intranets AND deploy on Vapor).

(Solution A) For now, I see only one possible long-term solution. We could create a big-ass-bundle that includes all assets needed for fields - fields.bundle.js and fields.bundle.css. But:

  • the bundle files would be HUGE; it would make the first page load very VERY slow, and basically cancel out a BIG benefit of running a server-side rendering (loading assets as they're needed, instead of loading a bunch of JS that few pages use);
  • it would be uncomfortable to add new items to the bundle, if you create a new field type (you'd have to edit a file, and run laravel mix); so the workflow would be as unconfortable as running a SPA;

Because this solution cancels out something I love about Backpack - the ease of customization, I don't really like it. We could do it as opt-in, to only make it more difficult for people who use Vapor (a minority), but... it wouldn't be a great experience for them either.

I'll think about this some more, try a few things, and get back to you. If anybody has a better idea, please let us know.

(Solution B) Just thought of this - if we can have all public assets in the vendor folder (Problem 1 solved by having the vendors separately instead of having to delete somthing from it), maybe we can just:

  • not have the public/packages folder in the repo (gitignore it);
  • publish the CSS and JS assets from vendor upon deployment; this should be as simple as having this in our deployment process
php artisan vendor:publish --provider="Backpack\CRUD\BackpackServiceProvider" --tag="minimum"
php artisan vendor:publish --provider="Prologue\Alerts\AlertsServiceProvider"
# maybe, if it's used
php artisan elfinder:publish

(of course, we can make a command that does all that, something like php artisan backpack:publish-packages)

What do you think of Solution B @mwisner ?

tabacitu avatar Nov 18 '19 08:11 tabacitu

Just thought of a way to reduce the /vendor/ directory size in production:

We don’t really need all CSS and JS in the vendor folder in production, do we? They’re not really used from vendor there. We could split that into a different package, that’s only required-dev in composer. That would install it on localhost, where you publish the assets, but not in production, where you don’t.

Food for thought.

tabacitu avatar Dec 09 '19 05:12 tabacitu

Is there any temporary solution to this before version 4.2? I bought a license but now can not use it. Thanks

baj84 avatar Dec 13 '20 07:12 baj84

@baj84 the solution given by @mwisner works as he said.

We haven't implemented it yet, and like you already know, we are feature freeze during last months trying to get backpack buggy-free the most we can.

As you should understand it is not the best interest of our users if we ship new features with previous bugs unresolved. Some are damn tricky bastards.

So you should be able to deploy to vapor if you run the script to clear the assets until we fix it in the root, that, like you said, we can only do in 4.2 because it will be a breaking change.

Let me know if you need further assistance.

Best, Pedro

pxpm avatar Dec 14 '20 13:12 pxpm

@baj84 I agree with your that we should have a clearer process for this. I've made a note to go through the process myself and write a tutorial for it. But it might take a while - like Pedro said we're currently focused on getting to inbox zero in terms of issues (this is one of the issues though 😂).

For now it should be possible to:

Alternatively, a possibly better process (if you don't ever edit the JS files Backpack comes with, or use FileManager) would be to:

Personally I prefer the second option. Can't wait to use Vapor ourselves 🥳 Let us know what you think of Vapor once you use it for your Laravel+Backpack project.

tabacitu avatar Dec 14 '20 14:12 tabacitu

@baj84 I agree with your that we should have a clearer process for this. I've made a note to go through the process myself and write a tutorial for it. But it might take a while - like Pedro said we're currently focused on getting to inbox zero in terms of issues (this is one of the issues though 😂).

For now it should be possible to:

* [install vendors separately in Vapor](https://blog.laravel.com/vapor-reusable-vendors)

* publish the assets upon deployment

Alternatively, a possibly better process (if you don't ever edit the JS files Backpack comes with, or use FileManager) would be to:

* [install vendors separately in Vapor](https://blog.laravel.com/vapor-reusable-vendors)

* create an alias from `public/packages` to `vendor/backpack/crud/public/packages` - see [point 3 here](https://backpackforlaravel.com/articles/tips-and-tricks/once-in-a-while-re-publish-backpack-s-css-and-js-assets)

Personally I prefer the second option. Can't wait to use Vapor ourselves 🥳 Let us know what you think of Vapor once you use it for your Laravel+Backpack project.

How to create a symlink in vapor to the vendor folder?? while deploying vapor treats the symlink as a real folder and says the same message "Vapor applications may not have more than 300 public assets. "

IsmailAshour avatar Dec 15 '20 17:12 IsmailAshour

@tabacitu aftor alot of tries I think two solutions not working .

IsmailAshour avatar Dec 15 '20 18:12 IsmailAshour

@drashoor , you're right. I just tried the method I suggested - the alias to the public/packages folder, and it didn't work for me either. Not because Vapor still thinks it's more than 300 items (it passed that part just fine) but because Vapor still thinks the assets are in the S3 bucket where the public assets are hosted. Which... is false. So the admin panel ends up with no CSS and no JS loaded, and the looks (and is) broken. So no, that's NOT a working solution. However...

Working Solution

I tried using @mwisner 's purge method above, and it worked very well for me. Here's a Laravel + Backpack install with just one CRUD for Users, so you can see it's all working fine: https://mythic-ocean-xadvunxvs9cz.vapor-farm-c1.com/admin/login 🥳 I'll probably delete this in a few days, I'll leave it up until then so you can see it's actually working, deployed and hosted using Laravel Vapor.

Thanks again @mwisner for the solution! Kudos to you for making it public so others can do that too!

Important Caveat

Of course @mwisner purge technique has a big downside: you have to delete the CSS and JS for the Backpack fields you're not using, to reduce the number of assets from about ~3800 to 300.

That means, this is not a one-size-fits-all solution. It requires quite a bit of tinkering to deploy a Laravel+Backpack project on Vapor. But then again, it that's true for any Laravel project - because of limitations imposed by either AWS or Lambda. This shouldn't be a big problem though, since projects where Vapor makes economic sense are only BIG projects, with a lot of users - hence a lot of resources. And it's a tinkering you do just once. For small/medium projects Laravel Vapor does NOT make sense at all - it will cost considerably more that a DigitalOcean droplet, for no benefits. Small projects don't need scaling, so they don't need Laravel Vapor.

Step-by-step Guide

I've tried to make this as smooth as possible for anybody doing this. And after a lot of trial&error I ended up writing this guide, as a gist. Please let me know what you think about it, if it works for you and if we should add anything else. Definitely comment there with your code if you

  • customize any files or filters to load the CSS/JS from CDNs
  • implement file uploads (I know that's totally different on Vapor)

Hope it helps! Let me know how it goes 😀🤞

tabacitu avatar Dec 16 '20 18:12 tabacitu

Aaaand right after I spent hours tinkering with that solution, I see this came out 😅 https://blog.laravel.com/vapor-docker-based-deployments

tabacitu avatar Dec 17 '20 04:12 tabacitu

After studying docker-based deployments on Laravel Vapor, I think we have a winner! It should allow us to install a large Laravel app (like one that uses Backpack) without any downsides, without having to delete CSS&JS files. I think that's a much better solution than my 7-step guide.

I haven't tried it yet, though... If anybody tries it, please leave feedback here, let us know how it went. I'll do the same.

Cheers!

tabacitu avatar Dec 17 '21 03:12 tabacitu

Just tested with vapor docker runtime, and it seems the issue still persist. from taylor's tweat, this seems a limitation within vapor, maybe we shall bypass it from override vapor CLI (well the first option is reduce number of files for sure.)

wanghanlin avatar Mar 21 '22 10:03 wanghanlin

https://blog.laravel.com/vapor-unlimited-assets-uploads-10x-faster

sometimes you wait and it magically solves itself 🤣

ziming avatar May 13 '22 14:05 ziming

Haha I love it when that happens! 🎉🎉🎉

We still have to test and make sure it all works, before we close this issue. And probably write a guide about it, or a blog article, or something.

If anybody does try Backpack on Vapor after the change above, please let us know. We're also open to publishing an article about it on our blog, if you wanna do that...

tabacitu avatar May 16 '22 16:05 tabacitu

Wish we could test it, but we are still on EC2 over at my place.

Look forward to the positive news to whoever testing it!

ziming avatar May 16 '22 16:05 ziming

@promatik is going to test this again, on v6. With the steps here I'm pretty sure we have a clear and valid way of deploying Backpack on Vapor.

But.

We need to make it even more clear. And have it documented in the Backpack docs. Official support.

tabacitu avatar Sep 04 '23 12:09 tabacitu