242

Tôi đã đọc và tìm hiểu về Docker , và tôi đang cố gắng chọn chính xác thiết lập Django để sử dụng. Cho đến nay cũng có:

Docker Soạn hoặc Dockerfile

Tôi hiểu rằng nó Dockerfilesđược sử dụng Docker Compose, nhưng tôi không chắc có nên đặt mọi thứ vào một Dockerfile lớn với nhiều FROMlệnh cho các hình ảnh khác nhau không?

Tôi muốn sử dụng một số hình ảnh khác nhau bao gồm:

uwsgi
nginx
postgres
redis
rabbitmq
celery with cron

Vui lòng tư vấn về các thực tiễn tốt nhất trong việc thiết lập loại môi trường này bằng Docker .

Nếu nó giúp, tôi đang dùng Mac, nên sử dụng boot2docker .

Một số vấn đề tôi đã có:

  1. Docker Compose không tương thích với Python3
  2. Tôi muốn lưu trữ dự án của mình, vì vậy nếu một Dockerfile lớn không lý tưởng, thì tôi cảm thấy cần phải phá vỡ nó bằng cách sử dụng Docker Compose
  3. Tôi ổn để làm cho dự án Py2 & Py3 tương thích, vì vậy tôi đang nghiêng về django-compose
|
149

Câu trả lời là không.

Docker Compose (sau đây gọi là compose) sẽ sử dụng Dockerfile nếu bạn thêm lệnh xây dựng vào dự án của bạn docker-compose.yml.

Quy trình làm việc Docker của bạn phải là để xây dựng một Dockerfilehình ảnh phù hợp cho từng hình ảnh bạn muốn tạo, sau đó sử dụng compose để lắp ráp các hình ảnh bằng cách sử dụng buildlệnh.

Bạn có thể chỉ định đường dẫn đến Dockerfiles cá nhân của mình bằng cách sử dụng build /path/to/dockerfiles/blahnơi sống /path/to/dockerfiles/blahcủa blah Dockerfile.

|
343

Dockerfile

Dockerfile là một tệp văn bản đơn giản chứa các lệnh mà người dùng có thể gọi để lắp ráp một hình ảnh.

Ví dụ, Dockerfile

FROM ubuntu:latest
MAINTAINER john doe 

RUN apt-get update
RUN apt-get install -y python python-pip wget
RUN pip install Flask

ADD hello.py /home/hello.py

WORKDIR /home

Docker Soạn

Docker Soạn

  • là một công cụ để xác định và chạy các ứng dụng Docker đa container.

  • xác định các dịch vụ tạo nên ứng dụng của bạn docker-compose.ymlđể chúng có thể chạy cùng nhau trong một môi trường biệt lập.

  • có được một ứng dụng chạy trong một lệnh chỉ bằng cách chạy docker-compose up

Ví dụ, docker-compose.yml

version: '3'
services:
  web:
    build: .
    ports:
    - "5000:5000"
    volumes:
    - .:/code
    - logvolume01:/var/log
    links:
    - redis
  redis:
    image: redis
volumes:
  logvolume01: {}
|
  • 1

    @sg câu trả lời là câu hỏi không đúng dựa trên sự thiếu hiểu biết về Docker vs Docker Compose. Giải thích ngắn gọn về cách hai người tương tác có lẽ là câu trả lời tốt nhất tôi có thể nghĩ ra.

    – Trịnh Ngọc Thọ 00:44:16 30/08/2017
  • 1

    Tôi không biết tại sao sự cố chính xác này không nằm trên trang chủ của Docker. Cảm ơn.

    – Trịnh Duy Thành 11:33:23 11/03/2018
  • 1

    Tôi thấy loại tài liệu này bị thiếu trong các công cụ / giải pháp / khung phát hành gần đây nhất trên web. Tôi đoán thật khó để biết tại sao ai đó cần nó trong trường hợp bạn đã biết / tự phát minh ra giải pháp.

    – Đặng Việt Trinh 12:13:08 18/03/2018
  • 1

    Điều còn thiếu từ câu trả lời này là thông tin thêm về sáng tác. Tập lệnh soạn thảo có gọi dockerfile không? Làm thế nào để nó biết những gì để sáng tác? Ví dụ cho thấy image: redisnhưng đó là từ dockerhub? thư mục địa phương? v.v ... điều này khiến cho một người mới như tôi khó hiểu về những gì đang diễn ra

    – Trịnh Quang Lâm 15:47:38 21/03/2018
  • 1

    @JoePhillips có chính xác! Là hình ảnh: redis, giống như từ: redis trong tập tin docker?

    – Lý Hồng Diễm 02:01:07 13/07/2018
