Подтвердить что ты не робот

Как обновить код из Git в контейнер Docker

У меня есть файл Docker, пытающийся развернуть код Django в контейнер

FROM ubuntu:latest
MAINTAINER { myname }

#RUN echo "deb http://archive.ubuntu.com/ubuntu/ $(lsb_release -sc) main universe" >> /etc/apt/sou$

RUN apt-get update

RUN DEBIAN_FRONTEND=noninteractive apt-get install -y tar git curl dialog wget net-tools nano buil$
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python python-dev python-distribute python-p$

RUN mkdir /opt/app
WORKDIR /opt/app

#Pull Code
RUN git clone [email protected]/{user}/{repo}

RUN pip install -r website/requirements.txt

#EXPOSE = ["8000"]
CMD python website/manage.py runserver 0.0.0.0:8000

И затем я создаю свой код как docker build -t dockerhubaccount/demo:v1 ., и это вытаскивает мой код из Bitbucket в контейнер. Я запускаю его как docker run -p 8000:8080 -td felixcheruiyot/demo:v1, и все выглядит нормально.

Теперь я хочу обновить код, так как я использовал git clone ..., у меня есть эта путаница:

  • Как я могу обновить свой код, когда у меня появятся новые коммиты, а в контейнерах Docker его сборка поставляется с новым кодом (примечание: при запуске сборки он не извлекает его из-за кеша).
  • Каков наилучший рабочий процесс для такого подхода?
4b9b3361

Ответ 1

Существует несколько подходов, которые вы можете использовать.

  • Вы можете использовать docker build --no-cache, чтобы избежать использования кеша Git.
  • Команда запуска вызывает git pull. Поэтому вместо запуска python manage.py у вас есть что-то вроде CMD cd /repo && git pull && python manage.py или используйте start script, если все сложнее.

Я предпочитаю 2. Вы также можете запустить задание cron для обновления кода в своем контейнере, но это немного больше работает и немного противоречит философии Docker.

Ответ 2

Я бы порекомендовал вам проверить код на вашем хосте и COPY на изображении. Таким образом, он будет обновляться всякий раз, когда вы вносите изменения. Кроме того, во время разработки вы можете привязать исходный каталог к ​​каталогу кода в контейнере, то есть любые изменения немедленно отражаются в контейнере.

Команда docker для репозиториев git, которая проверяет последнее обновление, была бы очень полезной, хотя!

Ответ 3

Другое решение.

Команда сборки Docker использует кеш, если строка инструкции точно такая же, как и в кешированном изображении. Итак, если вы пишете

RUN echo '2014122400' >/dev/null && git pull ...

В следующем обновлении вы измените следующее.

RUN echo '2014122501' >/dev/null && git pull ...

Это может предотвратить использование кеш-кером docker.

Ответ 4

Я хотел бы предложить другое возможное решение. Мне нужно предупредить, однако, что это определенно не "способ докеров" делать вещи и полагаться на существование томов (что может быть потенциальным блокировщиком в таких инструментах, как Docker Swarm и Kubernetes).

Основным принципом, который мы будем использовать, является тот факт, что содержимое каталогов контейнеров, которые используются в качестве тонов Докера, фактически хранится в файловой системе хоста. Ознакомьтесь с этой частью документации.

В вашем случае вы должны сделать /opt/app Docker Volume. Вам не нужно явно указывать том в папку в файловой системе хоста, поскольку, как я опишу ниже, отображение можно получить динамически.

Итак, для стартеров оставьте свой файл Docker точно так, как он есть, и переключите команду создания контейнера на что-то вроде:

docker run -p 8000:8080 -v /opt/app --name some-name -td felixcheruiyot/demo:v1

Команда docker inspect -f {{index .Volumes "/opt/webapp"}} some-name будет печатать полный путь файловой системы на хосте, где хранится ваш код (это, где я взял проверить трюк).

Вооружившись этим знанием, все, что вам нужно сделать, это заменить этот код и весь ваш набор. Таким образом, очень простое развертывание script будет выглядеть примерно так:

code_path=$(docker inspect -f {{index .Volumes "/opt/webapp"}} some-name)
rm -rfv $code_path/*
cd $code_path
git clone [email protected]/{user}/{repo}

Преимущества, которые вы получаете с таким подходом:

  • Не существует потенциально дорогостоящих отказов изображений без кекса.
  • Нет необходимости переносить конкретную запущенную информацию приложения в команду run. Dockerfile является единственным источником необходимых для приложения приложений

UPDATE

Вы можете достичь тех же результатов, о которых я упомянул выше, используя docker cp (начиная с Docker 1.8). Таким образом, контейнер не должен иметь томов, и вы можете заменить код в контейнере так же, как и в файловой системе хоста.

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

Ответ 5

Если вы используете GitHub, вы можете использовать API GitHub, чтобы не кэшировать определенные команды RUN.

Для анализа JSON необходимо установить jq: apt-get install -y jq

Пример:

docker build --build-arg SHA=$(curl -s 'https://api.github.com/repos/Tencent/mars/commits' | jq -r '.[0].sha') -t imageName .

В файле Docker (команда ARG должна быть права перед RUN):

ARG SHA=LATEST
RUN SHA=${SHA} \
    git clone https://github.com/Tencent/mars.git

Или если вы не хотите устанавливать jq:

SHA=$(curl -s 'https://api.github.com/repos/Tencent/mars/commits' | grep sha | head -1)

Если репозиторий имеет новые коммиты, будет выполнен git clone.