Развертывание с нулевым временем простоя Docker Node.js

У меня есть приложение React / Node.js, работающее на одном сервере с использованием docker-compose. Я пытаюсь добиться нулевого времени простоя для развертывания моего приложения реакции. Прямо сейчас процесс делает сборку webpack (заменяет файлы в моей папке dist), а затем docker down и docker up. Весь этот процесс занимает около 2-3 минут. Я понял, что с docker-compose я могу масштабировать свой контейнер вверх / вниз, но я не уверен, как передать свой код только одному из них и пересобрать веб-пакет. Я действительно не Я не хочу использовать Kubernetes / Swarm или Openshift, потому что это немного излишне. Мне интересно, достиг ли кто-нибудь еще чего-то подобного.

Мой docker-compose выглядит так:

node:
    build:
        context: ./env/docker/node
        args:
            - PROJECT_ROOT=/var/www/app
    image: react_app:rapp_node
    command: "npm run prod"
    expose:
        - "3333"
    networks:
        - react-net
    volumes_from:
        - volumes_source
    tty: false

nginx:
    env_file:
        - ".env"
    build:
        context: ./env/docker/nginx
    volumes_from:
        - volumes_source
    volumes:
        - ./env/data/logs/nginx/:/var/log/nginx
        - ./env/docker/nginx/sites/node.template:/etc/nginx/node.template
    networks:
        - react-net
        - nginx-proxy
    environment:
        NGINX_HOST: ${NGINX_HOST}
        VIRTUAL_HOST: ${NGINX_VIRTUAL_HOST}
        LETSENCRYPT_HOST: ${NGINX_VIRTUAL_HOST}
        ESC: $$
    links:
        - node:node
    command: /bin/sh -c "envsubst < /etc/nginx/node.template > /etc/nginx/sites-available/node.conf && nginx -g 'daemon off;'"

volumes_source:
    image: tianon/true
    volumes:
        - ./app:/var/www/app

А мой nginx выглядит примерно так:

server {
server_name www.${NGINX_HOST};
return 301 ${ESC}scheme://${NGINX_HOST}${ESC}request_uri;
}

server {
listen 80;
server_name ${NGINX_HOST};

root /var/www/app;

location / {
proxy_pass http://node:3333;
proxy_http_version 1.1;
proxy_set_header Upgrade ${ESC}http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host ${ESC}host;
proxy_cache_bypass ${ESC}http_upgrade;
}
}
0
задан 13 March 2018 в 17:37
2 ответа

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

Но, если вы хотите именно этого, то, что вы написали (, но это совсем не верный способ ), вы можете, например, запустить сценарий в контейнере, который проверяет новую версию вашего приложения, создает ее и переключает символическая ссылка со старой версии на новую, которую вы можете сделать атомарной следующим образом: ln -s new current_tmp && mv -Tf current_tmp current .

Итак, структура каталогов будет такой: / var / www / app - символическая ссылка на вашу текущую версию / var / www / app_v1 - каталог с текущей версией, который символически привязан к "/ var / www / app" / var / www / app_v2 - каталог с новой версией

Теперь вы можете выполнить команду ln -s / var / www / app_v2 / var / www / app_v2_sym && mv -Tf / var / www / app_v2_sym / var / www / app для переключения текущая версия приложения, которую использует Nginx.

0
ответ дан 4 December 2019 в 16:00

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

Да, вы действительно должны создавать новую версию вашего образа с вашим кодом при каждом коммите, который вы планируете отправить на этот сервер. Инструменты рассчитаны на этот тип рабочего процесса, поэтому вам будет легче, если вы воспользуетесь этим рабочим процессом. Docker Hub поддерживает выполнение этого за вас при каждой фиксации в ветке (бесплатно, если с открытым исходным кодом, и все еще бесплатно для одного частного репо) GitHub и BitBucket. Вот как это будет работать в роях с одним узлом, если вы каждый раз создаете новые образы в Docker Hub:

  1. Предполагая, что вы используете последнюю стабильную версию докера (17.12 на момент публикации)
  2. docker swarm init и теперь у вас есть рой с одним узлом. Вот и все. (Если у меня может быть только один сервер для развертывания докеров на , я всегда использую single-node-swarm, а не docker-compose по списку веских причин .
  3. С некоторыми изменениями, ваш compose файл может использоваться в качестве файла стека для docker stack deploy -c compose-file.yml stackname
  4. Чтобы гарантировать отсутствие простоев при развертывании, вы захотите добавить проверки работоспособности на ваш узел / nginx контейнеры, чтобы они знали, когда приложение действительно «готово к подключению». Swarm использует это также во время обновлений службы, поэтому это ключ.
  5. Если вы хотите, чтобы swarm сначала добавил новый контейнер, перед удалением старого контейнера добавьте order: start-first на https://docs.docker.com/compose/compose-file/#update_config .
  6. Затем просто измените теги изображений в файле создания , возможно, с myuser / myrepo: 1.0 до myuser / myrepo: 2.0 , а затем снова запустите ту же команду развертывания стека, и Swarm обнаружит различия и обновит службу w с новым образом (путем замены контейнера).

Чтобы проверить это, используйте httping, чтобы убедиться, что он по-прежнему доступен удаленно во время процесса обновления.

1
ответ дан 4 December 2019 в 16:00

Теги

Похожие вопросы