--- layout : post title : "自建Git托管服务" subtitle : "Git with a cup of tea" date : 2023-05-25 08:50:22 author : "Manford Fan" catalog : false header-img : "img/post-bg-universe.jpg" tags : - Git - Gitea --- 随着自己的服务越来越多,目前大概几十个,有些放在Github上,有些直接是放在本地的磁盘上,另外还有些自动化管理脚本,备份以及恢复脚本,内容管理工具等等,总体上比较杂乱,需要一个版本管理工具来系统记录一下。之前安装过Gogs,感觉也不错,可是当时没有太深入探究,倒是也能运行,遇到了不能使用`ssh`管理仓库的问题,然后就搁置了。前几天越发觉得需要一个这样的工具,于是找到了[Gitea](https://github.com/go-gitea/gitea)。Gitea是从Gogs这个开源代码Fork过来的,稍微了解了下两者的关系,多少有点[恩怨的](https://blog.gitea.io/2016/12/welcome-to-gitea/)意思,如果描述属实,我还是比较站Gitea。 ![gitea_about](/img/posts/gitea_about.png 'gitea_about') ## 一、环境准备 > 整体思路:***user → VPS(frps) → CrossChain(frpc) → CrossChain(nginx)*** 和其他火爆的应用一样,Gitea支持非常多种安装方案,具体可以参考[Gitea文档](https://docs.gitea.cn/),一如既往,这里还是选择使用本地化二进制安装包部署的方式,虽然最近我也有在了解Docker,并且安装了Docker和Docker的图形化管理工具Portainer,目前还在研究阶段,等了解差不多了之后可能会考虑这种部署方式。 #### 1. 下载二进制包 从https://dl.gitea.com/gitea/下载gitea,放在系统路径下,建议是`/usr/local/bin/`目录下,让所有人都可以访问。 ```bash wget -O gitea https://dl.gitea.com/gitea/1.19.3/gitea-1.19.3-linux-amd64 chmod +x gitea mv gitea /usr/local/bin/ ``` #### 2. 创建gitea用户 因为gitea不支持root用户安装使用,所以需要为这个应用单独创建一个用户,而且是需要可登录类型的,密码可以设定,也可以不设定。另外还要准备gitea安装的相关目录,并且owner要设定为之前新建的用户。 ```bash adduser --system --shell /bin/bash --gecos 'Git Version Control' --group --disabled-password --home /home/gitea gitea mkdir -p /opt/webdav/gitea/ mkdir -p /opt/webdav/gitea/custom/conf mkdir -p /opt/webdav/gitea/data mkdir -p /opt/webdav/gitea/log touch /opt/webdav/gitea/custom/conf/app.ini chown -R gitea:gitea /opt/webdav/gitea/ ``` #### 3. 数据库初始化 如下应该也是比较常见的初始化MySQL数据库的语句,之前搭建nextcloud,koel,jellyfin,cloudreve或者monica的时候都用过好多次,文档中也给出了基本示例,可以参考。 ```sql CREATE DATABASE gitea CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_unicode_ci'; CREATE USER 'gitea'@'localhost' IDENTIFIED BY 'PASSWORD'; GRANT ALL PRIVILEGES ON gitea.* TO 'gitea'@'localhost'; FLUSH PRIVILEGES; # Delete if necessary DROP DATABASE gitea; DROP USER 'gitea'@'localhost'; ``` ## 二、安装配置 gitea有着完善的文档支持,而且源码在Github上托管,理论上在安装配置以及使用上,有任何问题都能够在上面找到issue,我自己在实践的过程中也遇到了一些问题,大多也是这样解决的。 #### 1. 安装 ```bash sudo -u gitea gitea web --install-port 8111 --custom-path /opt/source-code/gitea/custom/ --work-path /opt/source-code/gitea/ --config /opt/source-code/gitea/custom/conf/app.ini ``` 之前说过,gitea是不允许使用root权限安装的,所以需要使用创建好的新用户执行如上命令,控制台输出没问题的话,我们就可以打开浏览器,输入`http://localhost:8111`,此时应该可以看到如下界面。 ![gitea_installation](/img/posts/gitea_installation.png 'gitea_installation') 上述使用的是域名访问,因为我提前做了域名解析,并通过frp透传到内网的8111端口所部署的服务——Gitea,如下是刚安装好的时候的界面,看起来还是比较清爽的。 ![gitea_ok](/img/posts/gitea_ok.png 'gitea_ok') #### 2. 配置nginx反向代理 在第一步中,看到可以使用域名进行访问,这里是需要配置nginx反向代理之后才能实现,[gitea文档](https://docs.gitea.cn/administration/reverse-proxies/)中也贴心的给出了相关的配置,可参考修改,如下是我线上环境的配置。 ``` server { server_name gitea.rustle.cc; listen [::]:443 ssl http2; listen 443 ssl http2; charset utf-8; access_log logs/gitea.access.log main; ssl_certificate /opt/configs/certs/rustle.cc.cer; ssl_certificate_key /opt/configs/certs/rustle.cc.key; location / { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_set_header Cache-Control no-cache; proxy_pass http://localhost:8111; # 如果您要使用本地存储策略,请将下一行注释符删除,并更改大小为理论最大文件尺寸 client_max_body_size 4000M; } } ``` #### 3. systemd管理 大部分情况下使用`systemd`来管理服务还是非常方便的,如下算是通用流程了,其他服务也可以参照修改。 ```bash cp gitea.service /lib/systemd/system/ systemctl daemon-reload systemctl start gitea.service # 如下是service内容 # [Unit] # Description=Gitea # After=syslog.target # After=network.target # # [Service] # RestartSec=2s # Type=simple # User=gitea # Group=gitea # ExecStart=/usr/local/bin/gitea web --port 8111 --custom-path /opt/webdav/gitea/custom/ --work-path /opt/webdav/gitea/ --config /opt/webdav/gitea/custom/conf/app.ini # Restart=always # # [Install] # WantedBy=multi-user.target ``` #### 4. 配置ssh密钥 和Github使用方法完全一致,使用`ssh-keygen -t rsa -b 4096 -C "mffan0922@163.com"`命令生成id_rsa和id_rsa.pub两个文件,将后者配置在网站上,后者自行保留。 ## 三、遇到问题 整体过程中,遇到的问题只有一个,那就是配置好ssh之后,无法使用ssh进行`clone/push/pull`等操作,先说结论:原因是,服务部署在内网,访问时是通过frp进行透传导致的。另外,之前Gogs的问题应该也是相同的原因导致的。 默认`app.ini`配置文件中,监听的ssh端口是22,原来使用frp透传ssh访问的时候,用的是VPS的54321端口,所以使用ssh进行`clone/push/pull`操作的时候实际访问的是VPS的22端口,但是VPS上既没有gitea用户,也没有gitea服务,自然就会失败。这个时候有两种解决方案:一种是将VPS的22端口作为frp的ssh转发端口,VPS本身的ssh端口修改成其他的;另一种方案是,在VPS上配置gitea服务,则什么问题都没有。 很显然,使用后者不切实际,这里采用的是前者的方案,修改好之后ssh还是无法执行`clone/push/pull`等操作,最终还是在issue中找到了问题所在,需要先执行一下图示的两个任务,后面就很顺利的使用ssh的功能了。 ![gitea_ssh_problem](/img/posts/gitea_ssh_problem.png 'gitea_ssh_problem') ## 四、参考文档 - [Gitea-GitHub](https://github.com/go-gitea/gitea) - [Gitea中文文档](https://docs.gitea.cn/) - [Gitea-安装包](https://dl.gitea.com/gitea/)