Introducing Laravel Vapor, a serverless hosting platform

Posted on July 24, 2019

This was originally a live blog. I'll be updating it to add screenshots and links as I get them.

Here's a video of the announcement: Taylor Otwell - Introducing Laravel Vapor


(image from Yaz Jallad)


There's currently one official way to get your apps into production: Forge.

People have been asking about auto-scaling, etc.

A few years ago I finished a whole product called Laravel Cloud. Hinted at it. Handled auto-scaling. But when I got done I just didn't feel like it was revolutionary enough. Didn't blow me away. Front end built by Steve, whole backend done, but tabled it. Wanted something that blew me away for deploying PHP applications.

Last 9-10 months 40 hours a week.

(image from Yaz Jallad)

What is Vapor?

https://vapor.laravel.com/

Starting with an example:

Vapor is ready for scale. 5000 users with 2312 requests a second still getting 12ms request times.

Laravel Vapor is a serverless deployment platform for Laravel, powered by AWS. On-demand auto-scaling with zero server maintenance.

Even made small tweaks to Laravel over the last few months to make it all seamless.

What is serverless?

Google Cloud Functions, Amazon Lambda, etc.

You deploy to their platform but never think about infrastructure. Of course there are actually servers but you never think about them. You don't worry about certs, PHP versions, how much scale my app needs, etc. because my app just scales elastically very quickly.

In the past you might've used Horizon to manage your queues; 20 Horizon processes working queue jobs. Now, you don't even have to think about it. If you get 1000 jobs on your queue they'll be executed within seconds. If no jobs, no workers. It's all entirely elastically scaled.

If no one is using your app, you're not getting charged for it.

How much does Vapor cost?

Unlimited teams, users, projects, deployments.

Price is $39/mo, $399/year (plus all your AWS costs).

What does Vapor do?

Teams

Built around teams from day one. Don't cost extra.

Unlimited teams, users, projects, deployments.

Customize their abilities.

Projects

Each project has multiple environments, listing recent deployments for each environment. Each env gets its own vanity URL. E.g. https://snowy-hurricane-12349834324432.vapor.build/ to see your actual app.

Staging domains get no-index header so they're not indexed.

Pushing code to Vapor

Has a command line tool. vapor deploy production from your project folder.

Uploads assets to Cloudfront for CDN then kicks off the application build.

Zero downtime, like Envoyer.

vapor deploy staging

Super easy rollback from the UI.

Config

vapor.yaml

Build steps, different config for each enviornment, etc... domain, storage, build steps for each

id: 4
name: vapor-laracon
environments:
    production:
        database: laracon-deb
        cache: laracon-cache
        domain: scenery.io
        storage: laracon-us-2019-storage
        build: 
            - `composer install --no-dev --classmap-authoritative`
            - `php artisan event:cache`
        deploy:
            - `php artisan migrate --force`
    staging:
        etc.

Build steps run locally. Deploy steps run on AWS.

Cloudfront/CDN

ASSET_URL env var injected so you can just use the asset helper in Laravel and it'll point to the right Cloudfront URLs.

Maintenance mode

Has a button right in the UI for it. You can still access the full app from your vanity URL to keep working on it while your production app is in maintenance mode.

Environment variables

You'll have to do it a lot less than you used to since Vapor knows so much about your app. For example we inject database, cache, queue variables for you. You'll think about them the most for third-party services for Pusher, Bugsnag, etc. and you can manage them in a textbox in Vapor.

Changes to .env don't change effect until you deploy again, but you can hit re-deploy to make that happen.

Secrets

Kinda like environment variables, but your env vars are limited to 4kb and your Passport private keys and other longer things might not be able to work that way.

Secrets are versioned, encrypted at rest, and versioned.

When I rollback, it rolls back the secret that it was deployed with as well.

Secrets are available as environment variables just like any others.

Commands

Run one-off Artisan commands against your serverless app. No servers to SSH into! Run them from the UI. See log output from the UI.

Metrics

HTTP requests, CLI/queue invocations, estimated cost, CLI/queue average duration, HTTP average duration, etc. over the last 24 hours, 30 days. Taylor has 87k of CLI/queue inviations and a few thousand HTTP requests in the last 30 days and showed around $3 on the chart.

