![]()
Вчера опубликовал статью о своем опыте настройки VPS. Обещал, что как только появится время, напишу пару баш скриптов, которые автоматизируют часть рутинной работы и сведут количество действий, выполняемых руками, к разумному минимуму.
Я напряг все имеющиеся извилины, откопал в аналах своей памяти скромные познания bash скриптинга и, потратив несколько часов, написал скромное приложение, которое упрощает и ускоряет процесс создания виртуальных хостов для Apache и Nginx.
Чтобы скрипт был хоть сколько-нибудь интересен не только мне и имел минимум привязки к среде, где он будет запускаться, я постарался вынести все пути и прочее в блок конфига, сохранив их в переменные. Тем не менее, я не рекомендую бездумно использовать его. Хотя бы глазами пробегитесь по коду, чтобы понимать, подойдет ли он вам «из коробки» (я сомневаюсь, если честно). Всякую ответственность за последствия, которые могут приключиться с вами после использования данного скрипта, само собой, я снимаю :) Все на свой страх и риск, как говорится. Но поломаться ничего не должно. Скрипт ничего не удаляет, не вносит изменений ни в какие файлы. Он может только намусорить…
Ниже код скрипта и некоторые комментарии к блоку конфига и способам использования.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 | #!/bin/bash ####### CONFIG START ######## OWNER_NAME='username' # Пользователь, которому будет принадлежать директория вирт. хоста OWNER_GROUP='username' # Группа, которой будет принадлежать директория вирт. хоста HOME_WWW=~username/www # Домашняя директория для вирт. хостов HOST_DIRS=('backup' 'logs' 'public_html') SERVER_IP='127.0.0.1' # IP адрес сервера WHEREIS_APACHE=/etc/apache2 WHEREIS_NGINX=/etc/nginx APACHE_HOSTS_DIR=$WHEREIS_APACHE'/sites-available' NGINX_HOSTS_DIR=$WHEREIS_NGINX'/sites-available' NGINX_HOSTS_ENABLED=$WHEREIS_NGINX'/sites-enabled' ######## CONFIG END ########## # COLORS SETCOLOR_SUCCESS="echo -en \\033[1;32m" SETCOLOR_FAILURE="echo -en \\033[1;31m" SETCOLOR_NORMAL="echo -en \\033[0;39m" SETCOLOR_NOTICE="echo -en \\033[1;33;40m" # FUNCTIONS function restart_servers { echo 'Перезапускаем Apache' /etc/init.d/apache2 reload echo 'Перезапускаем Nginx' /etc/init.d/nginx reload return 1 } function error_config { $SETCOLOR_FAILURE echo "$(tput hpa $(tput cols))$(tput cub 6)[Fail]" echo '[CONFIG ERROR]: '$1 $SETCOLOR_NORMAL exit } function error_force_exec { $SETCOLOR_FAILURE echo "$(tput hpa $(tput cols))$(tput cub 6)[Fail]" echo -n '[FORCE EXEC ERROR]: ' if [ -z "$1" ]; then echo 'Скрипт не может корректно выполнить все процедуры в автоматическом режиме' else echo $1 fi $SETCOLOR_NORMAL exit } function error_failure { $SETCOLOR_FAILURE echo "$(tput hpa $(tput cols))$(tput cub 6)[Fail]" echo '[ERROR]: '$1 $SETCOLOR_NORMAL exit } function error_notice { $SETCOLOR_NOTICE echo '[NOTICE]: '$1 $SETCOLOR_NORMAL return 1 } # Если запущен с ключем -f, значит задаем пользователю минимум вопросов # Игнорируются вопросы: # - имя директории виртуального хоста # - вопрос о перезапуске серверров (будут перезапущены) if [ "$1" == "-f" ]; then force_execution=true else force_execution=false fi echo $SETCOLOR_NORMAL if [ -d $HOME_WWW ]; then cd $HOME_WWW else error_config "Директория $HOME_WWW не существует" fi # Запрашивает имя домена, пока не будет введено function get_domain_name { echo -n "Имя домена: " read domain_name # Если ничего не было введено if [ -z $domain_name ]; then $SETCOLOR_FAILURE echo "Вы не ввели имя домена" $SETCOLOR_NORMAL get_domain_name else return 1 fi } # Запрашивает имя директории для виртуального хоста или предлагает создать автоматически # проверяет его на существование function get_host_dir { echo -n "Имя директории хоста: " read host_dir # Если ничего не было введено if [ -z $host_dir ]; then $SETCOLOR_NOTICE echo -n "Вы не ввели имя директории хоста. Создать автоматически? [Н/д]? " $SETCOLOR_NORMAL read answer case "$answer" in Y|y|д|Д) host_dir=${domain_name//\./_} host_dir=${host_dir//\-/} if [ -d ${HOME_WWW}'/'${host_dir} ]; then error_notice "Автоматический выбор имени директории невозможен. Задайте его самостоятельно" get_host_dir else error_notice "Директория хоста будет создана автоматически: $host_dir" fi return 1 ;; N|n|о|О) get_host_dir ;; *) get_host_dir ;; esac get_host_dir else return 1 fi } get_domain_name if $force_execution; then host_dir=${domain_name//\./_} if [ -d ${HOME_WWW}'/'${host_dir} ]; then error_force_exec fi else get_host_dir fi # Проверяем пути апача из конфига if [ -d $APACHE_HOSTS_DIR ]; then if [ -a $APACHE_HOSTS_DIR'/'$domain_name ]; then error_failure "Виртуальный хост $domain_name уже существует для Apache" fi else error_config "Директория $APACHE_HOSTS_DIR не существует" fi # Проверяем пути nginx из конфига if [ -d $NGINX_HOSTS_DIR ]; then if [ -a $NGINX_HOSTS_DIR'/'$domain_name ]; then error_failure "Виртуальный хост $domain_name уже существует Nginx" fi else error_config "Директория $NGINX_HOSTS_DIR не существует" fi echo "Домен: $domain_name" # Создаем директории виртуального хоста host_dir_path=${HOME_WWW}'/'${host_dir} echo "Создаем директории виртуального хоста:" mkdir $host_dir_path for dir_name in ${HOST_DIRS[@]}; do mkdir $host_dir_path'/'$dir_name echo -e "\t $host_dir_path/$dir_name" done touch ${host_dir_path}'/public_html/index.html' # Рекурсивно проставляем права chown -R $OWNER_NAME:$OWNER_GROUP $host_dir_path apache_template="<VirtualHost 127.0.0.1:8080> ServerAdmin webmaster@$domain_name ServerName $domain_name ServerAlias www.$domain_name DocumentRoot $HOME_WWW/$host_dir/public_html ScriptAlias /cgi-bin/ $HOME_WWW/$host_dir/public_html/cgi-bin/ ErrorLog $HOME_WWW/$host_dir/logs/apache.error.log LogLevel warn CustomLog $HOME_WWW/$host_dir/logs/apache.access.log combined </VirtualHost>" # Создаем конфиг виртуального хоста apache echo 'Создаем конфиг виртуального хоста apache:' touch ${APACHE_HOSTS_DIR}'/'${domain_name} echo -e "\t"${APACHE_HOSTS_DIR}'/'${domain_name} temp_ifs=$IFS IFS= echo $apache_template > ${APACHE_HOSTS_DIR}'/'$domain_name IFS=$temp_ifs # создаем симлинк a2ensite $domain_name nginx_template="server { listen $SERVER_IP:80; server_name $domain_name www.$domain_name; access_log $HOME_WWW/$host_dir/logs/nginx.access.log; location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar)$ { root /home/omm/www/$host_dir/public_html; } location / { proxy_pass http://backend; proxy_redirect off; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; charset utf-8; index index.html; root $HOME_WWW/$host_dir/public_html; } }" # Создаем конфиг виртуального хоста nginx echo 'Создаем конфиг виртуального хоста nginx:' touch ${NGINX_HOSTS_DIR}'/'${domain_name} echo -e "\t"${NGINX_HOSTS_DIR}'/'${domain_name} temp_ifs=$IFS IFS= echo $nginx_template > ${NGINX_HOSTS_DIR}'/'$domain_name IFS=$temp_ifs # создаем симлинк ln -s $NGINX_HOSTS_DIR'/'$domain_name $NGINX_HOSTS_ENABLED'/'$domain_name # Перезапускаем сервера if $force_execution; then restart_servers else echo -n 'Перезапустить Apache и Nginx? [Д/н] ' read restart_answer case "$restart_answer" in Y|y|д|Д) restart_servers ;; *) echo 'Apache и Nginx не были перезагружены' ;; esac fi $SETCOLOR_SUCCESS echo "$(tput hpa $(tput cols))$(tput cub 6)[OK]" $SETCOLOR_NORMAL |
Конфигурирование скрипта
В скрипте есть комментарии, но опишу переменные настройки еще раз.
OWNER_NAME – имя системного пользователя, которому будут принаджелать директории и файлы, создаваемые скриптом для виртуального хоста.
OWNER_GROUP – системная группа, которой будут принаджелать директории и файлы, создаваемые скриптом для виртуального хоста.
HOME_WWW – внутри этой директории будет создана директория виртуального хоста.
HOST_DIRS – директории виртуального хоста, которые будут созданы. По-умолчанию сюда вписана директория для логов apache и nginx, директория для бэкапов и директория, которая будет доступна по http протоколу, собственно, куда и нужно будет класть все файлы вашего сайта.
SERVER_IP – ip адрес вашего сервера. Прописывается в конфигах nginx.
WHEREIS_APACHE – директория установки Apache. Относительно нее будут искаться конфиги виртуальных хостов и прочее.
WHEREIS_NGINX – директория установки Nginx. Относительно нее будут искаться конфиги виртуальных хостов и прочее.
APACHE_HOSTS_DIR – директория, где Apache хранит конфиги для каждого отдельного виртуального хоста. Обычно это sites-available.
NGINX_HOSTS_DIR – директория, где Nginx хранит конфиги для каждого отдельного виртуального хоста. Обычно это sites-available.
NGINX_HOSTS_ENABLED – директория, где хранятся симлинки на конфиги виртуального хоста Nginx. В nginx нет утилиты подобной a2ensite, поэтому нужно знать, куда создать ссылку самим. Обычно данная директория называется sites-enabled.
Есть еще несколько переменных, в которых хранится код разукраски сообщений, которыми скрипт отписывается в консоль. Также можно поправить поведение ряда функци. Но все это совсем опционально и если очень хочется, то поглядите сами. Там все просто.
В скрипте есть еще две переменных, которые объявлены почти в конце листинга: apache_template и nginx_template. В них хранятся шаблоны для виртуальных хостов. Хотя бы посмотрите, что в них описано, чтобы быть уверенными в том, что конфиги имеют именно тот вид, который вам требуется.
Работа со скриптом
Скрипт может работать в двух режимах.
Простой запуск – запускаете скрипт и отвечаете на его вопросы. Он потребует ввести:
- имя домена, для которого создаются конфиги;
- имя директории виртуального хоста;
- спросит перезагрузить ли сервера, после того, как конфиги будут созданы
Если не задать скрипту имя директории виртуального хоста, то он создает ее автоматически. От перезагрузки серверов можно отказаться. Это удобно, когда вы планируете создать несколько виртуальных хостов подряд и нет смысла каждый раз заставлять Nginx и Apache делать reload (при reload создается избыточная нагрузка на процессор и потребляется больше памяти. Лучше сделать это один раз, когда все хосты будут добавлены).
Форсированный запуск – это типа автоматического режима. Скрипт задает только один вопрос – о имени домена. Все остальное он делает сам, в том числе перезагружает Nginx и Apache. При этом, если в ходе проверок скрипт выяснит, что выполнить какие-то операции он не сможет, то работа прекратится. Но учтите, что никаких подробных сообщений о проблеме не будет. Скрипт просто скажет, что он не может отработать в автоматическом режиме (скорее всего, конфликты с путями).
Для вызова скрипта в форсированом режиме необходимо запустить его с параметром –f
bash script_name.sh -f
На баше я пишу раз в сотню лет, так что, уж не обессудьте.

Спасибо, друг! Прям спас от мучительной смерти за тоннами манов!