我一直在阅读并了解Docker,并尝试正确选择要使用的Django设置。到目前为止,还有:
我理解Dockerfiles
中使用了Docker Compose
,但我不确定将所有内容放在一个大型Dockerfile中,并为不同的图像添加多个FROM
命令是不错的做法?
我想使用几个不同的图像,包括:
uwsgi
nginx
postgres
redis
rabbitmq
celery with cron
请使用 Docker 建议设置此类环境的最佳做法。
如果有帮助,我在Mac上,所以使用boot2docker。
我遇到的一些问题:
答案 0 :(得分:364)
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应用程序的工具。
在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: {}
答案 1 :(得分:158)
答案都不是。
如果您将build命令添加到项目的docker-compose.yml
,Docker Compose(此处称为compose)将使用Dockerfile。
您的Docker工作流程应该是为您要创建的每个图像构建合适的Dockerfile
,然后使用compose使用build
命令组合图像。
您可以使用build /path/to/dockerfiles/blah
指定单个Dockerfiles的路径,/path/to/dockerfiles/blah
就是Dockerfile
生活的地方。
答案 2 :(得分:76)
撰写文件描述 容器处于运行状态,留下如何构建的详细信息 容器到 Dockerfiles 。 http://deninet.com/blog/1587/docker-scratch-part-4-compose-and-volumes
在开发中使用Compose 定义应用时,可以使用此功能 在不同环境中运行应用程序的定义,例如 CI,分期和制作。 https://docs.docker.com/compose/production/
从1.11开始,Compose似乎被视为生产安全,因为https://docs.docker.com/v1.11/compose/production/不再有警告,不要像https://docs.docker.com/v1.10/compose/production/那样在生产中使用它。< / p>
答案 3 :(得分:38)
在我的工作流程中,我为系统的每个部分添加了一个Dockerfile,并将其配置为每个部分可以单独运行。然后我添加一个docker-compose.yml将它们组合在一起并链接它们。
最大优势(在我看来):当linking the containers时,您可以使用此名称定义名称并ping容器。因此,您的数据库可以使用名称db
访问,而不能通过其IP访问。
答案 4 :(得分:23)
“更好”是相对的。这完全取决于您的需求。 Docker compose用于编排多个容器。如果这些图像已经存在于docker注册表中,那么最好将它们列出在compose文件中。如果必须从计算机上的文件中构建这些映像或其他映像,则可以描述在Dockerfile中构建这些映像的过程。
我了解Docker Compose中使用了Dockerfile,但是我不确定是否将所有内容放入一个大Dockerfile中,并使用多个FROM命令来处理不同的映像?
在单个dockerfile中使用多个FROM不是一个好主意,因为有人建议删除该功能。 13026
例如,如果您要对使用数据库的应用程序进行泊坞化并在计算机上拥有该应用程序文件,则可以按如下方式将compose文件和dockerfile一起使用
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
答案 5 :(得分:20)
docker-compose的存在使您不得不编写大量使用docker-cli所需的命令。
docker-compose还使您可以轻松地同时启动多个容器,并通过某种形式的网络将它们自动连接在一起。
docker-compose的目的是充当docker cli,但能够更快地发出多个命令。
要使用docker-compose,您需要将之前运行的命令编码为docker-compose.yml
文件。
您不仅要将它们复制粘贴到yaml文件中,还有一种特殊的语法。
创建后,您必须将其喂入docker-compose cli,然后由cli来解析文件并使用我们指定的正确配置创建所有不同的容器。
因此,您将有单独的容器,例如,一个是redis-server
,第二个是node-app
,并且希望使用当前目录中的Dockerfile
创建的容器。 / p>
另外,在制作完该容器之后,您需要将一些端口从该容器映射到本地计算机,以访问其中运行的所有内容。
因此,对于您的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
});
因此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
的世界中,如果要重建图像,请编写{ {1}}。这就告诉Docker重新启动容器,但要对其进行重建以获取最新更改。
因此docker-compose up --build
使处理多个容器变得更加容易。下次您需要在后台启动这组容器时,可以执行docker-compose
,而要停止它们,可以执行docker-compose up -d
。
答案 6 :(得分:19)
Dockerfile和Docker Compose是Dockerland中的两个不同概念。当我们谈论Docker时,首先想到的是业务流程,操作系统级虚拟化,映像,容器等。我将尝试对它们进行如下解释:
图片: 映像是存储在受Docker信任的注册表中的一个不变的,可共享的文件。 Docker映像由一系列只读层构建而成。每层代表在映像的Dockerfile中给出的一条指令。图像包含运行所需的所有二进制文件。
容器: 图像的实例称为容器。容器只是要由主机OS运行的可执行映像二进制文件。正在运行的图像是一个容器。
Dockerfile:
Dockerfile是一个文本文档,其中包含所有命令/构建指令,用户可以在命令行上调用以组装映像。这将另存为Dockerfile
。 (请注意小写的“ f”。)
Docker-Compose:
Compose是用于定义和运行多容器Docker应用程序的工具。通过Compose,您可以使用YAML文件来配置应用程序的服务(容器)。然后,使用一个命令,就可以从配置中创建并启动所有服务。
撰写文件将另存为docker-compose.yml
。
答案 7 :(得分:3)
Dockerfile用于从裸露的Ubuntu构建映像,您可以在一个映像上添加名为mysql
的{{1}},在另一个名为mySQL
的映像上添加mywordpress
组成YAML文件是要获取这些图像并连贯地运行它们。
例如,如果您的mywordpress
文件中有一个服务电话docker-compose.yml
:
db
和称为worpress的服务,例如:
services:
db:
image: mySQL --- image that you built.
然后在mywordpress容器内,您可以使用wordpress:
image: mywordpress
连接到mySQL容器。之所以如此,是因为您的Docker主机创建了一个网桥(网络覆盖)。
答案 8 :(得分:2)
想象一下,您是一家软件公司的经理,而您刚购买了一台全新的服务器。只是硬件。
将Dockerfile
作为一组说明,您将告诉系统管理员该新服务器上的安装内容。例如:
/var/www
)通过对比,将docker-compose.yml
视为一组说明,您可以告诉系统管理员服务器如何与世界其他地区进行交互。例如,
(这不是一个精确的解释,但足以说明问题。)
答案 9 :(得分:0)
在微服务世界(具有通用的共享代码库)中,每个微服务都会有一个Dockerfile
,而在根级别(通常在所有微服务之外以及您的父POM所在的地方),您将定义一个{{1} },将所有微服务分组为功能完善的应用。
在您的情况下,“ Docker Compose”优先于“ Dockerfile”。考虑“应用程序”考虑“撰写”。