如何为GraphQL泊坞窗容器提供服务?

时间:2019-08-28 11:13:37

标签: node.js docker express graphql

我想运行两个不同的Docker容器:

  • ReactJS前端(使用create-react-app创建)
  • NodeJS后端(GraphQL端点)

第一个很简单。我已经运行npm build并使用nginx为该应用程序提供服务。一切正常,我没有问题。

第二个问题。即使我在防火墙配置中允许端口3001,也只能通过localhost:3001而不是my_ip_addr:3001访问它。这也只能工作一个小时左右-前端不再可以使用该API,我不确定为什么。

我的服务器文件如下:

import express from 'express';
import { graphqlExpress, graphiqlExpress } from 'apollo-server-express';
import bodyParser from 'body-parser';
import * as Schema from './schema';

const cors = require('cors');

const PORT = 3001;
const server = express();

const schemaFunction =
  Schema.schemaFunction ||
  function() {
    return Schema.schema;
  };
let schema;
const rootFunction =
  Schema.rootFunction ||
  function() {
    return schema.rootValue;
  };
const contextFunction =
  Schema.context ||
  function(headers, secrets) {
    return Object.assign(
      {
        headers: headers,
      },
      secrets
    );
  };

server.use(cors());
server.use('/graphql', bodyParser.json({limit: '50mb'}), graphqlExpress(async (request) => {
  if (!schema) {
    schema = schemaFunction(process.env)
  }
  const context = await contextFunction(request.headers, process.env);
  const rootValue = await rootFunction(request.headers, process.env);

  return {
    schema: await schema,
    rootValue,
    context,
    tracing: true,
  };
}));

server.use('/graphiql', graphiqlExpress({
  endpointURL: '/graphql',
  query: `# Run some stuff
`,
}));

server.listen(PORT, () => {
  console.log(`GraphQL Server is now running on http://localhost:${PORT}/graphql`);
  console.log(`View GraphiQL at http://localhost:${PORT}/graphiql`);
});

我如何在一个可以被另一个Docker容器访问的Docker容器中运行它?我不在乎可以从我的Linux服务器外部访问它(实际上,这可能是一个好处),但是我确实需要前端容器才能访问API端点。

编辑:

Dockerfile(前端)

# build environment
FROM node:9.6.1 as builder
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
ENV PATH /usr/src/app/node_modules/.bin:$PATH
COPY package.json /usr/src/app/package.json
RUN npm install --silent
RUN npm install react-scripts@1.1.1 -g --silent
COPY . /usr/src/app
RUN npm run build

# production environment
FROM nginx:1.13.9-alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=builder /usr/src/app/client/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Dockerfile(gql服务器)

FROM node
RUN mkdir /server
WORKDIR /server
COPY package.json /server
RUN npm install
COPY . /server
CMD ["npm", "run", "server"]

最后一条命令运行:nodemon server/src/server.js --exec babel-node -e js

docker命令为:docker run -dit --restart unless-stopped -p 3001:3001 {image_id}

3 个答案:

答案 0 :(得分:0)

使用docker compose使它们在同一网络中运行,docker-compose将自己创建一个网络,您的服务将在其中运行。 这可能会解决问题


version: "3.3"

services:
  my_back:
    image: redis:alpine
    container_name: redis-db
    ports:
      - 6379:6379

  my_front:
    image: my-image
    container_name: front-end
    environment:
      REDIS_HOSTNAME: "redis-db"

容器名称=主机名

答案 1 :(得分:0)

我认为您的问题可能在于Docker网络。您的前端容器可能无法访问后端,因为两个容器不在同一个网络中。您可以完美地创建2个容器和一个网络来连接它们。

但是,我建议您研究docker-compose。简而言之,使用撰写文件,您可以定义具有连接到主机的卷,网络,端口的多个服务。您可以在docker-compose文件中定义一个网络,并使用服务名称访问网络中的其他容器,该服务名称将在您的前端应用程序中放置ip或主机名。

version: '3.2'

services:
  frontend:
    build:
      context: frontend
      dockerfile: Dockerfile
    depends_on:
      - backend
    restart: always
  backend:
    build:
      context: backend
      dockerfile: Dockerfile
    restart: always

答案 2 :(得分:0)

问题可能出在您的 GraphQL Dockerfile 中。你在这里还需要一个 EXPOSE,例如:

EXPOSE 3001

根据documentation

<块引用>

EXPOSE 指令通知 Docker 容器正在监听 运行时指定的网络端口。

编辑:抱歉。根据文档,-p 标志会在运行时覆盖这些设置,因此实际上不太可能有太大区别。