docker运行可登录的gerrit容器

普通运行gerrit容器

常规运行gerrit容器发现根本没办法登录

bash 复制代码
  docker run -d --name gerrit \
     -p 8082:8080   \
     -p 29418:29418   \
     -v /home/bing/docker/gerrit/data:/var/gerrit/review_site   \
     -v /home/bing/docker/gerrit/etc:/var/gerrit/etc   \
     -v /home/bing/docker/gerrit/git:/var/gerrit/git   \
     -v /home/bing/docker/gerrit/index:/var/gerrit/index \
     -v /home/bing/docker/gerrit/cache:/var/gerrit/cache   \
     -v /home/bing/docker/gerrit/logs:/var/gerrit/logs   \
     -e GERRIT_INIT_ARGS="--install-plugin=download-commands"\
     gerritcodereview/gerrit:latest

登录页面报这个错误:

html 复制代码
Configuration Error
Check the HTTP server's authentication settings.
The HTTP server did not provide the username in the Authorization header when it forwarded the request to Gerrit Code Review.

If the HTTP server is Apache HTTPd, check the proxy configuration includes an authorization directive with the proper location, ensuring it ends with '/':

<VirtualHost 10.211.55.6:8082>
    ServerName 10.211.55.6

    ProxyRequests Off
    ProxyVia Off
    ProxyPreserveHost On

    <Proxy *>
          Order deny,allow
          Allow from all
    </Proxy>

    <Location /login/>
      AuthType Basic
      AuthName "Gerrit Code Review"
      Require valid-user
      ...
    </Location>


    AllowEncodedSlashes On
    ProxyPass / http://.../ nodecode
</VirtualHost>
    

这个错误非常明确,它揭示了问题的核心:

你的 Gerrit 配置了"HTTP 认证模式",但你直接访问了 Gerrit 容器,中间缺少了负责认证的"看门人"(Nginx 或 Apache)。

简单来说:Gerrit 以为前面有个代理服务器(Nginx)已经帮你验证过身份了,并会把你的用户名放在 HTTP Header 里传过来。但实际上,你直接连上了 Gerrit,所以 Gerrit 拿不到用户名,就报错了。

你有两个解决路径,方案一最简单(推荐),方案二是标准生产做法。

方案一:改用"开发模式"登录(最快解决问题,推荐测试环境使用)

这种方式不需要 Nginx,也不需要复杂的认证配置。修改配置后,登录页面会变成一个文本框,你想登录谁,输入用户名就直接以该身份登录。

操作步骤:

1 进入容器修改配置文件:

bash 复制代码
# 假设你的容器名字叫 gerrit,如果是其他名字请自行替换
docker exec -it gerrit vi /var/gerrit/etc/gerrit.config

注:如果容器里没有 vi 命令,可以使用 cat 查看后,在宿主机修改挂载的配置文件(如果你有挂载卷的话)

2 找到 [auth] 部分,修改为以下内容:

bash 复制代码
[auth]
    type = DEVELOPMENT_BECOME_ANY_ACCOUNT
    # 如果底下有 logoutUrl 这一行,建议注释掉或者删掉
    # logoutUrl =

3 保存并退出(在 vi 编辑器中按 Esc,输入 :wq 回车)。

4 重启 Gerrit 容器使配置生效:

bash 复制代码
docker restart gerrit

5 验证:再次访问 http://10.211.55.6:8082/,点击 Sign In 或 Login。

  • 预期结果:页面不再是报错,而是出现一个输入框 "Become any account"。你在里面输入 admin(或任意用户名),点击登录即可成功进入。

方案二:配置 Nginx 反向代理(标准生产做法)

如果你必须使用用户名/密码登录(例如为了安全起见),并且保留 HTTP 认证模式,那你必须在 Gerrit 前面再加一个 Nginx 容器。

1 原理:

浏览器 -> (输入密码) -> Nginx (验证通过) -> (把用户名写在 Header 里) -> Gerrit (读取 Header,放行)

2 简化版 Docker Compose 示例:

你需要创建一个 docker-compose.yml,包含 Gerrit 和 Nginx 两个服务:

bash 复制代码
version: '3'

services:
  gerrit:
    image: gerritci/gerrit:latest
    ports:
      - "8081:8080"  # 内部通讯端口,不对外开放
    volumes:
      - gerrit-volume:/var/gerrit
    environment:
      - CANONICAL_WEB_URL=http://10.211.55.6:8082/

  nginx:
    image: nginx:alpine
    ports:
      - "8082:80"  # 对外访问端口
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      # 下面这个 .htpasswd 文件需要用 htpasswd 工具生成,包含用户名和加密密码
      - ./htpasswd:/etc/nginx/.htpasswd:ro 
    depends_on:
      - gerrit

volumes:
  gerrit-volume:

3 Nginx 配置文件 (nginx.conf) 必须包含以下设置:

bash 复制代码
events {
    worker_connections 1024;
}

http {
    server {
        listen 80;
        server_name 10.211.55.6;

        # 开启基础认证
        auth_basic "Gerrit Code Review";
        auth_basic_user_file /etc/nginx/.htpasswd;

        location / {
            # 反向代理到 Gerrit 容器
            proxy_pass http://gerrit:8080;
            
            # 关键设置:把 Nginx 认证后的用户名传给 Gerrit
            # 默认 Gerrit 的 HTTP 认证模式也是看这个 header
            proxy_set_header Authorization ""; 
            proxy_set_header X-Remote-User $remote_user; 

            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $remote_addr;
        }
    }
}

