Docker中的应用程序具有不同的基本映像

时间:2019-09-03 04:26:18

标签: django docker dockerfile

我是Docker世界中的新手,我试图了解有关父映像的Docker概念。假设我想在docker上运行django应用程序。我想使用ubuntu和python,我想将postgresql作为我的数据库后端,并且我想在gunicorn Web服务器上运行django应用程序。我可以为ubuntu,python,postgres和gunicorn使用不同的基本映像,并创建我的django容器吗?

FROM ubuntu
FROM python:3.6.3
FROM postgres
FROM gunicorn
...

我正在考虑使用不同的基本映像,因为如果有一天我想更新其中一个映像,则只需更新基本映像,而不必进入ubuntu进行更新。

4 个答案:

答案 0 :(得分:2)

只要您正在执行multiple FROM in the same Dockerfile,就可以使用multi-stage build

Dockerfile的一部分将构建另一个使用的中间映像。

但这通常用于将用于构建最终程序的父母与执行最终程序所需的父母明确区分开。

答案 1 :(得分:2)

否,您不能像这样创建映像,在您发布的Dockerfile中,唯一将被视为基础映像的映像将是最后一个FROM gunicor。您需要的是多阶段构建,但在此之前,我将清除有关此类Dockerfile的一些概念。

  

父图像是图像所基于的图像。它指的是   Dockerfile中FROM指令的内容。每个后续   Dockerfile中的声明会修改此父映像。最   Dockerfile从父映像而不是基础映像开始。   但是,这些术语有时可以互换使用。

但是对于您而言,我不建议将所有内容都放入一个Dockerfile中。它将达到容器化的目的。

经验法则

  

每个容器一个过程

每个容器应只关注一个问题

将应用程序解耦到多个容器中,可以更轻松地水平扩展和重复使用容器。例如, Web应用程序堆栈可能由三个单独的容器组成,每个容器都有自己的唯一映像,以管理 Web应用程序数据库,和内存缓存(以分离的方式)。

dockerfile_best-practices

除了数据库,您还可以使用多阶段构建

  

如果您使用Docker 17.05或更高版本,则可以使用多阶段构建来   大大减少最终图像的大小,而无需   跳过箍以减少中间层的数量或   在构建过程中删除中间文件。

     

大多数情况下,您只能在最后阶段制作图片   有利于构建缓存并最小化图像层。

     

您的构建阶段可能包含几层,从小到大   频繁更改为更频繁更改,例如:

     
      
  • 安装构建应用程序所需的工具

  •   
  • 安装或更新库依赖项

  •   
  • 生成您的应用程序

  •   

use-multi-stage-builds

enter image description here

通过多阶段构建,Dockerfile可以包含multiple FROM行,每个stage都以新的FROM行和新的上下文开头。您可以copy artifacts中的stage to stage,未复制的工件将被丢弃。这样可以使最终图像保持较小,并且仅包含相关的伪像。

答案 2 :(得分:1)

有可能吗?是的,从技术上讲,多个基本映像(FROM XXXX)可以出现在单个docker文件中。但这不是您要尝试做的。它们用于多阶段构建。您可以详细了解here

答案是您的问题的答案是,如果要实现这种类型的Docker映像,则应使用一个基本映像,并使用类似RUN的命令在其中安装其他所有内容

FROM ubuntu

RUN apt install postgresql # install postgresql

...

显然不是那么简单。基本的ubuntu映像非常少,您必须使用RUN命令自行安装安装python,postgres和gunicorn所需的所有依赖项和工具。例如,如果您需要使用

下载python源代码
RUN wget https://www.python.org/ftp/python/3.7.4/Python-3.7.4.tgz 

wget(很可能)未预先安装在ubuntu映像中。您必须自己安装。

我应该这样做吗?我认为您反对应用程序的dockerization的整个想法。这不是要构建包含所有服务的整体巨型映像,而是将服务划分到单独的容器中。 (通常每个容器应有一项服务),然后使用docker联网工具使这些容器相互通信。也就是说,您应该为postgres使用一个容器,为nginx使用一个容器,为gunicorn使用一个容器,分别运行它们并通过网络连接它们。docker提供了一个很棒的工具docker-compose,可以自动进行这种多容器设置。您应该真正使用它。有关此示例的更多实际示例,请阅读此good article.

答案 3 :(得分:1)

您可以将官方docker映像用于Django https://hub.docker.com/_/django/。 它有据可查,并解释了其dockerfile。

如果要使用其他基础映像,则必须使用docker-compose。 您的docker-compose.yml看起来像

    version: '3'

    services:
    web:
        restart: always
        build: ./web
        expose:
        - "8000"
        links:
        - postgres:postgres
        - redis:redis
        volumes:
        - web-django:/usr/src/app
        - web-static:/usr/src/app/static
        env_file: .env
        environment:
        DEBUG: 'true'
        command: /usr/local/bin/gunicorn docker_django.wsgi:application -w 2 -b :8000

    nginx:
        restart: always
        build: ./nginx/
        ports:
        - "80:80"
        volumes:
        - web-static:/www/static
        links:
        - web:web

    postgres:
        restart: always
        image: postgres:latest
        ports:
        - "5432:5432"
        volumes:
        - pgdata:/var/lib/postgresql/data/

    redis:
        restart: always
        image: redis:latest
        ports:
        - "6379:6379"
        volumes:
        - redisdata:/data

    volumes:
    web-django:
    web-static:
    pgdata:
    redisdata:

关注此博客以获取详细信息https://realpython.com/django-development-with-docker-compose-and-machine/