The Codeberg Pages Server – with custom domain support, per-repo pages using the "pages" branch, caching and much more! Easy to selfhost too!
Find a file
Dependency bot 65487e41fb fix(deps): update golang deps non-major (#437)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| code.gitea.io/sdk/gitea | require | minor | `v0.20.0` -> `v0.21.0` |
| [github.com/go-acme/lego/v4](https://github.com/go-acme/lego) | require | minor | `v4.21.0` -> `v4.23.1` |
| [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql) | require | minor | `v1.8.1` -> `v1.9.2` |
| [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) | require | patch | `v1.14.24` -> `v1.14.28` |
| [github.com/pelletier/go-toml/v2](https://github.com/pelletier/go-toml) | require | patch | `v2.2.3` -> `v2.2.4` |
| [github.com/pires/go-proxyproto](https://github.com/pires/go-proxyproto) | require | patch | `v0.8.0` -> `v0.8.1` |
| [github.com/reugn/equalizer](https://github.com/reugn/equalizer) | require | minor | `v0.0.0-20210216135016-a959c509d7ad` -> `v0.2.0` |
| [github.com/rs/zerolog](https://github.com/rs/zerolog) | require | minor | `v1.33.0` -> `v1.34.0` |
| [github.com/urfave/cli/v2](https://github.com/urfave/cli) | require | patch | `v2.27.5` -> `v2.27.6` |

---

### Release Notes

<details>
<summary>go-acme/lego (github.com/go-acme/lego/v4)</summary>

### [`v4.23.1`](https://github.com/go-acme/lego/blob/HEAD/CHANGELOG.md#v4231-2025-04-16)

[Compare Source](https://github.com/go-acme/lego/compare/v4.23.0...v4.23.1)

Due to an error related to Snapcraft, some artifacts of the v4.23.0 release have not been published.

This release contains the same things as v4.23.0.

### [`v4.23.0`](https://github.com/go-acme/lego/blob/HEAD/CHANGELOG.md#v4230-2025-04-16)

[Compare Source](https://github.com/go-acme/lego/compare/v4.22.2...v4.23.0)

##### Added

-   **\[dnsprovider]** Add DNS provider for Active24
-   **\[dnsprovider]** Add DNS provider for BookMyName
-   **\[dnsprovider]** Add DNS provider for Axelname
-   **\[dnsprovider]** Add DNS provider for Baidu Cloud
-   **\[dnsprovider]** Add DNS provider for Metaregistrar
-   **\[dnsprovider]** Add DNS provider for F5 XC
-   **\[dnsprovider]** Add INFOBLOX_CA_CERTIFICATE option
-   **\[dnsprovider]** route53: adds option to use private zone
-   **\[dnsprovider]** edgedns: add account switch key option
-   **\[dnsprovider]** infoblox: update API client to v2
-   **\[lib,cli]** Add delay option for TLSALPN challenge

##### Changed

-   **\[dnsprovider]** designate: speed up API requests by using filters
-   **\[dnsprovider]** cloudflare: make base URL configurable
-   **\[dnsprovider]** websupport: migrate to API v2
-   **\[dnsprovider]** dnssimple: use GetZone

##### Fixed

-   **\[ari]** Fix retry on `alreadyReplaced` error
-   **\[cli,log]** Fix malformed log messages
-   **\[cli]** Kill hook when the command is stuck
-   **\[dnsprovider]** pdns: fix TXT record cleanup for wildcard domains
-   **\[dnsprovider]** allinkl: remove `ReturnInfo`

### [`v4.22.2`](https://github.com/go-acme/lego/blob/HEAD/CHANGELOG.md#v4222-2025-02-17)

[Compare Source](https://github.com/go-acme/lego/compare/v4.22.1...v4.22.2)

##### Fixed

-   **\[dnsprovider]** acme-dns: use new registred account

### [`v4.22.1`](https://github.com/go-acme/lego/blob/HEAD/CHANGELOG.md#v4221-2025-02-17)

[Compare Source](https://github.com/go-acme/lego/compare/v4.22.0...v4.22.1)

##### Fixed

-   **\[dnsprovider]** acme-dns: continue the process when the CNAME is handled by the storage

##### Added

### [`v4.22.0`](https://github.com/go-acme/lego/blob/HEAD/CHANGELOG.md#v4220-2025-02-17)

[Compare Source](https://github.com/go-acme/lego/compare/v4.21.0...v4.22.0)

##### Added

-   **\[cli]** Add `--private-key` flag to set the private key.
-   **\[cli]** Add `LEGO_DEBUG_ACME_HTTP_CLIENT` environment variable to debug the calls to the ACME server.
-   **\[cli]** Add `LEGO_EMAIL` environment variable for specifying email.
-   **\[cli]** Add `--hook-timeout` flag to run and renew commands.
-   **\[dnsprovider]** Add DNS provider for myaddr.{tools,dev,io}
-   **\[dnsprovider]** Add DNS provider for Spaceship
-   **\[dnsprovider]** acme-dns: add HTTP storage
-   **\[lib,cli,httpprovider]** Add `--http.delay` option for HTTP challenge.
-   **\[lib,cli,profiles]** Add support for Profiles Extension.
-   **\[lib]** Add an option to set CSR email addresses

##### Changed

-   **\[lib]** rewrite status management
-   **\[dnsprovider]** docs: improve units and default values

##### Removed

-   **\[dnsprovider]** netcup: remove TTL option

##### Fixed

-   **\[cli,log]** remove extra debug logs

</details>

<details>
<summary>go-sql-driver/mysql (github.com/go-sql-driver/mysql)</summary>

### [`v1.9.2`](https://github.com/go-sql-driver/mysql/blob/HEAD/CHANGELOG.md#v192-2025-04-07)

[Compare Source](https://github.com/go-sql-driver/mysql/compare/v1.9.1...v1.9.2)

v1.9.2 is a re-release of v1.9.1 due to a release process issue; no changes were made to the content.

### [`v1.9.1`](https://github.com/go-sql-driver/mysql/blob/HEAD/CHANGELOG.md#v191-2025-03-21)

[Compare Source](https://github.com/go-sql-driver/mysql/compare/v1.9.0...v1.9.1)

##### Major Changes

-   Add Charset() option. ([#&#8203;1679](https://github.com/go-sql-driver/mysql/issues/1679))

##### Bugfixes

-   go.mod: fix go version format ([#&#8203;1682](https://github.com/go-sql-driver/mysql/issues/1682))
-   Fix FormatDSN missing ConnectionAttributes ([#&#8203;1619](https://github.com/go-sql-driver/mysql/issues/1619))

### [`v1.9.0`](https://github.com/go-sql-driver/mysql/blob/HEAD/CHANGELOG.md#v190-2025-02-18)

[Compare Source](https://github.com/go-sql-driver/mysql/compare/v1.8.1...v1.9.0)

##### Major Changes

-   Implement zlib compression. ([#&#8203;1487](https://github.com/go-sql-driver/mysql/issues/1487))
-   Supported Go version is updated to Go 1.21+. ([#&#8203;1639](https://github.com/go-sql-driver/mysql/issues/1639))
-   Add support for VECTOR type introduced in MySQL 9.0. ([#&#8203;1609](https://github.com/go-sql-driver/mysql/issues/1609))
-   Config object can have custom dial function. ([#&#8203;1527](https://github.com/go-sql-driver/mysql/issues/1527))

##### Bugfixes

-   Fix auth errors when username/password are too long. ([#&#8203;1625](https://github.com/go-sql-driver/mysql/issues/1625))
-   Check if MySQL supports CLIENT_CONNECT_ATTRS before sending client attributes. ([#&#8203;1640](https://github.com/go-sql-driver/mysql/issues/1640))
-   Fix auth switch request handling. ([#&#8203;1666](https://github.com/go-sql-driver/mysql/issues/1666))

##### Other changes

-   Add "filename:line" prefix to log in go-mysql. Custom loggers now show it. ([#&#8203;1589](https://github.com/go-sql-driver/mysql/issues/1589))
-   Improve error handling. It reduces the "busy buffer" errors. ([#&#8203;1595](https://github.com/go-sql-driver/mysql/issues/1595), [#&#8203;1601](https://github.com/go-sql-driver/mysql/issues/1601), [#&#8203;1641](https://github.com/go-sql-driver/mysql/issues/1641))
-   Use `strconv.Atoi` to parse max_allowed_packet. ([#&#8203;1661](https://github.com/go-sql-driver/mysql/issues/1661))
-   `rejectReadOnly` option now handles ER_READ_ONLY_MODE (1290) error too. ([#&#8203;1660](https://github.com/go-sql-driver/mysql/issues/1660))

</details>

<details>
<summary>mattn/go-sqlite3 (github.com/mattn/go-sqlite3)</summary>

### [`v1.14.28`](https://github.com/mattn/go-sqlite3/compare/v1.14.27...v1.14.28)

[Compare Source](https://github.com/mattn/go-sqlite3/compare/v1.14.27...v1.14.28)

### [`v1.14.27`](https://github.com/mattn/go-sqlite3/compare/v1.14.26...v1.14.27)

[Compare Source](https://github.com/mattn/go-sqlite3/compare/v1.14.26...v1.14.27)

### [`v1.14.26`](https://github.com/mattn/go-sqlite3/compare/v1.14.25...v1.14.26)

[Compare Source](https://github.com/mattn/go-sqlite3/compare/v1.14.25...v1.14.26)

### [`v1.14.25`](https://github.com/mattn/go-sqlite3/compare/v1.14.24...v1.14.25)

[Compare Source](https://github.com/mattn/go-sqlite3/compare/v1.14.24...v1.14.25)

</details>

<details>
<summary>pelletier/go-toml (github.com/pelletier/go-toml/v2)</summary>

### [`v2.2.4`](https://github.com/pelletier/go-toml/releases/tag/v2.2.4)

[Compare Source](https://github.com/pelletier/go-toml/compare/v2.2.3...v2.2.4)

<!-- Release notes generated using configuration in .github/release.yml at v2.2.4 -->

#### Highlight

In this release, [@&#8203;mikattack](https://github.com/mikattack) removed the last dependency of go-toml! 🎉  (https://github.com/pelletier/go-toml/pull/981)

#### What's Changed

##### Documentation

-   Fix typos in comments and tests by [@&#8203;alexandear](https://github.com/alexandear) in https://github.com/pelletier/go-toml/pull/972

##### Other changes

-   Replace `stretchr/testify` with an internal test suite by [@&#8203;mikattack](https://github.com/mikattack) in https://github.com/pelletier/go-toml/pull/981
-   Update to go 1.24 by [@&#8203;pelletier](https://github.com/pelletier) in https://github.com/pelletier/go-toml/pull/982

#### New Contributors

-   [@&#8203;alexandear](https://github.com/alexandear) made their first contribution in https://github.com/pelletier/go-toml/pull/972
-   [@&#8203;mikattack](https://github.com/mikattack) made their first contribution in https://github.com/pelletier/go-toml/pull/981

**Full Changelog**: https://github.com/pelletier/go-toml/compare/v2.2.3...v2.2.4

</details>

<details>
<summary>pires/go-proxyproto (github.com/pires/go-proxyproto)</summary>

### [`v0.8.1`](https://github.com/pires/go-proxyproto/releases/tag/v0.8.1)

[Compare Source](https://github.com/pires/go-proxyproto/compare/v0.8.0...v0.8.1)

#### What's Changed

-   Fix Go Documentation of Default timeout by [@&#8203;TheM1984](https://github.com/TheM1984) in https://github.com/pires/go-proxyproto/pull/121
-   build(deps): bump golang.org/x/net from 0.23.0 to 0.36.0 by [@&#8203;dependabot](https://github.com/dependabot) in https://github.com/pires/go-proxyproto/pull/122
-   bump Go and golang.org/x/net by [@&#8203;pires](https://github.com/pires) in https://github.com/pires/go-proxyproto/pull/125

#### New Contributors

-   [@&#8203;TheM1984](https://github.com/TheM1984) made their first contribution in https://github.com/pires/go-proxyproto/pull/121

**Full Changelog**: https://github.com/pires/go-proxyproto/compare/v0.8.0...v0.8.1

</details>

<details>
<summary>rs/zerolog (github.com/rs/zerolog)</summary>

### [`v1.34.0`](https://github.com/rs/zerolog/compare/v1.33.0...v1.34.0)

[Compare Source](https://github.com/rs/zerolog/compare/v1.33.0...v1.34.0)

</details>

<details>
<summary>urfave/cli (github.com/urfave/cli/v2)</summary>

### [`v2.27.6`](https://github.com/urfave/cli/releases/tag/v2.27.6)

[Compare Source](https://github.com/urfave/cli/compare/v2.27.5...v2.27.6)

#### What's Changed

-   Use usage template in subcommand help by [@&#8203;meatballhat](https://github.com/meatballhat) in https://github.com/urfave/cli/pull/1986
-   Docs: Update cli.yml by [@&#8203;dearchap](https://github.com/dearchap) in https://github.com/urfave/cli/pull/2015
-   Fix:(issue\_2069) Add sep for string slice by [@&#8203;dearchap](https://github.com/dearchap) in https://github.com/urfave/cli/pull/2070

**Full Changelog**: https://github.com/urfave/cli/compare/v2.27.5...v2.27.6

</details>

---

### Configuration

📅 **Schedule**: Branch creation - Between 12:00 AM and 03:59 AM ( * 0-3 * * * ) (UTC), Automerge - Between 12:00 AM and 03:59 AM ( * 0-3 * * * ) (UTC).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://github.com/renovatebot/renovate/discussions) if that's undesired.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xNzYuNCIsInVwZGF0ZWRJblZlciI6IjM5LjI2NC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: woodpecker-bot <woodpecker-bot@obermui.de>
Co-authored-by: crapStone <me@crapstone.dev>
Reviewed-on: https://codeberg.org/Codeberg/pages-server/pulls/437
Co-authored-by: Dependency bot <renovate-bot@noreply.codeberg.org>
Co-committed-by: Dependency bot <renovate-bot@noreply.codeberg.org>
2025-06-10 23:54:25 +02:00
.gitea/ISSUE_TEMPLATE Meta: Redirect user support to Codeberg/Community (#277) 2024-01-18 20:35:32 +00:00
.helix chore: make project helix ready 2025-06-10 23:24:49 +02:00
.vscode Add config file and rework cli parsing and passing of config values (#263) 2024-02-15 16:08:29 +00:00
.woodpecker chore(deps): update woodpeckerci/plugin-docker-buildx docker tag to v6 (#494) 2025-06-10 21:34:40 +02:00
cli feat: add proxy protocol support (#394) 2024-10-29 17:56:00 +00:00
config feat: add proxy protocol support (#394) 2024-10-29 17:56:00 +00:00
examples/haproxy-sni Add prettier config and format files (#319) 2024-04-28 20:47:04 +00:00
html Allow serving custom error page (#393) 2024-11-17 16:28:52 +00:00
integration Add config file and rework cli parsing and passing of config values (#263) 2024-02-15 16:08:29 +00:00
server fix: timeout issue of gitea sdk client (#422) 2025-01-17 19:49:16 +00:00
.ecrc Add editorconfig, fix files and lint via ci 2022-11-11 23:51:45 +01:00
.editorconfig Add editorconfig, fix files and lint via ci 2022-11-11 23:51:45 +01:00
.env-dev Add config file and rework cli parsing and passing of config values (#263) 2024-02-15 16:08:29 +00:00
.envrc setup direnv (#433) 2025-02-15 19:32:29 +00:00
.gitignore setup direnv (#433) 2025-02-15 19:32:29 +00:00
.golangci.yml Add cert store option based on sqlite3, mysql & postgres (#173) 2023-02-10 03:00:14 +00:00
.prettierrc.json Add prettier config and format files (#319) 2024-04-28 20:47:04 +00:00
.yamllint.yaml Add yamllint (#321) 2024-04-28 21:48:07 +00:00
Dockerfile chore: update golang (#431) 2025-02-15 19:08:08 +00:00
example_config.toml Rename gitea to forge in cli args and env variables (#339) 2024-05-26 14:45:03 +00:00
FEATURES.md Add prettier config and format files (#319) 2024-04-28 20:47:04 +00:00
flake.lock chore: make project helix ready 2025-06-10 23:24:49 +02:00
flake.nix chore: make project helix ready 2025-06-10 23:24:49 +02:00
go.mod fix(deps): update golang deps non-major (#437) 2025-06-10 23:54:25 +02:00
go.sum fix(deps): update golang deps non-major (#437) 2025-06-10 23:54:25 +02:00
Justfile Add option to start http server for profiling (#323) 2024-04-30 19:50:03 +00:00
LICENSE Release under EUPL v. 1.2 2021-03-17 01:21:50 +01:00
main.go Add config file and rework cli parsing and passing of config values (#263) 2024-02-15 16:08:29 +00:00
README.md Allow serving custom error page (#393) 2024-11-17 16:28:52 +00:00
renovate.json chore: Configure Renovate (#284) 2024-04-27 18:47:42 +00:00
treefmt.toml chore: make project helix ready 2025-06-10 23:24:49 +02:00

Codeberg Pages

License: EUPL-1.2 status-badge

Gitea lacks the ability to host static pages from Git. The Codeberg Pages Server addresses this lack by implementing a standalone service that connects to Gitea via API. It is suitable to be deployed by other Gitea instances, too, to offer static pages hosting to their users.

End user documentation can mainly be found at the Wiki and the Codeberg Documentation.

Get It On Codeberg

Quickstart

This is the new Codeberg Pages server, a solution for serving static pages from Gitea repositories. Mapping custom domains is not static anymore, but can be done with DNS:

  1. add a .domains text file to your repository, containing the allowed domains, separated by new lines. The first line will be the canonical domain/URL; all other occurrences will be redirected to it.

  2. add a CNAME entry to your domain, pointing to [[{branch}.]{repo}.]{owner}.codeberg.page (repo defaults to "pages", "branch" defaults to the default branch if "repo" is "pages", or to "pages" if "repo" is something else. If the branch name contains slash characters, you need to replace "/" in the branch name to "~"): www.example.org. IN CNAME main.pages.example.codeberg.page.

  3. if a CNAME is set for "www.example.org", you can redirect there from the naked domain by adding an ALIAS record for "example.org" (if your provider allows ALIAS or similar records, otherwise use A/AAAA), together with a TXT record that points to your repo (just like the CNAME record): example.org IN ALIAS codeberg.page. example.org IN TXT main.pages.example.codeberg.page.

Certificates are generated, updated and cleaned up automatically via Let's Encrypt through a TLS challenge.

Chat for admins & devs

matrix: #gitea-pages-server:matrix.org

Deployment

Warning: Some Caveats Apply

Currently, the deployment requires you to have some knowledge of system administration as well as understanding and building code, so you can eventually edit non-configurable and codeberg-specific settings. In the future, we'll try to reduce these and make hosting Codeberg Pages as easy as setting up Gitea. If you consider using Pages in practice, please consider contacting us first, we'll then try to share some basic steps and document the current usage for admins (might be changing in the current state).

Deploying the software itself is very easy. You can grab a current release binary or build yourself, configure the environment as described below, and you are done.

The hard part is about adding custom domain support if you intend to use it. SSL certificates (request + renewal) is automatically handled by the Pages Server, but if you want to run it on a shared IP address (and not a standalone), you'll need to configure your reverse proxy not to terminate the TLS connections, but forward the requests on the IP level to the Pages Server.

You can check out a proof of concept in the examples/haproxy-sni folder, and especially have a look at this section of the haproxy.cfg.

If you want to test a change, you can open a PR and ask for the label build_pr_image to be added. This will trigger a build of the PR which will build a docker image to be used for testing.

Environment Variables

  • ACME_ACCEPT_TERMS (default: use self-signed certificate): Set this to "true" to accept the Terms of Service of your ACME provider.
  • ACME_API (default: https://acme-v02.api.letsencrypt.org/directory): set this to https://acme.mock.directory to use invalid certificates without any verification (great for debugging). ZeroSSL might be better in the future as it doesn't have rate limits and doesn't clash with the official Codeberg certificates (which are using Let's Encrypt), but I couldn't get it to work yet.
  • ACME_EAB_KID & ACME_EAB_HMAC (default: don't use EAB): EAB credentials, for example for ZeroSSL.
  • ACME_EMAIL (default: noreply@example.email): Set the email sent to the ACME API server to receive, for example, renewal reminders.
  • ACME_USE_RATE_LIMITS (default: true): Set this to false to disable rate limits, e.g. with ZeroSSL.
  • DNS_PROVIDER (default: use self-signed certificate): Code of the ACME DNS provider for the main domain wildcard. See https://go-acme.github.io/lego/dns/ for available values & additional environment variables.
  • ENABLE_HTTP_SERVER (default: false): Set this to true to enable the HTTP-01 challenge and redirect all other HTTP requests to HTTPS. Currently only works with port 80.
  • GITEA_API_TOKEN (default: empty): API token for the Gitea instance to access non-public (e.g. limited) repos.
  • GITEA_ROOT (default: https://codeberg.org): root of the upstream Gitea instance.
  • HOST & PORT (default: [::] & 443): listen address.
  • LOG_LEVEL (default: warn): Set this to specify the level of logging.
  • NO_DNS_01 (default: false): Disable the use of ACME DNS. This means that the wildcard certificate is self-signed and all domains and subdomains will have a distinct certificate. Because this may lead to a rate limit from the ACME provider, this option is not recommended for Gitea/Forgejo instances with open registrations or a great number of users/orgs.
  • PAGES_DOMAIN (default: codeberg.page): main domain for pages.
  • RAW_DOMAIN (default: raw.codeberg.page): domain for raw resources (must be subdomain of PAGES_DOMAIN).

Custom Error Page

A custom error page template can be served by creating custom/error.html. Data available to the template includes:

  • {{ .StatusCode }}: The HTTP status code (e.g. 404)
  • {{ .StatusText }}: The textual name associated with the status code (e.g. Not Found)
  • {{ .Message }}: The reason for the error

Contributing to the development

The Codeberg team is very open to your contribution. Since we are working nicely in a team, it might be hard at times to get started (still check out the issues, we always aim to have some things to get you started).

If you have any questions, want to work on a feature or could imagine collaborating with us for some time, feel free to ping us in an issue or in a general Matrix chat room.

You can also contact the maintainer(s) of this project:

Previous maintainers:

First steps

The code of this repository is split in several modules. The Architecture is explained in the wiki.

The cmd folder holds the data necessary for interacting with the service via the cli. The heart of the software lives in the server folder and is split in several modules.

Again: Feel free to get in touch with us for any questions that might arise. Thank you very much.

Test Server

Make sure you have golang v1.21 or newer and just installed.

run just dev now these pages should work:

Profiling

This section is just a collection of commands for quick reference. If you want to learn more about profiling read this article or google golang profiling.

First enable profiling by supplying the cli arg --enable-profiling or using the environment variable EENABLE_PROFILING.

Get cpu and mem stats:

go tool pprof -raw -output=cpu.txt 'http://localhost:9999/debug/pprof/profile?seconds=60' &
curl -so mem.txt 'http://localhost:9999/debug/pprof/heap?seconds=60'

More endpoints are documented here: https://pkg.go.dev/net/http/pprof