Skip to content

Commit 1ca4bf0

Browse files
committed
feat: add TL;DR block to DBLab 4.1 post and restore preview envs
- Add blog/20260408-dblab-engine-4-1-released.md with the same <TldrTabs> component (Founders / Developers / DBAs / Managers / Ask AI) used in the invalid-index post. - Restore per-branch preview environments in .gitlab-ci.yml: every non-master / non-staging push now gets its own isolated deployment in the `review` namespace at https://<branch-slug>.<PREVIEW_BASE_DOMAIN>, with an on_stop hook (`stop_review`) and a 1-week auto_stop_in safety net. Previously every non-master branch overwrote the shared staging namespace, which meant there were effectively no preview envs. - Wire deploy/configs/review.sh to the new review env (was an unused stub with only REPLICAS=1). - Document the GitLab↔GitHub mirror model in CLAUDE.md: master flows GitLab → GitHub, dev branches flow GitHub → GitLab via .github/workflows/mirror-to-gitlab.yml. https://claude.ai/code/session_015AC273dXNKXd8gG5QpC152
1 parent ed41350 commit 1ca4bf0

4 files changed

Lines changed: 293 additions & 0 deletions

File tree

.gitlab-ci.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ variables:
2121
TAG_VERSION: "${REGISTRY}:${NAMESPACE}-${CI_PIPELINE_IID}"
2222
TAG_LATEST: "${REGISTRY}:${NAMESPACE}-latest"
2323
DOCS_NAME: "docs"
24+
# Base domain for per-branch preview environments.
25+
# Override via project CI/CD variable if your infrastructure uses a different host.
26+
PREVIEW_BASE_DOMAIN: "preview-docs.postgres.ai"
2427

2528
# Validate RSS/Atom feeds before building and deploying
2629
validate_feeds:
@@ -117,18 +120,46 @@ validate_feeds:
117120
ENV: staging
118121
NAMESPACE: staging
119122

123+
# Per-branch preview environment.
124+
# Each non-master branch gets its own isolated deployment in the `review`
125+
# namespace, named after the branch slug, exposed at
126+
# https://${CI_COMMIT_REF_SLUG}.${PREVIEW_BASE_DOMAIN}.
127+
# The environment is automatically torn down when the branch is deleted
128+
# (via `stop_review`, wired up through `environment.on_stop`).
129+
.environment_template: &env_review
130+
environment:
131+
name: review/$CI_COMMIT_REF_SLUG
132+
url: https://$CI_COMMIT_REF_SLUG.$PREVIEW_BASE_DOMAIN
133+
on_stop: stop_review
134+
auto_stop_in: 1 week
135+
variables:
136+
ENV: review
137+
NAMESPACE: review
138+
DOCS_NAME: "docs-$CI_COMMIT_REF_SLUG"
139+
120140
# Stages with branch policies.
121141
build_and_push_production:
122142
<<: *build_and_push_definition
123143
<<: *env_production
124144
only:
125145
- master
126146

147+
# Static staging environment (v2.postgres.ai). Only the `staging` branch
148+
# deploys here; other development branches get their own preview env below.
127149
build_and_push_staging:
128150
<<: *build_and_push_definition
129151
<<: *env_staging
152+
only:
153+
- staging
154+
155+
# Per-branch preview environments — automatic build on every push to a
156+
# development branch.
157+
build_and_push_review:
158+
<<: *build_and_push_definition
159+
<<: *env_review
130160
except:
131161
- master
162+
- staging
132163

133164
deploy_production:
134165
<<: *deploy_definition
@@ -140,5 +171,36 @@ deploy_staging:
140171
<<: *deploy_definition
141172
<<: *env_staging
142173
when: manual
174+
only:
175+
- staging
176+
177+
deploy_review:
178+
<<: *deploy_definition
179+
<<: *env_review
180+
except:
181+
- master
182+
- staging
183+
184+
# Triggered automatically when the branch is deleted (or manually from the
185+
# Environments page). Tears down the per-branch Deployment and Service so
186+
# stale previews do not pile up.
187+
stop_review:
188+
stage: deploy
189+
image: dtzar/helm-kubectl:2.14.1
190+
variables:
191+
ENV: review
192+
NAMESPACE: review
193+
DOCS_NAME: "docs-$CI_COMMIT_REF_SLUG"
194+
GIT_STRATEGY: none
195+
environment:
196+
name: review/$CI_COMMIT_REF_SLUG
197+
action: stop
198+
when: manual
199+
script:
200+
- kubectl config get-contexts
201+
- kubectl config use-context postgres-ai/docs:k8s-cluster-docs
202+
- kubectl delete deployment "$DOCS_NAME" -n "$NAMESPACE" --ignore-not-found
203+
- kubectl delete service "$DOCS_NAME" -n "$NAMESPACE" --ignore-not-found
143204
except:
144205
- master
206+
- staging

