首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Forgejo及其Action自部署简明教程

Forgejo及其Action自部署简明教程

作者头像
柳神
发布2025-07-26 11:01:44
发布2025-07-26 11:01:44
28400
代码可运行
举报
文章被收录于专栏:清羽飞扬清羽飞扬
运行总次数:0
代码可运行

关于AI

清羽AI正在绞尽脑汁想思路ING···

清羽のAI摘要

GLM-4-Flash

碎碎念

哎哟我滴个天,陕西这鬼天气真是要命,前几天去趟西安博物院差点热化了,不下雨根本不敢出门啊!

反正最近宅在家里闲着,出去玩也出不去,没什么事情可做,就找了一些开源项目部署,于是找到了ForgeJo,作为Gitea的开源替代,二者部署方式基本一致,只是有部分细节稍微不同,于是捣鼓了一下ForgeJo,感觉还不错哦,功能方面打磨的也比较到位,符合我的要求。

😃来自本站,本站可确保其安全性,请放心点击跳转

清羽飞扬の代码仓库

LiuShen's Blog

不过 ForgeJo Action 的部署稍微有点麻烦。我主力服务器现在用的是 1Panel 面板来做运维,图个方便,就干脆顺手适配了一下 1Panel 的第三方应用商店,现在支持一键部署啦!

项目区别

在部署ForgeJo的过程中,很多人可能会搞混几个名字:GogsGiteaForgeJoGitLab。这些工具本质上都能用来搭建私有的Git仓库服务,但它们之间的关系和取舍点还是挺有意思的。

故事要从Gogs开始。Gogs是最早一批由国人开发的Go语言写的Git服务平台,主打一个“开箱即用、部署简单”。很多人最初自建 Git 服务就是靠它。

🙄引用站外地址,不保证站点的可用性和安全性

Gogs

一款极易搭建的自助Git服务

但由于Gogs项目长期由一个核心作者主导,节奏比较慢,社区声音也不多,于是就有一群核心贡献者决定另起炉灶,创建了GiteaGitea一出来,立刻把“社区驱动”挂在了旗帜上,不仅继承了Gogs的轻量特性,还快速迭代,增加了很多现代化功能,比如Issues、项目看板、Pull RequestWebhooks等等。尤其是中文用户多,文档全、更新快,很快成为Gogs的“精神续作”,用户非常广泛。

好景不长,Gitea后来出现了一些争议,项目仓库被私人商业公司接管、核心决策开始不透明化。于是,2022年底社区再次爆发,部分维护者又分叉出了ForgeJoForgeJo表面看和Gitea几乎一模一样,实际上它更强调社区治理、反对商业控制。ForgeJo仍然基于Gitea构建,所以配置文件、插件系统、UI等等几乎都通用。

Gitea收购?

关于Gitea是否被收购这个问题,其实情况有些微妙。严格来说Gitea项目本身并没有被外部公司直接收购,但在2022年下半年,Gitea的核心维护者之一、用户名为 lunny 的开发者,牵头成立了一家公司,名为 Gitea Limited。这家公司注册在香港,并在没有提前与社区广泛沟通的情况下,接管了Gitea项目的主要GitHub仓库、域名以及商标。这一行为虽然在法律上无可厚非,但在开源社区中引发了很大的争议,很多人认为原本由社区共治的项目突然被转交给一家私人公司,等于“悄悄地商业化”了。

这一变更过程几乎没有征询社区意见,导致一些长期参与Gitea开发的核心维护者感到被排除在外。这种不透明的项目治理模式引起了部分维护者的强烈不满。于是,这些维护者决定分叉Gitea,重新建立一个完全由社区驱动、保持开源纯洁性的项目,也就是后来诞生的 ForgeJoForgeJo的理念非常明确:不接受商业公司控制,坚持社区治理路线,强调开放透明的发展模式。虽然ForgeJo诞生时间较短,但由于它是在Gitea的基础上继续开发的,因此兼容性极好,几乎可以无缝替代原来的Gitea部署方案。

