Skip to content

Instantly share code, notes, and snippets.

@tabacitu
Last active December 16, 2020 18:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tabacitu/2617674467fc1fc9aaa23073ba34e035 to your computer and use it in GitHub Desktop.
Save tabacitu/2617674467fc1fc9aaa23073ba34e035 to your computer and use it in GitHub Desktop.
How to Deploy a Laravel+Backpack project on Laravel Vapor

Note: HUGE thanks to @mwisner, he's the one who figured out the solution here, and put together the first solution here. This is just a rephrasing of his solution, as a step-by-step guide that I think will apply to most Backpack projects.

How to deploy a Laravel+Backpack project on Vapor

Step 1. Follow the Vapor docs to install vapor, vapor-core and maybe even vapor-ui. Normally you do that by running vapor init.


Step 2. Remember to create a database using Vapor. It might take a few minutes for AWS to create the db. During this time, it'll say "Provisioning" in your Vapor > Databases. In the meantime, you can do the next few steps.


Step 3. Inside your vapor.yml, make sure you point the environment(s) to the database(s) you are creating or have created.


Step 4. Inside your vapor.yml, choose to install the vendor folder separately using by adding the line below (without the plus). This is needed because the vendor/backpack/crud folder is quite big, since it also contains all the CSS and JS assets for all plugins you might want to use.

id: 3
name: backpack-demo-vapor
+separate-vendor: true
environments:
    production:
        memory: 1024

Step 5. By default Backpack publishes all CSS and JS assets you might ever need, both for Backpack and all its features, inside public/packages. Which adds up to ~4000 files. That's a problem, because Vapor only allows 300 files in the public folder. So if you try to publish a regular Laravel+Backpack project, you'll run into an error saying "Vapor applications may not have more than 300 public assets.". In this case, there's only one thing you can do - delete everything inside public/packages that you don't actually use. We're going to help you do that.


Step 5.0. In this process, you should be armed with the following commands:

# get the number of files
find public -type f -print | wc -l

# get a list of the subdirectories of public/packages with the number of files each contains:
cd public/packages
find . -type f | cut -d/ -f2 | sort | uniq -c

Step 5.1. Check which directories contain the most files, using the commands above in your project, to know which fields should have their CSS and JS stripped. At this moment (Dec 2020), here's the output of the two commands above:

  • number of files - 3771
  • list of subdirectories with file count for each:
   6 @digitallyhappy
   1 animate.css
  20 backpack
  10 bootstrap-colorpicker
  97 bootstrap-datepicker
   2 bootstrap-daterangepicker
 162 bootstrap-iconpicker
2654 ckeditor
   6 cropperjs
   4 datatables.net
   5 datatables.net-bs4
   4 datatables.net-fixedheader
   5 datatables.net-fixedheader-bs4
   4 datatables.net-responsive
   5 datatables.net-responsive-bs4
   2 easymde
  78 jquery-colorbox
   4 jquery-cropper
  19 jquery-ui-dist
  77 line-awesome
   8 moment
  12 nestedSortable
  15 noty
   3 pc-bootstrap4-datetimepicker
  12 places.js
  66 select2
   2 select2-bootstrap-theme
   2 simplemde
  97 source-sans-pro
 165 summernote
 224 tinymce

That means we MUST delete the assets for the WYSIWYG editors and the fonts, since those have a large number of files.

Step 5.2. Let's automate deleting the unnecessary CSS and JS, upon deployment. Let's create a new file, vapor_build_purge.sh, in the root of the project, that will do just that:

#!/usr/bin/env bash
#
# copy backpack assets from vendor to the public folder
rm -rf public/packages || true
cp -r  vendor/backpack/crud/src/public/packages public/packages

# count how many CSS and JS assets are there at this moment
# whatever that number is, we have to drop it to under 300 
# to abide by Laravel Vapor's limitation
find public -type f -print | wc -l

