a1comms / gae-support-l5
Google App Engine & Local SDK Support for Laravel 5.1 apps.
Requires
- php: >=5.4.0
- google/apiclient: ^2.0
- illuminate/session: ~5.1
- illuminate/support: ~5.1
- league/flysystem: ~1.0
- tomwalder/php-gds: v2.1.0
Requires (Dev)
- illuminate/console: ~5.1
- phpunit/phpunit: ~4.4
README
Local SDK Support
This package has been changed from shpasser's version for more compatibility for those working with the local GAE SDK.
Google App Engine(GAE) Support package for Laravel 5.1.
Currently supported features:
- Generation of general configuration files,
- DataStore persistent session handler,
- Mail service provider,
- Queue service provider,
- Database connection,
- Filesystem,
- StackDriver Trace API
For Lumen see https://github.com/a1comms/GaeSupportLumen.
Installation
Pull in the package via Composer.
"require": { "a1comms/gae-support-l5": "~5.1" }
Then include the service provider within config/app.php
.
'providers' => [ Shpasser\GaeSupportL5\GaeSupportServiceProvider::class ];
Usage
Generate the GAE related files/entries.
Command template:
php artisan gae:setup --config --cache-config --bucket="your-bucket-id" --db-socket="cloud-sql-instance-socket-connection-string" --db-name="cloud-sql-database-name" --db-host="cloud-sql-instance-ipv4-address" app-id
Arguments and Options:
php artisan gae:setup [options] [--] app-id Arguments: app-id GAE application ID. Options: --config Generate "app.yaml" and "php.ini" config files. --cache-config Generate cached Laravel config file for use on Google App Engine. --bucket=BUCKET Use the specified GCS-bucket instead of the default one. --db-socket=DB-SOCKET Cloud SQL socket connection string for production environment. --db-name=DB-NAME Cloud SQL database name. --db-host=DB-HOST Cloud SQL database host IPv4 address for local environment.
--cache-config
option generates cached config file for GAE. This option is essential, because cached config file generated by php artisan config:cache
is not suitable for use on GAE. As well, cached config file generated for GAE probably will not work in local environment. This option should be used to generate cached config file before application is deployed on GAE.
--bucket
option defines the GCS-bucket ID to be used by the application for storage. Default GCS bucket is configured unless the option is used.
When --db-name
option is defined at least one of --db-socket
or --db-host
should
be also defined.
--db-socket
is set using the following format: /cloudsql/<app-id>:<cloud-sql-instance-name>
. Where <cloud-sql-instance-name>
is the Cloud SQL instance name and <app-id>
is the name of the application it belongs to.
Persistent Sessions in DataStore
We've included a session driver using DataStore for persistence, cached by memcache for faster access times and reduced billing, giving you the best of both worlds when it comes to speed and persistence.
To make use of this, set:
SESSION_DRIVER=gae
in.env
This should work without needing to enable billing as long as you don't have heavy usage, as minimal DataStore usage is included free.
You'll probably also want to enable garbage collection to clear out old sessions, which to keep billing at a minimum, we suggest to run once every 24 hours. This will delete any sessions that haven't been updated in 1 week.
To do this, create a cron.yaml
file that calls /gae/sessiongc
, for example:
cron: - description: daily session clearout url: /gae/sessiongc schedule: every day 00:00
If you don't require persistence and are happy with purely memcached, please see the previous session documentation below.
The mail driver configuration can be found in config/mail.php
and .env.production
,
these configuration files are modified / generated by the artisan command. There is
no need in any kind of custom configuration. All the outgoing mail messages are sent
with sender address of an administrator of the application, i.e. admin@your-app-id.appspotmail.com
.
The sender
, to
, cc
, bcc
, replyTo
, subject
, body
and attachment
parts of email message are supported.
Queues
The modified queue configuration file config/queue.php
should contain:
return array( ... /* |-------------------------------------------------------------------------- | GAE Queue Connection |-------------------------------------------------------------------------- | */ 'connections' => array( 'gae' => array( 'driver' => 'gae', 'queue' => 'default', 'url' => '/tasks', 'encrypt' => true, ), ... ), );
The 'default' queue and encryption are used by default.
In order to use the queue your app/Http/routes.php
file should contain the following route:
Route::post('tasks', array('as' => 'tasks', function() { return Queue::marshal(); }));
This route will be used by the GAE queue to push the jobs. Please notice that the route and the GAE Queue Connection 'url' parameter point to the same URL. Since the requests submitted using the route are issued by GAE itself it cannot be CSRF-protected. For more information on the matter please see http://laravel.com/docs/5.0/queues#push-queues.
Cache, Session and Log
Cache, Session and Log components are supported via the use of specific drivers / handlers:
- Cache - using the 'memcached' driver,
- Session - using the 'memcached' driver (or 'gae' for DataStore backed persistence, see above),
- Log - using 'syslog' handler.
The configuration options for the mentioned drivers / handlers are generated by the artisan command
and can be found in .env.production
configuration file.
Database
Google Cloud SQL is supported via Laravel's MySql driver. The connection configuration is added by
the artisan command to config/database.php
under cloudsql
. The connection parameters can be
configured using --db-socket
, --db-name
and --db-host
options via the artisan command.
The database related environment variables are set in .env.production
and .env.local
files.
The production
environment is configured to use the socket connection while the local
configured
to connect via the IPv4 address of the Google Cloud SQL instance. Use Google Developers Console in
order to obtain the socket connection string and enable the IPv4 address of your database instance.
The migrations are supported while working in local
environment only.
To use either the production
or the local
environment rename the appropriate file to .env
.
Filesystem
In order to support Laravel filesystem on GAE the artisan command modifies config/filesystem.php
to include an additional disk:
'gae' => [ 'driver' => 'gae', 'root' => storage_path().'/app', ],
and adds the following line to .env.production
file:
FILESYSTEM = gae
Optimizations
The optimizations allow the application to reduce the use of GCS, which is the only read-write storage available on GAE platform as of now.
In order to optimize view compilation the included cachefs
filesystem can be used to store
compiled views using memcached
service. cachefs
does not provide the application with a
reliable storage solution, information stored using memcached
is managed according to
memcached
rules and may be deleted when memcached
decides to. Since the views can
be compiled again without any information loss it is appropriate to store compiled
views using cachefs
.
cachefs
has the following structure:
/ +-- bootstrap +-- cache +-- framework +-- views
'/framework/views' is used to store the compiled views.
Use the following option to enable the feature in .env.production
and/or .env.local
file:
CACHE_COMPILED_VIEWS = true
'/bootstrap/cache' is used to store the services.json
, config.php
and routes.php
files,
in order to control caching of these files use the following options in .env.production
and/or .env.local
file:
CACHE_SERVICES_FILE = true CACHE_CONFIG_FILE = true CACHE_ROUTES_FILE = true
In order to use config.php
first generate it using the --cache-config
option of
php artisan gae:setup
command. routes.php
has to be generated using
php artisan route:cache
command.
Cache related options are:
- supported on GAE and/or in local environment as long as
memcached
service is present, - disabled while executing
php artisan gae:setup
command.
Additionally the initialization of GSC bucket can be skipped to boost the performance.
In order to do so, set the following option in the app.yaml
file:
env_variables: GAE_SKIP_GCS_INIT: true
the storage path will be set to /storage
directory of the GCS bucket and storage
directory structure creation will be skipped.
If not used the filesystem initialization can be removed to minimize GCS usage. In order to
do so, remove the following line from .env.production
file:
FILESYSTEM = gae
Google Trace API on App Engine
While running on App Engine, 0.1 requests per seconds per instance are sampled by the StackDriver Trace tool (https://cloud.google.com/trace/docs/faq).
Using the Trace API, we can submit custom time spans to debug performance while running on GAE.
To use, you first need to initialize the class in bootstrap/autoload.php
.
Underneath the following:
require __DIR__.'/../vendor/autoload.php';
Add these lines:
/* |-------------------------------------------------------------------------- | Start our GAE time tracing. |-------------------------------------------------------------------------- | | Initiate our GAETrace class to allow us to time trace our code. | Starting things here will make sure we can trace as much code as possible, | while ensuring the destructor will always run. | */ use \Shpasser\GaeSupportL5\Trace\GAETrace; $gae_trace = new GAETrace();
As details in the comments, this will ensure the destructor runs when the code exits, submitting the Trace data to the API.
After this, use of the class is static and can be used from anywhere in the Application.
use \Shpasser\GaeSupportL5\Trace\GAETrace; //... $span_id = GAETrace::startSpan("FriendlyName"); //...code here... GAETrace::endSpan($span_id);
Google have suggested submitting the data to the Trace API asynchronously, which we can do via a Push Queue on App Engine.
For this, we add the following to app.yaml
- url: /gae/trace_submit script: public/trace.php login: admin secure: always
Create queue.yaml
if it doesn't exist with the contents:
queue: - name: trace rate: 5/s retry_parameters: task_retry_limit: 7 task_age_limit: 2d
And create the file public/trace.php
with the contents:
<?php /* |-------------------------------------------------------------------------- | Register The Composer Auto Loader |-------------------------------------------------------------------------- | | Composer provides a convenient, automatically generated class loader | for our application. We just need to utilize it! We'll require it | into the script here so that we do not have to worry about the | loading of any our classes "manually". Feels great to relax. | */ require __DIR__.'/../vendor/autoload.php'; use \Shpasser\GaeSupportL5\Trace\GAETrace; GAETrace::submitTraceAsync();
We are using a different non-Laravel entry point to make sure there is no recursion in submitting traces, which could happen if you've got the core traced and we hit an error before $force_untraced is set.
Artisan Console for GAE
To support artisan
commands while running on GAE the package provides Artisan Console for GAE
.
The console is implemented as a separate service and not enabled by default for security reasons. To use the console securely /artisan
route has to be protected.
Installation
Include the service provider within config/app.php
.
'providers' => [ Shpasser\GaeSupportL5\GaeArtisanConsoleServiceProvider::class ];
If it isn't added automatically, add /gae/.*
URL handler to app.yaml
file.
handlers: - url: /gae/.* script: public/index.php login: admin secure: always - url: /.* script: public/index.php
/gae/.*
URL handler has to appear before the last one (url: /.*
), otherwise it will be ignored by GAE.
The suggested handler secures the route using GAE URL security options. For more information see https://cloud.google.com/appengine/docs/php/config/appconfig#PHP_app_yaml_Secure_URLs.
Usage
Enter URL http://your-app-id.appspot.com/gae/artisan in your browser and use the displayed form to submit artisan
commands.
Since GAE's filesystem is read-only the commands will not be able to perform write / update operations on it. For the same reason migrations have to be prepared on local development environment before the deployment takes place. Since the console is not really interactive all the commands are executed in non-interactive mode(by automatic appending of -n
option).
Deployment
Backup the existing .env
file if needed and rename the generated .env.production
to .env
before deploying your app.
Download and install GAE SDK for PHP and deploy your app.
Known Issues
As of now Laravel scheduled commands are not supported while running on GAE.
In order to use Artisan Console for GAE
the application class app/Console/Kernel
has be edited and any of the commands scheduled using its schedule()
function should be removed.