我有一个示例应用程序,我使用的是nodejs和reactjs,所以我的项目文件夹由client和server文件夹组成。使用create-react-app创建客户端文件夹。

我为每个文件夹创建了两个Dockerfile,并且在项目的根目录上使用了docker-compose.yml。

一切正常。现在我只想托管此应用程序。我正在尝试使用 Jenkins 。

由于我对开发人员方面知之甚少。我有些疑惑

1)如果我对客户端使用两个docker文件并使用react,并且由docker-compose.yml启动,它将在两个不同的容器中运行还是在单个容器中运行?从我所读过的内容来看,我认为将需要两个容器来使用docker-compose.yml文件。对此有些困惑?

2)也当我做sudo docker-compose时,它运行得很好,但它显示“基于nv创建生产版本,使用npm run build”,如何更改此版本。我是否需要为每个环境创建不同的docker-compose.yml文件。如何使用基于env的相同文件但不同的npm start或npm run构建?

3)我可以使用docker-compose.yml文件在jenkins中构建管道吗,还是在项目的根目录中需要Dockerfile?我已经看到大多数项目只有一个Dockerfile。那是我无法使用docker-compose.yml托管应用程序吗?

4)为什么我在docker-compose.yml文件的Command属性中对服务器使用NODE_COMMAND是因为当我在本地运行应用程序时我需要自动重新加载,因此在终端中如果我将NODE_COMMAND = nodemon代替运行节点index.js,但在生产中,如果我不提及任何NODE_COMMAND,它将仅使用节点index.js。

5)我是否需要每个客户端和服务器的Dockerfile中的CMD,因为当我运行docker-compose时,它将采用docker-compose.yml的命令。所以我认为优先级将来自docker-compose.yml文件。是吗 ?

6)docker-compose.yml文件中要求使用卷吗?

7)在环境文件中,我正在使用API​​_HOST和APP_SERVER_PORT,它在内部如何与package.json相关联?它在做代理人的事吗?当我们需要点击nodejs时,通常会给出“proxy”:“http://localhost:4000”,但是这里需要http://server:4000。这东西是怎么工作的?

8)当我们创建一个容器时,我们有3000、3001等端口...因此,通过使用docker-compose.yml文件中的导出环境和端口,容器端口和我们的应用程序端口将如何匹配。 ?

请参见下面的文件夹结构

movielisting
   client
     Dockerfile
     package.json
     package.lock.json
     ... other create-react-app folders like src..
   server
     Dockerfile
     index.js
   docker-compose.yml
   .env

Dockerfile-客户端
FROM node:10.15.1-alpine

#Create app directory and use it as the working directory
RUN mkdir -p /srv/app/client
WORKDIR /srv/app/client

COPY package.json /srv/app/client
COPY package-lock.json /srv/app/client

RUN npm install

COPY . /srv/app/client

CMD ["npm", "start"]

Dockerfile-服务器
FROM node:10.15.1-alpine

#Create app directory
RUN mkdir -p /srv/app/server
WORKDIR /srv/app/server

COPY package.json /srv/app/server
COPY package-lock.json /srv/app/server

RUN npm install

COPY . /srv/app/server

CMD ["node", "index.js"]

docker-compose.yml-项目的根目录
version: "3"

services:
  #########################
  # Setup node container
  #########################
  server:
    build: ./server
    expose:
      - ${APP_SERVER_PORT}
    environment:
      API_HOST: ${API_HOST}
      APP_SERVER_PORT: ${APP_SERVER_PORT}
    ports:
      - ${APP_SERVER_PORT}:${APP_SERVER_PORT}
    volumes:
      - ./server:/srv/app/server
    command: ${NODE_COMMAND:-node} index.js

    ##########################
    # Setup client container
    ##########################

  client:
    build: ./client
    environment:
      - REACT_APP_PORT=${REACT_APP_PORT}
    expose:
      - ${REACT_APP_PORT}
    ports:
      - ${REACT_APP_PORT}:${REACT_APP_PORT}
    volumes:
      - ./client/src:/srv/app/client/src
      - ./client/public:/srv/app/client/public
    links:
      - server
    command: npm run start

