使用 Docker 安装
Gitea 在其 Docker Hub 组织中提供自动更新的 Docker 镜像。您可以始终使用最新的稳定标签,也可以使用其他处理更新 Docker 镜像的服务。
此参考设置指南使用 docker-compose
引导用户完成设置,但 docker-compose
的安装不在此文档的范围之内。要安装 docker-compose
本身,请按照官方的 安装说明。
基础
最简单的设置只是创建一个卷和一个网络,并将 gitea/gitea:latest
镜像作为服务启动。由于没有可用的数据库,可以使用 SQLite3 初始化一个数据库。创建一个名为 gitea
的目录,并将以下内容粘贴到名为 docker-compose.yml
的文件中。请注意,卷应由具有配置文件中指定的 UID/GID 的用户/组拥有。如果您没有为卷提供正确的权限,容器可能无法启动。对于稳定版本,您可以使用 :latest
、:1
或指定特定版本,如 :1.22.3
,但如果您想使用 Gitea 的最新开发版本,则可以使用 :nightly
标签。如果您想运行来自发布分支的最新提交,则可以使用 :1.x-nightly
标签,其中 x 是 Gitea 的次要版本。(例如,:1.16-nightly
)
version: "3"
networks:
gitea:
external: false
services:
server:
image: gitea/gitea:1.22.3
container_name: gitea
environment:
- USER_UID=1000
- USER_GID=1000
restart: always
networks:
- gitea
volumes:
- ./gitea:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000"
- "222:22"
端口
要在不同端口上绑定集成的 OpenSSH 守护进程和 Web 服务器,请调整端口部分。通常只需要更改主机端口,并保持容器内的端口不变。
version: "3"
networks:
gitea:
external: false
services:
server:
image: gitea/gitea:1.22.3
container_name: gitea
environment:
- USER_UID=1000
- USER_GID=1000
restart: always
networks:
- gitea
volumes:
- ./gitea:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- - "3000:3000"
- - "222:22"
+ - "8080:3000"
+ - "2221:22"
数据库
MySQL 数据库
要在与 MySQL 数据库结合的情况下启动 Gitea,请将以上创建的 docker-compose.yml
文件中应用以下更改。
version: "3"
networks:
gitea:
external: false
services:
server:
image: gitea/gitea:1.22.3
container_name: gitea
environment:
- USER_UID=1000
- USER_GID=1000
+ - GITEA__database__DB_TYPE=mysql
+ - GITEA__database__HOST=db:3306
+ - GITEA__database__NAME=gitea
+ - GITEA__database__USER=gitea
+ - GITEA__database__PASSWD=gitea
restart: always
networks:
- gitea
volumes:
- ./gitea:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000"
- "222:22"
+ depends_on:
+ - db
+
+ db:
+ image: mysql:8
+ restart: always
+ environment:
+ - MYSQL_ROOT_PASSWORD=gitea
+ - MYSQL_USER=gitea
+ - MYSQL_PASSWORD=gitea
+ - MYSQL_DATABASE=gitea
+ networks:
+ - gitea
+ volumes:
+ - ./mysql:/var/lib/mysql
PostgreSQL 数据库
要在与 PostgreSQL 数据库结合的情况下启动 Gitea,请将以上创建的 docker-compose.yml
文件中应用以下更改。
version: "3"
networks:
gitea:
external: false
services:
server:
image: gitea/gitea:1.22.3
container_name: gitea
environment:
- USER_UID=1000
- USER_GID=1000
+ - GITEA__database__DB_TYPE=postgres
+ - GITEA__database__HOST=db:5432
+ - GITEA__database__NAME=gitea
+ - GITEA__database__USER=gitea
+ - GITEA__database__PASSWD=gitea
restart: always
networks:
- gitea
volumes:
- ./gitea:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000"
- "222:22"
+ depends_on:
+ - db
+
+ db:
+ image: postgres:14
+ restart: always
+ environment:
+ - POSTGRES_USER=gitea
+ - POSTGRES_PASSWORD=gitea
+ - POSTGRES_DB=gitea
+ networks:
+ - gitea
+ volumes:
+ - ./postgres:/var/lib/postgresql/data
命名卷
要使用命名卷而不是主机卷,请在 docker-compose.yml
配置中定义和使用命名卷。此更改将自动创建所需的卷。您无需担心命名卷的权限;Docker 将自动处理。
version: "3"
networks:
gitea:
external: false
+volumes:
+ gitea:
+ driver: local
+
services:
server:
image: gitea/gitea:1.22.3
container_name: gitea
restart: always
networks:
- gitea
volumes:
- - ./gitea:/data
+ - gitea:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000"
- "222:22"
MySQL 或 PostgreSQL 容器需要单独创建。
启动
从 2023 年 7 月开始,Compose V1 停止接收更新。它也不再包含在 Docker Desktop 的新版本中。
Compose V2 包含在所有当前支持的 Docker Desktop 版本中。请使用 V2 进行以下操作。
要启动基于 docker-compose
的此设置,请执行 docker-compose up -d
,以便在后台启动 Gitea。使用 docker-compose ps
将显示 Gitea 是否已正确启动。可以使用 docker-compose logs
查看日志。
要关闭设置,请执行 docker-compose down
。这将停止并杀死容器。卷仍然存在。
如果在 http 上使用非 3000 端口,请更改 app.ini 以匹配 LOCAL_ROOT_URL = https://127.0.0.1:3000/
。
安装
通过 docker-compose
启动 Docker 设置后,可以使用您喜欢的浏览器访问 Gitea 以完成安装。访问 http://server-ip:3000 并按照安装向导进行操作。如果数据库已如上所述使用 docker-compose
设置启动,请注意必须使用 db
作为数据库主机名。
使用环境变量配置 Gitea 内部的用户
USER
: git: 在容器内运行 Gitea 的用户的用户名。USER_UID
: 1000: 在容器内运行 Gitea 的用户的 UID(Unix 用户 ID)。如果使用主机卷,请将其与/data
卷所有者的 UID 匹配(对于命名卷,则不需要这样做)。USER_GID
: 1000: 在容器内运行 Gitea 的用户的 GID(Unix 组 ID)。如果使用主机卷,请将其与/data
卷所有者的 GID 匹配(对于命名卷,则不需要这样做)。
自定义
此处介绍的自定义文件 此处 应放置在 /data/gitea
目录中。如果使用主机卷,则很容易访问这些文件;对于命名卷,可以通过另一个容器或通过 /var/lib/docker/volumes/gitea_gitea/_data
直接访问来完成。配置文件将在安装后保存到 /data/gitea/conf/app.ini
中。
升级
❗❗ 确保您已将卷数据到 Docker 容器外部的某个地方。 ❗❗
要将您的安装升级到最新版本,请执行以下操作。
# Edit `docker-compose.yml` to update the version, if you have one specified
# Pull new images
docker-compose pull
# Start a new container, automatically removes old one
docker-compose up -d
使用环境变量管理部署
除了上面的环境变量之外,app.ini
中的任何设置都可以通过以下形式的环境变量来设置或覆盖:GITEA__SECTION_NAME__KEY_NAME
。这些设置在每次 Docker 容器启动时都会应用,不会传递到 Gitea 的子进程中。完整的说明 此处。
这些环境变量可以在 docker-compose.yml
中传递到 Docker 容器。以下示例将在主机或 docker-compose.yml
所在目录的 .env
文件中设置了必要的 env 变量 GITEA__mailer__FROM
、GITEA__mailer__HOST
、GITEA__mailer__PASSWD
后启用 smtp 邮件服务器。
也可以通过定义一个名为 GITEA__section_name__KEY_NAME__FILE
的环境变量来使用文件内容来设置或覆盖设置,该变量指向一个文件。
...
services:
server:
environment:
- GITEA__mailer__ENABLED=true
- GITEA__mailer__FROM=${GITEA__mailer__FROM:?GITEA__mailer__FROM not set}
- GITEA__mailer__PROTOCOL=smtps
- GITEA__mailer__SMTP_ADDR=${GITEA__mailer__SMTP_ADDR:?GITEA__mailer__SMTP_ADDR not set}
- GITEA__mailer__SMTP_PORT=${GITEA__mailer__SMTP_PORT:?GITEA__mailer__SMTP_PORT not set}
- GITEA__mailer__USER=${GITEA__mailer__USER:-apikey}
- GITEA__mailer__PASSWD="""${GITEA__mailer__PASSWD:?GITEA__mailer__PASSWD not set}"""
Gitea 会在每次新安装时自动生成新的密钥/令牌,并将它们写入 app.ini 文件。如果你想手动设置密钥/令牌,可以使用以下 Docker 命令来使用 Gitea 的内置 生成实用程序函数。在安装后不要丢失或更改你的 SECRET_KEY,否则加密的数据将无法解密。
以下命令将输出一个新的 SECRET_KEY
和 INTERNAL_TOKEN
到 stdout
,你可以将其放到你的环境变量中。
docker run -it --rm gitea/gitea:1 gitea generate secret SECRET_KEY
docker run -it --rm gitea/gitea:1 gitea generate secret INTERNAL_TOKEN
...
services:
server:
environment:
- GITEA__security__SECRET_KEY=[value returned by generate secret SECRET_KEY]
- GITEA__security__INTERNAL_TOKEN=[value returned by generate secret INTERNAL_TOKEN]
SSH 容器穿透
由于 SSH 在容器内运行,因此如果需要 SSH 支持,则需要将 SSH 从主机穿透到容器。一种选择是在非标准端口上运行容器 SSH(或将主机端口移动到非标准端口)。另一个可能更直接的选择是,Gitea 用户可以通过 SSH 登录到主机上的 Gitea 用户,然后将这些连接中继到 Docker。
了解 SSH 访问 Gitea(无穿透)
要了解需要发生的事情,你需要先了解没有穿透的情况下会发生什么。所以我们将尝试解释这一点。
- 客户端使用网页将他们的 SSH 公钥添加到 Gitea。
- Gitea 将为该密钥在运行用户(
git
)的.ssh/authorized_keys
文件中添加一个条目。 - 此条目包含公钥,但也包含一个
command=
选项。Gitea 使用此命令将该密钥与客户端用户匹配并管理身份验证。 - 然后,客户端使用
git
用户向 SSH 服务器发出 SSH 请求,例如git clone git@domain:user/repo.git
。 - 客户端将尝试使用服务器进行身份验证,将一个或多个公钥一次一个地传递给服务器。
- 对于客户端提供的每个密钥,SSH 服务器将首先检查其配置以查看
AuthorizedKeysCommand
是否匹配公钥,然后检查git
用户的authorized_keys
文件。 - 将选择第一个匹配的条目,如果这是一个 Gitea 条目,则现在将执行
command=
。 - SSH 服务器为
git
用户创建一个用户会话,并使用git
用户的 shell 运行command=
。 - 这将运行
gitea serv
,它将接管剩余 SSH 会话的控制权,并管理 Gitea 对 git 命令的身份验证和授权。
现在,为了使 SSH 穿透正常工作,我们需要主机 SSH 匹配公钥,然后在 Docker 上运行 gitea serv
。有多种方法可以做到这一点。但是,所有这些方法都需要一些关于传递到主机的 Docker 的信息。
SSH Shim(使用 authorized_keys)
在这种选择中,主机只需使用 Gitea 创建的 authorized_keys
,但在步骤 9 中,主机运行的 gitea
命令是一个 shim,它实际上运行 ssh 进入 Docker,然后运行真正的 Docker gitea
本身。
-
为了使转发正常工作,需要在
docker-compose.yml
中将容器的 SSH 端口(22)映射到主机端口 2222。由于此端口不需要暴露到外部世界,因此可以将其映射到主机机器的localhost
ports:
# [...]
- "127.0.0.1:2222:22" -
接下来,在主机上创建
git
用户,该用户与容器值USER_UID
/USER_GID
共享相同的UID
/GID
。这些值可以作为环境变量设置在docker-compose.yml
中。environment:
- USER_UID=1000
- USER_GID=1000 -
将主机的
/home/git/.ssh
挂载到容器中。这确保了authorized_keys
文件在主机git
用户和容器git
用户之间共享,否则 SSH 身份验证无法在容器内工作。volumes:
- /home/git/.ssh/:/data/git/.ssh -
现在需要在主机上创建 SSH 密钥对。此密钥对将用于在主机上使用
git
用户对容器进行身份验证。作为主机上的管理员用户运行:(管理员用户是指可以 sudo 到 root 的用户)sudo -u git ssh-keygen -t rsa -b 4096 -C "Gitea Host Key"
-
请注意,根据 SSH 的本地版本,你可能需要考虑在此处使用
-t ecdsa
。 -
现在需要修改主机上的
/home/git/.ssh/authorized_keys
。它需要与 Gitea 容器内的authorized_keys
一样工作。因此,将上面创建的密钥的公钥(“Gitea 主机密钥”)添加到~/git/.ssh/authorized_keys
中。作为主机上的管理员用户运行sudo -u git cat /home/git/.ssh/id_rsa.pub | sudo -u git tee -a /home/git/.ssh/authorized_keys
sudo -u git chmod 600 /home/git/.ssh/authorized_keys重要:来自
git
用户的公钥需要“按原样”添加,而通过 Gitea 网页界面添加的所有其他公钥将以command="/usr [...]
为前缀。然后
/home/git/.ssh/authorized_keys
将看起来有点像# SSH pubkey from git user
ssh-rsa <Gitea Host Key>
# other keys from users
command="/usr/local/bin/gitea --config=/data/gitea/conf/app.ini serv key-1",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty <user pubkey> -
下一步是创建假的宿主
gitea
命令,该命令将把命令从宿主转发到容器。此文件的名称取决于你的 Gitea 版本。-
对于 Gitea v1.16.0+。作为主机上的管理员用户运行
cat <<"EOF" | sudo tee /usr/local/bin/gitea
#!/bin/sh
ssh -p 2222 -o StrictHostKeyChecking=no [email protected] "SSH_ORIGINAL_COMMAND=\"$SSH_ORIGINAL_COMMAND\" $0 $@"
EOF
sudo chmod +x /usr/local/bin/gitea
-
以下是 SSH 请求发出时发生的事情的详细解释。
- 客户端使用网页将他们的 SSH 公钥添加到 Gitea。
- 容器中的 Gitea 将为该密钥在运行用户(
git
)的.ssh/authorized_keys
文件中添加一个条目。- 但是,由于主机的
/home/git/.ssh/
被挂载为/data/git/.ssh
,这意味着该密钥也被添加到主机git
用户的authorized_keys
文件中。
- 但是,由于主机的
- 此条目包含公钥,但也包含一个
command=
选项。- 此命令匹配 Gitea 二进制文件在容器中的位置,但也匹配 shim 在主机上的位置。
- 然后,客户端使用
git
用户向主机 SSH 服务器发出 SSH 请求,例如git clone git@domain:user/repo.git
。 - 客户端将尝试使用服务器进行身份验证,依次将一个或多个公钥传递给主机。
- 对于客户端提供的每个密钥,主机 SSH 服务器将首先检查其配置以查看
AuthorizedKeysCommand
是否匹配公钥,然后检查主机git
用户的authorized_keys
文件。- 因为
/home/git/.ssh/
在主机上被挂载为/data/git/.ssh
,所以这意味着他们添加到 Gitea 网页的密钥将被找到。
- 因为
- 将选择第一个匹配的条目,如果这是一个 Gitea 条目,则现在将执行
command=
。 - 主机 SSH 服务器为
git
用户创建一个用户会话,并使用主机git
用户的 shell 运行command=
。 - 这意味着主机运行主机
/usr/local/bin/gitea
shim,它从主机到容器打开一个 SSH,并将剩余的命令参数直接传递给容器上的/usr/local/bin/gitea
。 - 这意味着容器
gitea serv
被运行,接管剩余 SSH 会话的控制权,并管理 Gitea 对 git 命令的身份验证和授权。
注意
仅当以下情况时,使用 authorized_keys
的 SSH 容器穿透才有效
- 容器中使用
opensshd
- 如果
AuthorizedKeysCommand
未与SSH_CREATE_AUTHORIZED_KEYS_FILE=false
结合使用以禁用授权文件密钥生成 LOCAL_ROOT_URL
未更改(取决于更改)
如果你尝试在主机上运行 gitea
,你将尝试通过 SSH 登录到容器,然后在其中运行 gitea
命令。
永远不要将 Gitea 主机密钥
作为 SSH 密钥添加到 Gitea 界面的用户中。
SSHing Shell(使用 authorized_keys)
在这种选择中,主机只需使用 Gitea 创建的 authorized_keys
,但在步骤 8 中,我们将主机运行的 shell 更改为直接通过 SSH 进入 Docker,然后在其中运行 shell。这意味着随后运行的 gitea
是真正的 Docker gitea
。
-
在这种情况下,我们按照 SSHing Shim 的设置进行设置,只是我们没有创建
/usr/local/bin/gitea
,而是为 git 用户创建了一个新的 shell。作为主机上的管理员用户运行cat <<"EOF" | sudo tee /home/git/ssh-shell
#!/bin/sh
shift
ssh -p 2222 -o StrictHostKeyChecking=no [email protected] "SSH_ORIGINAL_COMMAND=\"$SSH_ORIGINAL_COMMAND\" $@"
EOF
sudo chmod +x /home/git/ssh-shell
sudo usermod -s /home/git/ssh-shell git请务必小心 - 如果你以后尝试以 git 用户身份登录,你将直接通过 SSH 登录到 Docker。
以下是 SSH 请求发出时发生的事情的详细解释。
- 客户端使用网页将他们的 SSH 公钥添加到 Gitea。
- 容器中的 Gitea 将为该密钥在运行用户(
git
)的.ssh/authorized_keys
文件中添加一个条目。- 但是,由于主机的
/home/git/.ssh/
被挂载为/data/git/.ssh
,这意味着该密钥也被添加到主机git
用户的authorized_keys
文件中。
- 但是,由于主机的
- 此条目包含公钥,但也包含一个
command=
选项。- 此命令匹配 Gitea 二进制文件在容器中的位置。
- 然后,客户端使用
git
用户向主机 SSH 服务器发出 SSH 请求,例如git clone git@domain:user/repo.git
。 - 客户端将尝试使用服务器进行身份验证,依次将一个或多个公钥传递给主机。
- 对于客户端提供的每个密钥,主机 SSH 服务器将首先检查其配置以查看
AuthorizedKeysCommand
是否匹配公钥,然后检查主机git
用户的authorized_keys
文件。- 因为
/home/git/.ssh/
在主机上被挂载为/data/git/.ssh
,所以这意味着他们添加到 Gitea 网页的密钥将被找到。
- 因为
- 将选择第一个匹配的条目,如果这是一个 Gitea 条目,则现在将执行
command=
。 - 主机 SSH 服务器为
git
用户创建一个用户会话,并使用主机git
用户的 shell 运行command=
。 - 主机
git
用户的 shell 现在是我们的ssh-shell
,它从主机到容器打开一个 SSH 连接(在容器中为容器git
打开一个 shell)。 - 容器 shell 现在运行
command=
选项,这意味着容器gitea serv
被运行,接管剩余 SSH 会话的控制权,并管理 Gitea 对 git 命令的身份验证和授权。
注意
仅当以下情况时,使用 authorized_keys
的 SSH 容器穿透才有效
- 容器中使用
opensshd
- 如果
AuthorizedKeysCommand
未与SSH_CREATE_AUTHORIZED_KEYS_FILE=false
结合使用以禁用授权文件密钥生成 LOCAL_ROOT_URL
未更改(取决于更改)
如果你以后尝试以主机上的 git
用户身份登录,你将直接通过 SSH 登录到 Docker。
永远不要将 Gitea 主机密钥
作为 SSH 密钥添加到 Gitea 界面的用户中。
Docker Shell(使用 authorized_keys)
类似于上面的 ssh shell 技术,我们可以使用一个 shell,它只是使用 docker exec
。作为主机上的管理员用户运行
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
以下是 SSH 请求发出时发生的事情的详细解释。
- 客户端使用网页将他们的 SSH 公钥添加到 Gitea。
- 容器中的 Gitea 将为该密钥在运行用户(
git
)的.ssh/authorized_keys
文件中添加一个条目。- 但是,由于主机的
/home/git/.ssh/
被挂载为/data/git/.ssh
,这意味着该密钥也被添加到主机git
用户的authorized_keys
文件中。
- 但是,由于主机的
- 此条目包含公钥,但也包含一个
command=
选项。- 此命令匹配 Gitea 二进制文件在容器中的位置。
- 然后,客户端使用
git
用户向主机 SSH 服务器发出 SSH 请求,例如git clone git@domain:user/repo.git
。 - 客户端将尝试使用服务器进行身份验证,依次将一个或多个公钥传递给主机。
- 对于客户端提供的每个密钥,主机 SSH 服务器将首先检查其配置以查看
AuthorizedKeysCommand
是否匹配公钥,然后检查主机git
用户的authorized_keys
文件。- 因为
/home/git/.ssh/
在主机上被挂载为/data/git/.ssh
,所以这意味着他们添加到 Gitea 网页的密钥将被找到。
- 因为
- 将选择第一个匹配的条目,如果这是一个 Gitea 条目,则现在将执行
command=
。 - 主机 SSH 服务器为
git
用户创建一个用户会话,并使用主机git
用户的 shell 运行command=
。 - 主机
git
用户的 shell 现在是我们的docker-shell
,它使用docker exec
为容器上的git
用户打开一个 shell。 - 容器 shell 现在运行
command=
选项,这意味着容器gitea serv
被运行,接管剩余 SSH 会话的控制权,并管理 Gitea 对 git 命令的身份验证和授权。
请注意,上面 docker 命令中的 gitea
是容器的名称。如果你将它命名为其他名称,请不要忘记更改它。主机 git
用户也必须有权限运行 docker exec
。
注意
仅当以下情况时,使用 authorized_keys
的 Docker shell 穿透才有效
- 容器中使用
opensshd
- 如果
AuthorizedKeysCommand
未与SSH_CREATE_AUTHORIZED_KEYS_FILE=false
结合使用以禁用授权文件密钥生成 LOCAL_ROOT_URL
未更改(取决于更改)
如果你以后尝试以主机上的 git
用户身份登录,你将直接使用 docker exec
登录到 Docker。
可以类似于上面创建 Docker execing shim。
使用 AuthorizedKeysCommand 的 Docker Shell
AuthorizedKeysCommand 路线提供了另一种不需要对 compose 文件或 authorized_keys
进行大量更改的选择,但需要对主机 /etc/sshd_config
进行更改。
在这种选择中,主机 SSH 使用 AuthorizedKeysCommand
,而不是依赖于共享 Gitea 创建的 authorized_keys
文件。我们继续在步骤 8 中使用一个特殊的 shell 来执行到 Docker,然后在其中运行 shell。这意味着随后运行的 gitea
是真正的 Docker gitea
。
-
在主机上创建一个具有运行
docker exec
权限的git
用户。 -
我们将再次假设 Gitea 容器被称为
gitea
。 -
修改
git
用户的 shell,以使用docker exec
将命令转发到容器内的sh
可执行文件。作为主机上的管理员用户运行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
现在所有尝试以主机上的 git
用户身份登录的尝试都将被转发到 Docker,包括 SSH_ORIGINAL_COMMAND
。现在我们需要在主机上设置 SSH 身份验证。
我们将通过利用 SSH AuthorizedKeysCommand 来将密钥与 Gitea 接受的密钥进行匹配来实现。
将以下代码块添加到主机的 /etc/ssh/sshd_config
中
Match User git
AuthorizedKeysCommandUser git
AuthorizedKeysCommand /usr/bin/docker exec -i -u git gitea /usr/local/bin/gitea keys -c /data/gitea/conf/app.ini -e git -u %u -t %t -k %k
(从 1.16.0 开始,你不需要设置 -c /data/gitea/conf/app.ini
选项。)
最后,重启 SSH 服务器。作为主机上的管理员用户运行
sudo systemctl restart sshd
以下是 SSH 请求发出时发生的事情的详细解释。
- 客户端使用网页将他们的 SSH 公钥添加到 Gitea。
- 容器中的 Gitea 将为该密钥在其数据库中添加一个条目。
- 然后,客户端使用
git
用户向主机 SSH 服务器发出 SSH 请求,例如git clone git@domain:user/repo.git
。 - 客户端将尝试使用服务器进行身份验证,依次将一个或多个公钥传递给主机。
- 对于客户端提供的每个密钥,主机 SSH 服务器都会检查其配置中的
AuthorizedKeysCommand
。 - 主机运行上面的
AuthorizedKeysCommand
,它会执行到 Docker 中,然后运行gitea keys
命令。 - Docker 上的 Gitea 会在它的数据库中查找公钥是否匹配,并返回类似于
authorized_keys
命令的条目。 - 此条目包含公钥,但也包含一个
command=
选项,它与容器中 Gitea 二进制文件的位置匹配。 - 主机 SSH 服务器为
git
用户创建了一个用户会话,并使用主机git
用户的 shell 运行command=
。 - 主机
git
用户的 shell 现在是我们的docker-shell
,它使用docker exec
为容器上的git
用户打开一个 shell。 - 容器 shell 现在运行
command=
选项,这意味着容器gitea serv
被运行,接管剩余 SSH 会话的控制权,并管理 Gitea 对 git 命令的身份验证和授权。
注意
使用 AuthorizedKeysCommand
的 Docker shell 传递将仅在以下情况下有效:
- 主机
git
用户被允许运行docker exec
命令。
如果你以后尝试以主机上的 git
用户身份登录,你将直接使用 docker exec
登录到 Docker。
可以类似于上面创建 Docker execing shim。
带有 AuthorizedKeysCommand 的 SSH Shell
为主机 git
用户创建密钥,如上所述,将其添加到 Docker /data/git/.ssh/authorized_keys
中,最后创建并设置 ssh-shell
,如上所述。
将以下代码块添加到主机的 /etc/ssh/sshd_config
中
Match User git
AuthorizedKeysCommandUser git
AuthorizedKeysCommand /usr/bin/ssh -p 2222 -o StrictHostKeyChecking=no [email protected] /usr/local/bin/gitea keys -c /data/gitea/conf/app.ini -e git -u %u -t %t -k %k
(从 1.16.0 开始,你不需要设置 -c /data/gitea/conf/app.ini
选项。)
最后,重启 SSH 服务器。作为主机上的管理员用户运行
sudo systemctl restart sshd
以下是 SSH 请求发出时发生的事情的详细解释。
- 客户端使用网页将他们的 SSH 公钥添加到 Gitea。
- 容器中的 Gitea 将为该密钥在其数据库中添加一个条目。
- 然后,客户端使用
git
用户向主机 SSH 服务器发出 SSH 请求,例如git clone git@domain:user/repo.git
。 - 客户端将尝试使用服务器进行身份验证,依次将一个或多个公钥传递给主机。
- 对于客户端提供的每个密钥,主机 SSH 服务器都会检查其配置中的
AuthorizedKeysCommand
。 - 主机运行上面的
AuthorizedKeysCommand
,它会 SSH 到 Docker 中,然后运行gitea keys
命令。 - Docker 上的 Gitea 会在它的数据库中查找公钥是否匹配,并返回类似于
authorized_keys
命令的条目。 - 此条目包含公钥,但也包含一个
command=
选项,它与容器中 Gitea 二进制文件的位置匹配。 - 主机 SSH 服务器为
git
用户创建了一个用户会话,并使用主机git
用户的 shell 运行command=
。 - 主机
git
用户的 shell 现在是我们的git-shell
,它使用 SSH 为容器中的git
用户打开一个 shell。 - 容器 shell 现在运行
command=
选项,这意味着容器gitea serv
被运行,接管剩余 SSH 会话的控制权,并管理 Gitea 对 git 命令的身份验证和授权。
注意
使用 AuthorizedKeysCommand
的 SSH 容器传递将仅在以下情况下有效:
opensshd
在容器中运行
如果您尝试在将来以主机上的 git
用户身份登录,您将直接 ssh
到 Docker 中。
永远不要将 Gitea 主机密钥
作为 SSH 密钥添加到 Gitea 界面的用户中。
SSHing shims 可以类似于上面创建。