如何在启动RabbitMQ Docker容器时添加初始用户?

Mar*_*rco 45 rabbitmq docker

目前我正在使用DockerHub中的默认RabbitMQ映像启动RabbitMQ Docker容器.使用以下命令.

docker run --restart=always \
-d \
-e RABBITMQ_NODENAME=rabbitmq \
-v /opt/docker/rabbitmq/data:/var/lib/rabbitmq/mnesia/rabbitmq \
-p 5672:5672 \
-p 15672:15672 \
--name rabbitmq rabbitmq:3-management
Run Code Online (Sandbox Code Playgroud)

我需要在首次启动映像时提供默认用户/和虚拟主机.例如,创建默认的"测试用户".

目前,我必须通过使用管理插件并通过web ui添加用户/虚拟主机来手动执行此操作.有没有办法在启动RabbitMQ图像时提供默认设置?

sud*_*udo 54

提出了一个适合我需求的解决方案,留在这里以防万一其他人需要它.

摘要

我们的想法是采用一个标准的rabbitmq容器,启用管理插件,然后使用它创建所需的配置,然后导出并使用它来启动新的容器.下面的解决方案创建了一个派生的docker镜像,但它也可以在运行时挂载这两个文件(例如使用docker compose).

参考

组件

  • 官方rabbitmq图片,管理插件版本(rabbitmq:management)
  • 自定义映像基于原始映像,使用此Dockerfile(使用版本3.6.6):

    FROM rabbitmq:3.6.6-management
    ADD rabbitmq.config /etc/rabbitmq/
    ADD definitions.json /etc/rabbitmq/
    RUN chown rabbitmq:rabbitmq /etc/rabbitmq/rabbitmq.config /etc/rabbitmq/definitions.json
    CMD ["rabbitmq-server"]
    
    Run Code Online (Sandbox Code Playgroud)
  • rabbitmq.config只是告诉rabbitmq从json文件加载定义
  • definitions.json包含用户,vhosts等,可以通过管理Web界面的导出功能生成

rabbitmq.config示例:

[
  {rabbit, [
    {loopback_users, []}
  ]},
  {rabbitmq_management, [
    {load_definitions, "/etc/rabbitmq/definitions.json"}
  ]}
].
Run Code Online (Sandbox Code Playgroud)

definitions.json示例:

{
 "rabbit_version": "3.6.6",
 "users": [
  {
   "name": "user1",
   "password_hash": "pass1",
   "hashing_algorithm": "rabbit_password_hashing_sha256",
   "tags": ""
  },
  {
   "name": "adminuser",
   "password_hash": "adminpass",
   "hashing_algorithm": "rabbit_password_hashing_sha256",
   "tags": "administrator"
  }
 ],
 "vhosts": [
  {
   "name": "\/vhost1"
  },
  {
   "name": "\/vhost2"
  }
 ],
 "permissions": [
  {
   "user": "user1",
   "vhost": "\/vhost1",
   "configure": ".*",
   "write": ".*",
   "read": ".*"
  }
 ],
 "parameters": [],
 "policies": [],
 "queues": [],
 "exchanges": [],
 "bindings": []
}
Run Code Online (Sandbox Code Playgroud)

Alternave版本

派生新的docker镜像只是一种解决方案,在可移植性至关重要时效果最佳,因为它避免了在图片中包含基于主机的文件管理.

在某些情况下,使用官方映像并从主机本地存储器提供配置文件可能是首选.

rabbitmq.config和definitions.json文件以相同的方式生成,然后在运行时挂载.

笔记:

  • 我假设他们已经被放置在/ etc/so /中,为了这些例子
  • 文件需要全局可读或由rabbitmq用户或组拥有(docker容器内的数字id为999),这需要由主机的sysadmin处理

docker run示例:

    docker run --rm -it \
        -v /etc/so/rabbitmq.config:/etc/rabbitmq/rabbitmq.config:ro \
        -v /etc/so/definitions.json:/etc/rabbitmq/definitions.json:ro \
        rabbitmq:3.6-management
Run Code Online (Sandbox Code Playgroud)

