使用 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 权限,因此也要手动创建目录。
与rootless 镜像不同,标准镜像内的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 (推荐)

  1. 为了使转发正常工作,需要将容器的 SSH 端口(22)映射到主机端口 2222。
#docker-compose.yml ports: - "127.0.0.1:2222:22"
  1. 接下来要使容器git用户的uidgid 与主机上的git用户一致。
#docker-compose.yml environment: - USER_UID=1000 - USER_GID=1000
  1. 然后,创建主机与容器互联的密钥。
# 生成 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
  1. 接下来将主机/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 文件。
  1. 在主机创建虚假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 }}."
参考文档:
If you have any questions, please contact me.