Gitea 如何将web 也打包进exe的?

Gitea 的 Web 界面不是单独部署的前端项目,而是编译进 Go 可执行文件里的。这也是为什么你下载一个 gitea.exe 就能运行 Web 服务。

核心原理:

gitea.exe
│
├── Go 后端代码
│      ├── HTTP Server
│      ├── Git API
│      ├── 用户系统
│      └── 数据库操作
│
├── 内嵌 Web 静态资源
│      ├── HTML模板
│      ├── CSS
│      ├── JavaScript
│      └── 图片
│
└── 启动
       |
       ↓
   HTTP :3000

1. Gitea 使用 Go 的 embed 机制

Go 1.16 开始提供:

embed

可以把文件编译进二进制。

例如:

目录:

gitea
│
├── main.go
│
└── templates
       |
       ├── home.tmpl
       └── login.tmpl

代码:

package main

import (
    "embed"
)

//go:embed templates/*
var templates embed.FS


func main(){

}

编译:

go build

生成:

gitea.exe

此时:

templates/

已经进入 exe。


2. Gitea 源码结构

大概:

gitea
│
├── main.go
│
├── routers
│     |
│     ├── web.go
│     └── api.go
│
├── services
│
├── models
│
├── templates
│
├── web_src
│
└── public
      |
      ├── css
      ├── js
      └── images

其中:

templates

服务端模板:

例如:

首页
登录页
仓库页
用户页

public

静态资源:

CSS
JS
图片
字体

3. Web请求流程

浏览器:

GET

http://localhost:3000/user/login

进入:

HTTP Server
      |
      ↓
Router
      |
      ↓
Controller
      |
      ↓
Template Engine
      |
      ↓
HTML
      |
      ↓
浏览器

例如:

login.tmpl
      |
      ↓
渲染
      |
      ↓
login.html

4. 为什么一个 exe 可以运行?

传统网站:

Apache/Nginx
       |
       |
PHP
       |
网页文件

需要:

服务器
+
代码
+
网页文件

Gitea:

gitea.exe

里面包含:

HTTP服务器
+
业务代码
+
模板
+
JS/CSS

所以:

双击 gitea.exe

        ↓

启动HTTP服务

        ↓

浏览器访问

5. 类似的软件设计

这种模式叫:

单文件应用(Single Binary Application)

很多现代软件采用:

Go:

  • Gitea
  • Prometheus
  • Grafana Agent

Rust:

  • 一些 Web 服务

C++:

也可以:

Qt程序
 |
 ├── Qt资源系统(.qrc)
 |
 ├── HTML
 |
 ├── CSS
 |
 └── JS

编译:

app.exe

内部:

:/web/index.html
:/web/style.css

6. 如果用 Qt 实现类似 Gitea

结构:

Qt Git Server.exe

│
├── Qt HTTP Server
│
├── SQLite
│
├── Git命令调用
│
└── qrc资源
       |
       ├── index.html
       ├── css
       └── js

编译:

GitServer.exe

启动:

http://localhost:8080

原理和 Gitea 非常类似。


所以 Gitea 的本质是:

Go 编写的 Git 管理系统 + Go 内置 HTTP 服务 + embed 将 Web 前端资源编译进 exe,最终形成一个单文件 GitHub 私有服务器。

这也是为什么 Gitea 在 Windows、Linux、ARM 上都可以直接复制一个文件运行。

类似文章