<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://mediawiki.comfac.net/index.php?action=history&amp;feed=atom&amp;title=Forgejo_Pages</id>
	<title>Forgejo Pages - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://mediawiki.comfac.net/index.php?action=history&amp;feed=atom&amp;title=Forgejo_Pages"/>
	<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Forgejo_Pages&amp;action=history"/>
	<updated>2026-06-05T11:00:18Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Forgejo_Pages&amp;diff=255&amp;oldid=prev</id>
		<title>Justinaquino: Added Forgejo Pages setup guide</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Forgejo_Pages&amp;diff=255&amp;oldid=prev"/>
		<updated>2026-04-28T13:24:36Z</updated>

		<summary type="html">&lt;p&gt;Added Forgejo Pages setup guide&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= Forgejo Pages — Complete Setup Guide =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;**Wiki:** wiki.gi7b.org | **Last updated:** 2026-04-28&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;**Status:** Production — `pages.gi7b.org` live on PC03&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Forgejo does &amp;#039;&amp;#039;&amp;#039;not&amp;#039;&amp;#039;&amp;#039; have a built-in static site server. To serve Pages, you run a&lt;br /&gt;
separate &amp;lt;code&amp;gt;ronmi/forgejo-pages&amp;lt;/code&amp;gt; container alongside Forgejo. It reads files from a&lt;br /&gt;
special branch in each repo via the Forgejo API and serves them over HTTP.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
Browser → Cloudflare DNS → NPM (SSL) → forgejo-pages:8080 → Forgejo API → repo branch&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* **Forgejo:** `https://git.gi7b.org` (container: `forgejo`, internal port 3000)&lt;br /&gt;
* **Pages server:** `https://pages.gi7b.org` (container: `forgejo-pages`, internal port 8080)&lt;br /&gt;
* **Routing:** path-based — `https://pages.gi7b.org/{owner}/{repo}/`&lt;br /&gt;
* **Branch name:** `static-pages` (exact, hardcoded default in this image)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Gotchas — Read This First ==&lt;br /&gt;
&lt;br /&gt;
=== 1. There is no built-in Pages in Forgejo ===&lt;br /&gt;
&amp;lt;code&amp;gt;ENABLE_FORGEJO_PAGES = true&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;app.ini&amp;lt;/code&amp;gt; does nothing. It is not a real setting.&lt;br /&gt;
You need the external &amp;lt;code&amp;gt;ronmi/forgejo-pages&amp;lt;/code&amp;gt; container.&lt;br /&gt;
&lt;br /&gt;
=== 2. Branch must be named exactly `static-pages` ===&lt;br /&gt;
Not &amp;lt;code&amp;gt;gh-pages&amp;lt;/code&amp;gt;, not &amp;lt;code&amp;gt;pages&amp;lt;/code&amp;gt;, not &amp;lt;code&amp;gt;static_pages&amp;lt;/code&amp;gt;. The image default is &amp;lt;code&amp;gt;static-pages&amp;lt;/code&amp;gt;.&lt;br /&gt;
If the branch doesn&amp;#039;t exist in the repo, the server returns 404.&lt;br /&gt;
&lt;br /&gt;
=== 3. Use two separate tokens ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Token !! Scope !! Used by&lt;br /&gt;
|-&lt;br /&gt;
| `forgejo-pages` service token | `repository: read` | Docker container reads repo files via API&lt;br /&gt;
|-&lt;br /&gt;
| `git-push` personal token | `repository: read+write` + `user: read` | You/AI push code via git CLI&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Never use your account password for git CLI over HTTPS — it will be rejected.&lt;br /&gt;
&lt;br /&gt;
=== 4. NPM forward port is the internal container port ===&lt;br /&gt;
When NPM uses the container DNS name (&amp;lt;code&amp;gt;forgejo-pages&amp;lt;/code&amp;gt;), forward to port &amp;lt;code&amp;gt;8080&amp;lt;/code&amp;gt; (internal).&lt;br /&gt;
If using the host IP (&amp;lt;code&amp;gt;192.168.196.76&amp;lt;/code&amp;gt;), forward to port &amp;lt;code&amp;gt;8585&amp;lt;/code&amp;gt; (exposed host port).&lt;br /&gt;
Mixing these up causes 502 Bad Gateway.&lt;br /&gt;
&lt;br /&gt;
=== 5. Remove NPM Access List from git.gi7b.org ===&lt;br /&gt;
HTTP Basic Auth at the NPM layer blocks git CLI, API calls, and webhooks.&lt;br /&gt;
Forgejo&amp;#039;s own auth (tokens, SSH keys, 2FA) is the correct security layer for a git host.&lt;br /&gt;
&lt;br /&gt;
=== 6. SSH is more reliable than HTTPS for git push ===&lt;br /&gt;
HTTPS git auth has multiple failure modes (token scopes, credential helpers, NPM layers).&lt;br /&gt;
SSH just works. Set it up once per machine and never deal with tokens for pushing again.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Docker Compose Setup ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;File:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;/home/user/forgejo/compose.yml&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;yaml&amp;quot;&amp;gt;&lt;br /&gt;
services:&lt;br /&gt;
  server:&lt;br /&gt;
    image: codeberg.org/forgejo/forgejo:13&lt;br /&gt;
    container_name: forgejo&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    environment:&lt;br /&gt;
      - USER_UID=1000&lt;br /&gt;
      - USER_GID=1000&lt;br /&gt;
    volumes:&lt;br /&gt;
      - ./data:/data&lt;br /&gt;
      - /etc/localtime:/etc/localtime:ro&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;3001:3000&amp;quot;&lt;br /&gt;
      - &amp;quot;223:22&amp;quot;&lt;br /&gt;
    networks:&lt;br /&gt;
      - internal&lt;br /&gt;
      - proxy&lt;br /&gt;
