Implantação de tempo de inatividade zero Node.js Docker

Implantação de tempo de inatividade zero Node.js Docker

Eu tenho um aplicativo React/Node.js em execução em um único servidor usando docker-compose. Estou tentando obter uma implantação de tempo de inatividade de 0 para meu aplicativo React. O processo agora faz uma compilação do webpack (substitui os arquivos na minha pasta dist) e, em seguida, docker down e docker up. Todo esse processo leva cerca de 2 a 3 minutos. Percebi que com o docker-compose posso aumentar/diminuir meu contêiner, mas não tenho certeza de como enviar meu código apenas para um deles e reconstruir o webpack. Eu realmente não quero usar Kubernetes/Swarm ou Openshift, pois é um pouco exagerado. Gostaria de saber se mais alguém conseguiu algo semelhante a isso.

Meu docker-compose fica assim:

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

E meu nginx é algo assim:

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;
}
}

Responder1

Acho que a melhor maneira é usar qualquer orquestrador para isso, todos eles têm suporte para atualização contínua e você pode usar qualquer fluxo de atualização padrão.

Mas, se você quiser exatamente o que escreveu (mas esse não é um caminho verdadeirode forma alguma), você pode, por exemplo, executar um script no contêiner, que fará check-out de uma nova versão do seu aplicativo, compilá-lo e alternar o link simbólico da versão antiga para a nova, o que você pode fazer atômico assim: ln -s new current_tmp && mv -Tf current_tmp current.

Então, a estrutura dos diretórios ficará assim: /var/www/app - symlink to your current version /var/www/app_v1 - directory with current version, which symlinked to "/var/www/app" /var/www/app_v2 - directory with new version

Agora, você pode executar o comando ln -s /var/www/app_v2 /var/www/app_v2_sym && mv -Tf /var/www/app_v2_sym /var/www/apppara mudar a versão atual do aplicativo que o Nginx está usando.

Responder2

Eu recomendo fortemente um enxame simples de nó único para isso. É a solução perfeita para casos em que você não precisa de tempo de inatividade durante as atualizações, mas não pode ou não precisa de alta disponibilidade de vários nós. Ele realmente não adiciona sobrecarga ou mais encargos administrativos e usa os mesmos arquivos de composição.

Sim, você realmente deveria construir uma nova versão de sua imagem com seu código em cada commit que planeja enviar para este servidor. As ferramentas esperam esse tipo de fluxo de trabalho, então será mais fácil se você adotar esse fluxo de trabalho. O Docker Hub oferece suporte para fazer isso para você em cada commit em um branch (de graça se for de código aberto, e ainda de graça para um único repositório privado) do GitHub e do BitBucket. Veja como funcionaria em um enxame de nó único, supondo que você estivesse construindo novas imagens a cada vez no Docker Hub:

  1. Supondo que você esteja na versão estável recente do docker (17.12 a partir desta postagem)
  2. docker swarm inite agora você tem um enxame de nó único. É isso. (Se eu puder ter apenas um servidor para implantar coisas do DockerEu sempre uso um enxame de nó único e não docker-compose por uma lista de bons motivos.
  3. Com algumas alterações, seu arquivo de composição pode ser usado como um arquivo de pilha paradocker stack deploy -c compose-file.yml stackname
  4. Para garantir implantações com tempo de inatividade zero, você vai quereradicionar verificações de integridadeaos contêineres do seu nó/nginx para que eles saibam quando o aplicativo está realmente "pronto para conexões". O Swarm também usa isso durante as atualizações de serviço, por isso é fundamental.
  5. Se você quiser que o swarm adicione um novo contêiner primeiro, antes de remover o contêiner antigo, adicione order: start-firstaohttps://docs.docker.com/compose/compose-file/#update_config.
  6. Em seguida, basta alterar as tags de imagem no arquivo de composição, talvez myuser/myrepo:1.0para myuser/myrepo:2.0executar o mesmo comando de implantação de pilha novamente, e o Swarm detectará diferenças e atualizará o serviço com uma nova imagem (substituindo o contêiner).

Para testar isso, use httping para validar que ainda está disponível remotamente durante o processo de atualização.

informação relacionada