docker撰写示例:

    version: '2.1'
    services:
        rabbitmq:
            image: "rabbitmq:3.6-management"
            ports:
                - 5672:5672
                - 15672:15672
            volumes:
                - /etc/so/rabbitmq.config:/etc/rabbitmq/rabbitmq.config:ro
                - /etc/so/definitions.json:/etc/rabbitmq/definitions.json:ro
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的解决方案。@Tom.P 通过从 Rabbit 导出的定义对此进行了一些补充。将两者结合起来,这应该是公认的答案。这对我有用! (2认同)
  • @KentJohnson “definitions.json [...] 可以由管理 Web 界面的导出功能生成”这一事实已经是我的观点之一,我也是这样做的(提供的示例只是为了获得一个想法马上) (2认同)
  • 添加了chown命令以确保权限正常(感谢@Tom P.)并添加了一个使用运行时安装的官方映像+配置文件的备用解决方案 (2认同)
  • 我发现这个密码哈希脚本对我也非常有用 https://gist.github.com/lukebakken/7b4da46ed9abb7ed14f7a60b49f9e52e (2认同)
  • 很好的解决方案。主要问题是找到definitions.json 的文档。但是您可以手动完成所有配置,然后导出定义 https://medium.com/@thomasdecaux/deploy-rabbitmq-with-docker-static-configuration-23ad39cdbf39 (2认同)

geo*_*ord 45

您可以创建一个简单的Dockerfile来扩展基本映像的功能并创建一个默认用户.您需要的Docker文件如下:

FROM rabbitmq

# Define environment variables.
ENV RABBITMQ_USER user
ENV RABBITMQ_PASSWORD user

ADD init.sh /init.sh
EXPOSE 15672

# Define default command
CMD ["/init.sh"]
Run Code Online (Sandbox Code Playgroud)

和init.sh:

#!/bin/sh

# Create Rabbitmq user
( sleep 5 ; \
rabbitmqctl add_user $RABBITMQ_USER $RABBITMQ_PASSWORD 2>/dev/null ; \
rabbitmqctl set_user_tags $RABBITMQ_USER administrator ; \
rabbitmqctl set_permissions -p / $RABBITMQ_USER  ".*" ".*" ".*" ; \
echo "*** User '$RABBITMQ_USER' with password '$RABBITMQ_PASSWORD' completed. ***" ; \
echo "*** Log in the WebUI at port 15672 (example: http:/localhost:15672) ***") &

# $@ is used to pass arguments to the rabbitmq-server command.
# For example if you use it like this: docker run -d rabbitmq arg1 arg2,
# it will be as you run in the container rabbitmq-server arg1 arg2
rabbitmq-server $@
Run Code Online (Sandbox Code Playgroud)

