步骤/目录:
1.搭建局域网内的gogs
    (1)安装gogs的依赖项
    (2)为gogs设置mariadb
    (3)为gogs新建系统用户并安装gogs
    (4)gogs初次登录设置
        a. 数据库设置
        b. localhost改为树莓派的局域网ip
        c. 设置管理员
        d. 后续设置
    (5)gogs最新版的问题
2.使用frp将gogs映射到外网
    (1)购买阿里云服务器,安装frp并配置frps服务器端
    (2)树莓派下载frp并配置frpc客户端
    (3)其他
    (4)设置frpc开机自启并开启服务
3.验证

本文首发于个人博客https://lisper517.top/index.php/archives/8/,转载请注明出处。
本篇文章的目的是搭建一个能从外网访问的,自己的git服务。
本文实验日期为2022年2月5日。使用的是树莓派4B(内存8G版),系统为Pi OS 32位桌面版(2022年1月28日更新,镜像名 2022-01-28-raspios-bullseye-armhf.img );云服务器为阿里云,系统镜像为Ubuntu 20.04。

1.搭建局域网内的gogs

这里选用gogs,轻量级、适合树莓派。gitlab太大;gitea据说对树莓派也不错。

(1)安装gogs的依赖项

包括MySQL服务器和Git(顺便安装unzip)。

简单介绍一下:Pi OS现在好像只有mariadb版的mysql,没有原版mysql了。即apt install能找到的只有mariadb-server而没有mysql-server。不过maria-mysql和mysql用起来可以说差别不大,都是一家兄弟。
通过PuTTY登录树莓派,输入以下命令:

apt install mariadb-server git unzip

发现git和unzip已经默认安装且都是最新版,但mariadb出现问题。考虑到实验时间(2022年2月5日)距离4B系统发布时间(2022年1月28日)很近,估计是清华的源没来得及更新。添加上默认源后apt update一下,然后mariadb-server安装成功。

(2)为gogs设置mariadb

首先对mariadb进行基础设置:

mysql_secure_installation

首先需要输入root密码,但第一次进还没设置root密码,根据提示直接按回车。剩下的全选y,注意途中要设置root密码。感兴趣的可以仔细读一下。
然后可以进入mysql,为gogs创建一个用户及database了:

mysql -uroot -p

输入密码,进入mysql命令行后,进行以下四步操作(创建gogs数据库,创建gogs用户,刷新权限,退出mysql命令行):

CREATE DATABASE gogs;
GRANT ALL PRIVILEGES ON gogs.* TO 'gogsuser'@'localhost' IDENTIFIED BY '你的密码'; #只开放了gogsuser对gogs库的权限
FLUSH PRIVILEGES;
QUIT

另外,mariadb-server默认使用3306端口。我安装过ufw,使用ufw allow 3306打开该端口。如果不希望mariadb对外网开放,也可以不开放此端口(若使用了frp映射了树莓派的3306端口,则本地打不打开3306的意义不大,除非需要局域网访问)。

(3)为gogs新建系统用户并安装gogs

退出mysql命令行后,

新建无法登录的用户git:

adduser --disabled-login git

这里还可以添加全名、电话等,此处全部留空。gogs默认需要用3000端口,我已预先安装过ufw,开放一下3000端口:ufw allow 3000(因为需要从本地查看gogs网页)。
进入git用户的根目录,下载gogs(用cat /proc/cpuinfo命令发现树莓派CPU为ARM v7):

cd /home/git
wget https://dl.gogs.io/0.12.3/gogs_0.12.3_linux_armv7.zip #建议不要下载最新版,可以选次新版
unzip gogs_0.12.3_linux_armv7.zip

确保git用户对/home/git目录的权限:

chown -R git:git /home/git

设置gogs开机自启动,并重启gogs服务:

cp /home/git/gogs/scripts/systemd/gogs.service /etc/systemd/system/gogs.service
systemctl enable gogs.service
systemctl restart gogs.service

最后检查一下gogs服务是不是active:

systemctl status gogs.service

不要忘了删除.zip文件:rm /home/git/gogs_0.12.3_linux_armv7.zip

(4)gogs初次登录设置

gogs网页默认在3000端口,如果见不到网页可以看看是不是该端口没有开放。

