Tutorial
Redis for Laravel on a private network, over TLS
How a serverless Laravel app gets a Scaleway Managed Database for Redis on a Private Network, over TLS, and what to keep in it on serverless containers.
In this post
A serverless Laravel app keeps its cache in the database by default, and for many apps that is fine. Once the cache gets busy, or you would rather let a serverless database sleep between visits, Redis is the usual next step. On Scaleway that is a Managed Database for Redis, and the safe way to reach it is over a Private Network, with TLS.
This post shows how to add one to a Laravel environment with Brewless, what Brewless sets up, and what belongs in Redis when your containers come and go.
How does a serverless Laravel app use Redis on Scaleway?
Through cache in brewless.yml. Brewless gives the environment a Scaleway Managed Database for Redis, puts the containers on the project's Private Network, and sets CACHE_STORE=redis and the REDIS_* variables. With brewless/laravel 0.8 or later, the connection speaks TLS and trusts only the certificate of that cache.
Add the cache
environments:
production:
region: fr-par
database: shop-main
cache: shop-cache
staging:
region: fr-par
database: shop-staging
cache:
name: shop-staging-cache
size: RED1-XS
On the next deploy, Brewless looks for a cache of that name in the region. One that stands is used as it is. Otherwise it makes one with the size you gave and the newest version of Redis Scaleway offers.
| Key | What it does |
|---|---|
cache: <name> |
Uses or makes a cache of that name, size RED1-micro |
cache.name |
The name of the cache at Scaleway |
cache.size |
The node type of a new cache: RED1-micro, RED1-2XS, RED1-XS, RED1-S, RED1-M, RED1-L or RED1-XL |
cache: false |
Lets the cache go from the environment; it keeps running at Scaleway |
Run brewless plan production first to see what the file asks for next to what stands.
Warning
Scaleway bills a cache by its size, for every hour it exists. A cache does not sleep.
cache: falsetakes it out of the environment, but it keeps running, and costing, until you remove it in your Scaleway console.
A cache that stands is not swapped for another name or size from brewless.yml; a deploy that asks for that is refused. Scaleway offers Managed Database for Redis in Paris, Amsterdam and Warsaw, not in Milan.
The Private Network
A cache is reached over the project's Private Network only, so cache brings network: private along. You can also set it on its own:
environments:
production:
network: private
What that does:
- Each Scaleway project gets one Private Network per region, called
brewless, made the first time an environment asks for it. Every environment of the project that saysnetwork: privatejoins it. Scaleway does not charge for a Private Network. - The web, release and worker containers go on it. For an environment that runs already, Scaleway deploys them again for that.
- A Managed Database the environment uses gets a private endpoint on the network, and
DB_HOSTandDB_PORTmove to it unless you set them yourself. Its public endpoint stays; remove it in your Scaleway console once nothing uses it. - A Serverless SQL Database cannot join a network. It stays as it is, reached over the internet with its key, next to a cache on the network.
An environment does not leave the network from brewless.yml: network: public for an environment on it is refused. A container or database that is on another Private Network already is not moved; setting up stops and says which. See A Private Network.
The variables Brewless sets
| Variable | Value |
|---|---|
CACHE_STORE |
redis |
REDIS_CLIENT |
phpredis |
REDIS_HOST, REDIS_PORT |
The cache's endpoint on the Private Network |
REDIS_USERNAME, REDIS_PASSWORD |
The user brewless of a cache Brewless made |
BREWLESS_REDIS_CA |
The certificate of the cache's cluster |
For a cache Brewless makes, the password of the brewless user goes into your own Secret Manager, as <application>-<environment>-cache-key, before the cache is made. Brewless never keeps it. A cache that stood there already has users of your own making, so REDIS_USERNAME and REDIS_PASSWORD are left for you to set with brewless env:push.
Laravel's default config/database.php reads these names. TLS is the one thing Laravel's default config does not set up from a variable. Require the package version that does:
composer require brewless/laravel:^0.8
With 0.8 or later, your redis connections speak TLS and trust the certificate in BREWLESS_REDIS_CA, and no other. A Private Network already keeps the traffic inside your project; TLS means the password and data are not readable on that network either.
Note
A variable change reaches the containers with the next deploy. Adding
cacheto an environment that runs puts the variables in the same deploy, as a new revision of the environment's variables.
What to keep in Redis on serverless
Serverless containers start and stop all day, and two of them never share memory or disk. Anything that has to be shared between requests goes to a store outside the container. Redis is a good fit for some of that, and not for all of it.
| What | Where | Why |
|---|---|---|
| Cache | Redis | Brewless sets CACHE_STORE=redis for you |
Locks (Cache::lock, withoutOverlapping, onOneServer) |
Redis | Locks use the cache store, so they move with it |
| Sessions | Redis, if you set SESSION_DRIVER=redis |
Fast, and takes a query off the database per request |
| Rate limiting | Redis | Uses the cache store |
| Jobs | Scaleway Queues or the database | Brewless's queue choices are sqs, database or none |
| Anything you cannot rebuild | The database or a bucket | A cache is for what you can work out again |
Cache. Fragments, expensive queries and the answers of slow services. With the cache in Redis, a page that only reads from the cache does not touch the database.
Locks. Cache::lock(), the scheduler's withoutOverlapping() and onOneServer() all go through the cache store. On serverless, where several replicas can run the same code at once, those locks are what keep a task from running twice. In Redis they are shared by every container of the environment.
Sessions. Brewless leaves SESSION_DRIVER alone. Set it to redis when you want sessions there; on a serverless database that saves a query on every request. Keep in mind that a session in a cache lives only as long as the cache does.
Jobs. The worker of an environment is called by Scaleway Queues as soon as a job is put on it, or by a trigger every minute when jobs wait in the database. The cache is not one of those choices. See Queues and schedule.
Tip
If you moved to Redis so a Serverless SQL Database can sleep, check the rest of the app too. Jobs that wait in the database, or a schedule that runs every minute, keep it awake whatever the cache does. Read Serverless SQL or Managed PostgreSQL for Laravel.
Summary
- Add
cachewith a name, and a size ifRED1-microis too small, in Paris, Amsterdam or Warsaw. - Accept that the environment joins the project's Private Network, and remove the public endpoint of a managed database yourself once nothing uses it.
- Require
brewless/laravel0.8 or later so the connection uses TLS. - Keep the cache, locks and, if you want, sessions in Redis; keep jobs at Scaleway Queues or in the database.
- Remember that the cache bills every hour, and that
cache: falsedoes not remove it.
The full description is in A cache.
Frequently asked questions
How do I add Redis to a Laravel app on Brewless?
Add cache with a name under the environment in brewless.yml and deploy. Brewless uses a cache of that name in the region or makes one, puts the environment on the Private Network, and sets CACHE_STORE=redis and the REDIS_* variables.
Is the Redis cache reachable from the internet?
No. It is reached over the Private Network of your Scaleway project only, which nothing outside the project can reach, and the connection uses TLS on top of that.
Which Redis sizes can I choose?
Scaleway's node types from RED1-micro to RED1-XL, set with cache.size. Without a size a new cache gets RED1-micro. A cache that stands is not resized from brewless.yml; that is refused.
Does Brewless put Laravel sessions in Redis?
Brewless sets CACHE_STORE=redis only. Laravel can keep its sessions and locks in the same cache, but you choose that yourself, for example with SESSION_DRIVER=redis in your variables.
In which regions is Managed Database for Redis available?
Scaleway offers it in Paris, Amsterdam and Warsaw, not in Milan. An environment in Milan cannot have a cache from brewless.yml.