目前,Gitea依然在积极维护和更新,功能也非常丰富,社区规模较大。不过,由Gitea Limited管理的模式意味着未来的方向可能会更偏向商业化,比如推出商业支持计划、专属插件、付费功能等。而ForgeJo则选择了另一条路线,力图保持项目的独立性和社区性。

GitLab则是另一条路线了,它完全不是Gogs这条Go系的延伸,而是一个Ruby起家的超大型DevOps平台。它不仅是Git托管工具,还是一个完整的CI/CD流水线平台,甚至包括了代码审查、代码质量分析、容器仓库、项目Wiki、权限管理等等,几乎覆盖了整个软件开发生命周期。当然,它也因此变得异常庞大:几GB内存是常态,部署配置极其复杂,小团队或个人基本折腾不动。虽然GitLab功能强大到离谱,但更适合大型团队或者企业环境,不太适合像我这样只想自建个轻量代码库、顺便跑个Action的个人用户。

特性

Gogs

Gitea

ForgeJo

GitLab

起源

最初项目

从Gogs分叉

从Gitea分叉

独立开发

开发语言

Go

Go

Go

Ruby + Go

更新节奏

稳定适中

快但复杂

功能丰富度

基础够用

功能齐全

功能齐全

功能极其强大

社区治理

作者主导

社区+公司

纯社区驱动

公司主导

系统资源占用

极低

非常高

部署难度

简单

简单

简单

麻烦

适合人群

个人用户

个人/小团队

个人/小团队

中大型团队

说到这里,其实也就能看出来各家的定位了:Gogs是最轻量的基础版,不太推荐使用,功能略显简陋,Gitea是功能全面的主流选手,ForgeJo是理想主义的社区坚守者,而GitLab就是面向企业的全能怪兽。如果你只是想找个能自己托管、顺手用的Git服务,又不想买大服务器、不想被商业牵着走,GiteaForgeJo就是最好的选择。而我,选择了 ForgeJo

部署教程

应用商店

如果你是1Panel用户,我比较推荐使用应用商店一键部署,可以更加便捷的连接到本地的数据库,以及方便管理。下面是我自己整理的三方仓库:

🙄引用站外地址,不保证站点的可用性和安全性

🌭清羽飞扬自建第三方1Panel应用仓库

github.com@willow-god

由于主要用于自用,所以应用并不是很多,你可以选择性的将仓库中app内的文件夹移动到/opt/1panel/resource/apps/local目录下,刷新一下本地应用即可看到。

如果懒得一个个选可以创建一个定时任务,脚本内容如下:

代码语言:javascript
代码运行次数:0
运行
复制
#!/bin/bash

set -e

# 配置路径
GIT_REPO="https://cnb.cool/Liiiu/appstore"
TMP_DIR="/opt/1panel/resource/apps/local/appstore-localApps"
LOCAL_APPS_DIR="/opt/1panel/resource/apps/local"

echo "📥 Cloning appstore repo..."
git clone "$GIT_REPO" "$TMP_DIR"

mkdir -p "$LOCAL_APPS_DIR"

for app_path in "$TMP_DIR/apps/"*; do
  [ -d "$app_path" ] || continue

  app_name=$(basename "$app_path")
  local_app_path="$LOCAL_APPS_DIR/$app_name"

  echo "🔁 Updating app: $app_name"
  [ -d "$local_app_path" ] && rm -rf "$local_app_path"
  cp -r "$app_path" "$local_app_path"
done

echo "🧼 Cleaning up temporary repo..."
rm -rf "$TMP_DIR"

echo "✅ Sync completed."

国外环境请替换为 GitHub 仓库: GIT_REPO="https://github.com/willow-god/appstore"

执行一次定时任务后,在全部应用部分点击同步本地应用即可实现!

