Dockerfiles中的重复

时间:2018-03-17 22:44:16

标签: docker dockerfile

我有一个Django Web应用程序,它在后台使用芹菜进行定期任务。

现在我有三个码头图像

  • 一个用于django应用程序
  • 一个芹菜工人
  • 一个用于芹菜调度程序

Dockerfile s看起来像这样:

FROM alpine:3.7

ENV PYTHONUNBUFFERED 1

RUN mkdir /code
WORKDIR /code
COPY Pipfile Pipfile.lock ./

RUN apk update && \
 apk add python3 postgresql-libs jpeg-dev git && \
 apk add --virtual .build-deps gcc python3-dev musl-dev postgresql-dev zlib-dev && \
 pip3 install --no-cache-dir pipenv && \
 pipenv install --system && \
 apk --purge del .build-deps

COPY . ./

# Run the image as a non-root user
RUN adduser -D noroot
USER noroot

EXPOSE $PORT

CMD <Different CMD for all three containers>

所以除最后一行外,它们都完全一样。

在这里创建某种包含除CMD之外的所有内容的基本图像是否有意义。并且所有三个图像都使用它作为基础并仅添加它们各自的CMD?

或者不会给我带来任何好处,因为无论如何都要缓存一切?

您认为上述分离是否合理?

两个小小的奖励问题:

  • 有时,apk update ..图层由docker缓存。 docker如何知道这里没有更新?
  • 我经常读到我应尽可能减少图层以减小图像尺寸。但这不是针对缓存的想法,会导致更长的构建吗?

2 个答案:

答案 0 :(得分:1)

我建议查看docker-compose以简化多个容器的管理。

使用与您上面发布的Docker文件类似的单个Docker文件,然后创建一个docker-compose.yml,看起来像这样:

version: '3'
services:
  # a django service serving an application on port 80
  django:
    build: .
    command: python manage.py runserver
    ports:
      - 8000:80
  # the celery worker
  worker:
    build: .
    command: celery worker
  # the celery scheduler
  scheduler:
    build: .
    command: celery beat

当然,将此处的命令修改为您当前用于当前单独的Dockerfiles的任何内容。

如果要重建映像,docker-compose build将从Dockerfile重建第一个服务的容器映像,然后将构建的映像重用于其他服务(因为它们已存在于缓存中)。 docker-compose up将启动容器映像的3个实例,但每次都会覆盖run命令。

如果你想变得更加成熟,那么django和芹菜的常见组合就有plenty of resources

答案 1 :(得分:1)

我建议使用一个Dockerfile,只在运行时更新你的CMD。 Litle位修改也适用于本地和Heroku。

就Heroku而言,他们提供环境变量以使用环境变量启动容器。 heroku set-up-your-local-environment-variables

    FROM alpine:3.7

ENV PYTHONUNBUFFERED 1
ENV APPLICATION_TO_RUN=default_application

RUN mkdir /code
WORKDIR /code
COPY Pipfile Pipfile.lock ./

RUN apk update && \
 apk add python3 postgresql-libs jpeg-dev git && \
 apk add --virtual .build-deps gcc python3-dev musl-dev postgresql-dev zlib-dev && \
 pip3 install --no-cache-dir pipenv && \
 pipenv install --system && \
 apk --purge del .build-deps

COPY . ./

# Run the image as a non-root user
RUN adduser -D noroot
USER noroot

EXPOSE $PORT

CMD $APPLICATION_TO_RUN

因此,当您运行容器时,请将您的应用程序名称传递给运行命令。

docker run -it --name test -e APPLICATION_TO_RUN="celery beat" --rm test