节点和docker – 如何处理babel或打字稿?

我有一个节点应用程序,我想在Docker容器中托pipe,应该是直接的,如本文所示:

https://nodejs.org/en/docs/guides/nodejs-docker-webapp/

然而,在我的项目中,源代码不能直接运行,必须从ES6和/或Typescript编译。 我使用gulpbuild立与babel,browserify和tsify – 与浏览器和服务器不同的设置。

在这种情况下,build立和自动化泊坞窗图像的最佳工作stream程是什么? networking上是否有描述这种工作stream的资源? 如果Dockerimage在npm install之后执行构build,还是应该创build一个shell脚本来完成所有这些操作,并且只需要将Dockerfile一起打包?

如果Dockerfile应该执行构build – 图像将需要包含所有的dev-dependencies,这是不理想的?

注:我已经能够build立一个docker集装箱,并运行它 – 但这需要事先安装和build立所有的文件。

一个可能的解决scheme是将您的构build过程包装在一个特殊的泊坞窗图像中。 它通常被称为Builder图像 。 它应该包含所有的构build依赖项:nodejs,npm,gulp,babel,tsc等。它封装了所有构build过程,无需在主机上安装这些工具。

首先运行构build器映像,将源代码目录挂载为卷。 输出目录可以使用相同或不同的卷。 第一个图像需要你的代码并运行所有的构build命令。

作为您的第一步,您需要将构build好的代码打包到生产Docker镜像中,就像现在一样。

以下是TypeScript的docker生成器映像的示例: https : //hub.docker.com/r/sandrokeil/typescript/

可以为几个项目使用相同的docker构build器,因为它通常被devise为围绕一些常用工具的通用包装。 但是build立你自己的描述更复杂的程序是可以的。

builder映像的好处在于,你的主机环境保持不受污染,只需修改builder映像的Dockerfile,就可以自由尝试更新版本的编译器/不同工具/更改顺序/并行执行任务。 在任何时候,你都可以使用构build过程来回滚你的实验。

遵循以下步骤:

第一步:确保你的依赖关系中有你的babel依赖关系, 不是依赖于package.json。 另外添加一个从node_modules文件夹引用到babel的部署脚本。 你将在docker中调用这个脚本这就是我的package.json文件的样子

 { "name": "tmeasy_api", "version": "1.0.0", "description": "Trade made easy Application", "main": "build/index.js", "scripts": { "build": "babel -w src/ -d build/ -s inline", "deploy" : "node_modules/babel-cli/bin/babel.js src/ -d build/", }, "devDependencies": { "nodemon": "^1.9.2" }, "dependencies": { "babel-cli": "^6.10.1", "babel-polyfill": "^6.9.1", "babel-preset-es2015": "^6.9.0", "babel-preset-stage-0": "^6.5.0", "babel-preset-stage-3": "^6.22.0" } } 

构build是为了您的本地计算机上的开发目的,部署将从您的dockerfile中调用。

第二步:因为我们想要自己做转换,所以请确保使用开发过程中使用的构build文件夹添加.dockerignore。 这就是我的.dockerignore文件的样子。

  build node_modules 

第3步。构build您的dockerfile。 下面是我的docker文件的示例

 FROM node:6 MAINTAINER stackoverflow ENV NODE_ENV=production ENV PORT=3000 # use changes to package.json to force Docker not to use the cache # when we change our application's nodejs dependencies: ADD package.json /tmp/package.json RUN cd /tmp && npm install RUN mkdir -p /var/www && cp -a /tmp/node_modules /var/www # copy current working directory into docker; but it first checks for # .dockerignore so build will not be included. COPY . /var/www/ WORKDIR /var/www/ # remove any previous builds and create a new build folder and then # call our node script deploy RUN rm -f build RUN mkdir build RUN chmod 777 /var/www/build RUN npm run deploy VOLUME /var/www/uploads EXPOSE $PORT ENTRYPOINT ["node","build/index.js"] 

