如何在阻止端口的同时仅允许通过特定的URL访问MERN项目中的Docker容器?

时间:2019-02-15 17:18:13

标签: docker docker-compose

我在Docker上建立了一个MERN项目。开发环境良好;这是我遇到的麻烦。

这是我想要的行为:

  • 开发中:
    • 这是容器的状态:
      • Nodemon在节点表示映像(来自node:alpine)容器中运行,并且向主机打开了 port 9000 。 (这是后端/ api)
      • MongoDB根据官方映像在其自己的容器中运行,并且向主机开放端口27017 。 (这是数据库)
      • React在其映像(来自node:alpine)容器中进行热装,并向主机打开了 port 3000 。 (这是前端)
  • 生产中:
    • 这是容器的状态:
      • 节点在节点表示映像(来自node:alpine)容器中运行,主机没有没有端口
      • MongoDB根据官方映像在其自己的容器中运行,并且主机没有没有端口
      • React在其映像(来自nginx:alpine)容器中运行,并且向主机打开了端口80

后端/ api使用容器名称引用数据库,前端/反应容器使用容器名称引用后端。

我将proxy: localhost:9000放入了 package.json 文件中。在生产中,我将以下内容放入 nginx.conf 文件中。

location / {
    root   /usr/share/nginx/html;
    index  index.html index.htm;
    try_files $uri /index.html;
}
location /api {
    proxy_pass http://localhost:9000;
}

在生产docker-compose.yml文件中,我删除了docker-compose.yml文件中存在的expose: "9000"ports: "9000:9000"。我运行docker-compose -f docker-compose.yml -f docker-compose.production.yml up


我的问题是,由于某些原因,端口“ localhost:9000”和“ localhost:27017”仍在生产中公开。我希望除“ example.com/api”之外的所有路由都经过React。只有“ example.com/api”必须直接转到后端。

此外,我不确定是否与此相关,但是有没有一种方法可以确保“ example.com/api”转到后端而不必执行require("express")().get('/api'...?与之类似,默认情况下,仅执行require("express")().get('/'...就会调用“ example.com/api”。

注意:我使用网络而不是链接来将容器连接在一起。后端同时连接到React和MongoDB,而React和MongoDB没有连接。


这是我的docker-compose.yml:

version: "3.7"
services:
##############################
# Back-End Container
##############################
  backend:
    container_name: backend
    build:
      context: ./backend/
      target: development
    restart: always
    expose:
      - "9000"
    environment:
      - MONGO_URI=mongodb://db:27017/db
      - PORT=9000
      - NODE_ENV=development
      - DEBUG=app
      - JWT_SECRET=secretsecret
      - JWT_EXPIRY=30d
    ports:
      - "9000:9000"
      - "9229:9229"
    volumes:
      - "./backend/:/home/node/app/"
      - /home/node/app/node_modules/
    depends_on:
      - db
    networks:
      - client
      - server
##############################
# Front-End Container
##############################
  frontend:
    container_name: frontend
    build:
      context: ./frontend/
      target: development
    restart: always
    expose:
      - "3000"
      - "35729"
    environment: 
      - NODE_ENV=development
      - REACT_APP_PORT=3000
      - CHOKIDAR_USEPOLLING=true
    ports:
      - "3000:3000"
      - "35729:35729"
    volumes:
      - "./frontend/:/home/node/app/"
      - /home/node/app/node_modules/
    networks:
      - client
##############################
# MongoDB Container
##############################
  db:
    container_name: db
    image: mongo
    restart: always
    volumes:
      - dbdata:/data/db/
    ports:
      - "27017:27017"
    networks:
      - server
networks:
  client:
  server:
volumes:
  dbdata:

这是我的.env文件

MONGO_URI=db:27017/somedb?authSource=admin
PORT=9000
MONGO_PORT=27017
MONGO_INITDB_ROOT_USERNAME=mongoadmin
MONGO_INITDB_ROOT_PASSWORD=secret
MONGO_INITDB_DATABASE=somedb
NODE_ENV=production

这是我的docker.compose.production.yml:

version: "3.7"
services:
##############################
# Back-End Container
##############################
  backend:
    container_name: backend
    init: true
    environment:
      - MONGO_URI=mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@${MONGO_URI}
      - PORT=${PORT}
      - NODE_ENV=${NODE_ENV}
    build:
      context: ./backend/
      target: production
    restart: always
    depends_on:
      - db
    networks:
      - client
      - server
##############################
# Front-End Container
##############################
  frontend:
    container_name: frontend
    build:
      context: ./frontend/
      target: production
    restart: always
    environment:
      - NODE_ENV=${NODE_ENV}
    expose:
      - "80"
    ports:
      - "80:80"
    networks:
      - client
##############################
# MongoDB Container
##############################
  db:
    container_name: db
    image: mongo
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: ${MONGO_INITDB_ROOT_USERNAME}
      MONGO_INITDB_ROOT_PASSWORD: ${MONGO_INITDB_ROOT_PASSWORD}
    volumes:
      - dbdata:/data/db/
    ports:
      - "27017:27017"
    networks: 
      - server
networks:
  client:
  server:
volumes:
  dbdata:

Dockerfile仅具有FROM,WORKDIR,RUN,COPY和CMD。

1 个答案:

答案 0 :(得分:0)

  

我运行docker-compose -f docker-compose.yml -f docker-compose.production.yml。

为什么要包含开发docker-compose.yml?我要做的就是删除该部分并直接运行docker-compose.production.yml。不需要任何覆盖。

要运行解决方案:

import pytest @pytest.hookimpl(hookwrapper=True) def pytest_runtest_makereport(item, call): out = yield report = out.get_result() report.session = item.session def pytest_runtest_logreport(report): print(report.session)

对于那些寻找为什么代理不导致后端根源的人来说,是因为I didn't include a forward slash in the url of the proxy in the nginx.conf