Docker Compose проти Dockerfile - що краще?


384

Я читав і дізнавався про Докера , і намагаюся правильно вибрати налаштування Джанго. Поки є або:

Docker Compose або Dockerfile

Я розумію, що Dockerfilesвикористовуються в Docker Compose, але я не впевнений, чи є хорошою практикою розміщувати все в один великий Dockerfile з декількома FROMкомандами для різних зображень?

Я хочу використовувати кілька різних зображень, які включають:

uwsgi
nginx
postgres
redis
rabbitmq
celery with cron

Будь ласка, порадьте, які найкращі практики створення цього типу середовища за допомогою Docker .

Якщо це допомагає, я на Mac, тому використовую boot2docker .

Деякі проблеми у мене були:

  1. Docker Compose не сумісний із Python3
  2. Я хочу скласти контейнерний проект, тому якщо один великий Dockerfile не є ідеальним, я вважаю, що мені потрібно розбити його за допомогою Docker Compose
  3. Я все в порядку, щоб зробити проект Py2 & Py3 сумісним, тому я схиляюся до django-compose

5
Справу було б краще викласти так: "Чи слід запускати додаток як один або кілька контейнерів?" Здається, це залежить, і питання масштабування та розділення проблем (один контейнер на послугу) слід враховувати. Це може допомогти: stackoverflow.com/questions/30534939 / ... і quora.com / ...
Фаб'єн Snauwaert

Офіційні документи Docker "Початок роботи" .
jchook

Відповіді:


238

Відповідь - ні.

Docker Compose (тут позначається як compose) використовуватиме Dockerfile, якщо ви додасте команду build до проекту docker-compose.yml .

У вашому робочому процесі Docker має бути створено відповідне Dockerfileдля кожного зображення, яке ви хочете створити, а потім використовуйте buildкоманду compose для складання зображень за допомогою команди.

Ви можете вказати шлях до ваших індивідуальних Dockerfiles, скориставшись build /path/to/dockerfiles/blahде життям /path/to/dockerfiles/blahбла Dockerfile.


10
ви використовуєте docker-composeу виробництві чи лише розробники? Спасибі за вашу допомогу.
Аарон Лелев'є

18
@booyaa Чи можете ви, будь ласка, детальніше розглянути це?
Мартін Тома

2
Дякую за відповідь! Dockerfile вкажіть конфігурацію для зображення, а docker-compose.yml збирайте зображення разом. Одне, що я хочу зазначити, це те, що якщо docker-compose.ymlвикористовувати лише загальнодоступне зображення (витягування зображення з Інтернету / док-хабу), то не потрібно Dockerfile для запуску команди docker-compose up.
Oldyoung

549

Докерфайл

введіть тут опис зображення

Dockerfile - це простий текстовий файл, який містить команди, які користувач може викликати для складання зображення.

Приклад, 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 Compose

введіть тут опис зображення

Docker Compose

  • є інструментом для визначення та запуску багатоконтейнерних програм Docker.

  • визначте сервіси, які складають вашу програму, docker-compose.ymlщоб вони могли працювати разом в ізольованому середовищі.

  • просто запустіть додаток, що працює в одній команді docker-compose up

Наприклад, docker-compose.yml

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

43
@sg відповідь полягає в тому, що питання неправильно формується на основі нерозуміння Докер проти Докер Композит. Коротко пояснення того, як вони взаємодіють - це, мабуть, найкраща відповідь, яку я можу придумати.
mpowered

53
Я поняття не маю, чому ця точна розбивка не знаходиться на домашній сторінці Докера. Дякую.
codykochmann

4
Я бачу, що такого роду документи відсутні в останніх випущених інструментах / рішеннях / рамках в Інтернеті. Я думаю, важко зрозуміти, навіщо комусь це потрібно, якщо ви вже знаєте / винайшли рішення.
Пітер Бранфорн

36
Чого не вистачає в цій відповіді, це більше інформації про композицію. Чи пише сценарій складання докерфайлу? Як воно знає, що скласти? Приклад показує, image: redisале це від dockerhub? локальний каталог? і т. д ... це робить заплутаним для новонародженого, як я, щоб зрозуміти, що відбувається насправді
Джо Філіпс,

5
Ця відповідь наполягає на багатоконтейнерній цілі docker compose, але, ймовірно, існує багато інших сценаріїв, які ви хочете використовувати docker compose навіть лише з одним контейнером, наприклад, вказуючи порт, на якому потрібно працювати ваш контейнер (неможливо в dockerfile afaik).
Пансул

99

Файл Compose описує контейнер у його робочому стані , залишаючи деталі про те, як скласти контейнер до Dockerfiles . http://deninet.com/blog/1587/docker-scratch-part-4-compose-and-volumes

Коли ви визначаєте додаток із Compose у розробці, ви можете використовувати це визначення для запуску програми в різних середовищах, таких як CI, постановка та виробництво . https://docs.docker.com/compose/production/

Також здається, що Compose вважається виробництвом безпечним з 1.11 , оскільки https://docs.docker.com/v1.11/compose/production/ більше не має попередження не використовувати його у виробництві, як https: // docs .docker.com / v1.10 / композиція / виробництво / робить.


1
Дякуємо, що вирішили проблему. Чи можете ви, будь ласка, додати ще трохи того, що було визначено для безпеки виробництва у 1.11?
М. А. Хоссайн Тону

92

docker-compose існує для того, щоб вам не довелося писати багато команд, які вам доведеться виконати з docker-cli.

docker-compose також спрощує запуск декількох контейнерів одночасно та автоматично з'єднує їх разом із деякою формою мереж.

Мета docker-compose - функціонувати як docker cli, але набагато швидше видавати кілька команд.

Щоб використовувати docker-compose, вам потрібно кодувати команди, які ви виконували раніше, у docker-compose.ymlфайл.

Ви не просто збираєтесь скопіювати вставити їх у файл yaml, є спеціальний синтаксис.

Після створення ви повинні подати його до док-композиційного кліпу, і кліп повинен буде розібрати файл і створити всі різні контейнери з правильною конфігурацією, яку ми задаємо.

Отже, у вас будуть окремі контейнери, скажімо, наприклад, один є, redis-serverа другий є, node-appі ви хочете, що створено за допомогою Dockerfileу вашому поточному каталозі.

Крім того, зробивши цей контейнер, ви зіставите порт із контейнера на локальну машину, щоб отримати доступ до всього, що працює всередині нього.

Отже, для вашого docker-compose.ymlфайлу ви хочете почати перший рядок так:

version: '3'

Це повідомляє Docker версію, docker-composeяку ви хочете використовувати. Після цього потрібно додати:

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

Зверніть увагу на відступ, дуже важливий. Також зауважте, що для однієї служби я захоплюю зображення, але для іншої послуги я кажу docker-composeзаглянути всередину поточного каталогу, щоб створити зображення, яке буде використано для другого контейнера.

Потім ви хочете вказати всі різні порти, які ви хочете відкрити на цьому контейнері.

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

Зауважте, тире, тире у файлі yaml - це те, як ми визначаємо масив. У цьому прикладі я зіставляю 8081свою локальну машину 8081з контейнером так:

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

Отже, перший порт - це ваша локальна машина, а другий - порт на контейнері, ви також можете розрізняти два, щоб уникнути плутанини на зразок:

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

Розвиваючи такий docker-compose.ymlфайл, він створить ці контейнери по суті одній і тій же мережі, і вони матимуть вільний доступ для спілкування один з одним будь-яким способом, яким вони захочуть, та обміном інформацією, скільки вони захочуть.

Коли два контейнери створені за допомогою, docker-composeнам не потрібні декларації портів.

Тепер у моєму прикладі нам потрібно зробити конфігурацію коду в додатку Nodejs, який виглядає приблизно так:

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

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

Я використовую цей приклад вище, щоб зрозуміти, що може бути певна конфігурація, яку вам доведеться зробити додатково до docker-compose.yml файлу, який може бути специфічним для вашого проекту.

Тепер, якщо ви коли-небудь опинитеся на роботі з додатком Nodejs і перепрофілюєте, ви хочете переконатися, що ви знаєте про порт за замовчуванням, який використовує Nodejs, і я додам це:

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

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

Тож Докер побачить, що шукає додаток Node redis-server і перенаправляє це з'єднання на цей запущений контейнер.

Весь час, Dockerfileєдине містить це:

FROM node:alpine

WORKDIR '/app'

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

CMD ["npm", "start"]

Отже, тоді як перед тим, як вам доведеться запустити, docker run myimageстворити екземпляр усіх контейнерів або служб всередині файлу, який ви можете замість цього запустити, docker-compose upі вам не потрібно вказувати зображення, оскільки Docker буде шукати в поточній робочій директорії і шукатиdocker-compose.yml файл всередині.

Раніше docker-compose.ymlнам доводилося мати справу з двома окремими командами docker build .та docker run myimage, але у docker-composeсвіті, якщо ви хочете відновити свої написані вами зображення docker-compose up --build. Це говорить Docker знову запускати контейнери, але відновлювати його, щоб отримати останні зміни.

Так що docker-composeполегшує роботу з декількома контейнерами. Наступного разу, коли вам потрібно запустити цю групу контейнерів у фоновому режимі, яку ви можете зробити, docker-compose up -dі зупинити їх, ви можете це зробити docker-compose down.


13
@Chris Це майже так, якби між цим та прийнятою відповіддю є знання, які варті 3 років.
Наруто Семпай

Цікаво, чи є якась вагома причина для мене, docker-compose upякщо в моїй ситуації є лише одна послуга? Ще одне слово, порівняйте docker run xxx, будь-яка вигода, якщо я використовую docker-compose up?
атлін

@atline см реакції Pansoul, щоб stackoverflow.com/a/45549372/3366962 про переваги використанняdocker-compose для окремих контейнерів
go2null

1
@PaulRazvanBerg, ви "Або" частина правильна (і 6379є портом Redis за замовчуванням).
KrishPrabakar

1
Приклади docker-compose.yml допомогли мені відповісти на деякі питання, які я мав щодо docker-compose. Прийнята відповідь не корисна, особливо людям, які не знайшли докерів.
maulik13

43

У своєму робочому процесі я додаю Dockerfile для кожної частини моєї системи та конфігурую її так, щоб кожна частина могла працювати окремо. Потім я додаю docker-compose.yml, щоб об'єднати їх і зв’язати.

Найбільша перевага (на мою думку): коли пов'язуванні контейнерів ви можете визначити ім'я та пінг ваших контейнерів з цим ім'ям. Тому ваша база даних може бути доступною з ім'ям, dbа не через IP-адресу.


Чи можете ви детальніше розглянути питання про доступ до db за назвою?
Ведран Марічевич.

На якій частині? У docker-compose це тривіально, тому що це звичайний спосіб визначення ваших служб, щоб дати йому ім’я та мати його доступним, не потребуючи його налаштування. У нашому КІ я створюю мережу, створюю контейнер у цій мережі і даю їм ім’я. Тоді вони також доступні за їх іменем всередині контейнерів (не від хоста)
n2o

Я маю на увазі композитор. Отже, я пов'язую зображення в композиторі та в моєму конфігурації додатків замість IP, я орієнтуюся на MySQL за будь-яким ім'ям, яке я дав у файлі композитора?
Ведран Марічевич.

Це правильно. Вам навіть не потрібно вказувати посилання. Вони пов'язані за замовчуванням, якщо мережа не визначена по-іншому. У цьому прикладі сервіс "web" може пінг-хосту "redis" за назвою "redis"
n2o

37

"краще" відносне. Все залежить від ваших потреб. Докер композиція призначена для оркестрування декількох контейнерів. Якщо ці зображення вже є в реєстрі докера, то краще перелічити їх у складеному файлі. Якщо ці зображення чи деякі інші зображення повинні бути побудовані з файлів на вашому комп'ютері, ви можете описати процеси складання цих зображень у Dockerfile.

Я розумію, що Dockerfiles використовуються в Docker Compose, але я не впевнений, чи є хорошою практикою розміщувати все в один великий Dockerfile з кількома командами FROM для різних зображень?

Використання декількох FROM в одному dockerfile - не дуже гарна ідея, оскільки є пропозиція видалити функцію. 13026

Якщо, наприклад, ви хочете докерізувати програму, яка використовує базу даних та файли додатків на вашому комп'ютері, ви можете використовувати композиційний файл разом із докерфайлом, як описано нижче.

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

Докерфайл

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

30

Dockerfile і Docker Compose - це дві різні концепції в Докерленді. Коли ми говоримо про Докера, першими, що спадають на думку, є оркестрація, віртуалізація на рівні ОС, зображення, контейнери тощо. Я спробую пояснити кожне так:

Зображення: Зображення - це незмінний, доступний для доступу файл, який зберігається в реєстрі Докер-надійного. Зображення Докера складається з серії шарів, доступних лише для читання. Кожен шар являє собою інструкцію, яка подається в Dockerfile зображення. Зображення містить усі необхідні бінарні файли для запуску.

введіть тут опис зображення

Контейнер: Екземпляр зображення називається контейнером . Контейнер - це лише двійковий файл зображення, який повинен управляти хост-операцією. Виконане зображення - це контейнер.

введіть тут опис зображення

Dockerfile: Dockerfile - це текстовий документ, який містить усі команди / інструкції побудови, користувач може зателефонувати в командному рядку, щоб зібрати зображення. Це буде збережено як Dockerfile. (Зверніть увагу на малі "f".)

введіть тут опис зображення

Docker-Compose: Compose - це інструмент для визначення та запуску багатоконтейнерних програм Docker. За допомогою Compose ви використовуєте файл YAML для налаштування послуг (контейнерів) програми. Потім за допомогою однієї команди ви створюєте та запускаєте всі служби зі своєї конфігурації. Файл Compose буде збережено якdocker-compose.yml .


14

Уявіть, що ви менеджер програмної компанії, і ви щойно купили новий сервер. Просто апаратне забезпечення.

Розгляньте Dockerfileяк набір інструкцій, які б ви сказали своєму системному адміністратору, що потрібно встановити на цьому абсолютно новому сервері. Наприклад:

  • Нам потрібен Linux Debian
  • додати веб-сервер apache
  • нам також потрібен postgresql
  • встановити командира опівночі
  • коли все готово, скопіюйте всі файли * .php, * .jpg тощо. у веб-сервер веб-сервера ( /var/www)

Навпаки, подумайте docker-compose.ymlяк про набір інструкцій, які б ви сказали своєму системному адміністратору, як сервер може взаємодіяти з рештою світу. Наприклад,

  • він має доступ до спільної папки з іншого комп’ютера,
  • його порт 80 такий же, як порт 8000 хост-комп'ютера,
  • і так далі.

(Це не точне пояснення, але досить добре для початку.)


4

Докерфіли - це побудова зображення, наприклад, з голої кістки Ubuntu, ви можете додати mysqlпокликане mySQLна одне зображення, а mywordpressна друге зображення, що називається mywordpress.

Складіть YAML-файли, щоб зробити ці зображення та запустити їх злагоджено. наприклад, якщо у вашому docker-compose.ymlфайлі є службовий дзвінок db:

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

і послуга під назвою worpress, наприклад:

wordpress: 
    image: mywordpress

то всередині контейнера mywordpress, який ви можете використовувати dbдля підключення до свого контейнера mySQL. Ця магія можлива тому, що ваш хокер докера створює мережевий міст (мережеве накладання).


0

У світі мікросервісів (маючи спільну спільну кодову базу) кожна мікросервіс мала б Dockerfileа на кореневому рівні (як правило, поза всіма мікросервісами та де мешкає ваш батьківський POM), ви визначили бdocker-compose.yml щоб згрупувати всі мікросервіси у повномасштабну програму.

У вашому випадку "Docker Compose" надається перевагу "Dockerfile". Подумайте "Додаток" Подумайте "Створити".


0

Dockerfile - це файл, який містить текстові команди для збирання зображення.

Docker compose використовується для запуску середовища з декількома контейнерами.

У вашому конкретному сценарії, якщо у вас є кілька сервісів для кожної згаданих технологій (сервіс 1 за допомогою reddis, сервіс 2 за допомогою mq кролика тощо), ви можете мати Dockerfile для кожної з служб і загальний docker-compose.yml для запуску всі "Dockerfile" як контейнери.

Якщо ви хочете, щоб усі вони були в одній службі, докер-композиція стане життєздатним варіантом.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.