Also has alarms. Can configure an alarm to say, e.g., "If I get more than 1k requests per minute for over 5 minutes, Slack or webhook or email me". Http Requests, CLI/Queue invocations, etc.

Logs

Can view/tail your logs rightin Vapor. AWS CloudWatch is not a lot of fun.

Can type a search phrase and it auto updates anything that matches.

Databases

Adding Fixed DB:

Fixed size--you can pick the specs. db.t2.micro for $15/mo, etc... normal Amazon stuff.

Max disk size to scale it up to ($0.115/GB/mo) will auto scale up to your max.

Public vs private. Private live in your network, can't be accessed from your local. But env vars auto injected into your local.

Attaching DB add in vapor.yaml.

Scaling: You can scale the fixed-size database and you can scale it up or down to any other size and it'll automatically adjust. Keep using your app.

Adding serverless DB

Autoscaling, etc. on the DB as well

Alarms on it etc.

Backup and restore DB

Can restore to any point in time in the last 3 days. Name the restored db, pick the time, and it creates a new Db with the same specs back to the old one. Down to the second, nothing about hourly, daily, etc.

DB Commands

vapor database:shell database-name here

Run queries from in there against the DB.

Jumpboxes

Add a tiny box in the network and you can SSH in there. So you can use TablePlus/etc. to ssh into that box and manage the DB from there.

Caches

Similar to DB. Can make Redis clusters directly from the UI with as many nodes as you want in the cluster.

If you don't need a full Redis cluster, Vapor will automatically set up a DynamoDB (serverless, autoscaling) cache for your app.

Attach in yaml, I think.

Redis tooling already installed in Vapor. As soon as you turn it on it already flips Laravel over to Redis without you having to do anything.

Can manually scale up the nuber of nodes without any downtime.

Great metrics on the cache; CPU usage, hit rate, miss rate, etc.

vapor cache:tunnel (i think) tunnels to 6378 (one short of the usual Redis port), and you can use any Redis GUI app and set up localhost on that port and directly attach to that cache.

Queues

It just works. Maps event source mapping into SQS.

Scheduler

Auto set up to run php artisan schedule:run command every minute. Always. No config needed. (Uses CloudWatch)

Custom domains

Separate page for domains. Can even purchase domains (AWS Route53) directly from the UI. Automatically makes wildcard certs and DNS zones.

If not purchased through Vapor, just add a domain you own to Vapor. Point to AWS name servers and then you can manage DNS through Vapor, or manage your own DNS on your own and just point certain CNAME records etc.

Email

You can use whatever you want. Vapor auto sets up DKIM etc. for you if it's managing your domain.

File Uploads

Send files straight to S3. Uses "pre-signed URLs". Complicated in the backend so Vapor simplifies it.

Wrote a JS package on npm lets you do vapor.store

Vapor.store(file, {
    progress: currentProgress => {
        this.uploadProgress = Math.round(currentProgress * 100);
    }
}).then(storedFile => {
    // storedFile.uuid, .key, .bucket, .extension
});

Uploads these files into a temp directory in your storage bucket. Will be cleaned after 24 hours. Only gets moved into true storage when your backend copies that file from the temp directory into the more permanent directory.

CI

You can deploy from your CI pipeline.

In composer.json you'll add laravel/vapor-cli in your vapor file, so you can run Vapor from your CI.

Configure your CI deploy step:

php vendor/bin/vapor deploy production

Boom.

Test

vapor test

Spins up Docker with exact Vapor identical build and runs phpunit test.

CLI

Every single thing that he showed in the UI (create DBs, scale DBs, scale cache, etc.) can all happeen in the DB. E.g. vapor database foo and you pick everything in a UI.

Can even vapor metrics production.


That's it for now! I'll work on getting better pictures and go back and try to re-organize and re-structure it a bit later, but for now, time to shut the computer for a bit. 👋


Comments? I'm @stauffermatt on Twitter


Tags: laravel  •  vapor

Subscribe

For quick links to fresh content, and more thoughts that don't make it to the blog