.env
API_HOST="http://localhost:4000"
APP_SERVER_PORT=4000
REACT_APP_PORT=3000

package.json-客户端
"proxy": "http://server:4000"

我能重构什么,

任何帮助表示赞赏。

最佳答案

1)如果我使用两个docker文件作为客户端并使用react,并且由docker-compose.yml启动,它将在两个不同的容器中运行还是在单个容器中运行?从我所读过的内容来看,我认为将需要两个容器来使用docker-compose.yml文件。对此有些困惑?

每个dockerfile将构建一个docker镜像。因此,最后您将获得两个图像,一个用于react应用程序,另一个用于后端,即nodejs应用程序

2)同样,当我执行sudo docker-compose时,它运行得很好,但根据环境如何显示“使用npm run build创建生产版本”,我如何更改此版本。我是否需要为每个环境创建不同的docker-compose.yml文件。如何使用基于env的相同文件但不同的npm start或npm run构建?

您需要按照其Dockerfile中的步骤构建react应用程序,以便能够将其用作普通应用程序。另外,您可能会使用环境变量在生成期间使用build-args自定义镜像,例如传递自定义路径或其他任何内容。

3)我可以使用docker-compose.yml文件在jenkins中构建管道,还是在项目的根目录中使用Dockerfile?我已经看到大多数项目只有一个Dockerfile。那是我无法使用docker-compose.yml托管应用程序吗?

如果将dockerfile与jenkins一起使用以构建镜像并保留docker-compose.yml文件用于部署应用程序本身而不使用build关键字,那会更好。

4)为什么我在docker-compose.yml文件的Command属性中使用NODE_COMMAND作为服务器的原因是因为当我在本地运行应用程序时我需要自动重新加载,因此在终端中如果我将NODE_COMMAND = nodemon代替运行节点index.js,但是在生产环境中,如果我不提及任何NODE_COMMAND,它将仅使用节点index.js。

在docker-compose.yml文件中使用command将覆盖在构建步骤中设置的dockerfile的CMD
5)我是否需要在每个客户端和服务器的Dockerfile中使用CMD,因为当我运行docker-compose时,它将使用docker-compose.yml命令。所以我认为优先级将来自docker-compose.yml文件。是吗 ?

一般来说,是的,您需要它,但是,只要您要使用它从docker-compose文件中覆盖它,就可以将其添加为CMD ["node", "--help"]或其他名称

6)docker-compose.yml文件中要求使用卷吗?

如果您在容器之间共享文件,或者需要保持数据在主机上的持久性,则需要卷

7)在环境文件中,我正在使用API​​_HOST和APP_SERVER_PORT,它在内部如何与package.json相关联?它在做代理人的事吗?当我们需要点击nodejs时,通常会给出“proxy”:“http://localhost:4000”,但是这里需要http://server:4000。这东西是怎么工作的?

一旦启动应用程序,server是docker网络中的nodejs容器的别名。以及为什么命名为server?因为您在此部分的docker-compose.yml文件中拥有此文件:

services:
  server:

但是当然,您可以通过在docker-compose.yml文件中的network关键字内向其添加别名来对其进行更改



8)在创建容器时,我们有端口3000、3001 ...,因此,通过使用docker-compose.yml文件中的导出环境和端口,容器端口和我们的应用程序端口将如何匹配。那?

Docker本身不知道您的应用程序正在使用哪个端口,因此您必须使它们都使用相同的端口。在nodejs中,这可以通过使用环境变量来实现

更多细节:
  • https://docs.docker.com/engine/reference/commandline/build/#set-build-time-variables---build-arg
  • https://docs.docker.com/compose/networking/
  • https://docs.docker.com/compose/compose-file/#aliases
  • https://docs.docker.com/compose/compose-file/#command
  • https://facebook.github.io/create-react-app/docs/deployment
  • 关于docker - 节点并使用docker-compose.yml文件运行,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54841515/

    10-16 16:05
    查看更多