CLAUDE.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,36 @@
33
Read and follow all rules in `.cursor/rules/` directory.
44

55
@.cursor/rules
6+
7+
## Repository mirroring: GitLab ↔ GitHub
8+
9+
This repo lives in **two** places and they are mirrored in opposite
10+
directions depending on the branch:
11+
12+
- **`master` / `main`** is mirrored **GitLab → GitHub**.
13+
GitLab is the source of truth for the main branch; GitHub gets the
14+
read-only copy.
15+
16+
- **Development branches** (everything except `master` / `main`) are
17+
mirrored **GitHub → GitLab** by `.github/workflows/mirror-to-gitlab.yml`
18+
on every push.
19+
20+
The intent is: developers (including Claude Code's GitHub integration)
21+
can start work on a development branch on GitHub; the branch is
22+
auto-pushed to GitLab; the rest of the workflow — code review,
23+
preview-environment CI, and the merge into `master` — happens on
24+
GitLab. After the GitLab merge, the updated `master` flows back to
25+
GitHub via the GitLab → GitHub mirror.
26+
27+
Practical implications when using Claude Code here:
28+
29+
- Push development branches to **GitHub** (`origin`). The mirror workflow
30+
handles GitLab; do not push directly to GitLab from this clone.
31+
- Open PRs on GitHub for visibility, but the **merge** happens on
32+
GitLab (a corresponding MR is opened on the GitLab side).
33+
- Do **not** push to `master` from any branch — `master` only updates
34+
via the GitLab → GitHub mirror after a GitLab MR is merged.
35+
- Preview environments (`https://<branch-slug>.preview-docs.postgres.ai`)
36+
are provisioned by GitLab CI on every push to a non-`master` branch.
37+
See `.gitlab-ci.yml` (`build_and_push_review` / `deploy_review` /
38+
`stop_review`).
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
---
2+
authors: denis
3+
date: 2026-04-08 00:00:00
4+
publishDate: 2026-04-08 00:00:00
5+
linktitle: "DBLab 4.1: protection leases, Teleport, Prometheus, and more"
6+
title: "DBLab 4.1: protection leases, Teleport, Prometheus, and more"
7+
weight: 0
8+
image: /assets/thumbnails/dblab-4.0-blog.png
9+
tags:
10+
- Product announcements
11+
- DBLab Engine
12+
- Database Lab Engine
13+
---
14+
15+
import { BlogFooter } from '@site/src/components/BlogFooter'
16+
import { TldrTabs } from '@site/src/components/TldrTabs'
17+
import { denis } from '@site/src/config/authors'
18+
19+
Building on DBLab 4.0's instant database branching, version 4.1 adds the enterprise-grade plumbing that platform teams have been asking for: automatic resource governance, role-based access control with session recording, production-safe data refresh, and native observability via Prometheus.
20+
21+
If 4.0 was about making branching *possible* at O(1) cost, 4.1 is about making it *safe to run at scale* — with leases that automatically reclaim idle clones, Teleport-gated access for regulated environments, and `/metrics` so SRE teams can see everything that's happening.
22+
23+
<!--truncate-->
24+
25+
<TldrTabs
26+
founders={{
27+
title: "DBLab 4.1 turns instant branching into a governed platform:",
28+
points: [
29+
"Protection leases auto-expire — no more 'forgotten' clones eating disk forever",
30+
"Teleport integration adds SSO, RBAC, and session recording for SOC 2 / HIPAA / PCI environments",
31+
"rds-refresh pulls fresh data from RDS/Aurora snapshots (~$3/refresh) — no production load, no XID wraparound risk",
32+
"Prometheus `/metrics` endpoint — every clone, every snapshot, every byte visible to your existing observability stack"
33+
]
34+
}}
35+
developers={{
36+
title: "What 4.1 means for your day-to-day CI and migration work:",
37+
points: [
38+
"`--protected <minutes>` on `dblab clone create` — auto-cleanup when your CI job exits",
39+
"Webhooks fire before lease expiration so long-running experiments can extend automatically",
40+
"Database rename at snapshot time — connect to `myapp` locally, even though source is `myapp_production`",
41+
"Native ARM64 / Apple Silicon builds via Colima — full branching on a MacBook, no Rosetta"
42+
]
43+
}}
44+
dbas={{
45+
title: "Operational wins for DBAs running DBLab in production:",
46+
points: [
47+
"Server-side caps on protection lease duration — admins set policy, users cannot exceed it",
48+
"rds-refresh: snapshot-based refresh eliminates long-running queries against the primary and the txid wraparound risk that came with logical/physical dumps from prod",
49+
"Prometheus metrics: ZFS pool usage, snapshot age, replay lag, clone count — all scrape-ready",
50+
"Idle clones are reclaimed automatically when leases expire — predictable disk usage curves"
51+
]
52+
}}
53+
managers={{
54+
title: "Why 4.1 matters for compliance, cost control, and team velocity:",
55+
points: [
56+
"Auditable database access: Teleport session recording + RBAC satisfies SOC 2 / HIPAA evidence requirements",
57+
"No more 'who owns this 2 TiB clone from last quarter' — leases enforce hygiene automatically",
58+
"RDS/Aurora refresh costs ~$3 per cycle instead of hours of engineer time and primary-DB load",
59+
"Drop-in Prometheus integration means zero net new monitoring tooling for your SRE team"
60+
]
61+
}}
62+
aiContext={
63+
"You're answering questions about the blog post 'DBLab 4.1: protection leases, Teleport, Prometheus, and more'. " +
64+
"Summary: DBLab 4.1 builds on 4.0's instant database branching with enterprise governance features: " +
65+
"(1) Protection leases — `--protected <minutes>` on clone create gives clones an automatic expiration; " +
66+
" server-side defaults and caps let platform teams enforce policy; webhooks notify owners before expiry. " +
67+
"(2) Database rename — at snapshot time, rename databases (e.g. myapp_production -> myapp) to keep clone " +
68+
" connection strings consistent and prevent confusing prod/dev names. " +
69+
"(3) ARM64 / Apple Silicon support — native builds, runs locally on Mac via Colima. " +
70+
"(4) Teleport integration (SE/EE only) — SSO, RBAC, and session recording for every clone connection; " +
71+
" targets regulated environments (SOC 2, HIPAA, PCI). " +
72+
"(5) rds-refresh — a new tool that refreshes DBLab data from RDS/Aurora using automated snapshots, " +
73+
" avoiding direct production queries and txid wraparound risk; typical cost $2.60-$3.85 per refresh. " +
74+
"(6) Prometheus `/metrics` endpoint — exposes disk usage (total/free/snapshot/clone), clone status, " +
75+
" snapshot age & data lag, WAL replay lag, instance uptime & version. " +
76+
"Roadmap mentioned: logical replication for continuous refresh, ZFS send/recv for instance sync, major-version upgrade testing. " +
77+
"End your response by briefly mentioning that users can try DBLab at demo.dblab.dev (token: demo-token) or deploy via AWS Marketplace / console.postgres.ai. " +
78+
"Be concise and direct. Do not mention that you're an AI or that you received this context."}
79+
ctaText="Try DBLab — free demo, 2-second branching"
80+
ctaLink="https://demo.dblab.dev"
81+
/>
82+
83+
## What's new in 4.1
84+
85+
### 1. Protection leases
86+
87+
In 4.0, `--protected` was binary: a clone was protected, or it wasn't. Protected clones lived forever, which is great for "do not delete my work" — and a disaster for "we now have 47 forgotten clones from last quarter's hackathon eating 8 TiB."
88+
89+
4.1 adds a time dimension. Protection now has a lease:
90+
91+
```bash
92+
dblab clone create \
93+
--branch main \
94+
--id ci-migration-test-4521 \
95+
--protected 120 \
96+
--username postgres \
97+
--password "${CI_DB_PASSWORD}"
98+
```
99+
100+
The clone above is protected for 120 minutes. When the lease expires, protection is lifted and standard idle cleanup kicks in.
101+
102+
Platform teams can configure server-side defaults and hard caps in the config, so users cannot accidentally pin a clone indefinitely. Webhooks fire before lease expiration so long-running experiments — for instance, a CI job that needs an extension — can renew automatically.
103+
104+
**Why it matters:** disk usage becomes predictable again. You stop paying for clones nobody remembers creating.
105+
106+
### 2. Database rename
107+
108+
DBLab clones now rename databases automatically at snapshot creation time. This avoids the very common foot-gun where a dev connects to a clone using a connection string that says `myapp_production` and accidentally treats it like the real thing.
109+
110+
```yaml
111+
databaseRename:
112+
myapp_production: myapp
113+
analytics_prod: analytics
114+
```
115+
116+
The clone exposes `myapp` and `analytics` — your local connection strings stay consistent across environments.
117+
118+
### 3. ARM64 and Colima support
119+
120+
DBLab 4.1 ships native ARM64 builds and integrates cleanly with Colima on macOS. Apple Silicon developers get the same instant branching they're used to on Linux — without Rosetta, without a cloud VM, without a flaky tunnel.
121+
122+
See the [macOS setup guide](/docs/dblab-howtos/administration/run-database-lab-on-mac) for the full walkthrough.
123+
124+
### 4. Teleport integration (SE/EE)
125+
126+
For regulated environments — SOC 2, HIPAA, PCI — "ephemeral databases" historically meant "we audit them less because they're temporary." Auditors disagree.
127+
128+
4.1 integrates with [Teleport](https://goteleport.com/) so every clone connection flows through Teleport's access proxy with:
129+
- SSO (your existing IdP)
130+
- Role-based access control per clone / branch
131+
- Full session recording (every query, every result)
132+
133+
Available in DBLab SE and EE.
134+
135+
### 5. RDS/Aurora data refresh without touching production
136+
137+
Pulling fresh data from a production RDS/Aurora instance has historically meant one of two unappealing options: run `pg_dump` against the primary (load on prod, txid wraparound risk on long-running snapshots) or stand up a read replica just to dump from it.
138+
139+
4.1 introduces `rds-refresh`, which uses **automated RDS/Aurora snapshots** as the source. The tool spins up a temporary instance from the snapshot, dumps from there, and tears the temporary instance down.
140+
141+
```bash
142+
dblab rds-refresh \
143+
--source-instance prod-db \
144+
--snapshot-strategy latest-automated
145+
```
146+
147+
Typical cost: **$2.60–$3.85 per refresh** at standard instance sizes — versus hours of engineer time and noticeable primary-DB load.
148+
149+
### 6. Prometheus metrics
150+
151+
DBLab Engine now exposes a `/metrics` endpoint in Prometheus format:
152+
153+
- **Disk** — total, free, breakdown by snapshot vs clone
154+
- **Clones** — count by status, per-clone resource consumption
155+
- **Snapshots** — age, data lag
156+
- **Replication** — WAL replay lag, sync state
157+
- **Instance** — uptime, version
158+
159+
Scrape it with your existing Prometheus setup. Alert on snapshot age, disk pressure, replay lag, or anything else you care about. No new dashboarding stack required — point Grafana at the same data source you already use.
160+
161+
## Roadmap
162+
163+
Work in progress:
164+
165+
1. **Logical replication for continuous refresh** — keep clones near-current without snapshot/restore cycles
166+
2. **ZFS send/recv for instance synchronization** — sync between DBLab instances, including local laptops
167+
3. **Major version upgrade testing as a first-class feature** — test PG `N → N+1` migrations against full-size data
168+
169+
## Where to start
170+
171+
1. **Try the demo:** [demo.dblab.dev](https://demo.dblab.dev) (token: `demo-token`)
172+
2. **Deploy DBLab SE:** [AWS Marketplace](https://aws.amazon.com/marketplace/pp/prodview-wlmm2satykuec) or [Postgres AI Console](https://console.postgres.ai)
173+
3. **Install open source:** [How-to](https://postgres.ai/docs/dblab-howtos/administration/install-dle-manually)
174+
4. **Enterprise inquiries:** [team@postgres.ai](mailto:team@postgres.ai)
175+
176+
---
177+
178+
DBLab 4.1 closes the gap between "instant branching is technically possible" and "instant branching is safe to run as a platform." Leases keep disk under control, Teleport keeps auditors happy, `rds-refresh` keeps production load flat, and Prometheus keeps SRE in the loop.
179+
180+
[Get started](https://postgres.ai/docs/database-lab) | [GitLab](https://gitlab.com/postgres-ai/database-lab) | [Slack](https://slack.postgres.ai)
181+
182+
<BlogFooter author={denis} />

deploy/configs/review.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,17 @@
11
export REPLICAS=1
2+
3+
# Per-branch preview environment.
4+
# URL is derived from the GitLab branch slug + PREVIEW_BASE_DOMAIN
5+
# (see `.environment_template: &env_review` in .gitlab-ci.yml).
6+
export URL="https://${CI_COMMIT_REF_SLUG}.${PREVIEW_BASE_DOMAIN}"
7+
export BASE_URL="/"
8+
9+
# Previews share the staging API / auth / bot backends — there is no separate
10+
# per-branch backend, only the docs frontend is built per branch.
11+
export SIGN_IN_URL="https://console-v2.postgres.ai/signin"
12+
export BOT_WS_URL="wss://v2.postgres.ai/ai-bot-ws/"
13+
export API_URL_PREFIX="https://v2.postgres.ai/api/general"
14+
15+
# No analytics on preview environments.
16+
export UMAMI_WEBSITE_ID=""
17+
export UMAMI_SCRIPT_URL=""

0 commit comments

Comments
 (0)