如何在 docker 和 mongo 中将我的 Keystone.js 应用正确设置为 运行?

How do I properly set up my Keystone.js app to run in docker with mongo?

我已经构建了我的应用程序,运行在本地运行良好。当我尝试在 docker (docker-compose up) 中 运行 它时,它似乎开始了,但随后抛出一条错误消息:

Creating mongodb ... done
Creating webcms  ... done
Attaching to mongodb, webcms

...

Mongoose connection "error" event fired with:
    MongoError: failed to connect to server [localhost:27017] on first connect

...

webcms exited with code 1

我读到 Keystone.js 您需要在 .env 中配置 Mongo 位置文件,我有:

MONGO_URI=mongodb://localhost:27017

这是我的 Docker 文件:

# Use node 9.4.0
FROM node:9.4.0

# Copy source code
COPY . /app

# Change working directory
WORKDIR /app

# Install dependencies
RUN npm install

# Expose API port to the outside
EXPOSE 3000

# Launch application
CMD ["node","keystone"]

...和我的 docker-compose

version: "2"
services:
  # NodeJS app
  web:
    container_name: webcms
    build: .
    ports:
    - 3000:3000
    depends_on:
    - mongo

  # MongoDB
  mongo:
    container_name: mongo
    image: mongo
    volumes:
      - ./data:/data/db/mongo
    ports:
      - 27017:27017

当我 运行 docker ps 它确认 mongo 正在运行并且 运行ning 在一个容器...

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                      NAMES
f3e06e4a5cfe        mongo               "docker-entrypoint.s…"   2 hours ago         Up 2 hours          0.0.0.0:27017->27017/tcp   mongodb

我要么缺少某些配置,要么配置不正确。谁能告诉我那是什么?

如有任何帮助,我们将不胜感激。

谢谢!

它不能正常工作,因为你发送了错误的主机。 您的容器不理解什么是 localhost:27017,因为它是您的计算机地址而不是它的容器地址。

重要的是要了解每个服务都有自己的容器和不同的 IP。 docker-compose 的美妙之处在于你不需要知道你的容器地址!足以知道您的服务名称:

version: "2"

volumes:
  db-data:
    driver: local

services:
  web:
    build: .
    ports:
      - 3000:3000
    depends_on:
      - mongo
    environment:
      - MONGO_URI=mongodb://mongo:27017

  mongo:
    image: mongo
    volumes:
      - "db-data:/data/db/mongo"
    ports:
      - 27017:27017

只需运行docker-compose up就可以了

如果不想出现复杂情况,最好使用mongo db atlas。您可以在本地和部署中使用它。

获取 mongo url 的简单步骤在 https://www.mongodb.com/cloud/atlas

中可用

然后添加一个环境变量 CONNECT_TO=mongodb://your_url

要将 .env 传递给 docker,请使用

docker run --publish 8000:3000 --env-file .env --detach --name kb keystoneblog:1.0

一些可能有帮助的事情:

首先。我不确定您的错误日志是什么样的,但隐藏在我的错误日志中的是:

...Error: The cookieSecret config option is required when running Keystone in a production environment.Update your app or environment config so this value is supplied to the Keystone constructor....

要解决此问题,请在您的 Keystone 入口文件(例如:index.js)中确保您的 Keystone 构造函数正确设置了 cookieSecret 参数:process.env.NODE_ENV === 'production'

接下来。将 mongo uri 从一个 Keystone 生成的 (mongoUri: mongodb://localhost/my-keystone) 更改为:mongoUri: 'mongodb://mongo:27017'。 Docker 需要它,因为它是 mongo 容器地址。此更改也应反映在 MONGO_URI:

下环境变量下的 docker-compose 文件中

... environment: - MONGO_URI=mongodb://mongo:27017 ...

进行这些更改后,您的 Keystone 构造函数应如下所示:

const keystone = new Keystone({
  adapter: new Adapter(adapterConfig),
  cookieSecret: process.env.NODE_ENV === 'production',
  sessionStore: new MongoStore({ url: 'mongodb://mongo:27017' }),
});

还有你的 docker-compose 文件,像这样(我使用网络而不是链接作为我的 docker-compose 因为 Docker 已经声明 links 是一个遗留选项. 我已经包含了我的,以防它对其他人有用):

version: "3.3"
services:
  mongo:
      image: mongo
      networks:
       - appNetwork
      ports:
       - "27017:27017"
      environment:
       - MONGO_URI=mongodb://mongo:27017
  appservice:
      build:
        context: ./my-app
        dockerfile: Dockerfile
      networks:
        - appNetwork
      ports:
        - "3000:3000"
networks:
 appNetwork:
   external: false