Деплой с помощью Mercurial
Итак, я все мучаю бедный сервер. Дальше — очередная, никому кроме меня не нужная стена текста про развертывание сайта с помощью mercurial. Если кратко, это поможет очень быстро вносить изменения в сайтик, и сильно ускорит его допиливание.

Это не красиво и долго. Самый простой выход — использовать для этого систему контроля версий (я привык к mercurial). Она сама будет смотреть за изменениями и перемещать только изменившиеся файлы. Да и мне будет легко видеть что поменялось от ревизии к ревизии.
Сказано-сделано.
создаем каталог для репозиториев:
Добавляем под домен для mercurial (/etc/nginx/conf.d/):
То есть, при обращении к hg.tqfp.org, просим пароль, если все хорошо, соединяем с сервером mercurial'а на локалхосте.
перезапускаем nginx:
теперь нужно бы добавить пользователей. Для этого используются утилиты от apache:
добавляем пользователя:
Добавляем файлик, который указывает, где искать репозитории (/etc/hgweb.conf):
А в /etc/mercurial/hgrc:
Теперь нужно запустить сам mercurial. Самое интересное, что готового скрипта для авто-запуска mercurial я не нашел (точнее, что-то нашел, но оно было нерабочим). Пришлось писать по аналогии с nginx'ом:
теперь его можно установить (предварительно, скопировав в /etc/init.d):
Позже я решил, что я буду включать mercurial только когда работаю над сайтом — на одну возможность хакнуть сайт будет меньше :)
ну, и запускаем сам mercurial:
Итак, создаем /var/repos/tqfp.org/.hg/hgrc:
Ну, и сам hg_sync.sh:
Вуаля!
Теперь мне на локалке достаточно написать:
и все изменения отправятся на сервер, сбросятся кэши и вы увидите обновленный сайтик :)

Зачем?
Я давно хотел, чтобы изменения на сайтик выкладывались как можно проще, потому, что сейчас это происходит так:- Я модифицирую код
- Вспоминаю, в каких файлах что сделал
- Перекидываю файлы по FTP
- Сношу три кэша (да, в лайвстрите аж 3 кэша)
- Бинго
Это не красиво и долго. Самый простой выход — использовать для этого систему контроля версий (я привык к mercurial). Она сама будет смотреть за изменениями и перемещать только изменившиеся файлы. Да и мне будет легко видеть что поменялось от ревизии к ревизии.
Сказано-сделано.
Ставим mercurial на сервер.
apt-get install mercurial
создаем каталог для репозиториев:
mkdir /var/repos
Добавляем под домен для mercurial (/etc/nginx/conf.d/):
upstream hg_backend {
server 127.0.0.1:8245;
}
server {
listen 80;
server_name hg.tqfp.org;
access_log /var/log/nginx/hg_access.log;
error_log /var/log/nginx/hg_error.log warn;
client_max_body_size 100m;
location / {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/hg.htpasswd;
proxy_pass https://hg_backend;
}
}
То есть, при обращении к hg.tqfp.org, просим пароль, если все хорошо, соединяем с сервером mercurial'а на локалхосте.
перезапускаем nginx:
service nginx restart
теперь нужно бы добавить пользователей. Для этого используются утилиты от apache:
apt-get install apache2-utils
добавляем пользователя:
htpasswd -m hg.htpasswd bsvi
Добавляем файлик, который указывает, где искать репозитории (/etc/hgweb.conf):
[collections]
/var/repos/ = /var/repos/
А в /etc/mercurial/hgrc:
[web]
style = gitweb
allow_push = *
push_ssl = false
baseurl =/.
Теперь нужно запустить сам mercurial. Самое интересное, что готового скрипта для авто-запуска mercurial я не нашел (точнее, что-то нашел, но оно было нерабочим). Пришлось писать по аналогии с nginx'ом:
#!/bin/sh
### BEGIN INIT INFO
# Provides: hg
# Required-Start: $remote_fs
# Required-Stop: $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Mercurial VCS
### END INIT INFO
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="Mercurial VCS"
NAME=hg
HOME=/var/$NAME
DAEMON=/usr/bin/$NAME
PIDFILE=/var/run/$NAME.pid
DAEMON_ARGS="serve --webdir-conf /etc/mercurial/hgweb.conf \
--address 127.0.0.1 --port 8085 --encoding utf8 --daemon --pid-file $PIDFILE"
SCRIPTNAME=/etc/init.d/$NAME
[ -x "$DAEMON" ] || exit 0
. /lib/init/vars.sh
. /lib/lsb/init-functions
do_start()
{
touch $PIDFILE
chown hg $PIDFILE
start-stop-daemon --start --pidfile $PIDFILE --exec $DAEMON \
--chuid hg:hg -- $DAEMON_ARGS || return 2
}
do_stop()
{
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 \
--pidfile $PIDFILE --name $NAME
RETVAL="$?"
[ "$RETVAL" = 2 ] && return 2
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 \
--exec $DAEMON
[ "$?" = 2 ] && return 2
rm -f $PIDFILE
return "$RETVAL"
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
restart|force-reload)
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
exit 3
;;
esac
:
теперь его можно установить (предварительно, скопировав в /etc/init.d):
update-rc.d hg defaults
Позже я решил, что я буду включать mercurial только когда работаю над сайтом — на одну возможность хакнуть сайт будет меньше :)
ну, и запускаем сам mercurial:
./hg start
Деплой
Теперь нужно решить, как мы будем разворачивать наш сайтик. Я для этого решил использовать немного небезопасный метод (привет, паранойя). Идея вот в чем: при пуше, вызывается скрпт, который создает симлинк из /var/repos/tqfp.org/.hg в chroot самого сайта (/var/www/tqfp.org/.hg). Там делается hg update и симлинк уничтожается. Если за пару секунд, за которые происходит это действо, кто-то успеет получить root'а и прицепить хук к окончанию апдейта mercurial, то он получит доступ ко всему серверу. Ничего лучше я не придумал (точнее, придумал, но получилось бы не так круто), поэтому — рискнем.Итак, создаем /var/repos/tqfp.org/.hg/hgrc:
[hooks]
changegroup = /var/repos/tqfp.org/hg_sync.sh
Ну, и сам hg_sync.sh:
#!/bin/sh
REPO_DIR=/var/repos/tqfp.org
DEST_DIR=/var/www/tqfp.org
if [ `whoami` = root ]; then
echo "root shall do su hg!"
exit 1
fi
ln -s $REPO_DIR/.hg $DEST_DIR/.hg
cd $DEST_DIR
hg update --clean
rm .hg
echo "flush_all" | /bin/netcat -q 2 127.0.0.1 11211
rm -rf templates/compiled/bsvi/*
rm -rf templates/cache/bsvi/*
Вуаля!
Теперь мне на локалке достаточно написать:
hg push
и все изменения отправятся на сервер, сбросятся кэши и вы увидите обновленный сайтик :)
1 комментарий
По методу — хитро — и деплой есть, и дыры (папка .hg) нет :)
Хотя тема деплоя раскрыта не полностью. Ведь можно(а лучше нужно) делать деплой определенной ветки.
Раздумываю еще… Abricos, к примеру, любит модернизировать базу данных при обновлении. Как бы так витиевато иметь возможность отката не из ночных бэкапов и привязать базу к меркуралу, причем содержимое базы категорически не должно быть в репо.