如果一切正常,你可以在此处搜索Forgejo并直接安装啦!

ForgeJo

本体的部署和Gitea基本一致,所以没有什么可讲的,我们可以使用Docker-Compose直接启动,在任意目录下创建文件docker-compose.yaml,写入一下内容:

代码语言:javascript
代码运行次数:0
运行
复制
networks:
  forgejo:
    external: false

services:
  server:
    image: codeberg.org/forgejo/forgejo:11
    container_name: forgejo
    environment:
      - USER_UID=1000
      - USER_GID=1000
    restart: always
    networks:
      - forgejo
    volumes:
      - ./forgejo:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - '3000:3000'
      - '222:22'

以上方式默认为SQLite启动,如果想要使用数据库启动,请参考文档:

🙄引用站外地址,不保证站点的可用性和安全性

ForgeJo

Beyond coding.We forge.

如果一切正常,反向代理3000端口即可成功访问初始化页面,完成初始化页面即可实现部署啦!222端口是用于SSH拉取仓库,如果你不常用SSH,那么HTTP拉取方式已经能够满足需要啦!

Actions

action也可以在上面的应用商店一键下载,速度更快哦!可以选择dind或者宿主机安装版本。

Forgejo actions和普通的Gitea actions有一定的相似性,但又不完全相同,需要手动进行初始化,才能正常执行。

一般安装都是直接在宿主机docker安装,并挂在宿主机sock文件,这种方式给的权限过大,有整个容器网络的删除权限,如果个人用无所谓,但是容易被人滥用导致数据丢失,所以出现了dind安装和另一个context安装的方式,后者需要配置无根Docker,稍微比较麻烦,所以在这里我推荐使用dind或者宿主机安装的方式。

dind和宿主机安装的利弊

DIND,全称是Docker-in-Docker,就是在容器里再运行一套Docker守护进程,这样这个容器就能自己管理镜像、运行其他容器了。

使用DIND的好处在于它更安全、更隔离,每个Runner拥有自己独立的Docker环境,不会干扰宿主机上其他容器的运行。这在多用户、多Runner场景下非常有用。但代价是资源占用会高一些,因为每个Runner容器内部都要再启动一个完整的Docker守护进程,内存和CPU会有额外开销。

所以按需选择即可,如果你只是自己用、追求部署简单、对安全性要求没那么高,宿主机的Docker Socket更实用;但如果你希望构建环境隔离,避免相互干扰或者潜在的安全隐患,使用DIND是更稳妥的选择,尽管它会多占一些资源。

宿主机安装

首先,在你的Forgejo实例找到注册密钥,一般在右上角头像,设置,action中即可以看到:

由于是宿主机直接安装,我建议使用个人密钥,所以在这里创建,如果你想提供给Forgejo实例内的所有用户使用,可以在网站管理中的action进行创建。

随后,创建docker-compose.yaml文件,写入以下内容:

代码语言:javascript
代码运行次数:0
运行
复制
version: "3.9"

services:
  forgejo_runner:
    image: code.forgejo.org/forgejo/runner:7.0.0
    container_name: forgejo-runner
    restart: always
    user: root
    command: >-
      /bin/sh -c '
        cd /data &&
        if [ ! -s .runner ]; then
          echo ">>> Registering runner..."
          forgejo-runner register --no-interactive \
            --instance "https://git.liushen.fun/" \
            --token "你的注册密钥" \
            --name "runner名称" \
            --labels "标签,不敢乱填,看下面说明";
          forgejo-runner generate-config > config.yml
        fi;
        echo ">>> Starting daemon..."
        forgejo-runner --config config.yml daemon
      '
    volumes:
      - ./data:/data
      - /var/run/docker.sock:/var/run/docker-forgejo-runner.sock
    environment:
      - FORGEJO_INSTANCE_URL="https://git.liushen.fun/"
      - RUNNER_REGISTRATION_TOKEN="你的注册密钥"
      - RUNNER_NAME="forgejo-runner"
      - RUNNER_LABELS="标签,不敢乱填,看下面说明"
    networks:
      - 1panel-network
    labels:
      createdBy: "Apps"