我个人更喜欢在构build期间运行babel之后删除dev依赖项:

 FROM node:7 # Create app directory RUN mkdir -p /usr/src/app WORKDIR /usr/src/app # Install app dependencies COPY package.json /usr/src/app/ RUN npm install # Copy app source COPY src /usr/src/app/src # Compile app sources RUN npm run compile # Remove dev dependencies RUN npm prune --production # Expose port and CMD EXPOSE 8080 CMD [ "npm", "start" ] 

目前,我正在使用一个工作stream程,其中:

  1. npm installtsd install在本地tsd install
  2. gulp本地build设
  3. 在Dockerfile中,复制所有程序文件,但不是types/ node_modules到docker镜像
  4. 在Dockerfile中, npm install --production

这样我只得到图像中想要的文件,但是如果Dockerfile可以自己完成构build会更好。

Dockerfile:

 FROM node:5.1 # Create app directory RUN mkdir -p /usr/src/app WORKDIR /usr/src/app # Bundle app COPY package.json index.js /usr/src/app/ COPY views/ /usr/src/app/views/ COPY build/ /usr/src/app/build/ COPY public/ /usr/src/app/public/ # Install app dependencies RUN npm install --production --silent EXPOSE 3000 CMD [ "node", "index.js" ] 

我猜想在“成像过程”中可以通过在Dockerimage脚本中构build完整的自动化程序,然后在再次安装之前删除不需要的文件。

然而,在我的项目中,源代码不能直接运行,必须从ES6和/或Typescript编译。 我使用gulpbuild立与babel,browserify和tsify – 与浏览器和服务器不同的设置。 在这种情况下,build立和自动化泊坞窗图像的最佳工作stream程是什么?

当我理解你是正确的,你想在Docker容器中部署你的web应用,并为不同的目标环境提供不同的风格(你提到了不同的浏览器和服务器)。 (1)

如果Dockerfile应该执行构build – 图像将需要包含所有的dev-dependencies,这是不理想的?

这取决于。 如果你想提供一个准备好的图像,它必须包含你的web应用程序需要运行的一切。 一个好处是,你以后只需要启动容器,传递一些参数,你就可以走了。

在开发阶段,由于通常预定义的开发环境,该映像并不是真正必要的。 如果在每次更改之后生成这样的图像,则花费时间和资源。

build议的方法:我会build议一个双向的设置:

  1. 在开发过程中 :使用固定的环境来开发您的应用程序。 所有软件都可以在本地运行,也可以在Docker / VM内部运行。 我build议在dev-setup中使用一个Docker容器,特别是如果你在一个团队中工作,并且每个人都需要有相同的dev-basement。
  2. 部署Web应用程序 :正如我理解你的权利(1),你想部署应用程序的不同环境,因此需要创build/提供不同的configuration。 要实现这样的事情,你可以从一个shell脚本开始,将你的应用程序打包到不同的docker容器中。 您在部署之前运行脚本。 如果你正在运行Jekyll,那么在每次提交后都会调用你的shell脚本,所有的testing都运行正常。

用于开发和部署阶段的Docker容器:我想参考我的一个项目和一个同事: https : //github.com/k00ni/Docker-Nodejs-environment

这个docker提供了一个完整的开发和部署环境,通过维护:

  • Node.js的
  • NPM
  • Babel(自动从ECMA6转换到JavaScript上的文件更改)
  • 的WebPack

和Docker容器的其他JavaScript助手。 您只需通过泊坞窗容器内的卷链接您的项目文件夹。 它初始化你的环境(例如,从package.json部署所有的依赖),你很好。

您可以将其用于开发目的,使您和您的团队使用相同的环境(Node.js版本,NPM版本,…)另一个优点是,文件更改导致重新编译ECMA6 / ReactJS /。 ..文件到JavaScript文件(每次更改后无需手动执行此操作)。 我们使用Babel。

为了部署 ,只需扩展这个Docker镜像并更改所需的部分。 而不是在容器内部链接你的应用程序,你可以通过Git(或类似的东西)。 你将在同一个地下室工作。