LaravelSaaS启动器

starter-kit.spelt.com.br — Laravel SaaS模板

作者 Codijo

基于 Laravel 的 SaaS 启动模板,包含 API 与用户面板,集成 Spelt 的 SSO、订阅、积分与 webhook 处理,并附带 Docker 开发环境。

看看你的网站会是什么样

浏览真实页面截图,比较内容排版与手机效果。点击下方缩略图切换,放大查看整页细节。

2 个预览视图
桌面端首页1 / 2
桌面端截图首屏预览

由服务器浏览器实际访问页面后截取。

全部页面与视图 2

截图用于了解视觉与布局,交互效果请以实际项目为准。

采集于 2026-10-01查看来源

值得关注的模板亮点

从已有项目资料中,快速了解它的特点。

01

包含 API 与用户面板两个 Laravel 应用,另附可选官网

02

集成 Spelt SSO 登录,产品端不存储密码

03

提供订阅状态镜像、积分账本和访问控制中间件

04

webhook 处理带签名验证、队列处理和幂等性

05

提供 dev:token 与 dev:spelt-catalog 命令,无需 Spelt 账号即可本地开发

06

开发环境基于 Docker Compose,由外部部署库生成

模板详细介绍

这是一个用于搭建 SaaS 产品的起始仓库,代码分为 API(code/api)和用户面板(code/platform)两个 Laravel 应用,另有一个可选的官网(code/www)。模板将认证、订阅状态、积分账本和 webhook 处理等常见但重复的模块预先实现,并把这些能力与 Spelt 服务对接:用户通过 SSO 登录,订阅与计费由 Spelt 侧处理,产品代码中只保留订阅状态镜像、积分消费记录和访问控制等逻辑。

模板本身不是框架或库,而是一个可复制的仓库:生成项目后代码归使用者所有。开发环境依赖外部部署库 iporto/deploy,通过 deploy-scaffold-project 命令将模板与部署脚手架组合成完整项目,开发环境可用 Docker Compose 启动。

限制方面,模板与 Spelt 服务耦合,计费、发票、支付网关、优惠券、升降级等由 Spelt 运营,不在代码内;若要实际收费需要 Spelt 账号,但本地开发可通过 dev:token 和 dev:spelt-catalog 命令在没有账号的情况下运行。运行环境要求 Docker 20.10+、约 20 GB 磁盘空间和 4 GB 内存,支持 Linux 与 macOS。

LaravelSaaS启动器

适合你的项目吗?

适用场景

  • 快速启动一个需要订阅与积分体系的 Laravel SaaS 产品
  • 在本地开发环境中模拟 SSO 登录、订阅状态和积分消费
  • 作为代码模板复制后修改,构建自有品牌的 SaaS 应用
  • 需要将计费、发票和支付等运营环节委托给外部服务

适合人群

  • 熟悉 Laravel 并希望减少重复搭建 SaaS 基础模块的开发者
  • 计划使用 Spelt 作为计费与订阅后台的团队
  • 需要 API 与用户面板分离结构的项目
  • 能接受 Docker 开发环境并具备相应磁盘与内存资源的开发者

上手与定制指南

结合仓库当前版本的说明,按下面的资料检查内容、配置与运行要求。

  1. 1

    需要 Docker 20.10+(含 docker compose v2)、git 和 curl,建议预留 20 GB 磁盘和 4 GB 内存

  2. 2

    先克隆部署库 iporto/deploy 到 ~/.deploy-scripts,再运行 deploy-wizard 或手动执行 deploy-scaffold-project 生成项目

  3. 3

    生成项目时需指定域名,模板代码会被复制到 code/ 下的对应子目录

  4. 4

    本地开发可通过 dev:token 和 dev:spelt-catalog 命令创建测试账号与订阅,无需注册 Spelt

  5. 5

    实际收费需要 Spelt 账号,且域名、托管、数据库等外部服务可能产生额外费用

查看仓库使用说明

授权与来源资料

使用条件与限制

