Skip to content

Commit 018a774

Browse files
agjsclaude
andcommitted
docs: lead onboarding with "Use this template"
Quickstart, monorepo-layout, deployment, 404, landing hero, root README, AGENTS, and the bootstrap compose.env.tftpl comment now point users at GitHub's "Use this template" button instead of fork-style clone language. This is a template repository; forks create lineage we don't want. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent aecc76e commit 018a774

8 files changed

Lines changed: 40 additions & 34 deletions

File tree

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Single repository: `apps/api`, `apps/ui`, `apps/docs`, `infra/compose`, `infra/b
77
```bash
88
bun run regen # cross-app generators (ACL, OpenAPI, lint-meta, docs JSON)
99
bun run check # drift checks before push
10-
bun run rename:project # one-shot fork rebrand (boringstack → your project)
10+
bun run rename:project # one-shot rebrand after Use this template (boringstack → your project)
1111
./setup.sh --up # boot local dev stack
1212
./scripts/audit-repo-settings.sh # diff GitHub repo settings vs .github/desired-repo-settings.json
1313
```

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
</p>
2222

2323
<p align="center">
24-
<strong>Production-ready from the first fork.</strong><br />
24+
<strong>Production-ready from the first template clone.</strong><br />
2525
One monorepo for the full stack.
2626
</p>
2727

apps/docs/src/components/landing/HeroSection.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,10 @@ export function HeroSection() {
1717
className="mt-[0.55rem] max-w-[38rem] text-balance text-[2.45rem] leading-[1.08] tracking-[-0.02em] text-[var(--bs-text)] min-[421px]:text-[2.65rem] min-[641px]:text-[3.25rem] lg:text-[3.75rem]"
1818
id="bs-hero-title"
1919
>
20-
Production-ready from the first fork.
20+
Production-ready from the first template clone.
2121
</h1>
2222
<p className="mt-[1.25rem] max-w-[34rem] text-pretty text-base leading-[1.55] text-[var(--bs-muted-strong)] min-[641px]:mt-[1.15rem] min-[641px]:text-[1.05rem]">
23-
GitHub templates for the full stack. Fork the org, boot with compose/dev.sh, deploy
24-
on Compose.
23+
A GitHub template repository for the full stack. Click <b>Use this template</b>, boot with compose/dev.sh, deploy on Compose.
2524
</p>
2625

2726
<div aria-label="Primary actions" className="mt-9 grid w-full max-w-full gap-3 min-[641px]:mt-[2.1rem] min-[641px]:w-[min(100%,30rem)] min-[641px]:gap-[0.65rem]">

apps/docs/src/content/docs/404.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import DocCallout from "../../components/DocCallout";
3434

3535
## Popular starting points
3636

37-
- **[Quickstart](/quickstart/)**: fork the templates, boot Compose, sign in.
37+
- **[Quickstart](/quickstart/)**: use the template, boot Compose, sign in.
3838
- **[Why BoringStack](/architecture/why-boringstack/)**: the thesis, the fit check, and what's in the box.
3939
- **[Stack at a glance](/architecture/stack/)**: runtime, libraries, and tools, one place.
4040
- **[Commands cheatsheet](/reference/commands/)**: every command you'll run on a normal day.

apps/docs/src/content/docs/architecture/monorepo-layout.mdx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ import FaqItem from "../../../components/FaqItem.tsx";
1313
<PageIntro
1414
eyebrow="Repository contract"
1515
actions={[
16-
{ label: "Quickstart", href: "/quickstart/#step-1-clone-the-monorepo" },
16+
{ label: "Quickstart", href: "/quickstart/#step-1-use-this-template" },
1717
{ label: "Separation of concerns", href: "/architecture/separation-of-concerns/" },
1818
]}
1919
facts={[
2020
{ value: "apps/", label: "api · ui · docs" },
2121
{ value: "infra/", label: "compose · bootstrap" },
22-
{ value: "1", label: "git clone" },
22+
{ value: "1", label: "template clone" },
2323
]}
2424
>
2525
BoringStack ships as a single monorepo. API, UI, docs site, and Compose infra
@@ -32,7 +32,7 @@ The runtime is composed from `apps/api`, `apps/ui`, and `infra/compose`. Optiona
3232
<DocFileTree
3333
root="boringstack/"
3434
title="Monorepo layout"
35-
caption="one clone, explicit join points"
35+
caption="one template clone, explicit join points"
3636
nodes={[
3737
{ name: "apps/api/", detail: "Bun + Elysia + Drizzle API" },
3838
{ name: "apps/ui/", detail: "Vite + React SPA" },
@@ -86,10 +86,12 @@ Each app keeps its own `package.json`, lockfile, and lint config. CI workflows l
8686
]}
8787
/>
8888

89-
<Aside type="note" title="Forking">
90-
Fork the whole monorepo on GitHub. API, UI, docs, Compose, and bootstrap
91-
infrastructure stay together in one tree. On a VPS, clone the monorepo and
92-
run Compose from `infra/compose/compose`.
89+
<Aside type="note" title="Use this template">
90+
The monorepo is a GitHub template. Click **Use this template** on
91+
[`boringstack-xyz/boringstack`](https://github.com/boringstack-xyz/boringstack)
92+
to create a fresh repo under your org — API, UI, docs, Compose, and bootstrap
93+
infrastructure all in one tree, no fork relationship. On a VPS, clone your repo
94+
and run Compose from `infra/compose/compose`.
9395
</Aside>
9496

9597
## What lives where

apps/docs/src/content/docs/quickstart.mdx

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Quickstart
3-
description: "Clone the BoringStack monorepo, run setup.sh, sign in at localhost:3001."
3+
description: "Use the BoringStack template on GitHub, clone your new repo, run setup.sh, sign in at localhost:3001."
44
---
55

66
import CommandRun from "../../components/docs-kit/CommandRun";
@@ -18,13 +18,13 @@ import FaqItem from "../../components/FaqItem.tsx";
1818
{ label: "What's running", href: "#whats-running" },
1919
]}
2020
facts={[
21-
{ value: "1", label: "git clone" },
21+
{ value: "1", label: "click Use this template" },
2222
{ value: "Docker", label: "only prerequisite" },
2323
{ value: "0", label: "local Node or Bun installs" },
2424
]}
2525
>
26-
Clone the [BoringStack monorepo](https://github.com/boringstack-xyz/boringstack),
27-
run `./setup.sh --up`, and Compose starts Postgres, Valkey, api-dev (migrations +
26+
Click **Use this template** on the [BoringStack monorepo](https://github.com/boringstack-xyz/boringstack),
27+
clone your new repo, run `./setup.sh --up`, and Compose starts Postgres, Valkey, api-dev (migrations +
2828
OpenAPI), and ui-dev (Vite on :3001 with generated client). Optional overlays:
2929
Mailpit, Bull Board, observability, GlitchTip.
3030
</PageIntro>
@@ -46,8 +46,8 @@ import FaqItem from "../../components/FaqItem.tsx";
4646
items={[
4747
{
4848
label: "01",
49-
title: "Clone the monorepo",
50-
body: "One repo contains apps/api, apps/ui, infra/compose, and apps/docs.",
49+
title: "Use this template",
50+
body: "Click \"Use this template\" on GitHub, then clone the new repo created under your org.",
5151
},
5252
{
5353
label: "02",
@@ -75,14 +75,18 @@ You now have Postgres, Valkey, the API, and the UI running locally with hot relo
7575
- About 4 GB of free RAM.
7676
- No local Node or Bun needed for the default path; everything runs in containers.
7777

78-
## Step 1. Clone the monorepo
78+
## Step 1. Use this template
79+
80+
The BoringStack monorepo is a [GitHub template repository](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template). On the [`boringstack-xyz/boringstack`](https://github.com/boringstack-xyz/boringstack) page, click **Use this template → Create a new repository** to make a fresh copy under your org with full ownership and no fork relationship.
81+
82+
Then clone the repo you just created:
7983

8084
```bash
81-
git clone https://github.com/boringstack-xyz/boringstack.git
82-
cd boringstack
85+
git clone https://github.com/<your-org>/<your-repo>.git
86+
cd <your-repo>
8387
```
8488

85-
Fork the monorepo on GitHub if you want your own copy under your org. API, UI, docs, Compose, and bootstrap infrastructure all live in this one tree.
89+
API, UI, docs, Compose, and bootstrap infrastructure all live in this one tree. Run `bun run rename:project` from the root any time to rebrand the BoringStack identifiers across the codebase.
8690

8791
<DocFileTree
8892
root="boringstack/"

apps/docs/src/content/docs/topics/deployment.mdx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Deployment
3-
description: Boring deployment. Single-host VPS, Docker, one monorepo fork, GHCR images, one prod profile. HTTPS via ACME, perimeter locked by Cloudflare.
3+
description: Boring deployment. Single-host VPS, Docker, one repo created from the GitHub template, GHCR images, one prod profile. HTTPS via ACME, perimeter locked by Cloudflare.
44
---
55

66
import { Aside } from "@astrojs/starlight/components";
@@ -23,8 +23,9 @@ import FaqItem from "../../../components/FaqItem.tsx";
2323
]}
2424
>
2525
BoringStack runs on a VPS you control: Docker Compose, GHCR images, Traefik
26-
TLS, and Cloudflare at the edge. Fork the monorepo, fill compose/.env, then
27-
boot the production profile manually or let OpenTofu do first provisioning.
26+
TLS, and Cloudflare at the edge. Use the GitHub template to create your repo,
27+
fill compose/.env, then boot the production profile manually or let OpenTofu
28+
do first provisioning.
2829
</PageIntro>
2930

3031
## The mental model
@@ -81,15 +82,15 @@ Push to `main` with changes under `apps/api` or `apps/ui`. Path-filtered release
8182

8283
## First-time wiring
8384

84-
Three things need configuring before the first deploy. The release workflows handle everything else from your monorepo fork URL.
85+
Three things need configuring before the first deploy. The release workflows handle everything else from your repo URL.
8586

8687
### 1. Publish images to GHCR
8788

88-
The API and UI release workflows run on push to `main` when their app paths change. They use `${{ github.event.repository.name }}` plus an app suffix, so a fork named `acme-stack` publishes `ghcr.io/<your-owner>/acme-stack-api:latest` and `ghcr.io/<your-owner>/acme-stack-ui:latest` automatically. The default `GITHUB_TOKEN` has `packages: write` via the workflow grant, so the first push from a freshly-forked repo works without secret setup.
89+
The API and UI release workflows run on push to `main` when their app paths change. They use `${{ github.event.repository.name }}` plus an app suffix, so a repo named `acme-stack` publishes `ghcr.io/<your-owner>/acme-stack-api:latest` and `ghcr.io/<your-owner>/acme-stack-ui:latest` automatically. The default `GITHUB_TOKEN` has `packages: write` via the workflow grant, so the first push from a fresh template clone works without secret setup.
8990

9091
After the first publish, **make the GHCR package public** so the VPS can pull without credentials:
9192

92-
1. Go to the fork's Packages tab and open both containers: `<repo>-api` and `<repo>-ui`.
93+
1. Go to your repo's Packages tab and open both containers: `<repo>-api` and `<repo>-ui`.
9394
2. Package settings → Change visibility → Public.
9495

9596
Without this, downstream consumers (your VPS) need a pull credential.
@@ -122,7 +123,7 @@ The module derives `IMAGE_OWNER`, `API_IMAGE_NAME=<repo>-api`, and `UI_IMAGE_NAM
122123

