VMware+Alpine代替Docker部署Gogs服务

SEO

本文解决了以下问题:

  • 使用Gogs搭建本地Git服务器
  • 在VMware安装Alpine报错sfdisk(missing)
  • 在Alpine中运行Golang程序提示./xxx not found
  • 在Alpine中部署Gogs并分配用户
  • 设置Alpine Linux自启动服务
  • 已配置公钥git clone仍需密码
  • Gogs报错bash not found无法commit

前言

最近中了docker的毒,发现Alpine Linux真是个好东西,麻雀虽小五脏俱全。
只可惜Docke依赖Hyper-V和VMware Workstation不相容,由于业务关系只好放弃Docker for windows。
之前在Ubuntu Server虚拟机里跑Gogs觉得太重,空镜像1GB+而且很多服务用不上。
这里决定尝试更加轻量化的Vmware+Alpine搭建本地Git服务器。

踩坑

让Gogs在Alpine Linux上跑起来需要踩不少坑……(结论可直接跳至安装部署章节)

安装系统

安装Alpine必须联网,否则在系统分区那一步会报错sfdisk (missing)无法继续。

无法运行

进入系统第一个遇到的坑就是Alpine Linux无法直接运行Gogs官网提供的二进制Linux-amd64发行版,提示./gogs not found错误。
查看官网linux_amd64版gogs二进制文件依赖如下:

root@ubuntu:/mnt/gogs# ldd gogs 
	linux-vdso.so.1 (0x00007fffe1654000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fceb6cae000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fceb6c8b000)
	libpam.so.0 => /lib/x86_64-linux-gnu/libpam.so.0 (0x00007fceb6c79000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fceb6a87000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fceb6cb8000)
	libaudit.so.1 => /lib/x86_64-linux-gnu/libaudit.so.1 (0x00007fceb6a5b000)
	libcap-ng.so.0 => /lib/x86_64-linux-gnu/libcap-ng.so.0 (0x00007fceb6a53000)

同样是基于Alpine Linux可以正常运行的Docker官方image中版gogs二进制文件依赖如下:

bash-5.0# ldd gogs 
	/lib/ld-musl-x86_64.so.1 (0x7f5962502000)
	libpam.so.0 => /lib/libpam.so.0 (0x7f59624f3000)
	libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7f5962502000)

看来本质上还是gnu libc和musl libc的差异,go的CGO 提供了 golang 和 C 语言相互调用的机制,被调用的C代码默认为动态库编译时链接,然而Alpine使用更为精简的musl libc与主流Linux发行版采用gun libc不兼容,动态库妥妥的找不到啊。

因此解决方法有三:

  1. 在Alpine里面安装glibc让Alpine不再是Alpine
  2. 用musl重新编译Gogs保持Alpine原貌
  3. 静态编译Gogs不再依赖外部so

方法三可通过CGO_ENABLED=0 go build关闭CGO让Golang编译静态库与libc无关。
也可以直接拿Gogs官方Docker镜像里Alpine base二进制文件来用(哈哈)

补齐依赖

前文ldd显示依赖pam,使用apk add linux-pam添加
Alpine默认不含git,使用apk add git添加

公钥无效

成功安装并添加ssh key但无法通过ssh clone提示需要git账户密码
原因是git账户没有限制登录,需要修改/etc/shadow中git第二个字段为*

无法提交

ssh可以clone但无法commit报错bash not found看来Gogs依赖bash
手动安装apk add bash

安装部署

前期准备

安装系统,使用官网40M的虚拟机专用镜像alpine-virt-3.12.0-x86_64.iso
环境配齐

apk add git bash linux-pam

用户配置

创建一个用户专门用作git相关服务

adduser git -D -G Gogs -u 1000

修改/etc/shadow文件中第二个字段为*限制git登录,类似

git:*:18460:0:99999:7:::

从gogs官方docker镜像的/app文件夹中找到gogs二进制文件,复制到/home/git/gogs
切换git用户并运行gogs web服务

su git
./gogs web

确认hostname:3000可以正常显示

开机启动

手动创建一个daemon实现开机启动并防止gogs被中断,这里用nohup实现。熟悉OpenRC也可以自行编写服务实现。

Alpine Linux 的开机自启目录在/etc/local.d下,该目录下的README简要描述了用法:

This directory should contain programs or scripts which are to be run
when the local service is started or stopped.

If a file in this directory is executable and it has a .start extension,
it will be run when the local service is started. If a file is
executable and it has a .stop extension, it will be run when the local
service is stopped.

All files are processed in lexical order.

Keep in mind that files in this directory are processed sequentially,
and the local service is not considered started or stopped until
everything is processed, so if you have a process which takes a long
time to run, it can delay your boot or shutdown processing.

综上,只需要创建.start结尾的脚本并激活local服务即可。

vi gogs.start
    su - git -c "nohup /home/git/gogs/gogs web >/dev/null 2>&1 &"
chmod +x gogs.start
rc-update add local

注意:这里su - git一定要加-代表切换用户的同时改变工作目录为用户home dir
不加能够以git身份启动gogs但会导致HTTP500权限错误。

迁移

最后一步,迁移原有服务器的用户数据。
参考Gogs官方社区,在源系统执行./gogs backup获得包含数据库和仓库的完整备份
进入目标系统执行./gogs restore --from="gogs-backup-xxx.zip"完成恢复
仓库较大可选择仅备份数据库并手动迁移gogs-repositories文件夹(文末链接)

尾声

让这台虚拟机随系统登录静默启动,锦上添花。
使用vmrun命令vmrun.exe start C:YourPathalpine.vmx nogui
使用gpeditt.msc将这句话加入登录脚本,搞定!

参考

Installed Go binary not found in path on Alpine Linux Docker - Stack Overflow
shell脚本中使用其他用户执行脚本 - Bigben - 博客园
使用nohup不产生log文件方法 - azureology - 博客园
Alpine Linux 实现开机自启脚本 – 刺客博客
How to backup, restore and migrate - Tips, Tricks, and How-To's - Gogs Discussion

原文地址:https://www.cnblogs.com/azureology/p/13393571.html