免费使用 · 保留许可声明

本次收录的是公开仓库中采用 MIT 许可的免费版本;免费范围为该版本代码,不代表外部服务或第三方素材免费。

使用时需要遵守

  • 允许免费使用、修改、商用和分发该版本代码。
  • 分发代码副本或实质性部分时,保留原作者版权声明和完整 MIT 许可声明。
  • 代码按现状提供;担保与责任限制以原许可证及适用法律为准。

额外费用与待核对事项

  • 实际部署上线收费产品需要注册 Spelt 账号;本地开发可用 dev:token 免账号运行。
  • 计费与访问控制委托给外部 Spelt 服务,非纯本地实现。
  • 模板与 Spelt 服务耦合,集成层位于 Spelt\* 命名空间,替换需自行改造。
  • 套餐、结账、发票、支付网关、优惠券、升降级、客服、税务等均由 Spelt 运营,不在代码内。
  • 开发环境依赖外部部署库 iporto/deploy,需另行克隆。
  • 运行需约 20 GB 空闲磁盘与 4 GB 内存。
  • 演示图片、字体、图标及其他第三方素材需按各自许可核对,不能仅凭代码的 MIT 许可判断。
  • 域名、托管、数据库、支付或 AI 等外部服务可能另外收费。
查看原文依据

Permission is hereby granted, free of charge

许可证原文

Para colocar um produto no ar de verdade você precisa de uma conta lá

README 原文

