В чем разница между Docker Compose и Dockerfile

Я читал и узнавал о Docker и пытаюсь правильно выбрать настройку Django для использования. Пока есть либо:

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

person Aaron Lelevier    schedule 06.04.2015    source источник
comment
Вопрос лучше было бы сформулировать так: «Должен ли я запускать свое приложение как один или несколько контейнеров?» Кажется, это зависит от того, что следует учитывать вопросы масштабирования и разделения задач (один контейнер на службу). Это может помочь: использовать отдельные контейнеры докеров для моего веб-приложения"> stackoverflow.com/questions/30534939/ и quora.com/< /а>   -  person Fabien Snauwaert    schedule 29.04.2017
comment
Установите docker-compose, запустив ''' apt install python3 pip3 && pip3 uninstall docker-compose && pip3 install docker-compose, и при такой установке нет общих проблем   -  person Kayvan Nouredin    schedule 13.11.2020


Ответы (11)


Ответ - ни то, ни другое.

Docker Compose (далее compose) будет использовать Dockerfile, если вы добавите команду сборки в файл docker-compose.yml вашего проекта.

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

Вы можете указать путь к своим отдельным файлам Dockerfile, используя build /path/to/dockerfiles/blah, где /path/to/dockerfiles/blah — это место, где живет Dockerfile бла.

person booyaa    schedule 07.04.2015
comment
вы используете docker-compose в производстве или только в разработке? Спасибо за вашу помощь. - person Aaron Lelevier; 07.04.2015
comment
@booyaa Не могли бы вы уточнить это? - person Martin Thoma; 11.07.2017
comment
Спасибо за ответ! Dockerfile указывает конфигурацию для изображения, а docker-compose.yml собирает изображения вместе. Я хочу отметить одну вещь: если docker-compose.yml использовать только общедоступный образ (извлекая образ из Интернета/концентратора докеров), то он не нужен Dockerfile для запуска команды docker-compose up. - person Oldyoung; 17.09.2019

Докерфайл

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

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

  • — это инструмент для определения и запуска многоконтейнерных приложений 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: {}
person cyb3rZ    schedule 07.08.2017
comment
@sg ответ заключается в том, что вопрос неправильно сформулирован из-за непонимания Docker и Docker Compose. Кратко объяснить, как они взаимодействуют, вероятно, лучший ответ, который я могу придумать. - person mpowered; 30.08.2017
comment
Я понятия не имею, почему этой точной разбивки нет на домашней странице Docker. Спасибо. - person codykochmann; 11.03.2018
comment
Я вижу, что такого рода документы отсутствуют в самых последних выпущенных инструментах/решениях/фреймворках в Интернете. Я думаю, трудно понять, зачем это кому-то нужно, если вы уже знаете/изобрели решение самостоятельно. - person Peter Branforn; 18.03.2018
comment
Чего не хватает в этом ответе, так это дополнительной информации о составлении. Вызывает ли сценарий создания файла dockerfile? Откуда он знает, что сочинять? В примере показано image: redis, но это из dockerhub? локальный каталог? и т.д... это сбивает с толку такого новичка, как я, чтобы понять, что на самом деле происходит - person Joe Phillips; 21.03.2018
comment
Этот ответ настаивает на многоконтейнерной цели docker compose, но, вероятно, есть много других сценариев, в которых вы хотите использовать docker compose даже с одним контейнером, например, указать порт, на котором вы хотите запустить свой контейнер (невозможно в dockerfile afaik). - person Pansoul; 16.05.2019
comment
@omidrezabagheri ваше редактирование переместило объявление logvolume01 внутрь службы redis, что привело к недопустимой конфигурации. Если вы не знакомы с объявлениями томов за пределами определений служб, взгляните на: docs.docker.com/compose/compose-file/ Возможно, вы захотите отменить это изменение. - person kalehmann; 14.08.2019
comment
Создает ли docker-compose динамические «вытягивание докеров» и «запуск докеров» и т. д. для запуска службы? - person Satish Patro; 17.03.2021

docker-compose существует, чтобы вам не приходилось писать массу команд, которые вам пришлось бы делать с docker-cli.

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

Цель docker-compose — функционировать как docker cli, но гораздо быстрее выполнять несколько команд.

Чтобы использовать docker-compose, вам нужно закодировать команды, которые вы запускали ранее, в файл docker-compose.yml.

Вы же не будете просто копипастить их в yaml файл, там специальный синтаксис.

После создания вы должны передать его в cli docker-compose, и cli должен будет проанализировать файл и создать все различные контейнеры с правильной конфигурацией, которую мы укажем.

Таким образом, у вас будут отдельные контейнеры, скажем, один — 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 и Redis, вы хотите убедиться, что знаете, какой порт по умолчанию использует Nodejs, поэтому я добавлю это:

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

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

Таким образом, Docker увидит, что приложение 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.

person Daniel    schedule 21.12.2018
comment
@Chris Как будто между этим и принятым ответом есть 3 года знаний. - person Naruto Sempai; 31.01.2019
comment
Интересно, есть ли у меня веская причина использовать docker-compose up хотя бы одну услугу в моей ситуации? Другое слово, сравните с docker run xxx, какая польза от использования docker-compose up? - person atline; 02.09.2019
comment
@atline см. ответ Pansoul на stackoverflow.com/a/45549372/3366962 о преимуществах использования docker-compose для отдельных контейнеров. - person go2null; 28.10.2019
comment
Если вы подключаете локальную машину и контейнер через порт 4001, почему вы можете подключить Redis через порт 6379? Или дело в том, что внутри приложения узла вы уже находитесь в контейнере и вызываете сервер Redis из контейнера? - person Paul Razvan Berg; 23.11.2019
comment
@PaulRazvanBerg ваша часть Или верна (а 6379 — это порт Redis по умолчанию). - person KrishPrabakar; 07.02.2020
comment
Примеры для docker-compose.yml помогли мне ответить на некоторые вопросы о docker-compose. Принятый ответ бесполезен, особенно для новичков в докере. - person maulik13; 24.03.2020
comment
О, Ман, ты должен заслужить принятый ответ... кристально ясное объяснение. Благодаря тонну. - person Vishnu; 25.07.2020

Файл компоновки Docker — это способ декларативно организовать запуск нескольких контейнеров, а не запускать каждый файл Docker отдельно с помощью сценария bash, который был бы намного медленнее и сложнее в отладке.

Однако большую часть времени вы будете использовать Dockerfiles с Kubernetes вместо Docker compose в производственной среде, поскольку Kubernetes значительно упрощает автоматизацию развертывания (самовосстановление, откаты, балансировка нагрузки и т. д.). Docker compose больше подходит для локального тестирования.

person Peeter Kokk    schedule 12.07.2016
comment
Спасибо, что подняли этот вопрос. Не могли бы вы добавить еще кое-что из того, что было исправлено для безопасности производства в версии 1.11? - person M A Hossain Tonu; 07.11.2017

Dockerfile и Docker Compose — это две разные концепции в Dockerland. Когда мы говорим о Docker, первое, что приходит на ум, — это оркестровка, виртуализация на уровне ОС, образы, контейнеры и т. д. Я попытаюсь объяснить каждое из них следующим образом:

Изображение. Образ — это неизменяемый общедоступный файл, который хранится в доверенном реестре Docker. Образ Docker состоит из серии слоев, доступных только для чтения. Каждый уровень представляет собой инструкцию, которая задается в Dockerfile образа. Образ содержит все необходимые двоичные файлы для запуска.

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

Контейнер. Экземпляр изображения называется контейнером. Контейнер — это просто исполняемый двоичный файл образа, который должен запускаться основной ОС. Работающий образ — это контейнер.

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

Dockerfile: Dockerfile – это текстовый документ, содержащий все команды/инструкции по сборке, которые пользователь может вызывать из командной строки для сборки образа. Это будет сохранено как Dockerfile. (Обратите внимание на строчную букву «f».)

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

Docker-Compose. Compose — это инструмент для определения и запуска многоконтейнерных приложений Docker. С Compose вы используете файл YAML для настройки служб вашего приложения (контейнеров). Затем с помощью одной команды вы создаете и запускаете все службы из вашей конфигурации. Файл Compose будет сохранен как docker-compose.yml.

person Waqas Ahmed    schedule 04.09.2019

В моем рабочем процессе я добавляю Dockerfile для каждой части моей системы и настраиваю его так, чтобы каждая часть могла работать отдельно. Затем я добавляю файл docker-compose.yml, чтобы объединить их и связать.

Самое большое преимущество (на мой взгляд): при связывании контейнеров можно определить имя и пинг ваши контейнеры с этим именем. Поэтому ваша база данных может быть доступна по имени db, а не по IP-адресу.

person n2o    schedule 29.08.2016
comment
Не могли бы вы подробнее рассказать о доступе к БД по имени? - person Wexoni; 07.06.2018
comment
В какой части? В docker-compose это тривиально, потому что это обычный способ при определении ваших сервисов дать ему имя и сделать его доступным без необходимости его настройки. В нашем CI я создаю сеть, создаю контейнер в этой сети и даю им имя. Затем они также доступны по имени внутри контейнеров (не с хоста) - person n2o; 07.06.2018
comment
В композиторе я имею в виду. Итак, я связываю изображения в композиторе, а в конфигурации моего приложения вместо IP я нацеливаю MySQL на любое имя, которое я дал ему в файле композитора? - person Wexoni; 07.06.2018
comment
Это правильно. Вам даже не нужно указывать ссылку. Они связаны по умолчанию, если сеть не указана иначе. В этом примере веб-служба может пинговать узел redis по его имени redis - person n2o; 10.06.2018

лучше относительно. Все зависит от ваших потребностей. Docker compose предназначен для организации нескольких контейнеров. Если эти образы уже существуют в реестре докеров, то лучше перечислить их в файле компоновки. Если эти образы или какие-то другие образы должны быть собраны из файлов на вашем компьютере, вы можете описать процессы сборки этих образов в Dockerfile.

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

Использование нескольких FROM в одном dockerfile — не очень хорошая идея, потому что есть предложение удалить эту функцию. 13026

Если, например, вы хотите докеризовать приложение, которое использует базу данных и имеет файлы приложения на вашем компьютере, вы можете использовать файл компоновки вместе с файлом докеры следующим образом.

докер-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
person Akongnwi Devert    schedule 25.09.2018

Представьте, что вы менеджер компании-разработчика программного обеспечения и только что купили новый сервер. Только оборудование.

Думайте о Dockerfile как о наборе инструкций, которые вы сообщаете своему системному администратору, что нужно установить на этот совершенно новый сервер. Например:

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

Напротив, думайте о docker-compose.yml как о наборе инструкций, которые вы должны сообщить своему системному администратору, как сервер может взаимодействовать с остальным миром. Например,

  • имеет доступ к общей папке с другого компьютера,
  • его порт 80 совпадает с портом 8000 хост-компьютера,
  • и так далее.

(Это не точное объяснение, но достаточно хорошее для начала.)

person Csongor Halmai    schedule 04.07.2019

Файлы Docker предназначены для создания образа, например, из голой кости Ubuntu, вы можете добавить mysql с именем mySQL на одно изображение и mywordpress на второе изображение с именем mywordpress.

Составление файлов YAML состоит в том, чтобы брать эти изображения и запускать их вместе. Например, если в вашем файле docker-compose.yml есть служба с именем db:

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

и служба под названием wordpress, например:

wordpress: 
    image: mywordpress

затем внутри контейнера mywordpress вы можете использовать db для подключения к контейнеру mySQL. Это волшебство возможно, потому что ваш хост-докер создает сетевой мост (наложение сети).

person Hugo R    schedule 14.08.2018

В мире микросервисов (с общей общей кодовой базой) каждый микросервис будет иметь Dockerfile, тогда как на корневом уровне (как правило, за пределами всех микросервисов и там, где находится ваш родительский POM) вы должны определить docker-compose.yml для группировки всех микросервисов в полноценное приложение. .

В вашем случае «Docker Compose» предпочтительнее «Dockerfile». Думайте "Приложение" Думайте "Создайте".

person KrishPrabakar    schedule 07.02.2020

Dockerfile — это файл, содержащий текстовые команды для сборки образа.

Docker compose используется для запуска многоконтейнерной среды.

В вашем конкретном сценарии, если у вас есть несколько сервисов для каждой упомянутой вами технологии (сервис 1 с использованием reddis, сервис 2 с использованием Rabbit mq и т. д.), вы можете иметь файл Dockerfile для каждого из сервисов и общий docker-compose.yml для запуска все «Dockerfile» как контейнеры.

Если вы хотите, чтобы все они были в одном сервисе, docker-compose будет подходящим вариантом.

person Mudassir Shahzad    schedule 08.05.2020