接下来在浏览器输入 树莓派本地ip:3000 ,出现gogs初次设置界面。主要分下面三个部分:

a. 数据库设置

数据库类型为MySQL,数据库用户和数据库用户密码就是刚才设置的gogsuser和密码。注意到下面的提示:

如果您使用 MySQL,请使用 INNODB 引擎以及 utf8_general_ci 字符集。

登录mariadb,输入show engines;检查,InnoDB为DEFAULT;输入show character set;,发现utf8和utf8mb4(utf8对应utf8_general_ci),输入show variables like "%char%";,发现其中character_set_databasecharacter_set_server对应的都是utf8mb4。退出mariadb,不知道配置文件在哪里,使用find / -name "*.cnf"找到/etc/mysql/mariadb.conf.d/50-server.cnf,找到其中两行:

character-set-server  = utf8mb4
collation-server      = utf8mb4_general_ci

改为

character-set-server  = utf8
collation-server      = utf8_general_ci

保存退出,重新进入mariadb,输入show variables like "%char%";,发现其中character_set_databasecharacter_set_server对应的都是utf8。

b. localhost改为树莓派的局域网ip

在 应用基本设置 中将2个localhost改为树莓派的局域网ip。如果gogs想部署在云服务器而非树莓派上,可以改成云服务器的ip,如果还买了域名也可以换成域名。

c. 设置管理员

在 可选设置-管理员账号设置 中设置一个管理员账号。

d. 后续设置

设置完后即可创建一个仓库试试。之后写了什么代码要在树莓派跑,就可以笔记本上传,树莓派使用git下载(邮箱中的@用%40代替):

git clone http://邮箱或用户名:密码@仓库url

如使用gogs_root下载该用户名下名为test的仓库:

git clone http://gogs_root:对应密码@树莓派本地ip:3000/gogs_root/test

另外,刚才完成的都是基础的设置。如果需要完整设置,可以调整文件/home/git/gogs/custom/conf/app.ini(该文件需要初次设置后才出现)。由于本文创建的是私有git,所以进行以下设置(另外一些设置用于以后可能开放):

DISABLE_REGISTRATION = true #只能由管理员创建账号
REQUIRE_SIGNIN_VIEW = true #必须登录才能查看页面
REGISTER_EMAIL_CONFIRM = true #注册时邮箱确认

[mailer]
ENABLED = true #开启邮件服务

[log]
ROOT_PATH = /var/logs/gogs_logs #习惯写到此文件夹下

创建一下gogs_logs:

mkdir /var/logs #之前没创建过这个文件夹
mv /home/git/gogs/log /var/logs/gogs_logs

(5)gogs最新版的问题

一开始我下载的是0.12.4版armv7压缩包,systemctl start gogs.servicesystemctl status gogs.service发现状态为failed,检查gogs.service看到ExecStart=/home/git/gogs/gogs web,于是试着手动启动gogs网页/home/git/gogs/gogs web,报错bash:gogs: No such file or directory,出现这个报错一般是gogs版本不对(生产环境可以看看原来是不是跑在docker下的)。试了0.12.4的其他版本还是不行,最后换成0.12.3版armv7包可以手动开启。感觉每次gogs最新版本都有点问题。下面给出操作过程:(从1.-(3)新建git用户后开始)

cd /home/git
wget https://dl.gogs.io/0.12.4/gogs_0.12.4_linux_armv7.zip
unzip gogs_0.12.4_linux_armv7.zip
cd gogs #解压后文件夹名为gogs
chown -R git:git /home/git
systemctl enable /home/git/gogs/scripts/systemd/gogs.service
systemctl restart gogs.service
systemctl status gogs.service #发现状态为failed
nano /home/git/gogs/scripts/systemd/gogs.service #看到ExecStart=/home/git/gogs/gogs web
./gogs web #试试手动启动,结果报错bash:gogs: No such file or directory
# 停止服务,删除文件
systemctl stop gogs.service
systemctl disable gogs.service
cd ..
rm -r gogs
rm gogs_0.12.4_linux_armv7.zip

2.使用frp将gogs映射到外网

之前 frp+云服务器搭建能从外网访问的redis 一文中使用同一阿里云服务器,已经配置过frps了。下面粘贴一下:

(1)购买阿里云服务器,安装frp并配置frps服务器端