# -----------------------------------
# start deleting stuff you don't need
# -----------------------------------
# definitely don't need this fluff
find public/packages -name '*.md' -delete
find public/packages -name '*.html' -delete
find public/packages -name '*.txt' -delete
find public/packages -name '*.json' -delete
find public/packages -name '*.gzip' -delete
find public/packages -name '*.map' -delete
# delete the assets for the fields & filters you're not using
rm -rf public/packages/ckeditor # 2654 files
rm -rf public/packages/tinymce # 224 files
rm -rf public/packages/summernote # 165 files
rm -rf public/packages/bootstrap-iconpicker # 162 files
rm -rf public/packages/source-sans-pro # 97 files
rm -rf public/packages/bootstrap-datepicker # 97 files
rm -rf public/packages/jquery-colorbox # 78 files
rm -rf public/packages/line-awesome # 77 files
rm -rf public/packages/select2/dist/js/i18n # 60 files
rm -rf public/packages/nestedSortable # 12 files
rm -rf public/packages/places.js # 12 files
rm -rf public/packages/bootstrap-colorpicker # 10 files
rm -rf public/packages/cropperjs # 6 files
rm -rf public/packages/jquery-cropper # 4 files
rm -rf public/packages/pc-bootstrap4-datetimepicker # 3 files
rm -rf public/packages/simplemde # 2 files
rm -rf public/packages/bootstrap-daterangepicker # 2 files

# count how many files there are now
find public -type f -print | wc -l

Now let's add that file as a build hook in our vapor.yml file, so that it always gets run before the actual deployment:

id: 3
name: backpack-fresh-on-vapor
separate-vendor: true
environments:
    production:
        memory: 1024
        cli-memory: 512
        runtime: php-7.4
        database: fresh
        build:
            - 'COMPOSER_MIRROR_PATH_REPOS=1 composer install --no-dev'
            - 'php artisan event:cache'
+           - 'sh vapor_build_purge.sh'

Now whenever we run vapor deploy production it will run that file before pushing everything to the servers. So we have it set up to do that, now let's customize and test it locally to make sure the number of files it deletes is enough.

Step 5.3. Change the vapor_build_purge.sh file according to your needs. Delete as many things as you can - it's a long way from ~3800 to ~300. Comment out the folders you DO need, so that they don't get removed.

Step 5.4. Add the fonts to all your pages from a CDN. Inside your config/backpack/base.php file you'll find a styles key, containing the CSS files that are loaded on ALL page loads. Since you've definitely removed the line-awesome and source-sans-pro directories, let's make Backpack load those fonts from CDNs, on each pageload:

-        // Load the fonts separately (so that you can replace them at will):
-        'packages/source-sans-pro/source-sans-pro.css',
-        'packages/line-awesome/css/line-awesome.min.css',
+        // Load the fonts from CDNs:
+        'https://cdn.jsdelivr.net/npm/source-sans-pro@3.6.0/source-sans-pro.css',
+        'https://cdn.jsdelivr.net/npm/line-awesome@1.3.0/dist/line-awesome/css/line-awesome.min.css',

Step 5.5. Check how many files you're down to, by running the script (sh vapor_build_purge.sh). The example file drops the number of files from 3771 to 83. Which will definitely be allowed by Laravel Vapor. If you're not under 300, find something else to delete, then run the script again to check.

If you ABSOLUTELY need a field, but hosting its assets is impossible (for example ckeditor contains 2654 files), you should:

  • publish that particular field type in your project, using php artisan backpack:publish crud/fields/ckeditor
  • open the file that was published to your resources/views/vendor/backpack/crud/fields/ckeditor
  • replace the paths to the CSS/JS assets with their equivalent from CDNs
  • delete the assets by making sure they're not commented out in vapor_build_purge.sh

Step 6. If you started this project before 2020 and then upgraded to the latest Laravel, make sure you've also upgraded your artisan and public/index.php files. Check the source code for those files in https://github.com/laravel/laravel and in your own project and if they're not the same, copy-paste to update them. Otherwise you might get an error saying "Fatal error: require(): Failed opening required '/var/task/bootstrap/../vendor/autoload.php'". Details here. Might want to run a composer dump-autoload too afterwards, and to make sure your application is still running fine on localhost (test in your browser).


Step 7. Hopefully by now AWS has created your database. If so, make sure to finish up your vapor.yml configuration as you normally would (e.g. adding build and deply hooks), then run vapor deploy production or whatever environment you want to deploy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment