2016-03-03 15 views
32

Tôi hiện đang phát triển một phụ trợ nút cho ứng dụng của tôi. Khi dockerizing nó (docker xây dựng.) Giai đoạn dài nhất là RUN npm install. RUN npm install hướng dẫn chạy trên mỗi thay đổi mã máy chủ nhỏ, ảnh hưởng đến năng suất bằng cách làm cho nhà phát triển chờ bản xây dựng hoàn thành mỗi lần.Làm thế nào để cache hướng dẫn cài đặt RUN npm khi docker xây dựng một Dockerfile

Tôi thấy rằng đang chạy npm install nơi mã ứng dụng tồn tại và thêm node_modules vào vùng chứa với lệnh ADD giải quyết vấn đề này, nhưng nó là cách thực hành tốt nhất. Nó loại phá vỡ toàn bộ ý tưởng của dockerizing nó và nó gây ra container để trọng lượng nhiều hơn nữa.

Bất kỳ giải pháp nào khác?

Trả lời

66

Ok vì vậy tôi đã tìm thấy this great article về hiệu quả khi viết tệp docker.

Đây là một ví dụ về một tập tin Docker xấu thêm mã ứng dụng trước khi chạy RUN npm install hướng dẫn:

FROM ubuntu 

RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list 
RUN apt-get update 
RUN apt-get -y install python-software-properties git build-essential 
RUN add-apt-repository -y ppa:chris-lea/node.js 
RUN apt-get update 
RUN apt-get -y install nodejs 

WORKDIR /opt/app 

COPY . /opt/app 
RUN npm install 
EXPOSE 3001 

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

Bằng cách chia các bản sao của ứng dụng thành 2 hướng dẫn COPY (một cho các tập tin và package.json cái còn lại cho các tập tin còn lại) và chạy lệnh cài đặt npm trước khi thêm mã thực, bất kỳ thay đổi mã nào sẽ không kích hoạt lệnh cài đặt RUN npm, chỉ những thay đổi của package.json mới kích hoạt nó. Better tập thực hành Docker:

FROM ubuntu 
MAINTAINER David Weinstein <[email protected]> 

# install our dependencies and nodejs 
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list 
RUN apt-get update 
RUN apt-get -y install python-software-properties git build-essential 
RUN add-apt-repository -y ppa:chris-lea/node.js 
RUN apt-get update 
RUN apt-get -y install nodejs 

# use changes to package.json to force Docker not to use the cache 
# when we change our application's nodejs dependencies: 
COPY package.json /tmp/package.json 
RUN cd /tmp && npm install 
RUN mkdir -p /opt/app && cp -a /tmp/node_modules /opt/app/ 

# From here we load our application's code in, therefore the previous docker 
# "layer" thats been cached will be used if possible 
WORKDIR /opt/app 
COPY . /opt/app 

EXPOSE 3000 

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

Đây là nơi các tập tin package.json thêm, cài đặt phụ thuộc của nó và sao chép chúng vào workdir container, nơi ứng dụng sống:

ADD package.json /tmp/package.json 
RUN cd /tmp && npm install 
RUN mkdir -p /opt/app && cp -a /tmp/node_modules /opt/app/ 

Để tránh NPM cài đặt giai đoạn trên mỗi docker xây dựng chỉ cần sao chép những dòng và thay đổi ^/opt/app^đến vị trí ứng dụng của bạn sống bên trong container.

+2

đó làm việc. Một số điểm mặc dù. 'ADD' không được khuyến khích cho' COPY', afaik. 'COPY' thậm chí còn hiệu quả hơn.IMO, hai đoạn cuối không cần thiết, vì chúng là bản sao và cũng từ quan điểm ứng dụng, không quan trọng ở đâu trên hệ thống tệp mà ứng dụng tồn tại, miễn là 'WORKDIR' được đặt. – eljefedelrodeodeljefe

+2

Tốt hơn là kết hợp tất cả các lệnh apt-get vào một RUN, bao gồm một 'apt-get clean'. Ngoài ra, hãy thêm ./node_modules vào .dockerignore của bạn, để tránh sao chép thư mục làm việc của bạn vào vùng chứa đã được xây dựng của bạn và để tăng tốc bản sao xây dựng bối cảnh của bản dựng. – Symmetric

+0

Vì lý do gì bạn thực hiện lệnh sao chép trong một RUN riêng biệt? Và có vấn đề gì nếu tôi di chuyển gói node_modules thay vì sao chép nó? Bởi vì nó có thể nhận được tương đối lớn tùy thuộc vào bao nhiêu bạn cài đặt –

2

Tôi tưởng tượng bạn có thể đã biết, nhưng bạn có thể bao gồm một tập tin .dockerignore trong cùng một thư mục chứa

node_modules 
npm-debug.log 

để tránh đầy hơi hình ảnh của bạn khi bạn push to Docker hub

5

tôi đã tìm thấy cách tiếp cận đơn giản nhất là tận dụng ngữ nghĩa sao chép của Docker:

Lệnh COPY sao chép tệp hoặc thư mục mới và thêm chúng vào hệ thống tệp của vùng chứa tại đường dẫn.

Điều này có nghĩa rằng nếu bạn lần đầu tiên sao chép một cách rõ ràng các tập tin package.json và sau đó chạy npm install bước mà nó có thể được lưu trữ và sau đó bạn có thể sao chép phần còn lại của thư mục nguồn. Nếu tệp package.json đã thay đổi thì tệp đó sẽ mới và nó sẽ chạy lại bộ nhớ đệm cài đặt npm cho các bản dựng trong tương lai.

Một đoạn mã từ ngày kết thúc của một Dockerfile sẽ trông như thế:

# install node modules 
COPY package.json /usr/app/package.json 
RUN cd /usr/app && npm install 

# install application 
COPY . /usr/app 
Các vấn đề liên quan