docker project switch, restart script
background
In the project deployment docker, when updating the project, you need to stop the original container and start the new container, so there will be a window period, resulting in unavailability Solution:
map different ports and start a new container, and forward nginx to the new container, stop the old container
Concrete operation
说明
- The nginx configuration file cannot be placed in the default nginx.conf
- The project_name in the startup script start.sh
不能
has an inclusion relationship (on the same server, if there is an inclusion relationship, the included container will be stopped) - The port entered when the project starts must
存在
be in the nginx configuration file upstream-app.conf
nginx configuration
Profile 1
The name is arbitrary, example 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/;
}
}
Profile 2
Any name, example: 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;
}
Write nginx replacement script (used to perform port replacement)
The name is 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
Write a startup script
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
The dockerfile is written normally
omit
Authorize the script
chmod +x start.sh
Execute the ./start script
./start
Enter the port number according to the prompt (the port number must exist in upstream-app), and enter y, y in sequence