Docker Compose 与 Dockerfile 之间有什么区别

What's the difference between Docker Compose vs. Dockerfile

我一直在阅读和学习 Docker,并且正在尝试正确选择要使用的 Django 设置。到目前为止有:

Docker Compose or Dockerfile

我知道 Dockerfiles 用于 Docker Compose,但我不确定是否最好将所有内容放在一个大 Docker 文件中,并针对不同的图像使用多个 FROM 命令?

我想使用几个不同的图像,包括:

uwsgi
nginx
postgres
redis
rabbitmq
celery with cron

请告知使用 Docker.

设置此类环境的最佳做法是什么

如果有帮助,我在 Mac,所以使用 boot2docker

我遇到的一些问题:

  1. Docker Compose 与 Python3
  2. 不兼容
  3. 我想将我的项目容器化,所以如果一个大的 Docker 文件 不理想,然后我觉得我需要使用 Docker Compose
  4. 将其分解
  5. 我可以让项目 Py2 和 Py3 兼容,所以我倾向于 django-compose

答案都不是。

Docker 如果您将构建命令添加到项目的 docker-compose.yml,Compose(此处简称为 compose)将使用 Docker 文件。

您的 Docker 工作流程应该是为您希望创建的每个图像构建合适的 Dockerfile,然后使用 assemble 使用 build 命令合成图像.

您可以使用 build /path/to/dockerfiles/blah 指定个人 Docker 文件的路径,其中 /path/to/dockerfiles/blah 是 blah 的 Dockerfile 所在的位置。

Docker 组合文件是一种声明式编排多个容器启动的方式,而不是 运行 每个 Docker 文件分别使用 bash 脚本,这样写起来会慢得多,调试起来也更难。

在我的工作流程中,我为系统的每个部分添加了一个 Dockerfile,并将其配置为每个部分都可以 运行 单独。然后我添加一个 docker-compose.yml 将它们放在一起并 link 它们。

最大的优势(在我看来):当linking the containers时,你可以定义一个名字并用这个名字来ping你的容器。因此,您的数据库可能可以通过名称 db 而不再通过其 IP 访问。

Docker文件

Docker文件是一个简单的文本文件,其中包含用户可以对assemble图像调用的命令。

例如,Docker文件

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 应用程序的工具。

  • docker-compose.yml 中定义构成您的应用程序的服务,这样它们就可以 运行 在一个孤立的环境中。

  • 仅需 运行ning docker-compose up

    即可在一条命令中获取应用程序 运行ning

例如,docker-compose.yml

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

Dockerfiles 是用来构建一个镜像的,例如从裸机 Ubuntu,你可以在一个镜像上添加名为 mySQLmysql,在第二个镜像上添加 mywordpress称为 mywordpress.

编写 YAML 文件是为了获取这些图像并将它们 运行 结合起来。 例如,如果您的 docker-compose.yml 文件中有一个名为 db:

的服务
services:
   db:
     image: mySQL  --- image that you built.

和一个名为 wordpress 的服务,例如:

wordpress: 
    image: mywordpress

然后在 mywordpress 容器中,您可以使用 db 连接到您的 mySQL 容器。这个魔法是可能的,因为你的 docker 主机创建了一个网桥(网络覆盖)。

“更好”是相对的。这完全取决于您的需求。 Docker compose 用于编排多个容器。如果这些图像已经存在于 docker 注册表中,那么最好将它们列在撰写文件中。如果必须从您计算机上的文件构建这些图像或其他一些图像,那么您可以在 Docker 文件中描述构建这些图像的过程。

I understand that Dockerfiles are used in Docker Compose, but I am not sure if it is good practice to put everything in one large Dockerfile with multiple FROM commands for the different images?

在单个 docker 文件中使用多个 FROM 不是一个好主意,因为有人提议删除该功能。 13026

例如,如果您想要 docker 化一个使用数据库的应用程序并且在您的计算机上有应用程序文件,您可以将一个 compose 文件与一个 docker 文件一起使用,如下所示

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
      

Docker文件

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

docker-compose 的存在是为了让您不必编写大量使用 docker-cli 必须编写的命令。

docker-compose 还可以轻松地同时启动多个容器,并通过某种形式的网络自动将它们连接在一起。

docker-compose 的目的是用作 docker cli,但可以更快地发出多个命令。

要使用 docker-compose,您需要将之前 运行ning 的命令编码到 docker-compose.yml 文件中。

您不只是将它们复制粘贴到 yaml 文件中,这里有一个特殊的语法。

创建后,您必须将其提供给 docker-compose cli,然后由 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 并将该连接重定向到此 运行ning 容器。

一直以来,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.

假设您是一家软件公司的经理,您刚刚购买了一台全新的服务器。只是硬件。

Dockerfile 视为一组说明,您将告诉您的系统管理员要在这个全新的服务器上安装什么。例如:

  • 我们需要一个 Debian linux
  • 添加 apache 网络服务器
  • 我们也需要 postgresql
  • 安装午夜指挥官
  • 全部完成后,将我们项目的所有*.php、*.jpg等文件复制到webserver的webroot中(/var/www)

相比之下,将 docker-compose.yml 视为一组指令,您将告诉您的系统管理员 服务器如何与世界其他部分交互。例如,

  • 它可以从另一台计算机访问共享文件夹,
  • 它的80端口与上位机的8000端口相同,
  • 等等。

(这不是一个精确的解释,但足以作为开始。)

Docker文件和Docker撰写在Docker领域是两个不同的概念。当我们谈论Docker时,首先想到的是编排、OS级虚拟化、图像、容器等。我将尝试解释如下:

图片: 图像是一种不可变的、可共享的文件,存储在 Docker 受信任的注册表中。 Docker 图像由一系列只读层构建而成。每层代表图像的 Docker 文件中给出的指令。图像将所有必需的二进制文件保存到 运行.

容器: 图像的实例称为 容器。容器只是一个可执行映像二进制文件,由主机 运行 OS。 运行ning 图像是一个容器。

Docker文件: Docker 文件是包含所有命令/构建说明的文本文档,用户可以在命令行上调用 assemble 图像。这将保存为 Dockerfile。 (注意小写 'f'。)

Docker-撰写: Compose 是一种用于定义和 运行 宁多容器 Docker 应用程序的工具。使用 Compose,您可以使用 YAML 文件来配置应用程序的服务(容器)。然后,使用一个命令,您可以从您的配置中创建并启动所有服务。 撰写文件将另存为 docker-compose.yml.

在微服务世界(有一个共同的共享代码库)中,每个微服务都有一个 Dockerfile 而在根级别(通常在所有微服务之外以及您的父 POM 所在的位置)您将定义一个 docker-compose.yml 将所有微服务组合成一个成熟的应用程序。

在你的情况下 "Docker Compose" 优于 "Dockerfile"。想"App" 想"Compose".

Docker文件是包含 assemble 图片的文本命令的文件。

Docker compose 用于运行 多容器环境。

在您的特定场景中,如果您提到的每种技术都有多个服务(服务 1 使用 reddis,服务 2 使用 rabbit mq 等),那么您可以为每个服务创建一个 Docker 文件和一个共同的 docker-compose.yml 到 运行 所有 "Dockerfile" 作为容器。

如果您希望将它们全部放在一个服务中,docker-compose 将是一个可行的选择。