此脚本还在端口15672初始化并公开RabbitMQ webadmin.

  • 关于 `sleep 5`,如果你想要一种更可靠的方法来等待 rabbitmq 被初始化,我建议使用它:`rabbitmqctl wait /var/lib/rabbitmq/mnesia/rabbitmq.pid`。我正在使用运行大量容器的 docker-compose,它对我有用。 (6认同)
  • 这实际上有用吗?在3.6.6上,如果没有运行节点/应用程序,我就无法添加任何用户.看起来你在运行```rabbitmq-server```之前添加它们. (4认同)
  • ```cd /tmp ; \ wget http://localhost:15672/cli/rabbitmqadmin ; \ mv ./rabbitmqadmin /rabbitmqadmin ; \ chmod +x /rabbitmqadmin ; \``` 我认为可以删除这些行,因为 admin 命令已经在容器内可用。 (2认同)
  • 我收到此错误:/usr/local/bin/docker-entrypoint.sh:line 296:/init.sh:权限被拒绝.我错过了什么? (2认同)

Ang*_*erd 12

Dockerhub上的RabbitMQ映像的最新版本具有内置功能,可将默认用户名/密码从“ guest” /“ guest”更改为其他名称。

在启动映像时,只需设置环境变量“ RABBITMQ_DEFAULT_USER”和“ RABBITMQ_DEFAULT_PASS”。

作为docker命令,您将运行以下图像:

docker run \
-e RABBITMQ_DEFAULT_USER=test-user \
-e RABBITMQ_DEFAULT_PASS=test-user \
-p 5672:5672 \
rabbitmq
Run Code Online (Sandbox Code Playgroud)

  • 这在 v3.9 中已被弃用。>> https://hub.docker.com/_/rabbitmq >> `警告:从 RabbitMQ 3.9 开始,下面列出的所有特定于 docker 的变量都已弃用,不再使用。请改用配置文件;访问 rabbitmq.com/configure 以了解有关配置文件的更多信息。作为起点,3.8 图像将打印出它从提供的环境变量生成的配置文件。` (3认同)

Tom*_* P. 10

我想补充一点,sudo的回应对我帮助很大.但它仍然错过了一个添加到Dockerfile的命令.

rabbitmq.config和definitions.json文件应归rabbitmq用户和组所有.所以在添加文件后运行chown.

在我的情况下完整的Dockerfile如下:

FROM rabbitmq:3-management-alpine
ADD definitions.json /etc/rabbitmq/
ADD rabbitmq.config /etc/rabbitmq/
RUN chown rabbitmq:rabbitmq /etc/rabbitmq/rabbitmq.config /etc/rabbitmq/definitions.json

EXPOSE 4369 5671 5672 15671 15672 25672

CMD ["rabbitmq-server"]
Run Code Online (Sandbox Code Playgroud)

rabbitmq.config文件具有以下内容,即从默认图像的配置和添加的定义加载合并:

[
    { rabbit, [
        {loopback_users, []},
        { tcp_listeners, [ 5672 ]},
        { ssl_listeners, [ ]},
        { hipe_compile, false } 
    ]},
    { rabbitmq_management, [
        { load_definitions, "/etc/rabbitmq/definitions.json"},
        { listeners, [
            { port, 15672 },
            { ssl, false } 

        ]}
    ]}
].
Run Code Online (Sandbox Code Playgroud)

可以从概览选项卡中的管理界面导出定义文件.

所以你首先要创建一个普通的'空'rabbitmq容器.定义您喜欢的任何用户,交换和队列.然后进入管理界面,导出定义并使用上述文件创建自己的图像.

下载定义是在您自己的密码的定义文件中获取正确密码哈希的最简单方法.如果您不希望这样做,请按照此处(https://www.rabbitmq.com/passwords.html)中的说明生成正确的哈希值.

  • @TomP.非常推荐Rabbit出口.这真的节省了我的时间!它完全准确.这应该与sudo的答案结合作为公认的答案. (3认同)

Dáv*_*nár 9

上述解决方案有一个警告:它们将“禁用”官方 Rabbit docker 镜像中存在的docker-entrypoint.sh脚本。这对您来说可能是问题,也可能不是问题。该脚本创建初始 RabbitMQ 配置文件;添加了一些好的默认值(例如,如果容器在内存限制下运行,则总内存限制)。

如果您想保持完全兼容性并且不想“禁用”此脚本,您可以使用以下方法。它将添加一个admin带有密码的附加用户admin,并保持guest用户不变。这对于开发很有用。

这种方法是使用definitions.json管理插件使用文件来初始化用户。为了通知插件有关该definitions.json文件的信息,我们使用RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS环境变量(而不是rabbitmq.conf文件)。

创建definitions.json文件:

{
  "users": [
    {
      "name": "guest",
      "password_hash": "R184F4Fs6JLdo8tFqRjWnkJL2DlAZJupxEqkO/8kfV/G63+z",
      "hashing_algorithm": "rabbit_password_hashing_sha256",
      "tags": "administrator"
    },
    {
      "name": "admin",
      "password_hash": "FGA5ZeTOLHnIp4ZjxIj0PsShW/DpLgdYAlHsbli7KMMa8Z0O",
      "hashing_algorithm": "rabbit_password_hashing_sha256",
      "tags": "administrator"
    }
  ],
  "vhosts": [
    {
      "name": "/"
    }
  ],
  "permissions": [
    {
      "user": "guest",
      "vhost": "/",
      "configure": ".*",
      "write": ".*",
      "read": ".*"
    },
    {
      "user": "admin",
      "vhost": "/",
      "configure": ".*",
      "write": ".*",
      "read": ".*"
    }
  ],
  "parameters": [],
  "policies": [],
  "queues": [],
  "exchanges": [],
  "bindings": []
}

Run Code Online (Sandbox Code Playgroud)

创建自定义Dockerfile

FROM rabbitmq:3.8.3-management

ADD --chown=rabbitmq ./definitions.json /etc/rabbitmq/

ENV RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS="-rabbitmq_management load_definitions \"/etc/rabbitmq/definitions.json\""

Run Code Online (Sandbox Code Playgroud)

使用以下命令构建镜像: docker build --tag myrabbit:1.0.0 .

然后运行它: docker run -d -p 5672:5672 -p 15672:15672 --restart unless-stopped --name rabbitmq myrabbit:1.0.0


Mar*_*tin 6

在我的例子中,sleep 5上述解决方案不起作用,因为 RabbitMQ 启动时间更长且不可预测。发布等待 RabbitMQ 启动并运行的解决方案:

  • Dockerfile

    FROM rabbitmq:3-management
    ADD init.sh /
    ADD config_rabbit.sh /
    RUN chmod +x /init.sh /config_rabbit.sh
    ENTRYPOINT ["/init.sh"]
    
    Run Code Online (Sandbox Code Playgroud)
  • 初始化程序

    #!/bin/bash
    
    # Launch config script in background
    # Note there is no RabbitMQ Docker image support for executing commands after server (PID 1) is running (something like "ADD schema.sql /docker-entrypoint-initdb.d" in MySql image), so we are using this trick
    /config_rabbit.sh &
    
    # Launch
    /docker-entrypoint.sh rabbitmq-server
    
    Run Code Online (Sandbox Code Playgroud)
  • 配置兔子.sh

    #!/bin/bash
    
    # This script needs to be executed just once
    if [ -f /$0.completed ] ; then
      echo "$0 `date` /$0.completed found, skipping run"
      exit 0
    fi
    
    # Wait for RabbitMQ startup
    for (( ; ; )) ; do
      sleep 5
      rabbitmqctl -q node_health_check > /dev/null 2>&1
      if [ $? -eq 0 ] ; then
        echo "$0 `date` rabbitmq is now running"
        break
      else
        echo "$0 `date` waiting for rabbitmq startup"
      fi
    done
    
    # Execute RabbitMQ config commands here
    
    # Create user
    rabbitmqctl add_user USER PASSWORD
    rabbitmqctl set_permissions -p / USER ".*" ".*" ".*"
    echo "$0 `date` user USER created"
    
    # Create queue
    rabbitmqadmin declare queue name=QUEUE durable=true
    echo "$0 `date` queues created"
    
    # Create mark so script is not ran again
    touch /$0.completed
    
    Run Code Online (Sandbox Code Playgroud)


090*_*9EM 6

使用 RabbitMQ 3.7 和较新的rabbitmq.conf ( sysctl ) 配置格式,以下在 Docker 中使用默认用户和队列设置 RabbitMQ,您可以选择在 dockerfile 中添加以下 RUN 命令来创建用户...

RUN rabbitmqctl add_user {username} {password}
RUN rabbitmqctl set_user_tags {username} administrator
RUN rabbitmqctl set_permissions ...
Run Code Online (Sandbox Code Playgroud)

rabbitmq.conf

# Default user
default_user = testuser
default_pass = testpassword

## The default "guest" user is only permitted to access the server
## via a loopback interface (e.g. localhost).
loopback_users.guest = true

# IPv4
listeners.tcp.default = 5672

## HTTP listener and embedded Web server settings.
management.tcp.port = 15672

# Load queue definitions
management.load_definitions = /etc/rabbitmq/definitions.json

#Ignore SSL
ssl_options.verify               = verify_peer
ssl_options.fail_if_no_peer_cert = true
Run Code Online (Sandbox Code Playgroud)

定义.json

{
  "rabbit_version": "3.7.11",
  "users": [
    {
      "name": "testuser",
      "password_hash": "txn+nsYVkAaIMvDsH8Fsyb3RWMCMWihRUVCk/wICL1NBKKvz",
      "hashing_algorithm": "rabbit_password_hashing_sha256",
      "tags": "administrator"
    }
  ],
  "vhosts": [ { "name": "test-vhost" } ],
  "permissions": [
    {
      "user": "testuser",
      "vhost": "test-vhost",
      "configure": ".*",
      "write": ".*",
      "read": ".*"
    }
  ],
  "topic_permissions": [],
  "parameters": [],
  "global_parameters": [
    {
      "name": "cluster_name",
      "value": "rabbit@test-rabbit"
    }
  ],
  "policies": [],
  "queues": [
    {
      "name": "testqueue",
      "vhost": "test-vhost",
      "durable": true,
      "auto_delete": false,
      "arguments": {}
    }
  ],
  "exchanges": [],
  "bindings": []
}
Run Code Online (Sandbox Code Playgroud)

Dockerfile

FROM rabbitmq:3.7-management

COPY rabbitmq.conf /etc/rabbitmq
COPY definitions.json /etc/rabbitmq

RUN ls /etc/rabbitmq
RUN cat /etc/rabbitmq/rabbitmq.conf
Run Code Online (Sandbox Code Playgroud)

用于构建和运行容器的 Docker 命令...

docker build -t rabbitmq-with-queue .
docker run --rm -it --hostname my-rabbit -p 5672:5672 -p 15672:15672 rabbitmq-with-queue
Run Code Online (Sandbox Code Playgroud)