networks:
  1panel-network:
    external: true

以上有一个标签的配置内容,这个标签是用于判断采用哪个action的重要依据,如果没有成功配置可能会导致无法分配action执行,建议的默认值如下:

代码语言:javascript
代码运行次数:0
运行
复制
ubuntu-latest:docker://gitea/runner-images:ubuntu-latest,ubuntu-24.04:docker://gitea/runner-images:ubuntu-24.04,ubuntu-22.04:docker://gitea/runner-images:ubuntu-22.04,ubuntu-20.04:docker://gitea/runner-images:ubuntu-20.04

尝试部署,应该就可以实现咯!

DinD安装

这种方法的安全性更高,不给最高权限,不会害怕影响到宿主机的数据。

还是先获取注册密钥,然后再在服务器的任意位置创建文件docker-compose.yaml,写入内容:

代码语言:javascript
代码运行次数:0
运行
复制
version: "3.9"

services:
  dind:
    image: docker:24.0-dind
    container_name: forgejo-dind
    privileged: true
    restart: always
    environment:
      DOCKER_TLS_CERTDIR: ""
    volumes:
      - forgejo-dind-data:/var/lib/docker
    networks:
      - 1panel-network

  forgejo_runner:
    image: code.forgejo.org/forgejo/runner:7.0.0
    container_name: ${CONTAINER_NAME:-forgejo-runner}
    depends_on:
      - dind
    restart: always
    user: "1000:1000"
    environment:
      - DOCKER_HOST=tcp://dind:2375
      - FORGEJO_INSTANCE_URL=${FORGEJO_INSTANCE_URL}
      - RUNNER_REGISTRATION_TOKEN=${RUNNER_REGISTRATION_TOKEN}
      - RUNNER_NAME=${RUNNER_NAME:-default-runner}
      - RUNNER_LABELS=${RUNNER_LABELS:-docker:docker://node:20-bookworm}
    command: >
      /bin/sh -c '
        cd /data &&
        if [ ! -s .runner ]; then
          echo ">>> Registering runner..." &&
          forgejo-runner register --no-interactive \
            --instance ${FORGEJO_INSTANCE_URL} \
            --token ${RUNNER_REGISTRATION_TOKEN} \
            --name ${RUNNER_NAME} \
            --labels ${RUNNER_LABELS} &&
          forgejo-runner generate-config > config.yml;
        fi &&
        echo ">>> Starting daemon..." &&
        forgejo-runner --config config.yml daemon
      '
    volumes:
      - ./data:/data
    networks:
      - 1panel-network

volumes:
  forgejo-dind-data:

networks:
  1panel-network:
    external: true

请自行替换一些变量,这里我就懒得改咯!

如果一切正常,会启动两个容器,一个是runner本身,一个是dind,当runner接收到任务后,会在dind创建容器,执行任务,执行完成后,会自动清理dind内部的容器。

action具体怎么配置的话,大家自己琢磨琢磨吧~主要是我还没玩明白呢!

配置教程

Action具体倒是没啥能配置的,在这里我主要讲解一下Forgejo本体的配置和主题,自定义。

配置文件

找到Forgejo映射的目录,找到gitea文件夹,比如:/data/gitea/conf,如果没什么问题。里面会有一个app.ini文件,这里存的就是我们的所有配置,所有配置请查看说明文档:

🙄引用站外地址,不保证站点的可用性和安全性

Forgejo

app.ini-example

这里我主要说明几个建议修改的配置项。

顶部的实例信息,可以设置实例的名称,和说明文字:

代码语言:javascript
代码运行次数:0
运行
复制
APP_NAME = 清羽Git
RUN_MODE = prod
APP_SLOGAN = 清羽飞扬の个人仓库
RUN_USER = 默认即可
WORK_PATH = /data/gitea

Server:这里规定了一些实例相关的配置文本,和ssh端口,如果你是用外部的222映射,注意修改端口:

代码语言:javascript
代码运行次数:0
运行
复制
[server]
APP_DATA_PATH = /data/gitea
DOMAIN = git.liushen.fun
SSH_DOMAIN = git.liushen.fun
HTTP_PORT = 3000
ROOT_URL = https://git.liushen.fun/
DISABLE_SSH = false
SSH_PORT = 222  # 这个端口记得修改
SSH_LISTEN_PORT = 22
LFS_START_SERVER = true
LFS_JWT_SECRET = abcdefgabcdefgabcdefgabcdefgabcdefgabcd
OFFLINE_MODE = false

Picture:这里设置了个人头像的一些配置,默认使用gravatar头像,但是由于已知原因,在国内速度不理想,所以可以按照以下方式修改:

代码语言:javascript
代码运行次数:0
运行
复制
[picture]
AVATAR_UPLOAD_PATH = /data/gitea/avatars
REPOSITORY_AVATAR_UPLOAD_PATH = /data/gitea/repo-avatars
DISABLE_GRAVATAR = false
GRAVATAR_SOURCE = https://weavatar.com/avatar/
AVATAR_MAX_WIDTH = 4096
AVATAR_MAX_HEIGHT = 4096
AVATAR_MAX_FILE_SIZE = 1048576
AVATAR_MAX_ORIGIN_SIZE = 262144
AVATAR_RENDERED_SIZE_FACTOR = 2
ENABLE_FEDERATED_AVATAR = false

其他的配置比如邮箱配置,主题配置,可以参考配置文件及其说明文档进行开发。

自定义页面

/data/gitea文件夹下,实际上还有一个templates文件夹,但是这个文件夹在启动的时候会在docker内部自动补全,外部一般看不到,所以在这里我们只需要覆盖一下即可实现自定义,具体templates文件夹的结构可以看下面forgejo源码:

🙄引用站外地址,不保证站点的可用性和安全性

Forgejo

Templates

比如我需要覆写主页的代码,可以找到这个文件地址:

那么我们可以创建以下文件data/gitea/templates/home.tmpl,这样在挂载的时候就会覆盖掉原始文件。

比如本站的home.tmpl内容如下:

代码语言:javascript
代码运行次数:0
运行
复制
{{template "base/head" .}}

<style>
  :root {
    /* 亮色模式默认值 */
    --home-text: #2c3e50;
    --home-text-light: #7f8c8d;
    --home-text-dark: #2c3e50;
    --home-primary: #3498db;
    --home-primary-dark: #2980b9;
    --home-secondary: #ffffff;
    --home-secondary-dark: #f8f9fa;
    --home-border: #dfe6e9;
    --home-card-bg: #f8f9fa;
    --home-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  }

  @media (prefers-color-scheme: dark) {
    :root {
      --home-text: #ecf0f1;
      --home-text-light: #bdc3c7;
      --home-text-dark: #ecf0f1;
      --home-primary: #3498db;
      --home-primary-dark: #2980b9;
      --home-secondary: #2d2d2d;
      --home-secondary-dark: #252525;
      --home-border: #444;
      --home-card-bg: #252525;
      --home-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
    }
  }

  .custom-home {
    display: flex;
    justify-content: space-between;
    align-items: center;
    min-height: calc(100vh - 130px);
    padding: 2rem 8%;
  }

  .custom-home .left {
    flex: 1;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 2rem;
  }

  .custom-home .left img {
    max-width: 70%;
    max-height: 60%;
    object-fit: contain;
    filter: drop-shadow(var(--home-shadow));
    transition: transform 0.3s ease;
  }

  .custom-home .left img:hover {
    transform: scale(1.05);
  }

  .custom-home .right {
    flex: 1;
    padding: 2rem;
    color: var(--home-text);
  }

  .custom-home .right h1 {
    font-size: 3.5rem;
    margin-bottom: 1.5rem;
    font-weight: 700;
    color: var(--home-primary);
    line-height: 1.2;
  }

  .custom-home .right h2 {
    font-size: 1.75rem;
    margin-bottom: 2rem;
    color: var(--home-text-light);
    font-weight: 400;
    line-height: 1.5;
  }

  .custom-home .right .description {
    font-size: 1.1rem;
    color: var(--home-text-light);
    margin-bottom: 2rem;
    line-height: 1.6;
  }

  .custom-home .right p.credit {
    font-size: 1rem;
    color: var(--home-text-light);
    margin-top: 2rem;
    position: relative;
    padding-left: 1.5rem;
  }

  .custom-home .right p.credit:before {
    content: "";
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    height: 60%;
    width: 3px;
    background: var(--home-primary);
    border-radius: 3px;
  }

  .action-buttons {
    display: flex;
    gap: 1rem;
    margin-top: 2.5rem;
    flex-wrap: wrap;
  }

  .btn {
    padding: 0.75rem 1.5rem;
    border-radius: 50px;
    text-decoration: none;
    font-weight: 500;
    transition: all 0.3s ease;
    text-align: center;
  }

  .btn-secondary {
    background-color: var(--home-secondary);
    color: var(--home-text);
    border: 1px solid var(--home-border);
  }

  .btn-secondary:hover {
    background-color: var(--home-secondary-dark);
    transform: translateY(-2px);
  }

  .features {
    display: flex;
    gap: 1.5rem;
    margin: 2rem 0;
    flex-wrap: wrap;
  }

  .feature-item {
    flex: 1;
    min-width: 150px;
    padding: 1rem;
    border-radius: 8px;
    background-color: var(--home-card-bg);
    text-align: center;
  }

  .feature-icon {
    font-size: 1.5rem;
    margin-bottom: 0.5rem;
    color: var(--home-primary);
  }

  @media (max-width: 992px) {
    .custom-home {
      flex-direction: column;
      text-align: center;
      padding: 4rem 5%;
    }

    .custom-home .right {
      padding: 2rem 0;
    }

    .custom-home .right h1 {
      font-size: 2.5rem;
    }

    .custom-home .right h2 {
      font-size: 1.5rem;
    }

    .custom-home .right p.credit {
      padding-left: 0;
    }

    .custom-home .right p.credit:before {
      display: none;
    }

    .action-buttons {
      justify-content: center;
    }
  }

  @media (max-width: 576px) {
    .custom-home .right h1 {
      font-size: 2rem;
    }

    .custom-home .right h2 {
      font-size: 1.25rem;
    }

    .action-buttons {
      flex-direction: column;
      gap: 0.75rem;
    }

    .btn {
      width: 100%;
    }
  }
</style>

<div class="custom-home">
  <div class="left">
    <img src="https://git.liushen.fun/assets/img/logo.png" alt="QingYu Git Logo">
  </div>
  <div class="right">
    <h1>QingYu Git</h1>
    <h2>您的自托管Git解决方案</h2>
    
    <div class="description">
      QingYu Git提供稳定、高效的代码托管服务,专为国内开发者优化。<br>
      支持Git仓库管理、代码审查、CI/CD集成,让您的开发流程更加顺畅。
    </div>
    
    <div class="features">
      <div class="feature-item">
        <div class="feature-icon">⚡</div>
        <div>极速访问</div>
      </div>
      <div class="feature-item">
        <div class="feature-icon">🛡️</div>
        <div>数据安全</div>
      </div>
      <div class="feature-item">
        <div class="feature-icon">🌐</div>
        <div>国内优化</div>
      </div>
    </div>
    
    <div class="action-buttons">
      <a href="/explore/repos" class="btn btn-secondary">浏览仓库</a>
      <a href="/user/login" class="btn btn-secondary">登录账户</a>
      <a href="/user/sign_up" class="btn btn-secondary">注册新账户</a>
    </div>
    
    <p class="credit">基于 <strong>ForgeJo</strong> 构建 | 专为国内开发者优化</p>
  </div>
</div>

{{template "base/footer" .}}

这样就可以得到本站同款主页啦!

自定义图标

除了tmpl存放的模板文件夹,我们可以在data/gitea中创建一个public文件夹,这个文件夹内的所有内容都会被映射到网络路径上,比如上传图片文件:

代码语言:javascript
代码运行次数:0
运行
复制
local_path: ./data/gitea/public/assets/img/favicon.png
web_url: https://git.liushen.fun/assets/img/favicon.png

即可访问到如上本站的图标,按照这个原理,我们可以覆盖任意文件实现自定义所有图像,比如网站图标:

这里就不一一举例了,大家应该都懂哩!

自定义主题

我之前也自定义了主题,但是到后面发现其实也就默认的好用,适配最好,所以也都删哩,大家可以按需尝试!

同样是assets文件夹,自定义图标位置我们用的是img子文件夹,在自定义主题我们使用的是css子文件夹:

主题的css使用theme-前缀,后面是主题名称,一个主题对应一个css文件,css文件可以尝试搜索gitea-theme获取别人写好的,但是我总感觉有点兼容问题,所以后面恢复了默认主题QAQ:

🙄引用站外地址,不保证站点的可用性和安全性

Gitea-Themes

github.com@topics

只是放在这里无法启用主题,还需要一定的配置,在上面说的配置文件app.ini文件中,添加[ui]配置项,完整配置可看:

🙄引用站外地址,不保证站点的可用性和安全性

forgejo-UI配置项

codeberg.org@forgejo

这里我们只需要THEMEDEFAULT_THEME两个参数:

代码语言:javascript
代码运行次数:0
运行
复制
;; Set the default theme for the Gitea install
DEFAULT_THEME = forgejo-auto
;;
;; All available themes. Allow users select personalized themes regardless of the value of `DEFAULT_THEME`.
;; By default available:
;;  - forgejo-auto, forgejo-light, forgejo-dark
;;  - gitea-auto, gitea-light, gitea-dark
;;  - forgejo-auto-deuteranopia-protanopia, forgejo-light-deuteranopia-protanopia, forgejo-dark-deuteranopia-protanopia
;;  - forgejo-auto-tritanopia, forgejo-light-tritanopia, forgejo-dark-tritanopia
THEMES = gitea-auto,gitea-light,gitea-dark

THEMES添加所有的主题,主题名称对应文件名称THEME-{主题名称}.css

然后重新创建docker

代码语言:javascript
代码运行次数:0
运行
复制
docker compose up -d --force-recreate

如果一切正常,你就可以在设置上修改主题啦!

总结

Forgejo配置完毕!事实上,开源项目商业化的事情早已屡见不鲜。今天是GiteaAlist,明天也许就轮到了ForgejoOpenList等新的项目涌现。问题的关键不在于是否收购,而在于收购方的信誉。以Alist为例,其背后的公司曾因投毒和黑产行为破坏多个开源项目,如今几乎人人避之不及。而Gitea虽然也经历了商业化,但至少目前尚未传出类似恶劣的声誉,用户群体依然庞大。

开源项目的发展确实需要资金和资源的支持,收购本身并非原罪。只是我个人认为,选择一个有信誉、有社区责任感的“下家”,才是真正对得起广大用户与每一位贡献者的做法。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-07-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 碎碎念
  • 项目区别
  • 部署教程
    • 应用商店
    • ForgeJo
    • Actions
      • 宿主机安装
      • DinD安装
  • 配置教程
    • 配置文件
    • 自定义页面
    • 自定义图标
    • 自定义主题
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档