# Laravel hosting without lock-in: what happens when you leave

What lock-in means for Laravel hosting, why owning your cloud accounts matters, and what keeps running when you export, detach and leave Brewless.

## In short

- Hosting without lock-in means your app runs in cloud accounts you own, so leaving your deploy tool does not mean moving your app.
- With Brewless, the containers, database, files, queues, secrets, registry and DNS sit in your own Scaleway and bunny.net accounts and are billed to you directly.
- When you detach an environment, deploying, rolling back and scaling through Brewless stop, while your containers, data, domains, certificates and secrets keep running.
- `brewless export` writes everything Brewless knows about an environment as files, including Terraform that imports every resource as it is, without any secret values.
- After leaving, a release is three plain calls to your provider, and the client and the Laravel package that answers them are open source.

Every hosting platform says you can leave. The useful question is what you would have to move, rebuild or rewrite when you do. For a lot of Laravel hosting the honest answer is: the app, the database, the files, the DNS and the secrets, because all of them live in the platform's account, not yours.

This post looks at what lock-in means for Laravel hosting, how owning your cloud accounts changes it, and what exactly stops and what keeps running when you leave [Brewless](/).

## What is lock-in in Laravel hosting?

Lock-in is the cost of leaving: the work, the risk and the downtime of moving your app away from the platform that runs it. It is high when the platform owns the infrastructure, the data or the contract, because leaving then means rebuilding all of it elsewhere. It is low when those are yours and the platform only operates them.

There are a few kinds of lock-in, and they are easy to mix up:

| Kind | What it looks like | Question to ask |
| --- | --- | --- |
| Infrastructure | Your app runs in the platform's cloud account | Whose account are the containers in? |
| Data | Your database and files sit in the platform's account | Can I reach my data without the platform? |
| Contract | You pay the cloud through the platform | Who bills me for the cloud? |
| Configuration | The setup only exists in the platform's database | Can I get it out as files? |
| Code | Your app depends on the platform's runtime or SDK | Does my app run without its package? |

A platform can be fine on one row and bad on another. A tool that deploys into your own AWS account, for example, takes care of the first three rows, but leaves you with a US provider.

## Owning your cloud accounts

With Brewless, you open the Scaleway project and the bunny.net account yourself, and hand Brewless an API key limited to that one project. Everything Brewless sets up goes into those accounts:

| Yours, billed to you by the provider | Brewless's |
| --- | --- |
| Web runtime | Deploys |
| Database | Release history |
| Queues | Rollback |
| Storage | Dashboard |
| Secrets | Audit trail |
| Builds | Drift checks |
| Container registry | |
| DNS and CDN | |

Three choices keep the right-hand column small:

- **Visitor traffic never passes through Brewless.** It goes from bunny.net straight to your containers.
- **Builds run in your own Scaleway project**, as a job there. Your code goes from your machine into your project and never passes through Brewless.
- **Secrets stay in your own Secret Manager.** Brewless keeps the names and revisions of your variables, never their values.

That also covers the data and contract rows: the database and the files are in your project, and Scaleway and bunny.net bill you directly. Brewless takes no percentage of the cloud bill.

## Export: get the configuration out as files

The configuration row is covered by the export. It writes everything Brewless knows about an environment as files:

```bash
brewless export production
```

| File | Contents |
| --- | --- |
| `environment.json` | The application, its framework, the environment and its region |
| `resources.json` | Every resource Brewless manages, with its identifier and settings |
| `domains.json` | The domains it answers on and how they are routed |
| `releases.json` | The latest releases, each with its commit and image |
| `variables.json` | The names of the variables and the secret that holds their values |
| `main.tf` | Terraform that takes the resources over as they are |
| `README.md` | What is in the folder and how to deploy without Brewless |

No value of a secret is in it. Exporting changes nothing, so you can run it any time, also just to see what Brewless holds. The console has the same under **Resources**.

> [!TIP]
> Run an export once early on, before you need it. Reading `resources.json` is the quickest way to see exactly what lives in your accounts.