123124
Use this once, after Quickstart and before the first production boot:
124125

125-
- [ ] BoringStack monorepo forked under your org/user.
126+
- [ ] Repo created from the BoringStack template (**Use this template** on [`boringstack-xyz/boringstack`](https://github.com/boringstack-xyz/boringstack)) under your org/user.
126127
- [ ] First API and UI images published to GHCR (push to `main`, then watch each Actions tab).
127128
- [ ] GHCR packages set to **Public**, or the VPS has a pull credential.
128129
- [ ] `compose/.env` has `IMAGE_OWNER` and any renamed `API_IMAGE_NAME` / `UI_IMAGE_NAME`.
@@ -132,7 +133,7 @@ Use this once, after Quickstart and before the first production boot:
132133
- [ ] [Firewall & TLS](/runbooks/firewall-and-tls/) verified: Cloudflare can reach the origin, direct requests cannot.
133134
- [ ] [Backups](/runbooks/backups/) configured and at least one restore drill run.
134135
- [ ] [Cloudflare Email setup](/runbooks/cloudflare-email-setup/) completed if Cloudflare is your outbound mail provider.
135-
- [ ] Optional OpenTofu path: `terraform.tfvars` has fork URLs, real `domain`, and production secrets.
136+
- [ ] Optional OpenTofu path: `terraform.tfvars` has your repo URL, real `domain`, and production secrets.
136137

137138
## First-time deploy
138139

@@ -141,7 +142,7 @@ The preferred path is [Provisioning with OpenTofu](/topics/provisioning-with-tof
141142
Manual path if you'd rather:
142143

143144
1. Provision a Ubuntu VPS with Docker installed.
144-
2. Clone your monorepo fork onto the VPS.
145+
2. Clone the repo you created from the template onto the VPS.
145146
3. Write `compose/.env` with `PUBLIC_UI_HOST`, `ACME_EMAIL`, `IMAGE_OWNER`, and the rest from `.env.example`.
146147
4. `STACK=prod ./scripts/compose-up.sh pull && STACK=prod ./scripts/compose-up.sh up -d`.
147148
5. Run the [Firewall & TLS runbook](/runbooks/firewall-and-tls/) to verify Cloudflare-only ingress.

infra/bootstrap/modules/bootstrap/templates/compose.env.tftpl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ STACK=${stack}
88
PUBLIC_UI_HOST=${public_ui_host}
99
ACME_EMAIL=${acme_email}
1010

11-
# GHCR coordinates derived from monorepo_repo by tofu. A fork + rename flow
12-
# needs no manual image-name override here.
11+
# GHCR coordinates derived from monorepo_repo by tofu. A "Use this template" +
12+
# rename flow needs no manual image-name override here.
1313
IMAGE_OWNER=${image_owner}
1414
API_IMAGE_NAME=${api_image_name}
1515
UI_IMAGE_NAME=${ui_image_name}

0 commit comments

Comments
 (0)