首先介绍一下frp。frp分为frps(server)和frpc(client),其中frps运行在有公网ip的云服务器上,frpc运行在内网中的机器上。frp主要用于把内网机器的端口映射到云服务器端口,比如把内网机器的22端口(一般用于ssh)映射到云服务器的6000端口,那么访问云服务器的6000端口即可接入内网机器的ssh服务。如果有其他方法搞到公网ip,也可以跳过这一步。

随便选择一个便宜的服务器,购买后安装镜像,这里选择的系统镜像是Ubuntu 20.04。在左侧 服务器运维-远程连接 中设置一下root账户密码,然后下载putty,通过putty连接:连接类型为SSH,端口为默认的22,主机地址填云服务器的ip地址。输入root和root密码后即登录到云服务器。

目前frp最新版本为0.38.0(2021年10月25更新)。这里安装frp到/bin目录下(wget github速度慢可以换成gitee上的仓库):

cd /bin
wget https://github.com/fatedier/frp/releases/download/v0.38.0/frp_0.38.0_linux_amd64.tar.gz
tar -zxvf frp_0.38.0_linux_amd64.tar.gz
mv frp_0.38.0_linux_amd64 frp
cd frp
nano frps.ini

然后配置一下frps.ini:

[common]
bind_port = 7000
#frpc上也要有相同的token值
token = 你的密码
#配置log
log_file = /var/logs/frps.log
log_level = info
log_max_days = 3
#frps统计板
dashboard_port = 7500
dashboard_user = wuhuqifei
dashboard_pwd = wuhuqifei
kcp_bind_port = 7000

解读一下配置选项:bind_port是frp使用的端口;token是密码令牌;log是日志相关;dashboard是统计板,设置好以后,网页访问 服务器ip:7500 即可看到frps的统计情况,user和pwd分别设置统计板的用户名密码(不用太复杂,简单易记即可)。如果后面运行frps时显示没有frps.log文件,可以自己新建一个并chmod改一下权限(或者直接删掉log相关设置)。最后的kcp_bind_port是多消耗15%左右流量、降低tcp延迟的,不要也可以不加。
详细配置可以参考frps_full.ini。
配置完成后,需要打开云服务器相应端口。在 安全-防火墙 中新增规则,打开7000和7500端口(云服务器在此处打开,非云服务器则使用ufw、iptables等。云服务器用ufw会出问题)。
附带一些github上常见问题:

流量是否经过服务器中转?
目前除了 xtcp 外,其他类型的内网穿透模式的流量都需要经过 frps 所在服务器中转。

网络传输速度慢是什么原因?
由于流量需要经过服务器转发,所以传输速度的快慢取决于服务器的下行带宽和客户端的上行带宽,通常家用宽带的上行带宽较低,限制了出口的速度。
另外一种情况是服务器部署在国外的 VPS 上,丢包率较高,也会影响到传输速度。这种情况下可以考虑开启 kcp 传输模式。
开启加密和压缩会消耗一定的 cpu 资源,且影响到传输速度,具体影响情况取决于机器性能。

客户端连接失败,提示 authorization failed
出现这种情况说明鉴权失败,检查 frps 和 frpc 的配置文件中的 token 是否一致。

客户端连接失败,提示 authorization timeout
出现这种情况是因为 frps 所在服务器和 frpc 所在服务器的系统时间相差较大。如果不希望在身份校验时加入系统时间,可以将 frps 配置文件中的 authentication_timeout 设置为 0 来解决这个问题。

frpc 能否在系统启动阶段无网络时一直等待而不是直接退出?
在 frpc 的配置文件中将 login_fail_exit 设置为 false,则 frpc 启动后会不断尝试连接 frps,直到连接成功,而不是直接退出。

最后使用./frps -c ./frps.ini即可启动frps。启动后不能关闭putty,这时可以访问 服务器ip:7500 查看是否成功开启。

设置frps开机自动开启参考 不同系统下的开机自动运行

(2)树莓派下载frp并配置frpc客户端

安装方法同上(版本是arm非64版,树莓派4B的CPU是64位但使用的Pi OS为32位。下载链接)。安装完成之后修改一下frpc.ini文件(frp文件夹放在/bin下为例):

[common]
server_addr = 云服务器ip地址
server_port = 7000
token = 你的密码
login_fail_exit = false
#下面的log部分也可以不加
log_file = /var/logs/frpc.log
log_level = info
log_max_days = 3

[pi4B-gogs-web-1]
type = tcp
local_ip = localhost
local_port = 3000
remote_port = 8181

[pi4B-gogs-ssh-1]
type = tcp
local_ip = localhost
local_port = 22
remote_port = 50022

(3)其他

检查一下端口开放情况:服务器需要开放8181和50022端口(不要用ufw,要在 安全-防火墙 中添加规则);树莓派需要开放3000和22端口(本例用ufw添加规则;如果不需要局域网访问也可以不加)。

另外,记得删除一下安装包。

(4)设置frpc开机自启并开启服务

frp在systemd文件夹中放了.service文件。拷贝到/etc/systemd/system下即可:

cd /bin/frp/systemd
cp frpc.service /etc/systemd/system/frpc.service

然后打开/etc/systemd/system/frpc.service,把其中的User=nobody删掉,ExecStart和ExecReload改一下即可(放在其他路径就改成其他的):

ExecStart=/bin/frp/frpc -c /bin/frp/frpc.ini
ExecReload=/bin/frp/frpc reload -c /bin/frp/frpc.ini

最后enable+start:

systemctl enable frpc.service
systemctl start frpc.service

3.验证

systemctl status frpc.service查看一下frpc状态为active。

浏览器访问 服务器ip:8181 ,出现gogs网页。
查看dashboard(服务器ip:7500),pi4B-gogs-web-1和pi4B-gogs-ssh-1已上线。
git clone试验成功。

标签: frp, 树莓派, gogs, git

已有 12 条评论

  1. 博主你好,我按照你的方式搭建了gogs,而且配置了nginx反向代理域名,能够通过域名正常访问,但是克隆仓库的时候就要我输入git@域名的密码,我尝试了很多,但是他都报"Permission denied, please try again.",可以给指导一下吗?

    1. 这个应该是git使用的问题,和gogs没关系。不知道你用的什么编辑器,比如VS code还是什么其它的,或者在命令行里?正常的git clone一个私有仓库是要密码的,这个密码是gogs用户的密码(登录gogs网页的用户名和密码),格式是 git clone http://邮箱或用户名:密码@仓库url 。你应该搜一下git clone命令如何使用,比如https://www.runoob.com/git/git-clone.html

      1. 我使用的ssh,刚在局域网内配好后是可以使用的,但是内网穿透后,又配了nginx就不行了

        1. 就是说在内网可以clone,在公网只能登录网页、不能clone?

          1. 是的,我准备再重新配一次,不配nginx,看看只内外穿透一下,看看可不可以,看是哪一步出了问题

            1. 如果知道docker,我更建议用docker配置gogs,详见另一篇文章https://lisper517.top/index.php/archives/24/

              1. 好的,我再看看

    2. 我想问下你是怎么找到我博客的,是百度吗

    3. https://unknwon.io/posts/151115_setup-gogs-with-https/ 中,提供了一种nginx配置。我使用的nginx配置如下(docker):
      server {
      listen 80;
      server_name 域名;
      rewrite ^(.*)$ https://$host$1 permanent;
      }

      server {
      listen 443 ssl http2;
      server_name 域名;
      charset utf-8;
      ssl_certificate ssl证书目录;
      ssl_certificate_key ssl证书目录;
      ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # TLSv1.3要求nginx 1.13.0及以上版本
      ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
      ssl_prefer_server_ciphers on;
      ssl_session_cache shared:SSL:10m;
      ssl_session_timeout 1d;
      ssl_session_tickets off;
      access_log /log/nginx.access.log;
      error_log /log/nginx.error.log;
      location / {
      proxy_pass http://localhost:3000;
      proxy_set_header Host $http_host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_set_header X-Real-Ip $remote_addr;
      proxy_set_header X-NginX-Proxy true;
      proxy_redirect off;
      }
      }

      location / { 后面是反向代理的部分

      1. 现在clone ssh是可以的,还没内网穿透

      2. 这个是配了内网穿透,我现在的hosts解析是公网ip,前面没配置内网穿透,可以克隆,hosts解析的是内网ip

添加新评论