【Docker】Gitea SSH容器直通:从权限配置到端口转发的实战避坑指南 1. 为什么需要SSH容器直通当你用Docker部署Gitea时会遇到一个典型问题默认情况下用户通过SSH访问仓库时请求会先到达宿主机的22端口而Gitea实际运行在容器内部的22端口。这就好比快递员把包裹送到你家门口宿主机但收件人住在你家阁楼容器——如果没有专门的通道快递永远送不到收件人手里。我最初部署时就踩过这个坑克隆仓库时总提示Connection refused折腾半天才发现SSH请求根本没进容器。后来发现SSH容器直通就是解决这个问题的标准方案它的核心原理是宿主机SSH服务接收外部请求通过预置脚本将请求转发到容器的映射端口如2222容器内Gitea处理真正的Git操作2. 环境准备与基础配置2.1 创建专用Git用户官方文档建议创建一个专用git用户这是为了避免权限混乱。实际操作中我发现很多人直接用root操作结果导致后续各种权限问题。正确做法是# 创建git用户会自动创建同名用户组 sudo adduser git关键点在于记录下这个用户的UID和GID$ id git uid1002(git) gid1002(git) groups1002(git)这个数字后面会用在docker-compose的环境变量中。我遇到过因为UID不匹配导致容器无法读写宿主机文件的情况所以务必确保一致。2.2 准备SSH密钥对切换到git用户生成密钥对sudo -u git ssh-keygen -t rsa -b 4096 -C Gitea Host Key这里有个细节新创建的git用户可能没有sudo权限需要先将其加入sudoers文件# 编辑sudoers文件 sudo visudo # 添加下面这行 git ALL(ALL) NOPASSWD: ALL然后将公钥写入授权文件sudo -u git bash -c cat /home/git/.ssh/id_rsa.pub /home/git/.ssh/authorized_keys3. 关键配置步骤详解3.1 编写SSH转发脚本这个脚本是直通功能的核心我把它放在/usr/local/bin/gitea#!/bin/sh ssh -p 2222 -o StrictHostKeyCheckingno git127.0.0.1 SSH_ORIGINAL_COMMAND\$SSH_ORIGINAL_COMMAND\ $0 $设置可执行权限sudo chmod x /usr/local/bin/gitea实测中发现如果权限设置不对比如只有755会导致git用户无法执行脚本。最稳妥的方法是直接777sudo chmod 777 /usr/local/bin/gitea3.2 配置安全的端口映射在docker-compose.yml中端口映射要特别注意安全性ports: - 30000:3000 # Web界面端口 - 127.0.0.1:2222:22 # 关键只允许本地访问2222端口这里127.0.0.1:前缀限制了只有本机可以访问2222端口避免暴露SSH到公网。我曾经忘记加这个限制结果服务器被扫描告警吓得赶紧加了防火墙规则。3.3 权限一致性配置确保容器内外用户权限一致environment: - USER_UID1002 # 必须与git用户的UID一致 - USER_GID1002 # 必须与git用户的GID一致 volumes: - /home/git/.ssh/:/data/git/.ssh4. 常见问题排查指南4.1 SSH连接被拒绝如果遇到Connection refused按这个顺序检查宿主机SSH服务是否运行sudo systemctl status sshd端口映射是否正确netstat -tuln | grep 2222容器是否正常监听docker exec -it gitea netstat -tuln | grep 224.2 权限不足问题典型错误提示是Permission denied重点检查/usr/local/bin/gitea脚本权限是否为777挂载的.ssh目录所有者是否为git用户容器内外的UID/GID是否匹配4.3 authorized_keys文件异常Gitea会自动管理这个文件手动修改会导致问题。正确的文件格式应该是# Gitea主机密钥原始内容 ssh-rsa AAAAB3... # 用户添加的公钥自动添加command前缀 command/usr/local/bin/gitea... ssh-rsa AAAAB3...如果发现格式混乱最简单的解决办法是备份原文件删除异常内容在Gitea网页重新添加公钥5. 完整docker-compose示例这是我经过多次验证的稳定配置version: 3 networks: gitea: external: false services: server: image: gitea/gitea:1.21.4 container_name: gitea environment: - USER_UID1002 - USER_GID1002 restart: always networks: - gitea volumes: - /home/git/data:/data - /home/git/.ssh/:/data/git/.ssh - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro ports: - 30000:3000 - 127.0.0.1:2222:22几个经验建议不要修改容器内的SSH端口保持22初始化时使用HTTP协议避免初始配置冲突数据卷建议用绝对路径避免相对路径的权限问题6. 验证与测试最后一步是验证直通是否成功ssh -T git你的服务器IP成功时会显示Hi there, 用户名! Youve successfully authenticated...如果要用实际仓库测试git clone git服务器IP:用户名/仓库名.git我在实际部署中发现有时候第一次连接会超时这是因为SSH主机密钥验证的原因。可以先用普通SSH连接一次接受密钥后续Git操作就会顺畅。