Мы реализовали деплой через GitLab CI и docker-compose. В процессе деплоя на удалённый сервер копируется файл docker-compose.yml и файлы Dockerfile и пр. для создания "вспомогательных" контейнеров типа nginx и mysql
Всё работает как нужно. Беспокоят 2 момента: даунтайм и "мусорные" образы docker (те, что с
Вот кусок файла .gitlab-ci.yml, ответственный собственно на деплой на удалённый сервер:
.template-secure-copy: &secure-copy
stage: deploy
image: covex/alpine-git:1.0
before_script:
- eval $(ssh-agent -s)
- ssh-add <(echo "$SSH_PRIVATE_KEY")
script:
- ssh -p 22 $DEPLOY_USER@$DEPLOY_HOST 'set -e ;
rm -rf '"$DEPLOY_DIRECTORY"'_tmp ;
mkdir -p '"$DEPLOY_DIRECTORY"'_tmp'
- scp -P 22 -r build/* ''"$DEPLOY_USER"'@'"$DEPLOY_HOST"':'"$DEPLOY_DIRECTORY"'_tmp' # */ <-- в оригинале строка не закоментирована =)
- ssh -p 22 $DEPLOY_USER@$DEPLOY_HOST 'set -e ;
cd '"$DEPLOY_DIRECTORY"'_tmp ;
docker login -u gitlab-ci-token -p '"$CI_JOB_TOKEN"' '"$CI_REGISTRY"' ;
docker-compose pull ;
if [ -d '"$DEPLOY_DIRECTORY"' ]; then cd '"$DEPLOY_DIRECTORY"' && docker-compose down --rmi local && rm -rf '"$DEPLOY_DIRECTORY"'; fi ;
cp -r '"$DEPLOY_DIRECTORY"'_tmp '"$DEPLOY_DIRECTORY"' ;
cd '"$DEPLOY_DIRECTORY"' ;
docker-compose up -d --remove-orphans ;
docker-compose exec -T php phing app-deploy -Dsymfony.env=prod ;
rm -rf '"$DEPLOY_DIRECTORY"'_tmp'
tags:
- executor-docker
Даунтайм сейчас - это 1-2-3 минуты. Начинается он с docker-compose down ... и до конца выполнения скрипта. Хочется его уменьшить.
А как сделать так, чтобы "мусорные" образы docker не появлялись - я вообще не понял. Про docker image prune знаю, хочется не очищать, а не захламлять.
UPD1:
Файл docker-compose.yml создаётся следующей конструкцией:
.template-docker-compose: &docker-compose
stage: build
image: covex/docker-compose:1.0
script:
- for name in `env | awk -F= '{if($1 ~ /'"$ENV_SUFFIX"'$/) print $1}'`; do
eval 'export '`echo $name|awk -F''"$ENV_SUFFIX"'$' '{print $1}'`'='$"$name"'';
done
- mkdir build
- docker-compose -f docker-compose-deploy.yml config > build/docker-compose.yml
- sed -i 's/\/builds\/'"$CI_PROJECT_NAMESPACE"'\/'"$CI_PROJECT_NAME"'/\./g' build/docker-compose.yml
- cp -R docker build
artifacts:
untracked: true
name: "$CI_COMMIT_REF_NAME"
paths:
- build/
tags:
- executor-docker
В результате этой процедуры получается такой docker-compose.yml
networks:
nw_external:
external:
name: graynetwork
nw_internal: {}
services:
mysql:
build:
context: ./docker/mysql
environment:
MYSQL_DATABASE: project
MYSQL_PASSWORD: project
MYSQL_ROOT_PASSWORD: root
MYSQL_USER: project
expose:
- '3306'
networks:
nw_internal: null
restart: always
volumes:
- database:/var/lib/mysql:rw
nginx:
build:
args:
app_php: app
server_name: project-dev1.ru
context: ./docker/nginx
depends_on:
php:
condition: service_started
networks:
nw_external:
ipv4_address: 192.168.10.13
nw_internal: null
ports:
- 80/tcp
restart: always
volumes_from:
- service:php:ro
php:
depends_on:
mysql:
condition: service_healthy
environment:
ENV_database_host: mysql
ENV_database_name: project
ENV_database_password: project
ENV_database_port: '3306'
ENV_database_user: project
ENV_mailer_from: andrey@mindubaev.ru
ENV_mailer_host: 127.0.0.1
ENV_mailer_password: 'null'
ENV_mailer_transport: smtp
ENV_mailer_user: 'null'
ENV_secret: ThisTokenIsNotSoSecretChangeIt
expose:
- '9000'
image: gitlab.site.ru:5005/dev1-projects/symfony:master
networks:
nw_internal: null
restart: always
volumes:
- /composer/vendor
- /srv
version: '2.1'
volumes:
database: {}
Dockerfile для сервиса nginx
FROM nginx:alpine
ARG server_name=docker.local
ARG app_php=app_dev
COPY ./default.conf /etc/nginx/conf.d/default.conf
RUN sed -i 's/@SERVER_NAME@/'"$server_name"'/g' /etc/nginx/conf.d/default.conf \
&& sed -i 's/@APP@/'"$app_php"'/g' /etc/nginx/conf.d/default.conf
Dockerfile для сервиса mysql
FROM mysql:5.7
HEALTHCHECK CMD mysqladmin ping --silent
Ответ
Нужно минимум два контейнера, которые будет zero downtime. Дальше процесс (хорошо описан тут): остановить один старый, запустиить один новый и так по очереди.
Но я буквально пару недель назад все это проходил и docker swarm это ОЧЕНЬ ПРОСТО, там пару команд, рецепт по ссылке в несколько раз сложнее. Для своего решения нужно настраивать балансировщик, а в docker swarm уже все есть и ставиться, ещё раз скажу, ОЧЕНЬ ПРОСТО.
Переходите сразу на docker swarm. Он очень быстро настраивается и нулевой downtime из коробки.
Просто docker service отличный инструмент, а docker stack вообще бомба (как раз поднимает все оружение из docker-compose подобного файла).
Комментариев нет:
Отправить комментарий