docs(skills): add codeberg-pages site-publishing skill
Skill covering publishing a static site to Codeberg Pages, including custom domains on the new git-pages server: pages branch, A/AAAA + CNAME DNS, the _git-pages-repository TXT authorization record, per-domain deploy webhooks (http:// for first deploy), Let's Encrypt issuance, and the obsolete .domains file. Verified against docs.codeberg.org. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017k4W786WWd8yN1m4Ypuxzx
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
---
|
||||
name: codeberg-pages
|
||||
description: >-
|
||||
Publish a static site to Codeberg Pages, including custom domains on the new
|
||||
"git-pages" server. Use when deploying a site to Codeberg Pages, setting up or
|
||||
debugging a codeberg.page / custom-domain deployment, wiring the DNS records
|
||||
(A/AAAA, CNAME), the _git-pages-repository TXT authorization record, or the
|
||||
deploy webhook — or when a custom domain serves a TLS error / never gets a
|
||||
certificate. Covers the 2025→2026 migration off the old Pages Server v2
|
||||
(.domains file) to git-pages (webhook + TXT authorization).
|
||||
---
|
||||
|
||||
# Publishing a site to Codeberg Pages
|
||||
|
||||
Codeberg Pages migrated from the old **Pages Server v2** (automatic deploy,
|
||||
`.domains` file) to the new **git-pages** server. On git-pages a deployment is
|
||||
**webhook-triggered** and a custom domain is authorized by a **TXT record**, not
|
||||
by a file in the repo. If you're following older docs or a `.domains`-based
|
||||
`deploy.sh`, that's why things silently don't work.
|
||||
|
||||
> All values below were verified against the official docs
|
||||
> (<https://docs.codeberg.org/codeberg-pages/> and `.../using-custom-domain/`).
|
||||
> Codeberg changes these; re-check the docs if something behaves unexpectedly.
|
||||
|
||||
## The mental model
|
||||
|
||||
1. Static site content lives on a branch named **`pages`** (per-repo site) — push
|
||||
your built site there.
|
||||
2. On git-pages, pushing alone does **not** deploy. A **webhook** on the repo,
|
||||
pointed at the domain you want, is what triggers a deployment.
|
||||
3. A custom domain is bound to the repo by a **TXT authorization record**
|
||||
(`_git-pages-repository.<domain>`) plus the normal A/AAAA/CNAME records.
|
||||
4. TLS (Let's Encrypt) is issued **only after the first successful deployment**.
|
||||
Before that, browsers show a TLS error — that is expected, not a bug.
|
||||
|
||||
## Basic deploy (no custom domain, `*.codeberg.page`)
|
||||
|
||||
- Put the site on a `pages` branch and push it.
|
||||
- Add a webhook: repo **Settings → Webhooks → Forgejo**, Target URL
|
||||
`https://<username>.codeberg.page/<repository>/`, **Branch filter: `pages`**.
|
||||
- (User/org site: name the repo `pages` and use Target URL
|
||||
`https://<username>.codeberg.page/`.)
|
||||
|
||||
## Custom domain setup (git-pages)
|
||||
|
||||
Do all four. Missing #2 or #3 is the usual cause of "DNS looks right but the site
|
||||
won't serve / no certificate."
|
||||
|
||||
### 1. DNS: point the domain at Codeberg
|
||||
|
||||
Exact values (verify against the docs — Codeberg has changed IPs before):
|
||||
|
||||
- **Apex domain** (`example.org`):
|
||||
- `A` → `217.197.84.141`
|
||||
- `AAAA` → `2a0a:4580:103f:c0de::2`
|
||||
- **Subdomain** (`www.example.org`, `foo.example.org`):
|
||||
- `CNAME` → `codeberg.page.` ← **note the trailing dot.**
|
||||
|
||||
**Trailing-dot trap:** in a zone file / most DNS UIs, a CNAME target *without* a
|
||||
trailing dot is treated as relative and the zone is appended — e.g. entering
|
||||
`codeberg.page` (or an old `<user>.codeberg.page`) can resolve to
|
||||
`codeberg.page.example.org.`, which is broken. Always use the fully-qualified
|
||||
`codeberg.page.` with the dot. (ALIAS/ANAME works where CNAME isn't allowed, but
|
||||
conflicts with DNSSEC-signed zones.)
|
||||
|
||||
### 2. TXT authorization record (this is how git-pages maps domain → repo)
|
||||
|
||||
Create one **per domain** you serve:
|
||||
|
||||
```
|
||||
_git-pages-repository.example.org. TXT "https://codeberg.org/<user>/<repo>.git"
|
||||
```
|
||||
|
||||
- Name: the `_git-pages-repository.` prefix on the exact domain (including each
|
||||
subdomain you serve — apex and `www` each need their own if both are used).
|
||||
- Value: the **HTTPS clone URL** of the repo, ending in `.git`.
|
||||
- (If you deploy via **Forgejo Actions** instead of a webhook, the record is
|
||||
`_git-pages-forge-allowlist.<domain>` with the same clone-URL value.)
|
||||
|
||||
### 3. Deploy webhook (per domain)
|
||||
|
||||
Repo **Settings → Webhooks → Forgejo**:
|
||||
|
||||
- **Target URL:** the domain itself, and **`http://` (not `https://`) for the
|
||||
first deployment** — this is documented, not a mistake (the cert doesn't exist
|
||||
yet). One webhook per domain, e.g. `http://example.org`, `http://foo.example.org`.
|
||||
- **Branch filter:** `pages`.
|
||||
- After the first successful deploy and cert issuance, you may switch the Target
|
||||
URLs to `https://`.
|
||||
|
||||
### 4. Trigger the first deploy
|
||||
|
||||
**Push to the `pages` branch** (re-run your deploy script / `git push origin pages`).
|
||||
The push fires the webhook, git-pages pulls and deploys, then requests a
|
||||
Let's Encrypt certificate.
|
||||
|
||||
- **Do NOT rely on the webhook "Test delivery" button** — the official docs say it
|
||||
fails by design and is not a valid way to verify or trigger a deploy. Verify by
|
||||
pushing and then checking the webhook's recent-deliveries log, or just load the
|
||||
site. (This corrects a common misconception that "Test delivery" triggers a deploy.)
|
||||
|
||||
## The `.domains` file is obsolete
|
||||
|
||||
Under the old Pages Server v2, a `.domains` file in the branch listed the domains
|
||||
and did apex-vs-alias redirects. On git-pages it is **no longer used** — authorization
|
||||
comes from the TXT record. It's harmless to leave, but you can delete it (and drop any
|
||||
`.domains` handling from `deploy.sh`). Bonus: on git-pages each domain gets its **own**
|
||||
deployment, so a second domain serves the site directly instead of 301-redirecting to
|
||||
the primary as the old `.domains` system did.
|
||||
|
||||
## TLS / certificate notes
|
||||
|
||||
- A cert is issued **only after the first successful webhook deployment**. A TLS
|
||||
error before that is expected.
|
||||
- If the domain has **CAA records**, they must allow Let's Encrypt (including the
|
||||
staging issuer) or the cert request is refused.
|
||||
- Cert still never issues after a successful deploy → confirm the `_git-pages-repository`
|
||||
TXT value exactly matches the repo's HTTPS `.git` URL, and that the webhook Target
|
||||
URL matches the domain.
|
||||
|
||||
## Quick troubleshooting checklist
|
||||
|
||||
- Browser TLS error, no cert → no successful deploy yet. Check webhook deliveries;
|
||||
push to `pages`; confirm webhook Target URL used `http://` for the first deploy.
|
||||
- "DNS is correct but site won't serve" → missing `_git-pages-repository` TXT, or
|
||||
missing/mis-branch-filtered webhook.
|
||||
- CNAME resolves to `codeberg.page.<yourzone>` → missing trailing dot; set target to
|
||||
`codeberg.page.`.
|
||||
- CAA present → ensure Let's Encrypt is allowed.
|
||||
- Old `.domains` behavior expected (redirects) → gone on git-pages; each domain now
|
||||
deploys independently.
|
||||
|
||||
## Sources
|
||||
|
||||
- Codeberg Pages: <https://docs.codeberg.org/codeberg-pages/>
|
||||
- Using custom domains: <https://docs.codeberg.org/codeberg-pages/using-custom-domain/>
|
||||
- pages-server (now in maintenance, superseded by git-pages):
|
||||
<https://codeberg.org/Codeberg/pages-server>
|
||||
Reference in New Issue
Block a user