72

Tệp Compose mô tả vùng chứa ở trạng thái chạy , để lại chi tiết về cách xây dựng vùng chứa thành Dockerfiles . http://deninet.com/blog/1587/docker-scratch-part-4-compose-and-volume

Khi bạn xác định ứng dụng của mình với Compose in Development , bạn có thể sử dụng định nghĩa này để chạy ứng dụng của mình trong các môi trường khác nhau như CI, dàn dựng và sản xuất . https://docs.docker.com/compose/production/

Dường như Compose được coi là sản xuất an toàn kể từ 1.11 , vì https://docs.docker.com/v1.11/compose/production/ không còn cảnh báo không sử dụng nó trong sản xuất như https: // docs .docker.com / v1.10 / soạn / sản xuất / không.

|
  • 1

    Cảm ơn đã đưa ra vấn đề. Bạn có thể vui lòng thêm một số chi tiết đã được sửa cho an toàn sản xuất ở mức 1.11 không?

    – Bùi Ân Thiện 14:34:19 07/11/2017
37

Trong quy trình làm việc của mình, tôi thêm Dockerfile cho từng phần trong hệ thống của mình và định cấu hình nó để mỗi phần có thể chạy riêng lẻ. Sau đó, tôi thêm một docker-compose.yml để mang chúng lại với nhau và liên kết chúng.

Lợi thế lớn nhất (theo ý kiến ​​của tôi): khi liên kết các container , bạn có thể xác định tên và ping các container của mình bằng tên này. Do đó, cơ sở dữ liệu của bạn có thể được truy cập bằng tên dbvà không còn bằng IP của nó.

|
  • 1

    Bạn có thể giải thích thêm về việc truy cập db theo tên không?

    – Bùi Ân Thiện 15:23:41 07/06/2018
  • 1

    Trên phần nào? Trong docker-compose, nó là tầm thường, bởi vì đó là cách thông thường khi xác định dịch vụ của bạn để đặt tên và có thể truy cập mà không cần phải định cấu hình. Trong CI của chúng tôi, tôi đang tạo một mạng, tạo container trong mạng này và đặt tên cho chúng. Sau đó, bạn cũng có thể truy cập chúng bằng tên của chúng bên trong các thùng chứa (không phải từ máy chủ lưu trữ)

    – Trịnh Trường Sơn 19:53:05 07/06/2018
  • 1

    Ý tôi là trong nhà soạn nhạc. Vì vậy, tôi liên kết các hình ảnh trong trình soạn thảo và trong cấu hình Ứng dụng của tôi thay vì IP, tôi nhắm mục tiêu MySQL bằng bất kỳ tên nào tôi đã đặt nó trong tệp soạn thảo?

    – Ngô Ðức Phong 20:11:31 07/06/2018
  • 1

    Đúng rồi. Bạn thậm chí không phải chỉ định một liên kết. Chúng được liên kết theo mặc định nếu mạng không được chỉ định khác nhau. Trong ví dụ này , dịch vụ "web" có thể ping máy chủ "redis" bằng tên "redis"

    – Tạ Diễm Chi 18:23:56 10/06/2018
23

"tốt hơn" là tương đối. Tất cả phụ thuộc vào nhu cầu của bạn là gì. Docker compose là để phối hợp nhiều container. Nếu những hình ảnh này đã tồn tại trong sổ đăng ký docker, thì tốt hơn là liệt kê chúng trong tệp soạn thảo. Nếu những hình ảnh này hoặc một số hình ảnh khác phải được xây dựng từ các tệp trên máy tính của bạn, thì bạn có thể mô tả các quy trình xây dựng những hình ảnh đó trong Dockerfile.