## The Terraform file

`main.tf` has, for every resource, a block that imports it and a block that describes it. With your own provider keys:

```bash
export SCW_ACCESS_KEY=... SCW_SECRET_KEY=... BUNNYNET_API_KEY=...
terraform init
terraform plan
```

The plan imports every resource and wants to change nothing. Some things are left out on purpose, such as the image and variables of a container, so a later plan does not undo a release, and the settings of a bunny.net pull zone, which are taken over as they are. [Leaving Brewless](https://docs.brewless.eu/applications/leaving) lists each of them.

## Detach: what stops and what keeps running

Detaching ends what Brewless does for an environment:

```bash
brewless detach production
```

A last export is made first, and nothing at your providers is touched.

| Stops | Keeps running |
| --- | --- |
| Deploying and rolling back through Brewless | Your containers and what they serve |
| Scaling through Brewless | Your database and its data |
| Watching for changes made elsewhere | Your domains and certificates, which your providers keep renewing |
| The test address, whose record leaves Brewless's zone | The trigger that calls your worker every minute |
| | Your secrets, in your own Secret Manager |

The environment, its releases and the audit trail stay in Brewless as a record of what happened. Detaching waits for work that is under way: while a deploy runs, it is refused.

> [!NOTE]
> Your provider keys belong to your organisation, not to one environment. When Brewless manages nothing else for you, disconnect them under **Providers**, and delete the key at Scaleway and bunny.net to end its access for good.

## Deploying without Brewless

The code row matters too. Your Laravel app needs the `brewless/laravel` package to take release commands, the queue and the schedule in its containers. That package is open source, as are the command line client and the base image your releases are built on.

After you leave, a release is three plain calls to your provider, described in the `README.md` of the export:

1. Build an image and push it to your registry.
2. Give the release container that image and call its release route with your ops secret. That runs your release commands, such as migrations.
3. Give the web and worker containers the same image.

You can script that in any pipeline, or keep using the Terraform from the export to manage the resources around it.

## Coming back

Leaving is not one-way. The resources are still yours and still running, so you can adopt them again on the **Resources** page of the environment. See [Applications and environments](https://docs.brewless.eu/applications/applications-and-environments#resources).

## Summary

1. Lock-in is the cost of leaving: infrastructure, data, contract, configuration and code.
2. With your own Scaleway and bunny.net accounts, the infrastructure, data and contract are yours from the start.
3. `brewless export` gets the configuration out as files, with Terraform that imports every resource.
4. `brewless detach` stops deploys, rollbacks and scaling through Brewless; your app, data, domains and secrets keep running.
5. A release without Brewless is three calls to your provider, with open-source tools.

Why owning your accounts also matters for EU sovereignty is in [How to host a Laravel app EU-sovereign](/blog/eu-sovereign-laravel-hosting).

## Frequently asked questions

### What happens to my Laravel app if I cancel Brewless?

It keeps running. Your containers, database, files, queues, secrets and DNS are in your own Scaleway and bunny.net accounts. You lose the deploys, rollbacks, dashboard and drift checks that Brewless provides.

### Do I need to migrate my data when I leave Brewless?

No. Your database and files never lived at Brewless. They stay in your Scaleway project, in the region you picked, under your contract with Scaleway.

### What is in a Brewless export?

The application and environment, every resource Brewless manages with its identifier and settings, the domains, the latest releases, the names of your variables, a Terraform file that imports the resources, and a README on deploying without Brewless. No secret values are in it.

### Can I deploy without Brewless after I detach?

Yes. Build an image and push it to your registry, give the release container that image and call its release route with your ops secret, then give the web and worker containers the same image. The README of the export describes the calls.

### Can I come back after detaching?

Yes. The environment, its releases and the audit trail stay in Brewless as a record. You adopt the resources again on the Resources page of the environment.

Source: https://test.brewless.eu/blog/laravel-hosting-without-lock-in
