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
6.4 KiB
name, description
| name | description |
|---|---|
| codeberg-pages | 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
- Static site content lives on a branch named
pages(per-repo site) — push your built site there. - On git-pages, pushing alone does not deploy. A webhook on the repo, pointed at the domain you want, is what triggers a deployment.
- A custom domain is bound to the repo by a TXT authorization record
(
_git-pages-repository.<domain>) plus the normal A/AAAA/CNAME records. - 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
pagesbranch 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
pagesand use Target URLhttps://<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.141AAAA→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 andwwweach 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://(nothttps://) 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-repositoryTXT value exactly matches the repo's HTTPS.gitURL, 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 usedhttp://for the first deploy. - "DNS is correct but site won't serve" → missing
_git-pages-repositoryTXT, or missing/mis-branch-filtered webhook. - CNAME resolves to
codeberg.page.<yourzone>→ missing trailing dot; set target tocodeberg.page.. - CAA present → ensure Let's Encrypt is allowed.
- Old
.domainsbehavior 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