使用docker-compose

时间:2018-10-28 12:19:43

标签: docker networking rabbitmq docker-compose

我想在一个容器中运行RabbitMQ,并在另一个容器中运行工作进程。工作进程需要访问RabbitMQ。

我希望通过docker-compose进行管理。

这是我到目前为止的docker-compose.yml文件:

version: "3"

services:

  rabbitmq:
    image: rabbitmq
    command: rabbitmq-server
    expose:
      - "5672"
      - "15672"

  worker:
    build: ./worker
    depends_on:
      - rabbitmq
    # Allow access to docker daemon
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

因此,我公开了RabbitMQ端口。工作进程使用以下URL访问RabbitMQ:

amqp://guest:guest@rabbitmq:5672/

它们在官方教程中使用的是哪个,但是localhost已被替换为rabbitmq,因为容器应为discoverable with a hostname identical to the container name:

  

默认情况下,Compose为您的应用设置单个网络。服务的每个容器都加入默认网络,并且都可以被该网络上的其他容器访问,并且可以在与容器名称相同的主机名下被发现。

每次运行此命令时,都会出现连接拒绝错误:

Recreating ci_rabbitmq_1 ... done                                                                                                                                                    
Recreating ci_worker_1   ... done                                                                                                                                                    
Attaching to ci_rabbitmq_1, ci_worker_1                                                                                                                                              
worker_1    | dial tcp 127.0.0.1:5672: connect: connection refused                                                                                                                   
ci_worker_1 exited with code 1        

我发现这很有趣,因为即使我将127.0.0.1指定为主机名,它也使用了IP localhost(我认为)为rabbitmq。我不是Docker网络方面的专家,所以也许这是理想的。

如果需要,我很乐意提供更多信息!


修改

存在一个几乎相同的问题here。我认为我需要等到rabbitmq启动后再运行worker。我尝试通过运行状况检查来做到这一点:

version: "2.1"

services:

  rabbitmq:
    image: rabbitmq
    command: rabbitmq-server
    expose:
      - "5672"
      - "15672"
    healthcheck:
      test: [ "CMD", "nc", "-z", "localhost", "5672" ]
      interval: 10s
      timeout: 10s
      retries: 5

  worker:
    build: .
    depends_on:
      rabbitmq:
        condition: service_healthy

(请注意其他版本)。但是,这不起作用-总是会因为不健康而失败。

4 个答案:

答案 0 :(得分:2)

如果您只是从另一个容器访问服务,也许不需要公开/映射主机上的端口。

从文档中:

  

公开公开端口,而无需将其发布到主机上-只有链接的服务才能访问它们。仅内部端口   可以指定。

expose:
 - "3000"
 - "8000"

所以应该像这样:

version: "3"

services:

  rabbitmq:
    image: rabbitmq
    command: rabbitmq-server
    expose:
      - "5672"
      - "15672"

  worker:
    build: ./worker
    depends_on:
      - rabbitmq
    # Allow access to docker daemon
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

还要确保仅在准备好在端口上进行服务器连接时才连接到rabitmq。

答案 1 :(得分:2)

啊哈!我修好了它。 @Ijaz完全正确-RabbitMQ服务需要一段时间才能启动,而我的工作人员会在运行之前尝试进行连接。

我尝试使用延迟,但是当RabbitMQ比平时花费更长的时间时,此操作失败。

这也表明存在较大的体系结构问题-如果排队服务(在我的情况下为RabbitMQ)在生产期间脱机怎么办?现在,我的整个网站都失败了。需要一些内置的冗余和轮询。

正如对此this related answer所述,我们可以在docker-compose 3+中使用运行状况检查:

version: "3"

services:

  rabbitmq:
    image: rabbitmq
    command: rabbitmq-server
    expose:
      - 5672
      - 15672
    healthcheck:
      test: [ "CMD", "nc", "-z", "localhost", "5672" ]
      interval: 5s
      timeout: 15s
      retries: 1

  worker:
    image: worker
    restart: on-failure
    depends_on:
      - rabbitmq

现在,worker容器将重新启动几次,而rabbitmq容器仍然不正常。 rabbitmq成功执行后-即当排队生效时,nc -z localhost 5672立即变得健康!

答案 2 :(得分:1)

这是正确的工作示例:

    version: "3.8"

    services:

    rabbitmq:
        image: rabbitmq:3.7.28-management
        #container_name: rabbitmq
        volumes:
            - ./etc/rabbitmq/conf:/etc/rabbitmq/
            - ./etc/rabbitmq/data/:/var/lib/rabbitmq/
            - ./etc/rabbitmq/logs/:/var/log/rabbitmq/
        environment:
            RABBITMQ_ERLANG_COOKIE: ${RABBITMQ_ERLANG_COOKIE:-secret_cookie}
            RABBITMQ_DEFAULT_USER: ${RABBITMQ_DEFAULT_USER:-admin}
            RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS:-admin}
        ports:
            - 5672:5672    #amqp
            - 15672:15672  #http
            - 15692:15692  #prometheus
        healthcheck:
        test: [ "CMD", "rabbitmqctl", "status"]
        interval: 5s
        timeout: 20s
        retries: 5

    mysql:
        image: mysql
        restart: always
        volumes:
        - ./etc/mysql/data:/var/lib/mysql
        - ./etc/mysql/scripts:/docker-entrypoint-initdb.d
        environment:
        MYSQL_ROOT_PASSWORD: root
        MYSQL_DATABASE: mysqldb
        MYSQL_USER: ${MYSQL_DEFAULT_USER:-testuser}
        MYSQL_PASSWORD: ${MYSQL_DEFAULT_PASSWORD:-testuser}
        ports:
        - "3306:3306"
        healthcheck:
        test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
        timeout: 20s
        retries: 10

    trigger-batch-process-job:
        build: .
        environment:
        - RMQ_USER=${RABBITMQ_DEFAULT_USER:-admin}
        - RMQ_PASS=${RABBITMQ_DEFAULT_PASS:-admin}
        - RMQ_HOST=${RABBITMQ_DEFAULT_HOST:-rabbitmq}
        - RMQ_PORT=${RABBITMQ_DEFAULT_PORT:-5672}
        - DB_USER=${MYSQL_DEFAULT_USER:-testuser}
        - DB_PASS=${MYSQL_DEFAULT_PASSWORD:-testuser}
        - DB_SERVER=mysql
        - DB_NAME=mysqldb
        - DB_PORT=3306
        depends_on:
        mysql:
            condition: service_healthy
        rabbitmq:
            condition: service_healthy

答案 3 :(得分:0)

docker compose v3.8 最干净的方式

version: "3.8"

  worker:
    build: ./worker
    rabbitmq:
        condition: service_healthy

  rabbitmq:
    image: library/rabbitmq
    ports:
    - 5671:5671
    - 5672:5672
    healthcheck:
      test: [ "CMD", "nc", "-z", "localhost", "5672" ]
      interval: 5s
      timeout: 10s
      retries: 3