A cobrança e o controle de acesso são delegados ao **[Spelt](https://spelt.com.br)**

README 原文

O kit nasce acoplado ao Spelt

README 原文

Planos e preços · checkout · faturas · pagamentos e gateways · cupons · inadimplência · upgrade e downgrade com prorrateio · área do cliente white-label · suporte · métricas de receita · fiscal.

README 原文

A camada de deploy — compose, Dockerfiles, nginx, workflows, os verbos `./deploy-run` e companhia — vem de outro repositório

README 原文

Disco | **20 GB livres**

README 原文
https://github.com/Codijo/starter-kit.spelt.com.br/blob/main/LICENSEhttps://github.com/Codijo/starter-kit.spelt.com.br/blob/main/README.md

DeepSeek 根据仓库许可证和 README 整理 ·2026-10-02。结果仅覆盖已读取资料,依赖、图片、字体及后续条款变更以各自原文为准。

项目核对记录与介绍依据

模板资料

来源平台
GitHub
资料与维护参考分
资料较完整 · 85 / 100
技术栈
Laravel
网站类型
SaaS · 启动器
这个分数如何计算

本站按许可资料(最高30分)、演示链接(12分)、预览图(10分)、Star数(15分)、记录的维护时间(15分)、描述完整度(8分)、功能记录(5分)和分类资料(5分)计算。它不是代码、安全或性能测试,也不是 Google 评分;有链接不代表已实测可用。

这个项目需要核对什么

记录的仓库更新时间
2026-09-30
截图检查日期
2026-10-02

已收录演示链接。请用你的内容与屏幕尺寸检查;有演示不代表表单、认证或支付已经可用。

目录记录的主要技术栈是 Laravel。请通过依赖清单和锁文件核对实际版本与托管要求。这些说明基于收录资料,不代表代码审计或部署实测。

查看具体选型方法 →

介绍的制作与核对状态

介绍由 AI 辅助整理目录与仓库资料。仓库作者不等于这篇介绍的审核者。

已完成服务器许可规则与 AI 来源核对;未经过人工编辑审核。

查看当时使用的来源资料

SHA-256: bb72b06ff03893d9103edddac3b2ad6626cf209a650a0a7e74ca834eb77408e2

2026-10-02T03:17:11.158Z

来源文件 / 仓库
<h1 align="center">Starter Kit</h1>

<p align="center">
  <strong>Um SaaS em Laravel no ar em dez minutos —<br>
  login, assinatura, créditos e webhooks já resolvidos.</strong>
</p>

<p align="center">
  <img alt="Laravel 12" src="https://img.shields.io/badge/Laravel-12-FF2D20?logo=laravel&logoColor=white">
  <img alt="PHP 8.2+" src="https://img.shields.io/badge/PHP-8.2+-777BB4?logo=php&logoColor=white">
  <img alt="Docker Compose v2" src="https://img.shields.io/badge/Docker%20Compose-v2-2496ED?logo=docker&logoColor=white">
  <a href="#subir-em-dez-minutos"><img alt="Começar em dez minutos" src="https://img.shields.io/badge/come%C3%A7ar-em%2010%20min-2ea44f"></a>
  <a href="LICENSE"><img alt="Licença MIT" src="https://img.shields.io/badge/licen%C3%A7a-MIT-blue"></a>
</p>

<!-- CAPTURA DE TELA — descomente as 3 linhas abaixo depois de colocar o arquivo.
     O que capturar está em docs/assets/README.md.
<p align="center">
  <img src="docs/assets/painel.png" alt="O painel do Platform rodando em platform.acme.test" width="820">
</p>
-->

Um ponto de partida para subir um SaaS: **API + Platform** em Laravel, com
autenticação, assinatura, créditos e webhooks já resolvidos — e um ambiente de
desenvolvimento que sobe com dois comandos.

A cobrança e o controle de acesso são delegados ao **[Spelt](https://spelt.com.br)**:
o kit já traz o SSO, o recebimento de webhooks e o modelo de créditos e planos.
Para colocar um produto no ar de verdade você precisa de uma conta lá — mas
**não para desenvolver**, como o passo 9 mostra.

Não é um framework nem uma biblioteca. É um **repositório para copiar**: você
gera o seu produto a partir dele e o código passa a ser seu.

---

## Índice

- [O que vem pronto](#o-que-vem-pronto)
- [O que você não vai construir](#o-que-você-não-vai-construir)
- [De onde vem cada peça](#de-onde-vem-cada-peça)
- [Requisitos](#requisitos)
- [Subir em dez minutos](#subir-em-dez-minutos)
  - [O caminho curto: o assistente](#o-caminho-curto-o-assistente)
  - [0. Os três caminhos](#0-os-três-caminhos) · [1. Clonar](#1-clonar-a-biblioteca-e-o-kit) · [2. Conferir a máquina](#2-confira-se-a-máquina-dá-conta) · [3. Base compartilhada](#3-a-base-compartilhada--uma-vez-por-máquina)
  - [4. Banco](#4-o-banco-do-seu-produto) · [5. Gerar o produto](#5-gerar-o-produto) · [6. Domínios](#6-resolver-os-domínios) · [7. Conferir](#7-conferir-antes-de-subir) · [8. Subir](#8-subir) · [9. Migrar e entrar](#9-migrar-e-entrar)
- [Quatro repositórios, dois momentos](#quatro-repositórios-dois-momentos)
- [Depois de subir: construir o produto](#depois-de-subir-construir-o-produto)
- [Produção](#produção)
- [Comandos úteis](#comandos-úteis)
- [Documentação](#documentação)
- [Licença](#licença)

---

## O que vem pronto

| | |
|---|---|
| `code/api` | API Laravel — contas, assinaturas, créditos, webhooks, tokens |
| `code/platform` | Painel do usuário — Laravel + Vite |
| `code/www` | Site institucional (opcional) |
| Artefatos de build | Ficam no `deploy.<projeto>`, não nos apps — os apps só têm o workflow que avisa |
| Ambiente de dev | gerado pela [biblioteca de deploy](#de-onde-vem-cada-peça), com nginx, PHP-FPM, banco e mail |

---

## O que você não vai construir

Todo SaaS precisa das mesmas coisas em volta do produto: plano, assinatura,
cobrança, fatura, inadimplência, upgrade, área do cliente, webhook, métrica de
receita. **Nada disso diferencia o seu produto — e tudo isso é obrigatório.**

É exatamente a parte que a categoria deixa para você. O padrão dos kits de SaaS
é entregar o gateway e os medidores de uso, e devolver a regra de negócio: o que
cada plano libera, quanto de crédito sobrou, o que acontece num downgrade.

Aqui essa regra já está escrita — e o que fica fora do seu código é operado pelo
[Spelt](https://spelt.com.br).

### Já resolvido no código do kit

| | Onde | O que resolve |
|---|---|---|
| **Entrada por SSO** | `Spelt\SsoController` | O usuário entra vindo do Spelt. O produto não guarda senha, não faz "esqueci minha senha", não faz verificação de e-mail. |
| **Webhook confiável** | `Spelt\WebhookController` · `VerifySpeltWebhookSecret` · `ProcessWebhookJob` | Assinatura verificada, evento gravado, processamento em fila e **idempotente** — reentrega não cobra nem provisiona duas vezes. |
| **Porta de acesso** | `EnsureSpeltAccess` | Assinatura vencida ou cancelada para de abrir o produto, sem `if` espalhado pelas controllers. |
| **Estado da assinatura** | `Billing\Subscription` · `SubscriptionSync` | O plano vigente espelhado localmente, para você consultar sem chamar a API a cada request. |
| **Saldo de créditos** | `Billing\CreditLedger` | Ledger de consumo — débito, crédito e saldo. É o modelo que mais dá trabalho de acertar e o que mais some dos kits. |
| **Reconciliação** | `spelt:reconcile` | Um webhook se perde. Este comando compara com a fonte e conserta, em vez de deixar o cliente com acesso errado. |
| **Cliente da API** | `SpeltClient` | Chamadas servidor-a-servidor já autenticadas. |
| **Volta ao portal** | `Spelt\PortalController` | O usuário vai ver fatura e trocar de plano no portal do Spelt, com a sua marca, e volta. |
| **Provisionamento** | `ProductProvisioner` | O ponto onde *o seu produto* entra: o que criar quando alguém assina, o que desligar quando cancela. É o hook que você implementa. |
| **Desenvolver sem conta** | `dev:token` · `dev:spelt-catalog` | Conta, assinatura e login funcionando na sua máquina, sem cadastro em lugar nenhum. |

### Operado pelo Spelt, fora do seu código

Planos e preços · checkout · faturas · pagamentos e gateways · cupons ·
inadimplência · upgrade e downgrade com prorrateio · área do cliente
white-label · suporte · métricas de receita · fiscal.

Você não implementa, não mantém e não corrige nada disso. A conta só é
necessária para **cobrar de verdade** — o passo 9 mostra o ambiente inteiro
funcionando sem ela.

### O que continua sendo seu

O produto. E o código: o kit não é dependência, é um repositório que você copia.

> [!NOTE]
> **O kit nasce acoplado ao Spelt** — é essa a proposta, e é de onde vem o que
> está na primeira tabela. A camada de integração fica isolada nos namespaces
> `Spelt\*`, então trocá-la é possível; mas se você não quer o Spelt, um kit
> genérico de SaaS provavelmente serve melhor.

---

## De onde vem cada peça

Este repositório **não se parece com o projeto que ele gera**, e isso é
deliberado. Aqui mora só o código dos apps. A camada de deploy — compose,
Dockerfiles, nginx, workflows, os verbos `./deploy-run` e companhia — vem de
outro repositório: a biblioteca [`iporto/deploy`](https://github.com/iporto/deploy).

São **duas origens e um destino**:

```
  starter-kit                        iporto/deploy
  (este repositório)                 (a biblioteca de deploy)
  ──────────────────                 ──────────────────────────────
  code/api                           template/deploy-project/
  code/platform                      deploy-scaffold-project
  code/www                           deploy-run · deploy-doctor · …
  docs/…/TEMPLATE.md
              │                                   │
              └─────────────────┬─────────────────┘
                                │
      deploy-scaffold-project acme.com --from-kit ~/starter-kit
                                │
                                ▼
                                deploy.acme.com/        ← o seu projeto
                                ├── docker-compose.dev.yml   ┐
                                ├── .docker/                 │ biblioteca
                                ├── .github/workflows/       │
                                ├── hosts · .env.dev.example ┘
                                ├── docs/TEMPLATE.md         ← kit
                                └── code/
                                    ├── api.acme.com/        ┐
                                    ├── platform.acme.com/   │ kit
                                    └── www.acme.com/        ┘
```

### O que cada origem coloca no projeto

| No projeto gerado | Vem de | Como se atualiza |
|---|---|---|
| `docker-compose.dev.yml` · `hosts` · `.env.dev.example` · `.gitignore` · `.dockerignore` | biblioteca | cópia — um `diff` contra `template/deploy-project/` mostra o que mudou |
| `.docker/` — nginx, php, console e o `Dockerfile` de cada app | biblioteca | idem |
| `.github/workflows/_build-image.yml` e `build.<app>.yml` | biblioteca | idem |
| `docs/coolify-deploy.md` | biblioteca | idem |
| `.deploy/bin/shim` e os verbos `./deploy-run`, `./deploy-sync`, `./deploy-mutagen` | biblioteca | **symlink** — um `git pull` na biblioteca atualiza todos os projetos de uma vez |
| `code/api.acme.com` · `code/platform.acme.com` · `code/www.acme.com` | **kit** | não atualiza: vira seu no instante em que é gerado |
| `docs/TEMPLATE.md` | **kit** | idem |
| `code/<app>/.github/workflows/notify-deploy.yml` | biblioteca | `deploy-scaffold-app code --apply` |
| `.env.dev`, domínios, senhas — e o produto | você | — |

> [!NOTE]
> **Cópia, não link, para tudo que não é verbo.** Um projeto gerado ontem não
> muda porque a biblioteca mudou hoje. É o que deixa você editar o `nginx.conf`
> do seu projeto sem medo — e é por isso que "puxar o template novo" é um `diff`
> consciente, nunca automático.

### Por que não é um repositório só

1. **A biblioteca serve projetos que não vieram do kit.** `deploy-scaffold-project
   acme.com` sem `--from-kit` monta a mesma base para código que já é seu, e
   `--adopt` a instala em volta de um projeto que já existe. Ela nasceu antes do
   kit e é usada por projetos que não têm nada a ver com ele.
2. **O kit vira seu; a biblioteca continua sendo dela.** O código dos apps é
   copiado uma vez e passa a ser editado por você. Os verbos são symlink pelo
   motivo oposto: corrigir um bug no `deploy-run` conserta todos os projetos no
   mesmo `git pull`.
3. **Duplicar a camada aqui dentro criaria duas cópias para manter.** Já
   aconteceu: `Dockerfile` e `.deploy/` chegaram a existir dentro de `code/api` e
   `code/platform`, divergiram do template e eram copiados assim para os projetos
   gerados. Foram removidos — o molde é um só.

A dependência é de mão única: **o kit precisa da biblioteca; a biblioteca não
precisa do kit.** O `deploy-wizard` sabe clonar este repositório como atalho para
quem não tem um clone à mão (`DEPLOY_KIT_REPO` aponta para outro), e nada além
disso.

> A árvore de repositórios que sai daqui — um repo de deploy, um por app — está
> em [Quatro repositórios, dois momentos](#quatro-repositórios-dois-momentos).

---

## Requisitos

| | Mínimo | Observação |
|---|---|---|
| Docker | 20.10+ | com `docker compose` v2 |
| Disco | **20 GB livres** | medido: ~11 GB em uso com tudo no ar |
| RAM | 4 GB | medido: ~1 GB em uso |
| `git`, `curl` | — | |

Funciona em Linux e macOS. Em Apple Silicon, as imagens de terceiros rodam
emuladas — mais lentas, porém estáveis.

> [!IMPORTANT]
> **Disco é o que mais reprova.** Uma VM recém-criada costuma vir com menos
> espaço do que o disco tem de verdade. O `deploy-doctor` do passo 2 mede antes
> de você instalar qualquer coisa.

---

## Subir em dez minutos

### O caminho curto: o assistente

```bash
git clone https://github.com/iporto/deploy.git ~/.deploy-scripts
~/.deploy-scripts/deploy-wizard
```

Ele pergunta o domínio do seu produto, detecta o que já existe na máquina e faz o
resto — mostrando cada comando antes de executar. Se preferir entender o que está
acontecendo, ou se algo falhar no meio, siga os passos abaixo: **são exatamente
os mesmos comandos.**

---

### 0. Os três caminhos

Defina onde cada coisa vai morar. **Todos os comandos deste guia usam estas
variáveis** — assim você não precisa adaptar caminho nenhum no meio do caminho.

```bash
PATH_DEPLOY_SCRIPTS=~/.deploy-scripts    # a biblioteca de deploy (ferramenta)
PATH_KIT=~/starter-kit                   # este repositório (o molde)
PATH_PROJECT=~/deploy.acme.com           # o seu produto (o que você vai construir)
```

> [!IMPORTANT]
> **Elas valem só nesta sessão do terminal.** O processo leva alguns minutos;
> se você abrir outra aba, redefina as três antes de continuar — os comandos
> seguintes dependem delas.

E troque **`acme`** pelo nome do seu produto, em `PATH_PROJECT` e nos comandos
adiante. O domínio determina o nome dos containers (`acme-php-api`), o diretório
dos apps (`code/api.acme.com`) e as linhas do `/etc/hosts`. Trocar pela metade
gera erros que não apontam para a causa.

### 1. Clonar a biblioteca e o kit

```bash
git clone https://github.com/iporto/deploy.git "$PATH_DEPLOY_SCRIPTS"
git clone https://github.com/Codijo/starter-kit.spelt.com.br.git "$PATH_KIT"

export PATH="$PATH_DEPLOY_SCRIPTS:$PATH"    # ponha no seu .bashrc/.zshrc
```

São dois clones porque são **duas origens**: o kit traz o código dos apps, a
biblioteca traz a camada de deploy. [De onde vem cada peça](#de-onde-vem-cada-peça)
mostra o que cada uma coloca no projeto gerado.

> [!TIP]
> **Em equipe, fixe a versão da biblioteca.** O clone acima segue a `main` — duas
> pessoas que clonam com uma semana de diferença rodam código diferente. Os
> [releases](https://github.com/iporto/deploy/releases) existem para isso:
>
> ```bash
> git clone --branch v1.0.0 --depth 1 \
>   https://github.com/iporto/deploy.git "$PATH_DEPLOY_SCRIPTS"
> ```

> [!TIP]
> Se já clonou algum dos dois, só ajuste a variável correspondente no passo 0 e
> pule o `git clone` dele.

### 2. Confira se a máquina dá conta

```bash
deploy-doctor
```

Verifica Docker, disco, RAM e portas **antes** de você instalar qualquer coisa.
Se houver bloqueio, ele diz qual e como resolver — melhor descobrir agora do que
no meio do caminho.

### 3. A base compartilhada — uma vez por máquina

```bash
deploy-infra up
```

Na primeira execução ele cria o `$PATH_DEPLOY_SCRIPTS/infra/.env.dev` e pede duas
senhas. Gere com `openssl rand -hex 24` — o próprio arquivo explica. Rode de novo e sobem Traefik,
MariaDB, Redis e Mailpit, na rede `shared`.

### 4. O banco do seu produto

```bash
deploy-infra createdb acme --print-env > /tmp/acme-db.env
```

Cria database, usuário e senha. Você não abre cliente SQL nenhum.

### 5. Gerar o produto

```bash
deploy-scaffold-project acme.com \
  --from-kit "$PATH_KIT" \
  --dir "$PATH_PROJECT" \
  --db-env /tmp/acme-db.env \
  --apply
```

O `--dir` é o que garante que o projeto nasça onde você decidiu, e não no
diretório em que por acaso você estava.

Isso cria o projeto com os apps já renomeados (`code/api.acme.com`,
`code/platform.acme.com`), os envs apontando para a infra, e o ambiente de dev.

### 6. Resolver os domínios

O comando imprime as linhas. Acrescente ao `/etc/hosts` **da máquina onde roda o
navegador**:

```
127.0.0.1 acme.test www.acme.test
127.0.0.1 api.acme.test
127.0.0.1 platform.acme.test
```

> [!WARNING]
> Sem isso você **não toma erro** — `.test` não resolve e o navegador tenta
> uma busca ou um host aleatório. O sintoma não aponta para a causa.

### 7. Conferir antes de subir

```bash
deploy-doctor "$PATH_PROJECT"
```

Agora com o projeto, ele verifica o que o passo anterior pediu: se os domínios
resolvem e se o `DB_HOST` dos apps aponta para a infra. É a checagem que pega o
erro mais confuso do fluxo — sem a linha no `hosts` **o navegador não dá erro**.

### 8. Subir

```bash
cd "$PATH_PROJECT"
./deploy-run dev
```

> [!NOTE]
> **A primeira subida leva alguns minutos.** Cada app roda `composer install`
> e o Platform ainda faz `npm install`. Enquanto isso, `/login` já responde mas o
> painel devolve **500 com "Vite manifest not found"** — é o servidor do Vite
> ainda subindo. Espere o arquivo `code/platform.acme.com/public/hot` aparecer.

### 9. Migrar e entrar

> [!WARNING]
> **Espere o `composer install` terminar.** Rodar o `migrate` antes falha com
> um erro sobre `vendor/autoload.php` que não sugere "aguarde". Para saber se já
> pode:
>
> ```bash
> deploy-doctor "$PATH_PROJECT"     # diz se as dependências estão instaladas
> ```

```bash
docker exec acme-php-api sh -c 'cd api.acme.com && php artisan migrate --force'
docker exec acme-php-api sh -c 'cd api.acme.com && php artisan dev:token'
```

> [!TIP]
> O nome do container é `<slug>-php-api` e o app fica em `api.<seu-dominio>` dentro
> dele. O `deploy-scaffold-project` imprime estes dois comandos já preenchidos ao
> terminar — copie de lá.

O `dev:token` cria conta, assinatura e usuário, e imprime um link pronto:

```
http://platform.acme.test/auth/dev-login?token=…
```

Abra e você está no painel. **Sem conta no Spelt** — é o caminho de
desenvolvimento, e ele só existe fora de produção.

---

## Quatro repositórios, dois momentos

O produto que nasce daqui **não é um repositório só**. É uma árvore:

```
deploy.acme.com/          infraestrutura — compose, nginx, envs, hosts
└── code/
    ├── api.acme.com/     repositório próprio
    ├── platform.acme.com/  repositório próprio
    └── www.acme.com/     repositório próprio
```

O `.gitignore` do projeto ignora `/code/*` **de propósito**: os apps não moram
dentro do repositório de deploy. Cada um tem o seu repositório.

**Quem constrói as imagens é o repositório de deploy**, que guarda os
Dockerfiles em `.docker/Code/<app>/`. O repositório do app não builda: ele
versiona o commit e avisa. Um Dockerfile muda todos os apps num commit só, e o
contexto de build pode ser inspecionado antes do push — é o que permite a
varredura de segredo.

O `deploy-scaffold-project` já entrega tudo isso iniciado: `git init` e primeiro
commit em cada caixa. Você só cria os repositórios remotos e dá `push`.

> [!WARNING]
> **Não commite os apps dentro do repositório de deploy.** Parece funcionar e
> falha calado: o `/code/*` deixa o código de fora do commit, quem clonar recebe
> um `code/` vazio e nenhum erro aparece.

### Momento 1 — você monta o projeto

É o quickstart acima. O assistente ou os nove passos geram a árvore, e o
scaffold imprime, ao terminar, o comando de `remote add` + `push` de cada caixa.

### Momento 2 — alguém entra no projeto andando

Quem chega depois **não usa o kit**. O caminho é outro: clonar o repositório de
deploy, criar `code/` e clonar dentro dele cada app a que tem acesso — o
ambiente sobe com um subconjunto.

O scaffold gera esse runbook já preenchido com os nomes reais do seu produto,
dentro do próprio projeto:

```bash
cat deploy.acme.com/docs/onboarding.md
```

E o `deploy-doctor` reconhece essa situação: `code/` vazio vira erro apontando
para o onboarding, em vez de deixar o ambiente subir com diretórios vazios no
lugar dos apps.

---

## Depois de subir: construir o produto

O ambiente no ar é o começo. O passo seguinte é desenhar o que você vai fazer:

1. Duplique `docs/TEMPLATE.md` — o scaffold já o copiou para `deploy.acme.com/docs/`.
2. Descreva o produto: o que ele faz, o que cobra, o que limita.
3. **É aí que aparecem as necessidades reais** — quais planos, quais créditos,
   quais features. E é aí que você cria a conta no Spelt e configura o catálogo
   (`php artisan dev:spelt-catalog`).

Até esse ponto, nada de credencial externa é necessário.

---

## Produção

O deploy de produção **não** usa os scripts deste ambiente. Ele é:

```
push no repo do app → versiona e avisa o repo de deploy
     └─ o repo de deploy builda → GHCR → webhook do Coolify
```

Cada app já vem com o `notify-deploy.yml`, que versiona e avisa. Os Dockerfiles
e o workflow de build ficam no `deploy.<projeto>`, gerados pelo scaffold. O
runbook está em `deploy.<projeto>/docs/coolify-deploy.md`.

---

## Comandos úteis

| | |
|---|---|
| `deploy-infra status` | o que está no ar e em qual contexto Docker |
| `deploy-infra down` | para a base, preservando os dados |
| `deploy-infra reset` | apaga os volumes — banco do zero |
| `./deploy-run dev` | sobe o projeto |
| `./deploy-run dev stop` | para o projeto |
| `deploy-scaffold-app ./code` | confere se os artefatos de build estão em dia |

O ambiente respeita o **contexto Docker ativo**: local por padrão, ou uma VM
remota se você apontar o contexto para lá. Nada muda nos comandos.

---

## Documentação

| | |
|---|---|
| [`docs/technical/starter-kit.md`](docs/technical/starter-kit.md) | **A spec de arquitetura.** Por que o kit é assim: as decisões travadas, a camada de integração com o Spelt, entitlements, provisionamento e o que deliberadamente ficou de fora. |
| [`docs/starter-kit-ideas/`](docs/starter-kit-ideas/) | **Como desenhar o produto antes de codar.** O brief força as decisões que o kit precisa saber — como cobra, o que limita, o que provisiona. |
| [`docs/starter-kit-ideas/TEMPLATE.md`](docs/starter-kit-ideas/TEMPLATE.md) | O molde do brief. É o arquivo que o scaffold copia para `docs/` do seu projeto. |
| [`example-transcribe.md`](docs/starter-kit-ideas/example-transcribe.md) · [`example-menu.md`](docs/starter-kit-ideas/example-menu.md) | Dois briefs preenchidos, para ver o formato funcionando. |
| [`iporto/deploy`](https://github.com/iporto/deploy) | A biblioteca de deploy: `deploy-doctor`, `deploy-infra`, `deploy-run` e o assistente. Tem README próprio. |
| `deploy.<projeto>/docs/coolify-deploy.md` | Gerado no seu projeto pelo scaffold — o runbook de produção. |

---

## Licença

[MIT](LICENSE). Copie, modifique, publique e venda — inclusive comercialmente,
inclusive sem abrir o seu código. O kit existe para virar o seu produto.
反馈内容错误

看看同类模板

对比同技术栈与用途的模板,找到更适合的视觉与内容结构。