【问题标题】:docker-compose wait-for.sh fails for waiting mongodbdocker-compose wait-for.sh 等待 mongodb 失败
【发布时间】:2019-10-27 23:47:52
【问题描述】:

我正在尝试通过遵循此guide 来设置一个具有简单 nodejs 和 mongodb 服务的 docker 网络,但是,在构建 nodejs 时它失败了,因为它无法连接到mongodb

docker-compose.yml

version: "3"
services:
  nodejs:
    container_name: nodejs # How the container will appear when listing containers from the CLI
    image: node:10 # The <container-name>:<tag-version> of the container, in this case the tag version aligns with the version of node
    user: node # The user to run as in the container
    working_dir: "/app" # Where to container will assume it should run commands and where you will start out if you go inside the container
    networks:
      - app # Networking can get complex, but for all intents and purposes just know that containers on the same network can speak to each other
    ports:
      - "3000:3000" # <host-port>:<container-port> to listen to, so anything running on port 3000 of the container will map to port 3000 on our localhost
    volumes:
      - ./:/app # <host-directory>:<container-directory> this says map the current directory from your system to the /app directory in the docker container
    command: # The command docker will execute when starting the container, this command is not allowed to exit, if it does your container will stop
      - ./wait-for.sh
      - --timeout=15
      - mongodb:27017
      - --
      - bash
      - -c
      - npm install && npm start
    env_file: ".env"
    environment: 
      - MONGO_USERNAME=$MONGO_USERNAME
      - MONGO_PASSWORD=$MONGO_PASSWORD
      - MONGO_HOSTNAME=mongodb
      - MONGO_PORT=$MONGO_PORT
      - MONGO_DB=$MONGO_DB
    depends_on:
      - mongodb

  mongodb:
    image: mongo:4.1.8-xenial
    container_name: mongodb
    restart: unless-stopped
    env_file: .env
    environment:
      - MONGO_INITDB_ROOT_USERNAME=$MONGO_USERNAME
      - MONGO_INITDB_ROOT_PASSWORD=$MONGO_PASSWORD
    volumes:  
      - dbdata:/data/db 
    networks:
      - app

networks:
  app:
   driver: bridge

volumes:
  dbdata:

app.js

const express = require('express');
var server = express();
var bodyParser = require('body-parser');

// getting-started.js
var mongoose = require('mongoose');
mongoose.connect('mongodb://simpleUser:123456@mongodb:27017/simpleDb', {useNewUrlParser: true});

server.listen(3000, function() {
  console.log('Example app listening on port 3000');
});

这是我使用的常见wait-for.sh 脚本。 https://github.com/eficode/wait-for/blob/master/wait-for

docker logs -f nodejs 给;

Operation timed out

感谢您的帮助!

【问题讨论】:

  • nodejs 驱动程序会自己等待 mongodb。默认的 connectTimeoutMS 是 30 秒 - 是您在等待参数中设置的两倍。问题在别处。检查 mongo 日志,尝试从 nodejs 容器手动登录等
  • 是的,你是对的@AlexBlex。问题是因为我使用的图像没有安装nc 命令。

标签: node.js mongodb docker docker-compose


【解决方案1】:

在这种情况下,我认为问题在于您正在使用使用netcat 命令的wait-for.sh 脚本(请参阅https://github.com/eficode/wait-for/blob/master/wait-for#L24),但node:10 图像没有安装netcat。 .

我建议基于 node:10 图像创建自定义图像并添加 netcat 或使用不同的方法(最好是基于 nodejs 的解决方案)来检查 mongodb 是否可访问

用于创建您自己的自定义映像的示例 Dockerfile 如下所示

FROM node:10

RUN apt update && apt install -y netcat

然后您可以通过将image: node:10 替换为

来构建此映像
build: 
  dockerfile: Dockerfile
  context: .

你应该没事的

【讨论】:

  • 你说得对,卡利斯。我切换到另一张图片node:10-alpine。不知道node:10和alpine版本有什么区别。
  • Alpine 是一个非常精简的 linux 版本。它非常轻巧,如果没有特别的理由,我会自己使用它。不过要注意的一件事是 alpine 使用 musl 而不是 glibc(许多其他基于 linux 的操作系统都使用它),因此某些核心功能(如日期格式等)可能存在细微差异wiki.musl-libc.org/functional-differences-from-glibc.html 除此之外 - Alpine是为您的应用程序创建轻量级图像的好选择
  • 啊,我明白了。说得通。再次感谢卡利斯!
【解决方案2】:

我发现问题是因为图像node:10 没有安装nc 命令所以它失败了。我切换到图像node:10-alpine 并且它起作用了。

【讨论】:

    猜你喜欢
    • 2021-06-24
    • 2022-01-16
    • 2018-02-22
    • 1970-01-01
    • 2021-04-24
    • 2023-02-02
    • 1970-01-01
    • 1970-01-01
    • 2020-06-17
    相关资源
    最近更新 更多