4

我在 Docker 容器内运行 node js 官方映像,我注意到 npm start 命令的启动时间比它在 Docker 外部时要长得多。

是否可以更改设置以使其运行得更快?也许为容器分配更多内存?

作为参考,我将在下面粘贴相关文件。

Dockerfile:

FROM node:8.1

WORKDIR var/www/app

# Global install yarn package manager
RUN apt-get update && apt-get install -y curl apt-transport-https && \
    curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
    echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
    apt-get update && apt-get install -y yarn

RUN npm install -g create-react-app

我用来启动容器的命令:

docker run --rm -ti \
--link api-container:api \
--name my-container -p 3000:3000 \
-v $(pwd):/var/www/app nxmohamad/my-container \
bash

启动脚本只是NODE_PATH=. react-scripts start

4

1 回答 1

9

Bind mounting from a Host > VM > Container with osxfs will be slower than normal file access. The Linux file cache is impacted to achieve "consistency" between the host and container. Some applications that depend on the file cache for speed can slow down. PHP web apps with frameworks are hit in particular as they load all files on each request.

React is likely in a slightly better position as the file reads only happens once on startup, but those reads will still be slow each startup.

Anything that actively writes to a directory is just going to be slower.

Workarounds

Caching

Some caching options were added to mounts in Docker 17.06 so users can control the mounts beyond the default 'consistent' level where all reads are passed out to OSX from the container.

It's likely the node_modules directory is the main cause of slowness, it's also the safest place to enable caching on as it doesn't change often.

This setup can get verbose depending on your directory structure as you have to mount each item in your app directory independently:

docker run --rm -ti \
  --link api-container:api \
  --name my-container -p 3000:3000 \
  -v $(pwd)/index.js:/var/www/app/index.js \
  -v $(pwd)/package.json:/var/www/app/package.json \
  -v $(pwd)/src:/var/www/app/src \
  -v $(pwd)/node_modules:/var/www/app/node_modules:cached \
  nxmohamad/my-container \
  bash

Syncing

The other option is using a tool like rsync or unison to keep a local volume in sync rather than relying on bind mounts from OSX or Windows.

A tool called docker-sync was written specifically for this. Getting a working configuration can be a bit difficult and it can get itself in a tangle sometimes (it's caused a couple of kernel oopses if I leave it running over a suspend) but it works in the end.

于 2017-11-30T01:04:54.960 回答