4 生成用户账户密码文件,htpasswd生成.htpasswd文件

这个工具的正确名称是 htpasswd(注意中间没有 w,且通常指 Apache HTTP Server 工具包中的工具)。它是用于管理存储用户名和密码(Basic Auth 认证)文件的标准工具。

由于你是在 Docker 环境下部署 Gerrit 和 Nginx,我提供两种方法来生成这个文件:

方法一:在你的宿主机上直接生成(标准方法)

如果你使用的是 Linux (Ubuntu/CentOS) 或 macOS,通常可以直接安装并使用。

1. 安装工具
  • Ubuntu / Debian:
bash 复制代码
sudo apt-get update
sudo apt-get install apache2-utils
  • CentOS / RHEL:
bash 复制代码
sudo yum install httpd-tools
2. 生成 .htpasswd 文件
  • 场景 A:创建新文件并添加第一个用户(例如 admin)
bash 复制代码
# -c 表示创建文件
# admin 是用户名
# 执行后会提示你输入两次密码
htpasswd -c .htpasswd admin
  • 场景 B:在已有文件中添加第二个用户(非常重要:不要加 -c!)
    注意:如果你在添加第二个用户时使用了 -c 参数,会覆盖并删除之前生成的所有用户!
bash 复制代码
# 没有 -c,表示追加
htpasswd .htpasswd user2
  • 场景 C:不生成本地文件,直接输出加密后的字符串
    如果你想把结果直接复制到 Docker Compose 的配置或 Kubernetes Secret 中:
bash 复制代码
# -n 表示不更新文件,直接输出到屏幕
htpasswd -nb admin mypassword123
# 输出结果类似:admin:$apr1$l3sxc1$W8wY8nG...
方法二:使用 Docker 容器生成(无需安装额外工具,最推荐)

如果你不想在宿主机安装 apache2-utils,可以直接起一个临时的 Nginx 或 Apache 容器来帮你生成,用完即删。

命令如下:

bash 复制代码
docker run --rm -v $(pwd):/app httpd:alpine htpasswd -bc /app/.htpasswd admin your_password

解释:

  • --rm: 容器运行完命令后自动删除。
  • -v $(pwd):/app: 把当前目录挂载到容器内的 /app 目录。
  • httpd:alpine: 使用 Apache 的官方轻量镜像(很小,下载快)。
  • htpasswd -bc /app/.htpasswd admin your_password: 在容器内执行生成命令,文件会保存在你当前目录下的 .htpasswd 文件中。
    执行完后,你的当前目录下就会有一个 .htpasswd 文件。
3. 如何在 Nginx 中使用这个文件

生成好文件后,假设你把它放在了 Nginx 配置目录下(比如 /etc/nginx/.htpasswd),你需要修改 nginx.conf 指向它:

bash 复制代码
server {
    listen 80;
    server_name 10.211.55.6;
    # 开启认证
    auth_basic "Gerrit Code Review";
    # 指定刚才生成的文件路径
    auth_basic_user_file /etc/nginx/.htpasswd; 
    location / {
        proxy_pass http://gerrit:8080;
        # ... 其他配置
    }
}

常用参数速查表

  • -c : Create a new file. (创建新文件,慎用,会覆盖旧文件)
  • -b : Batch mode. (命令行直接输入密码,不用交互式输入)
  • -n : Don't update file; display results on stdout. (只打印结果,不存文件)
  • -m : Force MD5 encryption of the password. (默认通常就是这个)
  • -B : Force bcrypt encryption of the password. (更安全,但可能需要 Nginx 特定版本支持)
  • -D : Delete user. (删除用户)
    示例:一行命令创建文件并设置密码(不交互):
bash 复制代码
htpasswd -bc .htpasswd admin 123456

然后启动:

bash 复制代码
docker-compose up -d

总结

  • 如果你只是想快速搭建起来玩玩、测试功能:请使用 方案一。把 type 改为 DEVELOPMENT_BECOME_ANY_ACCOUNT,这是最快跳过当前报错的方法。
  • 如果你是在为公司搭建正式的服务器:请使用 方案二。引入 Nginx 做认证代理,这样安全性更高,且符合 Gerrit 的标准部署架构。
相关推荐
cly19 小时前
SaltStack自动化(一): 原理与安装
运维·自动化·saltstack
RisunJan9 小时前
Linux命令-ipcrm命令(删除Linux系统中的进程间通信(IPC)资源)
linux·运维·服务器
f***24119 小时前
高效管理临时文件:自动化方案全解析
运维·自动化
超人小子9 小时前
自动化报表系统实战:用Python让报表工作智能化
运维·python·自动化
Joren的学习记录9 小时前
【Linux运维大神系列】Kubernetes详解2(kubeadm部署k8s1.27单节点集群)
linux·运维·kubernetes
赵文宇(温玉)9 小时前
Docker与VM的差异与最佳场景
docker·容器·eureka
lbb 小魔仙9 小时前
【Linux】K8s 集群搭建避坑指南:基于 Linux 内核参数调优的生产级部署方案
linux·运维·kubernetes
且去填词9 小时前
构建基于 DeepEval 的 LLM 自动化评估流水线
运维·人工智能·python·自动化·llm·deepseek·deepeval
techzhi9 小时前
docker compose和docker-compose的区别
运维·docker·容器