Docker和Node.js最佳实践

・7 分钟阅读

.多客户环境和数据中心

NODE_ENV设置为production运行,


-e "NODE_ENV=production"

全局npm依赖性

如果需要安装全局npm依赖项,建议将这些依赖项放在非root用户目录中。要实现这个,请将以下行添加到Dockerfile


ENV NPM_CONFIG_PREFIX=/home/node/.npm-global

ENV PATH=$PATH:/home/node/.npm-global/bin # optionally if you want to run npm global bin without specifying path


升级/降级Yarn

本地

如果需要为本地安装升级降级,可以通过在Dockerfile中发出以下命令来实现:

如果要全局升级yarn,请按照下一节中的说明操作。

遵循本地安装指令时,由于重复的Yarn,镜像最终会变大。


FROM node:6

ENV YARN_VERSION 1.16.0

RUN yarn policies set-version $YARN_VERSION


全局


FROM node:6

ENV YARN_VERSION 1.16.0

RUN curl -fSLO --compressed "https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz" 
 && tar -xzf yarn-v$YARN_VERSION.tar.gz -C /opt/ 
 && ln -snf /opt/yarn-v$YARN_VERSION/bin/yarn /usr/local/bin/yarn 
 && ln -snf /opt/yarn-v$YARN_VERSION/bin/yarnpkg /usr/local/bin/yarnpkg 
 && rm yarn-v$YARN_VERSION.tar.gz


如果使用的是基于alpine的镜像,则curl将不存在,因此你需要确保在使用时已安装它:


FROM node:6-alpine

ENV YARN_VERSION 1.5.1

RUN apk add --no-cache --virtual .build-deps-yarn curl 
 && curl -fSLO --compressed "https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz" 
 && tar -xzf yarn-v$YARN_VERSION.tar.gz -C /opt/ 
 && ln -snf /opt/yarn-v$YARN_VERSION/bin/yarn /usr/local/bin/yarn 
 && ln -snf /opt/yarn-v$YARN_VERSION/bin/yarnpkg /usr/local/bin/yarnpkg 
 && rm yarn-v$YARN_VERSION.tar.gz 
 && apk del .build-deps-yarn


处理内核信号

Node.js未设计为作为PID 1运行,在运行Docker的内部时会导致意外的行为,例如,作为PID 1运行的Node.js进程将不响应SIGINT (CTRL-C )和类似的信号,从Docker 1.13开始,你可以使用--init标志来包装你的进程。


docker run -it --init node

您还可以将Tini直接包含在Dockerfile中,以确保始终使用init包装器启动您的过程。

非root用户

默认情况下,Docker以根用户身份运行容器,容器内部可能构成安全问题。你希望尽可能将容器作为非权限用户运行,node镜像为node用户提供了这种用途,然后,Docker镜像可以通过以下方式与node用户一起运行:

 
-u"node"

或者,可以在Dockerfile中激活用户:


FROM node:6.10.3
...
# At the end, set the user to use when running this image
USER node


如果您不再需要在镜像中创建的用户,则可以使用以下命令将其删除:


# For debian based images use:
RUN userdel -r node

# For alpine based images use:
RUN deluser --remove-home node


如果需要更改用户的uid/gid,可以使用:


RUN groupmod -g 999 node && usermod -u 999 -g 999 node


如果你需要另一个用户名(ex,myapp )执行:


RUN usermod -d /home/myapp -l myapp node


对于基于alpine的镜像,没有groupmodusermod,因此要更改uid yf_xieyf gid,你必须删除以前的用户:


RUN deluser --remove-home node 
 && addgroup -S node -g 999 
 && adduser -S -G node -u 999 node


内存

如果在同一个主机上运行多个容器,就应该限制它们可以消耗多少内存。


-m "300M" --memory-swap "1G"

CMD

创建镜像时,可以绕过package.json =s start命令并将它直接发送到镜像本身,首先减少容器内部运行的进程数,其次,SIGTERMSIGINT等退出信号由Node.js进程接收,而不是npm吞噬它们。


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


运行Docker

以下是运行默认Node.js Docker容器化应用程序的示例:


$ docker run 
 -e "NODE_ENV=production" 
 -u "node" 
 -m "300M" --memory-swap "1G" 
 -w "/home/node/app" 
 --name "my-nodejs-app" 
 node [script]

安全

Docker团队提供了一个工具来分析运行中的容器是否存在潜在的安全问题,你可以从这里下载,并运行此工具:https://github.com/docker/docker-bench-security

node-gyp alpine

以下是在alpine variant上安装需要node gyp支持的软件包的依赖项的示例:


FROM node:alpine

RUN apk add --no-cache --virtual .gyp python make g++ 
 && npm install [ your npm dependencies here ] 
 && apk del .gyp


下面是一个多级构建示例


FROM node:alpine as builder

## Install build toolchain, install node deps and compile native add-ons
RUN apk add --no-cache python make g++
RUN npm install [ your npm dependencies here ]

FROM node:alpine as app

## Copy built node modules and binaries without including the toolchain
COPY --from=builder node_modules .


Yanyan profile image