&lt;br /&gt;
  pages:&lt;br /&gt;
    image: ronmi/forgejo-pages&lt;br /&gt;
    container_name: forgejo-pages&lt;br /&gt;
    restart: unless-stopped&lt;br /&gt;
    command: serve --server http://forgejo:3000 --token ${FORGEJO_PAGES_TOKEN} --bind :8080&lt;br /&gt;
    ports:&lt;br /&gt;
      - &amp;quot;8585:8080&amp;quot;&lt;br /&gt;
    networks:&lt;br /&gt;
      - internal&lt;br /&gt;
      - proxy&lt;br /&gt;
    depends_on:&lt;br /&gt;
      - server&lt;br /&gt;
&lt;br /&gt;
networks:&lt;br /&gt;
  internal:&lt;br /&gt;
    driver: bridge&lt;br /&gt;
  proxy:&lt;br /&gt;
    external: true&lt;br /&gt;
    name: npm_proxy&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;File:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;/home/user/forgejo/.env&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
FORGEJO_PAGES_TOKEN=your_read_only_repository_token_here&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Tokens ==&lt;br /&gt;
&lt;br /&gt;
=== Service Token (for forgejo-pages container) ===&lt;br /&gt;
Generated in Forgejo → Settings → Applications:&lt;br /&gt;
* **Name:** `forgejo-pages-service`&lt;br /&gt;
* **Repository and Organization Access:** All&lt;br /&gt;
* **Permissions:** `repository: Read` only, everything else No access&lt;br /&gt;
* Goes in `/home/user/forgejo/.env` as `FORGEJO_PAGES_TOKEN`&lt;br /&gt;
&lt;br /&gt;
=== Personal Push Token (for git CLI / AI agents) ===&lt;br /&gt;
Generated in Forgejo → Settings → Applications:&lt;br /&gt;
* **Name:** `git-push-{machinename}`&lt;br /&gt;
* **Repository and Organization Access:** All&lt;br /&gt;
* **Permissions:** `repository: Read and Write`, `user: Read`, everything else No access&lt;br /&gt;
* Used as the **password** when git prompts, or embedded in SSH-less workflows&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== NPM Proxy Host — pages.gi7b.org ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Details tab:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Domain Names | `pages.gi7b.org`&lt;br /&gt;
|-&lt;br /&gt;
| Scheme | `http`&lt;br /&gt;
|-&lt;br /&gt;
| Forward Hostname / IP | `forgejo-pages` (container name) OR `192.168.196.76` (host IP)&lt;br /&gt;
|-&lt;br /&gt;
| Forward Port | `8080` if using container name / `8585` if using host IP&lt;br /&gt;
|-&lt;br /&gt;
| Cache Assets | ✅ On&lt;br /&gt;
|-&lt;br /&gt;
| Block Common Exploits | ✅ On&lt;br /&gt;
|-&lt;br /&gt;
| Websockets Support | Off&lt;br /&gt;
|-&lt;br /&gt;
| Access List | **Publicly Accessible** (no HTTP Basic Auth)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;SSL tab:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Field !! Value&lt;br /&gt;
|-&lt;br /&gt;
| SSL Certificate | `pages.gi7b.org` (Let&amp;#039;s Encrypt)&lt;br /&gt;
|-&lt;br /&gt;
| Force SSL | ✅ On&lt;br /&gt;
|-&lt;br /&gt;
| HTTP/2 Support | ✅ On&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== SSH Setup for Git Push (per machine) ==&lt;br /&gt;
&lt;br /&gt;
Run once on each machine that needs to push to Forgejo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Generate key&lt;br /&gt;
ssh-keygen -t ed25519 -C &amp;quot;{machinename}-git&amp;quot; -f ~/.ssh/id_ed25519 -N &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Show public key to add to Forgejo&lt;br /&gt;
cat ~/.ssh/id_ed25519.pub&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add the public key in Forgejo → Settings → SSH / GPG Keys → Add Key.&lt;br /&gt;
&lt;br /&gt;
Set remote URL to SSH (note custom port 223):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
git remote set-url origin ssh://git@192.168.196.76:223/{owner}/{repo}.git&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Use the ZeroTier IP `192.168.196.76` directly — port 223 is not forwarded through&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;the public relay (PC06). SSH over ZeroTier is reliable for internal machines.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;For external machines, either forward port 223 through PC06 or use HTTPS with a token.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Publishing a Page (Repeatable Workflow) ==&lt;br /&gt;
&lt;br /&gt;
=== New repo — first time ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
git clone ssh://git@192.168.196.76:223/{owner}/{repo}.git&lt;br /&gt;
cd {repo}&lt;br /&gt;
&lt;br /&gt;
# Create orphan branch (no shared history with main)&lt;br /&gt;
git checkout --orphan static-pages&lt;br /&gt;
git rm -rf . 2&amp;gt;/dev/null || true&lt;br /&gt;
&lt;br /&gt;
# Create your site&lt;br /&gt;
mkdir -p .&lt;br /&gt;
cat &amp;gt; index.html &amp;lt;&amp;lt;&amp;#039;EOF&amp;#039;&lt;br /&gt;
&amp;lt;!DOCTYPE html&amp;gt;&lt;br /&gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&amp;lt;meta charset=&amp;quot;UTF-8&amp;quot;&amp;gt;&amp;lt;title&amp;gt;My Page&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;Hello from Forgejo Pages&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
EOF&lt;br /&gt;
&lt;br /&gt;
git add .&lt;br /&gt;
git commit -m &amp;quot;Initial pages content&amp;quot;&lt;br /&gt;
git push -u origin static-pages&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Live immediately at: &amp;lt;code&amp;gt;https://pages.gi7b.org/{owner}/{repo}/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Update existing pages ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
git checkout static-pages&lt;br /&gt;
# edit files&lt;br /&gt;
git add .&lt;br /&gt;
git commit -m &amp;quot;Update pages&amp;quot;&lt;br /&gt;
git push&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Via Forgejo Web UI (no git needed) ===&lt;br /&gt;
&lt;br /&gt;
1. Open repo → click &amp;#039;&amp;#039;&amp;#039;New File&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
2. Filename: &amp;lt;code&amp;gt;index.html&amp;lt;/code&amp;gt;, add content&lt;br /&gt;
3. In commit section: select &amp;#039;&amp;#039;&amp;#039;&amp;quot;Create a new branch&amp;quot;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
4. Branch name: &amp;lt;code&amp;gt;static-pages&amp;lt;/code&amp;gt;&lt;br /&gt;
5. Commit&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Verification ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Local test (on PC03)&lt;br /&gt;
curl -i http://localhost:8585/{owner}/{repo}/&lt;br /&gt;
&lt;br /&gt;
# Expected: HTTP/1.1 200 OK + your HTML&lt;br /&gt;
&lt;br /&gt;
# Check pages server logs&lt;br /&gt;
docker logs forgejo-pages --tail 20&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Browser: &amp;lt;code&amp;gt;https://pages.gi7b.org/{owner}/{repo}/&amp;lt;/code&amp;gt; (trailing slash matters)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Symptom !! Cause !! Fix&lt;br /&gt;
|-&lt;br /&gt;
| 400 Bad Request | No valid owner/repo path in URL | URL must be `/{owner}/{repo}/`&lt;br /&gt;
|-&lt;br /&gt;
| 404 Not Found | `static-pages` branch missing or no `index.html` at root | Create branch, push `index.html` to root&lt;br /&gt;
|-&lt;br /&gt;
| 502 Bad Gateway | NPM port mismatch or container not on `npm_proxy` network | Check forward port (8080 internal / 8585 host). Verify: `docker network inspect npm_proxy \ | grep forgejo`&lt;br /&gt;
|-&lt;br /&gt;
| Auth failed (git push) | Wrong token scope or using account password | Use personal push token with `repository: write`. Use SSH instead.&lt;br /&gt;
|-&lt;br /&gt;
| SSH connection refused | Port 223 not reachable from external machine | Use ZeroTier IP for internal machines. Forward port via PC06 for external.&lt;br /&gt;
|-&lt;br /&gt;
| Pages container crash-looping | Missing `serve` command or bad token | Check `docker logs forgejo-pages`. Verify `.env` token is correct.&lt;br /&gt;
|-&lt;br /&gt;
| Stale content | Browser cache | Hard refresh (Ctrl+Shift+R) or test with `curl`&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
</feed>