Tôi hiểu rằng Dockerfiles được sử dụng trong Docker Compose, nhưng tôi không chắc liệu có nên thực hiện mọi thứ trong một Dockerfile lớn với nhiều lệnh TỪ cho các hình ảnh khác nhau không?

Sử dụng nhiều TỪ trong một dockerfile không phải là một ý tưởng hay vì có một đề xuất để loại bỏ tính năng này. 13026

Ví dụ: bạn muốn dockerize một ứng dụng sử dụng cơ sở dữ liệu và có các tệp ứng dụng trên máy tính của bạn, bạn có thể sử dụng một tệp soạn thảo cùng với dockerfile như sau

docker-compose.yml

mysql:
  image: mysql:5.7
  volumes:
    - ./db-data:/var/lib/mysql
  environment:
    - "MYSQL_ROOT_PASSWORD=secret"
    - "MYSQL_DATABASE=homestead"
    - "MYSQL_USER=homestead"
  ports:
    - "3307:3306"
app:
  build:
    context: ./path/to/Dockerfile
    dockerfile: Dockerfile
  volumes:
    - ./:/app
  working_dir: /app

Dockerfile

FROM php:7.1-fpm 
RUN apt-get update && apt-get install -y libmcrypt-dev \
  mysql-client libmagickwand-dev --no-install-recommends \
  && pecl install imagick \
  && docker-php-ext-enable imagick \
  && docker-php-ext-install pdo_mysql \
  && curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
|
13

docker-compose tồn tại để giữ cho bạn phải viết một tấn lệnh bạn sẽ phải thực hiện với docker-cli.

docker-compose cũng giúp bạn dễ dàng khởi động nhiều container cùng một lúc và tự động kết nối chúng với nhau bằng một số hình thức kết nối mạng.

Mục đích của docker-compose là hoạt động như docker cli nhưng để phát hành nhiều lệnh nhanh hơn nhiều.

Để sử dụng docker-compose, bạn cần mã hóa các lệnh bạn đang chạy trước đó thành một docker-compose.ymltệp.

Bạn sẽ không chỉ sao chép dán chúng vào tập tin yaml, có một cú pháp đặc biệt.

Sau khi tạo xong, bạn phải cung cấp nó cho cler docker-compose và nó sẽ tùy thuộc vào cli để phân tích tệp và tạo tất cả các thùng chứa khác nhau với cấu hình chính xác mà chúng tôi chỉ định.

Vì vậy, bạn sẽ có các thùng chứa riêng biệt, ví dụ, một là redis-servervà thứ hai là node-appvà bạn muốn nó được tạo bằng Dockerfilethư mục hiện tại của bạn.

Ngoài ra, sau khi tạo vùng chứa đó, bạn sẽ ánh xạ một số cổng từ vùng chứa sang máy cục bộ để truy cập mọi thứ chạy bên trong nó.

Vì vậy, đối với docker-compose.ymltệp của bạn, bạn sẽ muốn bắt đầu dòng đầu tiên như vậy:

version: '3'

Điều đó cho Docker biết phiên bản docker-composebạn muốn sử dụng. Sau đó, bạn phải thêm:

version: '3'
services: 
  redis-server: 
    image: 'redis'
  node-app:
    build: .

Xin lưu ý các vết lõm, rất quan trọng. Ngoài ra, thông báo cho một dịch vụ tôi đang lấy một hình ảnh, nhưng đối với một dịch vụ khác tôi đang nói docker-composehãy nhìn vào bên trong thư mục hiện tại để xây dựng hình ảnh sẽ được sử dụng cho container thứ hai.

Sau đó, bạn muốn chỉ định tất cả các cổng khác nhau mà bạn muốn mở trên container này.

version: '3'
services: 
  redis-server: 
    image: 'redis'
  node-app:
    build: .
    ports:
      -

Xin lưu ý dấu gạch ngang, dấu gạch ngang trong tệp yaml là cách chúng tôi chỉ định một mảng. Trong ví dụ này, tôi ánh xạ 8081trên máy cục bộ của mình 8081vào container như vậy:

version: '3'
services: 
  redis-server: 
    image: 'redis'
  node-app:
    build: .
    ports:
      - "8081:8081"

Vì vậy, cổng đầu tiên là máy cục bộ của bạn và cổng còn lại là cổng trên container, bạn cũng có thể phân biệt giữa hai cổng để tránh nhầm lẫn như vậy:

version: '3'
services:
  redis-server:
    image: 'redis'
  node-app:
    build: .
    ports:
      - "4001:8081"

Bằng cách phát triển docker-compose.ymltệp của bạn như thế này, nó sẽ tạo ra các thùng chứa trên cùng một mạng và họ sẽ có quyền truy cập miễn phí để liên lạc với nhau theo bất kỳ cách nào họ muốn và trao đổi nhiều thông tin như họ muốn.

Khi hai container được tạo bằng cách sử dụng, docker-composechúng tôi không cần bất kỳ khai báo cổng nào.

Bây giờ trong ví dụ của tôi, chúng ta cần thực hiện một số cấu hình mã trong ứng dụng Nodejs trông giống như thế này:

const express = require('express');
const redis = require('redis');

const app = express();
const client = redis.createClient({
  host: 'redis-server'
});

Tôi sử dụng ví dụ này ở trên để làm cho bạn biết rằng có thể có một số cấu hình cụ thể mà bạn sẽ phải thực hiện ngoài docker-compose.ymltệp có thể dành riêng cho dự án của bạn.

Bây giờ, nếu bạn thấy mình làm việc với ứng dụng Nodejs và bạn muốn đảm bảo rằng bạn biết về cổng mặc định mà Nodejs sử dụng, vì vậy tôi sẽ thêm điều này:

const express = require('express');
const redis = require('redis');

const app = express();
const client = redis.createClient({
  host: 'redis-server',
  port: 6379
});

Vì vậy, Docker sẽ thấy rằng ứng dụng Node đang tìm kiếm redis-servervà chuyển hướng kết nối đó đến container đang chạy này.

Toàn bộ thời gian, Dockerfilechỉ có điều này:

FROM node:alpine

WORKDIR '/app'

COPY /package.json ./
RUN npm install
COPY . .

CMD ["npm", "start"]

Vì vậy, trong khi trước khi bạn phải chạy docker run myimageđể tạo một phiên bản của tất cả các vùng chứa hoặc dịch vụ bên trong tệp bạn có thể chạy docker-compose upvà bạn không phải chỉ định hình ảnh vì Docker sẽ tìm trong thư mục làm việc hiện tại và tìm docker-compose.ymltập tin bên trong đó.

Trước đây docker-compose.yml, chúng tôi đã phải đối phó với hai lệnh riêng biệt docker build .docker run myimage, nhưng docker-composetrên thế giới nếu bạn muốn xây dựng lại hình ảnh của mình, bạn viết docker-compose up --build. Điều đó nói với Docker khởi động lại các container nhưng xây dựng lại để có những thay đổi mới nhất.

Vì vậy, docker-composelàm cho nó dễ dàng hơn để làm việc với nhiều container. Lần tới khi bạn cần bắt đầu nhóm container này trong nền bạn có thể làm docker-compose up -dvà để ngăn chặn chúng, bạn có thể làm docker-compose down.

|
3

Dockerfiles là để xây dựng một hình ảnh ví dụ từ Ubuntu xương trần, bạn có thể thêm mysqlđược gọi mySQLtrên một hình ảnh và mywordpresstrên một hình ảnh thứ hai được gọi mywordpress.

Soạn các tệp YAML là để chụp những hình ảnh này và chạy chúng một cách cố kết. ví dụ: nếu bạn có trong docker-compose.ymltệp của mình một cuộc gọi dịch vụ db:

services:
   db:
     image: mySQL  --- image that you built.

và một dịch vụ được gọi là worpress, chẳng hạn như:

wordpress: 
    image: mywordpress

sau đó bên trong bộ chứa mywordpress bạn có thể sử dụng dbđể kết nối với bộ chứa myQuery của bạn. Điều kỳ diệu này là có thể bởi vì máy chủ docker của bạn tạo ra một cầu nối mạng (lớp phủ mạng).

|

Câu trả lời của bạn (> 20 ký tự)

Bằng cách click "Đăng trả lời", bạn đồng ý với Điều khoản dịch vụ, Chính sách bảo mật and Chính sách cookie của chúng tôi.

Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ hoặc hỏi câu hỏi của bạn.