Using environment specific variables in Laravel Vapor with Mix

I went down a bit of rabbit hole today, to the point where I was about to send a PR to the laravel/vapor-cli repository.

Consider this:

If I run vapor deploy staging locally, and I have this in .env: 

STRIPE_KEY=pk_test
MIX_STRIPE_KEY=${STRIPE_KEY}

And this in .env.staging: 

STRIPE_KEY=pk_live
MIX_STRIPE_KEY=${STRIPE_KEY}

Then mix is going to build `process.env.MIX_STRIPE_KEY` with a value of `pk_test`. 

My line of thinking is I need the Vapor build to use my .env.staging file to build those assets, damnit!

Alas, there is a better solution, mix-env-file.

The steps are as follows, replace "staging" with your environment of choice:

  1. Make sure you have the correct .env.staging present with vapor env:pull staging
  2. Install the mix-env-file package and set it up per the instructions
  3. Run your webpack specifying ENV_FILE=./.env.staging
  4. Your done!

Even better, this works very easily with a Continuous Integration service like CircleCI: in your vapor.yml build steps, just pull the correct .env as above prior to building assets and your done.

Under the hood with Laravel Vapor

Steve Thomas
Steve Thomas · 27th Aug

No sane developer willingly takes on the challenge of DevOps (or SysOps) on top of their already considerable full stack responsibilities. How does Laravel Vapor help us?

No sane developer willingly takes on the challenges of DevOps (or SysOps) on top of their already considerable full stack responsibilities but for most agencies, it’s a necessity to building, maintaining and delivering successful projects.

At Coding Labs, we work with self-funded startups and small to medium sized businesses, all of whom hope for viral growth, but are unable to predict when that growth might appear.

And what most clients know (or want to know) about infrastructure could fit on the back of a postage stamp.

They do universally agree that their infrastructure budget is not open-ended, and that their website being down while our team is drinking beer at the local on a Friday arvo:

is bad.

This presents a problem: how do we prepare our client infrastructure for unforeseen outages, traffic surges and fast paced growth without prematurely over-engineering and overcapitalising?

3 things we need in our client infrastructure

We have a pretty short (but no by no means trivial) list of requirements for our infrastructure:

  1. Autohealing when something goes bang (ie. automatically replace an app server that has gone AWOL)
  2. Autoscaling to meet demand (ie. CPU alarms, Instance Profiles, Code Deploy, ASGs, utilising managed services)
  3. Approachable for us mere mortals (ie. easy to onboard the team, looks and feels absolutely nothing like the AWS Console).

In my experience - which includes overseeing large highly available web apps, suffering through attaining an AWS Cloud Architect certification, exhaustive application of "RTFM", and a shit-ton of sheer persistence - I can confirm that infrastructure and deployment strategies can be cobbled together to deliver HA web apps that don't completely break very often.

I would go as far as to say that we have largely ticked off Autohealing and Autoscaling from our list by scratching our own itch, but things get ugly when we talk about Approachability.

In pursuit of Approachable infrastructure

Question: Who enjoys trawling through the AWS Console / CLI / docs looking to debug some obscure but crucial part of your infrastructure?

Answer: Psychopaths!

AWS (the awesome backbone on which Vapor is built) can do virtually all things infrastructure, on account of the 1,000+ services which can fulfil so many use cases it will make your head explode.

But when you are using a service developed by a behemoth company founded by a cyborg, you should first stop and try and break it down a little, preferably with a large hammer.

The Laravel team have fortunately invested huge effort to make a very large hammer specifically for AWS at scale: Laravel Vapor.

Why Laravel Vapor is a no-brainer for us

Laravel Vapor is a killer app, and I mean that literally because it actually killed off two of my internal DevOps apps I had built to tackle similar problems.

There is something very reassuring knowing that our chosen infrastructure / deployment tool is continuously battle-tested against thousands of diverse Laravel apps, and that the ecosystem will only get stronger for years to come through the wonders of Open Source and the Laravel community at-large.

In fact, there is no comparison to what we have been doing up until now, and therefore no decision to make; to Vapor - onward march!

Yuck things that we don't have to do any more:

  1. Ever tried AWS CodeDeploy coupled with autoscaling groups coupled with load balanced one-at-a-time deployments? Here's a tip - don't
  2. Maintaining EC2 launch configurations and AMIs
  3. Pushing .env changes to a fleet of instances simultaneously
  4. Configuring VPCs, subnets, security groups, IAM policies and users
  5. Managing infrastructure logic and configuration outside of the app repo
  6. Supervise queue workers
  7. Login in to AWS Console (well, not as often at least 🎉)

Shiny new things we can do now:

  1. Lower the barrier to entry so that less experienced developers can safely manage (some of) our deployed infrastructure
  2. Pulling and pushing environment specific .env files from the local command line
  3. Pairing .env, assets and secrets to deployments without any magic on our side
  4. 1-click rollback
  5. Running commands in deployed environments from local
  6. Creating deployments outside of CI workflow
  7. Give team members Vapor permissions and point them to the excellent docs instead of the daunting prospect of onboarding them to AWS and IAM

Things to watch out for...

No support for MySQL 5.6 / 5.7, Aurora RDS engines (yet?)

Not sure about you but I didn't even know MySQL 8.0 was a thing until I got my Vapor invite. I haven't hit any problems, but i'm expecting to break something that worked in 5.7 any day now.

I'm also a little surprised that RDS Aurora didn't make the initial cut (although I wouldn't be surprised if they roll out support for more RDS engines soon). Aurora is pretty powerful in comparison to the basic MySQL offerings whilst being more cost-effective than Aurora Serverless (I think).

Also keep in mind there is nothing stopping you from deploying your own database infrastructure as you see fit and connecting to it through .env.

Cache store [dynamodb] is not defined.

This happens if you started with Laravel < 5.8.17 and did not add the default config for DynamoDB to config/cache.php.

AWOL logs

For reasons I don't fully understand, some exceptions like the one generated by the DynamoDB omission above, are not getting logged anywhere that I can find.

I checked the Vapor dashboard, the tail command, and directly in CloudWatch to no avail. 🤷‍♂️

Stupid easy to deploy apps

vapor deploy production

It looks too easy and it is too easy. You can run this command on any branch, with any uncommitted changes, and any level of test failures (a security blanket that CI may have protected you from in the past).

Thank goodness for:

vapor rollback production

Stupid easy to break things

Many heads will be scratched over the coming years thanks to some of the more powerful vapor commands, which will reap wholesale destruction on inexperienced AWS users.

The team permissions are nice, and should be used carefully to ensure mission critical apps are firewalled from curious juniors.

In some cases it would be advisable to disable team deployments altogether and instead invoke them from the CI server with branch filtering.

Aurora Serverless is expensive

The holy grail for me to compliment Lambda powered app-servers has to be a serverless autoscaling database. Aurora Serverless is just that, but the downside is the costs can be rather prohibitive compared to conventional RDS.

Definitely run the calculate on this one before rolling it out to a busy site.

Learn AWS anyway

I don't think there is any suggestion from anyone that Laravel Vapor can totally circumvent the need for hands-on AWS experience, and there are definitely going to be times during debugging and customisation that you will need to get dirty and dirty with AWS.

Just be thankful that Vapor has done most of the boring stuff really, really well, and you will hopefully find yourself in the luxurious position of leveraging AWS rather than simply trying to keep the lights on.


« 1 2 3 4