我有一個使用 docker-compose 在單一伺服器上運行的 React/Node.js 應用程式。我正在嘗試為我的 React 應用程式實現 0 停機時間部署。現在的過程是進行 webpack 建置(替換我的 dist 資料夾中的檔案),然後 docker down 和 docker up。整個過程大約需要2-3分鐘。我意識到使用 docker-compose 我可以放大/縮小我的容器,但我不知道如何只將我的程式碼推送到其中 1 個容器並重建 webpack。我真的不想使用 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;
}
}
答案1
我認為更好的方法是使用任何編排器,它們都支援滾動更新,並且您可以使用任何標準更新流程。
但是,如果您想要的正是您所寫的(但這不是真正的方法根本不),例如,您可以在容器中運行腳本,該腳本將簽出應用程式的新版本,建立它並將符號連結從舊版本切換到新版本,您可以像這樣執行原子操作:ln -s new current_tmp && mv -Tf current_tmp current
。
所以,目錄的結構將是這樣的:
/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
現在,您可以執行命令ln -s /var/www/app_v2 /var/www/app_v2_sym && mv -Tf /var/www/app_v2_sym /var/www/app
來切換 Nginx 使用的應用程式的目前版本。
答案2
為此,我強烈建議一個簡單的單節點群。對於您在更新期間需要零停機但不能或不需要多節點高可用性的情況來說,這是完美的解決方案。它確實不會增加開銷或更多的管理負擔,並且使用相同的撰寫文件。
是的,您確實應該在計劃發送到該伺服器的每次提交中使用程式碼建立新版本的映像。這些工具需要這種類型的工作流程,因此如果您採用該工作流程,您會更輕鬆。 Docker Hub 支援在每次提交到 GitHub 和 BitBucket 的分支時為您執行此操作(如果開源則免費,對於單一私人儲存庫仍然免費)。假設您每次都在 Docker Hub 上建立新映像,那麼它在單節點群中的工作方式如下:
- 假設您使用最新的穩定 docker 版本(截至本文為 17.12)
docker swarm init
現在您有了一個單節點群。就是這樣。 (如果我只能有一台伺服器來部署 docker 的東西基於一系列充分的理由,我總是使用單節點群而不是 docker-compose。- 透過一些更改,您的撰寫文件可以用作堆疊文件
docker stack deploy -c compose-file.yml stackname
- 為了確保零停機部署,您需要添加健康檢查到您的節點/nginx 容器,以便它們知道應用程式何時真正「準備好連接」。 Swarm 在服務更新期間也會使用它,所以它是關鍵。
- 如果您希望 swarm 首先新增容器,請在刪除舊容器之前新增
order: start-first
至https://docs.docker.com/compose/compose-file/#update_config。 - 然後只需更改 compose 檔案中的映像標籤,也許
myuser/myrepo:1.0
然後myuser/myrepo:2.0
再次運行相同的堆疊部署命令,Swarm 將檢測差異並使用新映像更新服務(透過替換容器)。
要對此進行測試,請使用 httping 來驗證它在更新過程中仍然可以遠端使用。