Система управления прокси-сервером под NGINX на Ubuntu 14.04 в Azure.
Файлы конфигураций бекенд-хостов хранятся в Atlassian Stash, в роли CI/CD сервера выступает GoCD от Hashicorp.
Предназначена для предоставления девелоперам возможности управления конфигурацией хостов в процессе переноса сайтов проекта со старых на новые версии.
- Репозиторий
- Скрипты
- Скрипт
backup.sh
- Скрипт
nginx_update.sh
- Скрипт
- GoCD
Содержание
Репозиторий
Структура репозитория выглядит так:
$ tree azure-proxy/ azure-proxy/ ├── conf.d │ └── domain.tld.conf ├── scripts │ ├── backup.sh │ └── nginx_update.sh └── vhosts-backup ├── domain.tld.conf └── default
conf.d
: содержит файлы конфигурацийscripts
: скрипты для GoCDvhosts-backup
: последний бекап предыдущей версии файлов
Скрипты
Скрипт backup.sh
Скрипт backup.sh
выполняет копирование файлов с сервера с NGINX в локальный каталог vhosts-backup
, после чего — git push
с изменениями обратно в хранилище:
#!/usr/bin/env bash me="$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")" HOST="$1" USER="username" RSA_KEY=".ssh/service_id" if [ -e $RSA_KEY ]; then chmod 600 $RSA_KEY else echo -e "\nERROR: can not find $RSA_KEY to connect. Exit.\n" exit 1 fi if [ -z $HOST ]; then echo -e "\nERROR: HOST name must be specified as first argument. Exit.\n" exit 1 fi echo -e "\n[$me] NGINX backup started.\n" vhosts_backup () { scp -r -o StrictHostKeyChecking=no -i $RSA_KEY $USER@$1:/etc/nginx/conf.d/* vhosts-backup/ } if vhosts_backup $HOST; then git add . git status git commit -m "$(date +%Y%m%d) NGINX virtualhosts configs backup" || echo "[$me] Nothing to commit!" git push origin master else echo -e "\nERROR: something went wrong during SCP. Exit.\n" exit 1 fi echo -e "\n[$me] NGINX backup finished successfully.\n"
Скрипт nginx_update.sh
Второй скрипт — nginx_update.sh
:
- перемещает все имеющиеся на сервере файлы конфигураций в каталог
/tmp/nginx_tmp_prev_confd
- копирует все файлы конфигурации из локального каталога (репозитория)
conf.d
на сервер в каталог/etc/nginx/conf.d/
- проверяет их через
nginx -t
, и:- в случае ошибки — удаляет новые файлы, и откатывает файлы из каталога
/tmp/nginx_tmp_prev_confd
- если статус ОК — выполняет
nginx reload
- в случае ошибки — удаляет новые файлы, и откатывает файлы из каталога
Сам скрипт:
#!/usr/bin/env bash me="$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")" HOST="$1" USER="username" RSA_KEY=".ssh/service_id" NGINX_INIT="/etc/init.d/nginx" NGINX_BASEDIR="/etc/nginx" # remote conf.d location R_CONFD_DIR="$NGINX_BASEDIR/conf.d" # local conf.d location in repo L_CONFD_DIR="conf.d" # tmp fir for curent vhosts NGINX_PREV_TMP="/tmp/nginx_tmp_prev_confd" # tmp fir for new vhosts to be copied then to $R_CONFD_DIR NGINX_NEW_TMP="/tmp/nginx_tmp_new_confd" if [ -e $RSA_KEY ]; then chmod 600 $RSA_KEY else echo -e "\nERROR: can not find $RSA_KEY to connect. Exit.\n" exit 1 fi if [ -z $HOST ]; then echo -e "\nERROR: HOST name must be specified as first argument. Exit.\n" exit 1 fi echo -e "\n[$me] NGINX update started.\n" # Update process: # 1. vhosts_clean (): # a. Create /tmp/nginx_tmp_prev_confd on the remote # b. Move ( < !) all current configs from /etc/nginx/conf.d to /tmp/nginx_tmp_prev_confd so they can be rolled back later if any # 2. vhosts_copy() # a. Create /tmp/nginx_tmp_new_confd # b. Copy local conf.d directory content to the remote /tmp/nginx_tmp_new_confd # c. Copy /tmp/nginx_tmp_new_confd content to /etc/nginx/conf.d # 3. nginx -t - validate configs syntax # 4. nginx reload - load new configs vhosts_clean () { ssh -t -t -o StrictHostKeyChecking=no -i "$RSA_KEY" "$USER@$1" "bash -c ' if [ ! -d $NGINX_PREV_TMP ]; then mkdir $NGINX_PREV_TMP else rm -rfv $NGINX_PREV_TMP && mkdir -v $NGINX_PREV_TMP fi if [ -d $R_CONFD_DIR ]; then if sudo mv -v $R_CONFD_DIR/* $NGINX_PREV_TMP/; then echo "$R_CONFD_DIR content moved to $NGINX_PREV_TMP" echo "" else echo "ERROR: can not move files from $R_CONFD_DIR to $NGINX_PREV_TMP. Exit." exit 1 fi else echo "ERROR: can not find $R_CONFD_DIR. Exit." exit 1 fi '" } vhosts_copy () { ssh -t -t -o StrictHostKeyChecking=no -i "$RSA_KEY" "$USER@$1" "bash -c ' if [ -d $NGINX_NEW_TMP ]; then rm -rf $NGINX_NEW_TMP && mkdir $NGINX_NEW_TMP else mkdir $NGINX_NEW_TMP fi '" echo -e "\n$NGINX_NEW_TMP created.\n" scp -r -o StrictHostKeyChecking=no -i $RSA_KEY $L_CONFD_DIR/* $USER@$1:$NGINX_NEW_TMP/ ssh -t -t -o StrictHostKeyChecking=no -i "$RSA_KEY" "$USER@$1" "bash -c ' if [ -d $NGINX_NEW_TMP -a -d $R_CONFD_DIR ]; then sudo cp -rv $NGINX_NEW_TMP/* $R_CONFD_DIR/ echo "" else echo "ERROR: can not find $NGINX_NEW_TMP or $R_CONFD_DIR. Exit." exit 1 fi '" } nginx_rollback () { echo -e "\n[$me] NGINX rollback started.\n" ssh -t -t -o StrictHostKeyChecking=no -i "$RSA_KEY" "$USER@$1" "bash -c ' if [ -d $NGINX_PREV_TMP -a -d $R_CONFD_DIR ]; then sudo rm -rfv $R_CONFD_DIR/* sudo mv -v $NGINX_PREV_TMP/* $R_CONFD_DIR echo "" rm -rfv $NGINX_PREV_TMP rm -rfv $NGINX_NEW_TMP echo "" else echo "ERROR: can not find $NGINX_PREV_TMP or $R_CONFD_DIR to run NGINX rollback. Exit." exit 1 fi '" } nginx_check () { ssh -t -t -o StrictHostKeyChecking=no -i "$RSA_KEY" "$USER@$1" "bash -c ' if sudo $NGINX_BIN -t; then echo "" rm -rfv $NGINX_PREV_TMP rm -rfv $NGINX_NEW_TMP echo "" else exit 1 fi '" } nginx_reload () { ssh -t -t -o StrictHostKeyChecking=no -i "$RSA_KEY" "$USER@$1" "bash -c ' sudo $NGINX_INIT reload echo "" '" } echo -e "[$me] NGINX cleanup started.\n" if vhosts_clean $HOST; then echo -e "\n[$me] $R_CONFD_DIR cleaned up.\n" else echo -e "\n[$me] ERROR: can not clean $R_CONFD_DIR. Exit.\n" exit 1 fi echo -e "[$me] Copy new config files to $HOST.\n" if vhosts_copy $HOST; then echo -e "\n[$me] New configuration files placed.\n" else echo -e "\n[$me] ERROR: during vhosts_copy(). Exit.\n" exit 1 fi echo -e "[$me] Verifying new configuration.\n" if nginx_check $HOST; then nginx_reload $HOST else echo -e "\nERROR: NGINX can not validate new config files. Running NGINX rollback." nginx_rollback $HOST && nginx_check $HOST && nginx_reload $HOST echo -e "\nNGINX completed successfully but exiting with 1.\n" exit 1 fi
GoCD
Пайплайн в GoCD имеет два шага — NGINXbackup и NGINXupdate:
На NGINXbackup выполняется скрипт backup.sh,
которому первым аргументом передаётся имя прокси-хоста:
На NGINXupdate — обновление конфигурации NGINX:
И результат работы NGINXupdate: