Система управления прокси-сервером под 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:





