使用 Docker 安装 Gitea
slug
gitea-setup-from-docker
tags
docker
gitea
forgejo
date
Aug 13, 2024
summary
Gitea 是一个轻量级的 DevOps 平台软件,包括 Git 托管、代码审查、团队协作、软件包注册和 CI/CD。
status
Published
type
Post
1. 镜像选择
Gitea
提供的镜像包括 标准镜像
和 rootless镜像
。rootless
镜像使用 Gitea
内部 SSH 功能来提供 Git 协议,不支持 OpenSSH
,不需要 root
权限。项目 | 标准镜像 | rootless 镜像 |
执行用户 | root | 非 root |
ssh 端口 | 22 | 2222 |
git 用户与组 | 任意(由配置文件中指定) | 1000:1000 |
openssh | 支持 | 不支持 |
AppPath | /usr/local/bin/gitea | /usr/local/bin/gitea |
WorkPath | /data/gitea | /var/lib/gitea |
CustomPath | /data/gitea | /var/lib/gitea/custom |
ConfigFile | /data/gitea/conf/app.ini | /etc/gitea/app.ini |
2. 安装部署
2.1. 使用 rootless
镜像
2.1.1. 创建工作目录
docker 自动创建的目录是
root
权限,因此需要手动创建目录,以确保权限一致。rootless
镜像内的git
用户与组的id是1000:1000
,所以建议主机也使用1000:1000
。当然了,不一致也没关系,但需要通过
user: xxxx:xxxx
指定具体值。mkdir data config sudo chown 1000:1000 data config
2.1.2. 创建配置文件
特别注意:data config 文件夹应由user: xxxx:xxxx指定的用户所有,以确保主机能够正常访问这两个文件夹。
services: server: image: gitea/gitea:1.21-rootless container_name: gitea hostname: gitea restart: always user: 1000:1000 volumes: - ./data:/var/lib/gitea - ./config:/etc/gitea - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro ports: - "0.0.0.0:3000:3000" - "0.0.0.0:2222:2222"
2.1.3. 启动运行
注意:如果在 HTTP 上使用的是非 3000 端口,请将 app.ini 更改为匹配
LOCAL_ROOT_URL = http://localhost:3000/
docker compose up -d docker compose logs -f
2.2. 使用 标准
镜像
2.2.1. 创建工作目录
同上,docker 自动创建的目录是
root
权限,因此也要手动创建目录。与r
ootless
镜像不同,标准镜像内的git用
户id可以通过环境变量指定,自由度更高。mkdir data config sudo chown 1000:1000 data config
2.2.2. 创建配置文件
注意事项:
data
config
文件夹应由environment
指定的用户所有。
- 只需挂载一个路径
/data
,相比rootless
更简单
- 支持
openssh
标准22
端口
- 特别注意:生成的
ssh
文件夹是root
权限的,因此主机要有root
权限。
services: server: image: gitea/gitea:latest container_name: gitea hostname: gitea restart: always environment: - USER_UID=1000 - USER_GID=1000 volumes: - ./data:/data - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro ports: - "0.0.0.0:3000:3000" - "0.0.0.0:2222:22"
2.2.3. 启动运行
注意:如果在 HTTP 上使用的是非 3000 端口,请将 app.ini 更改为匹配
LOCAL_ROOT_URL = <http://localhost:3000/
。>docker compose up -d docker compose logs -f
3. SSH 容器透传
由于 SSH 在容器内运行,因此,如果需要 SSH 支持,则需要将 SSH 连接从主机转发到容器。
创建 Git 用户,并且要拥有
docker exec
权限。3.1. 创建 git
用户
这里的
git
用户用于ssh
容器透传。如果不需要 git clone git@host:username
功能,可以忽略。# uid 和 gid 也可以随机不指定。 sudo groupadd -g 1100 git && \ sudo useradd -c "Git Version Control" -m -d /home/git -s /bin/bash -u 1100 -g 1100 git # 将用户添加到docker用户组 sudo usermod -aG docker git
3.2. AuthorizedKeysCommand
该方法不需要通过挂载主机的
.ssh
目录,以获得容器内git
用户的 authorized_keys
,而是通过修改主机 /etc/sshd_config
文件来获取 authorized_keys
3.2.1. Docker Shell (推荐)
cat <<"EOF" | sudo tee -a /etc/ssh/sshd_config Match User git AuthorizedKeysCommandUser git AuthorizedKeysCommand /usr/bin/docker exec -i -u git gitea /usr/local/bin/gitea keys -e git -u %u -t %t -k %k EOF
i gitea
是容器名称,请注意修改。
- 标准镜像需要加
u git
指定git用户,否则以root
身份运行docker exec
会报错。
- 客户端执行
git clone
命令后,会进入容器执行gitea keys
命令,给客户端返回用户的authorized_keys
公钥信息,该信息是带有command="/usr/local/bin/gitea
路径的,与容器上Gitea
二进制文件的位置匹配。
- 通过验证后,主机 SSH 服务器为
git
用户建立会话,并使用主机git用户的shell
执行后续命令。因此,为了能够在容器内执行命令,我们还需要修改git
用户的默认shell
cat <<"EOF" | sudo tee /home/git/docker-shell #!/bin/sh /usr/bin/docker exec -i --env SSH_ORIGINAL_COMMAND="$SSH_ORIGINAL_COMMAND" gitea sh "$@" EOF # 修改git的默认shell sudo chmod +x /home/git/docker-shell sudo usermod -s /home/git/docker-shell git
- 客户端执行
git clone git@hotst:xxx
命令,实质就是通过ssh
连接主机的git
用户,然后 ssh 服务器根据AuthorizedKeysCommand
命令先到容器完成了xxx用户
的认证,最后再通过docker exec
方式去容器里面执行实际命令
3.2.2. SSH Shell
与
docker shell
基本一样,不同地方在于没有使用 docker exec
进入容器,而是通过 ssh git@127.0.0.1
进入容器。首先,要想ssh进入容器,则主机
git
用户要创建一个密钥,并提前添加到容器的 /data/git/.ssh/authorized_keys
目录。cat <<"EOF" | sudo tee -a /etc/ssh/sshd_config Match User git AuthorizedKeysCommandUser git AuthorizedKeysCommand /usr/bin/ssh -p 2222 -o StrictHostKeyChecking=no git@127.0.0.1 /usr/local/bin/gitea keys -e git -u %u -t %t -k %k EOF
3.3. authorized_keys
此方法是通过与容器共享
authorized_keys
文件的方式来进行用于认证,用于带有 openssh
的标准镜像。3.3.1. SSHing Shim (推荐)
- 为了使转发正常工作,需要将容器的 SSH 端口(22)映射到主机端口 2222。
#docker-compose.yml ports: - "127.0.0.1:2222:22"
- 接下来要使容器
git
用户的uid
和gid
与主机上的git
用户一致。
#docker-compose.yml environment: - USER_UID=1000 - USER_GID=1000
- 然后,创建主机与容器互联的密钥。
# 生成 authorized_keys 文件 sudo -u git mkdir /home/git/.ssh/ sudo -u git ssh-keygen -f "/home/git/.ssh/idrsa" -t rsa -b 4096 -C "Gitea Host Key" sudo -u git echo "$(cat /home/git/.ssh/idrsa.pub)" >> /home/git/.ssh/authorized_keys sudo -u git chmod 600 /home/git/.ssh/authorized_keys
- 接下来将主机
/home/git/.ssh
挂载到容器中。这可确保authorized_keys
文件在主机用户和容器之间共享。
volumes: - /home/git/.ssh/:/data/git/.ssh
通过 Gitea 界面添加的所有用户公钥都将有前缀
command="/usr [...]
。/home/git/.ssh/authorized_keys
内容如下:# SSH pubkey from git user ssh-rsa <Gitea Host Key> # other keys from users command="/app/gitea/gitea --config=/data/gitea/conf/app.ini
由于
authorized_keys
文件中command=选项
路径是 /app/gitea/gitea
,所以,当客户端执行 git clone
命令时会执行 /app/gitea/gitea
文件。- 在主机创建虚假
gitea
文件,该文件将把命令从主机转发到容器。
cat <<"EOF" | sudo tee /app/gitea/gitea #!/bin/sh ssh -p 2222 -o StrictHostKeyChecking=no git@127.0.0.1 "SSH_ORIGINAL_COMMAND=\\"$SSH_ORIGINAL_COMMAND\\" $0 $@" EOF sudo chmod +x /app/gitea/gitea
3.3.2. SSHing Shell
同样是通过 authorized_keys 认证,不同在于一个是路径上欺骗,另一个是通过修改git用户默认shell来实现。
原理完全一样,只是路径不同。一个是
/app/gitea/gitea
另一个是 /home/git/ssh-shell
cat <<"EOF" | sudo tee /home/git/ssh-shell #!/bin/sh shift ssh -p 2222 -o StrictHostKeyChecking=no git@127.0.0.1 "SSH_ORIGINAL_COMMAND=\\"$SSH_ORIGINAL_COMMAND\\" $@" EOF # 修改git的默认shell sudo chmod +x /home/git/ssh-shell sudo usermod -s /home/git/ssh-shell git
3.3.3. Docker Shell
也是共享 authorized_keys 来认证,不同在于通过 docker exec 到容器里面执行后续命令,而不是 ssh
cat <<"EOF" | sudo tee /home/git/docker-shell #!/bin/sh /usr/bin/docker exec -i -u git --env SSH_ORIGINAL_COMMAND="$SSH_ORIGINAL_COMMAND" gitea sh "$@" EOF sudo chmod +x /home/git/docker-shell sudo usermod -s /home/git/docker-shell git
4. Gitea Actions
4.1. Act Runner
4.1.1. 使用二进制文件
# 下载 wget <https://gitea.com/gitea/act_runner/releases/download/v0.2.7/act_runner-0.2.7-linux-amd64> mv act_runner-0.2.7-linux-amd64 gitea-runner chmod +x gitea-runner ./gitea-runner --version # 导出默认配置文件 ./gitea-runner generate-config > config.yaml # 注册 # ./gitea-runner --config config.yaml register ./gitea-runner register \\ --no-interactive \\ --instance <https://codes.wangyan.cloud> \\ --token xx \\ --name gitea-runner
4.1.2. 使用 Docker 镜像
导出配置文件
sudo docker pull gitea/act_runner:latest sudo docker run --entrypoint="" --rm -it gitea/act_runner:latest act_runner generate-config > config.yaml
配置 Cache
#vim config.yaml cache: enabled: true dir: "" # 使用步骤 1. 获取的 LAN IP host: "192.168.8.17" # 使用步骤 2. 获取的端口号 port: 3030
运行
#vim docker-compose.yml version: "3.8" services: runner: image: gitea/act_runner:nightly environment: CONFIG_FILE: /config.yaml GITEA_INSTANCE_URL: "<http://119.29.17.197:3000>" GITEA_RUNNER_REGISTRATION_TOKEN: "xx" GITEA_RUNNER_NAME: "gitea-runner" volumes: - ./config.yaml:/config.yaml - ./data:/data - /var/run/docker.sock:/var/run/docker.sock ports: - "3030:3030"
4.2. Actions Demo
vim .gitea/workflows/demo.yaml
name: Gitea Actions Demo run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀 on: [push] jobs: Explore-Gitea-Actions: runs-on: ubuntu-latest steps: - run: echo "🎉 The job was automatically triggered by a ${{ gitea.event_name }} event." - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by Gitea!" - run: echo "🔎 The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}." - name: Check out repository code uses: actions/checkout@v3 - run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner." - run: echo "🖥️ The workflow is now ready to test your code on the runner." - name: List files in the repository run: | ls ${{ gitea.workspace }} - run: echo "🍏 This job's status is ${{ job.status }}."
参考文档: