Docker-Projektwechsel, Skript neu starten
Hintergrund
Im Projektbereitstellungs-Docker müssen Sie beim Aktualisieren des Projekts den ursprünglichen Container stoppen und den neuen Container starten, sodass es einen Fensterzeitraum gibt, der zur Nichtverfügbarkeit führt. Lösung: Ordnen Sie
verschiedene Ports zu, starten Sie einen neuen Container und leiten Sie Nginx an weiter den neuen Behälter, stoppen Sie den alten Behälter
Konkreter Betrieb
说明
- Die Nginx-Konfigurationsdatei kann nicht in der Standard-nginx.conf abgelegt werden
- Der Projektname im Startskript start.sh
不能
hat eine Einschlussbeziehung (auf demselben Server wird der eingeschlossene Container gestoppt, wenn eine Einschlussbeziehung besteht). - Der beim Projektstart eingegebene Port muss
存在
in der Nginx-Konfigurationsdatei upstream-app.conf enthalten sein
Nginx-Konfiguration
Profil 1
Der Name ist beliebig, Beispiel app.conf
server {
listen 80;
# 修改为你自己的域名
server_name xx.venny.cn;
location / {
proxy_set_header Host $host;
root /app/html/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
try_files $uri $uri/ /index.html;
index /index.html;
}
location /api/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header Access-Control-Allow-Methods *;
add_header Access-Control-Allow-Origin $http_origin;
# 与自定义的保持一致
proxy_pass http://stream-app/;
}
}
Profil 2
Beliebiger Name, Beispiel: upstream-app.conf
# 自定义upstream名
upstream stream-app {
# server 127.0.0.1:8000 weight=10;
# server 127.0.0.1:8001 weight=10;
# server 127.0.0.1:8002 weight=10;
# server 127.0.0.1:8003 weight=10;
# server 127.0.0.1:8004 weight=10;
# server 127.0.0.1:8005 weight=10;
# server 127.0.0.1:8006 weight=10;
# server 127.0.0.1:8007 weight=10;
# server 127.0.0.1:8008 weight=10;
# server 127.0.0.1:8009 weight=10;
}
Schreiben Sie ein Nginx-Ersatzskript (wird zum Durchführen des Portaustauschs verwendet).
Der Name ist replace.sh
#!/bin/bash
port=$1
conf_name=$2
cat $conf_name | while read l
do
if [[ $l =~ "127.0.0.1:$port" ]];then
#去除#号
echo ${l##*#}
elif [[ $l =~ "server" ]];then
#添加#号
if [[ !($l =~ '#') ]];then
echo '# '$l
else
echo $l
fi
else
echo $l
fi
done
Schreiben Sie ein Startskript
start.sh
#/bin/bash
check_y(){
if [ -n "$1" ] && [ "$1" = 'y' ];then
echo 1
else
echo 0
fi
}
# 指定项目nginx配置文件位置,根据实际位置填写
ng_path=/etc/nginx/
# 指定项目upstream配置文件名称
ng_conf_name=upstream-qin.conf
# 指定项目名称
project_name=app
# 版本默认取当前日期
version=$(date +%Y%m%d%H%M%S)
echo '当前版本号:'$version
read -rp "请输入启动端口号:" port
echo '当前启动端口:'$port
echo "开始构建容器"
docker build -t $project_name:$version .
echo "容器构建成功!"
sleep 5
echo "容器启动中...."
# 健康检查(接口/health必须存在,否则健康检查失败)、及启动项目,容器启动端口固定8080
container_full_id=$(docker run \
--health-cmd="curl --fail localhost:8080/health || exit 1" \
--health-interval=5s \
--health-retries=15 \
--health-timeout=10s \
-itd -p $port:8080 --name=$project_name$version -v /app/logs:/logs -v /etc/localtime:/etc/localtime $project_name:$version)
echo "容器启动完毕...."
container_id=$(echo $container_full_id|cut -b 1-12)
echo "容器id为$container_id"
echo '开始健康检查'
health=1
while [[ -z "$(docker ps -a -f id=${
container_id} -f health=healthy | awk 'NR>1 {print $1}')" ]]
do
echo '执行中....'
if [[ "$(docker ps -a -f id=${
container_id} -f health=unhealthy | awk 'NR>1 {print $1}')" == $container_id ]];then
echo '健康检查失败'
health=2
break
fi
sleep 5;
done
if [[ $health != 1 ]];then
exit
fi
echo '健康检查成功'
sleep 3
echo "开始修改nginx配置"
sleep 1
# 替换nginx upstream文件
./replace.sh $port ${ng_path}${ng_conf_name} > ${project_name}.ng.conf.temp
cat ${project_name}.ng.conf.temp > ${ng_path}${ng_conf_name}
rm -f ${project_name}.ng.conf.temp
echo 'nginx配置修改成功'
echo '当前配置:'
cat ${ng_path}${ng_conf_name}
sleep 2
read -rp '是否重启nginx y/n:' reload_ngx
if [ "$(check_y $reload_ngx)" = "1" ];then
nginx -s reload
echo '重启nginx'
else
exit
fi
sleep 1
echo "开始关闭旧容器"
sleep 10
if [ -n "$container_id" ];then
close_containers=$(docker ps |grep $project_name|grep -v $container_id|awk '{print "docker rm -f "$1}'|/bin/bash)
echo $close_containers
for cc in $close_containers
do
echo "关闭容器$cc"
done
fi
read -rp '是否删除旧镜像y/n:' del_imgs
if [ "$(check_y $del_imgs)" = "1" ];then
echo "开始删除原镜像"
sleep 1
docker images|grep -v $version|grep $project_name|awk '{print "docker rmi -f "$1":"$2}'|/bin/bash
fi
Die Docker-Datei wird normal geschrieben
auslassen
Autorisieren Sie das Skript
chmod +x start.sh
Führen Sie das ./start-Skript aus
./start
Geben Sie die Portnummer gemäß der Eingabeaufforderung ein (die Portnummer muss in der Upstream-App vorhanden sein) und geben Sie nacheinander y, y ein