Как организовать деплой с Bitbacket
(Взято из комментария на хабре Q&A по причине удаления этого вопроса с ответами. Автор ответа Андрей Хохлов @andrhohlov )
VPS с Ubuntu, на нем установлен соответственно git и созданы 2 папки под сайты
test.example.com (тестовая версия сайта)
и example.com (боевая версия)
Создать на сервере директорию для репозиториев, например:
| 1 | sudo mkdir /var/www/git | 
Далее я дал права на папку с сайтами и репозиториями пользователю www-data (собственно с правами и была основная морока при реализации)
| 1 | sudo chown -R www-data:www-data /var/www | 
И все делал от имени этого пользователя (под ним работает apache или nginx).
Сгенерировал ему ключи
| 1 | sudo -u www-data ssh-keygen -t rsa | 
Создал конфиг файл
| 1 | sudo -u www-data nano /var/www/.ssh/config | 
и добавил в него
| 1 2 | Host bitbucket.org  IdentityFile ~/.ssh/id_rsa | 
Сгенерированый ключ нужно добавить в битбакет (Settings -> Deployment keys).
Если далее будет проблема с ключами, проверить права доступа к ним, если что выставить:
| 1 2 3 4 | sudo chmod 0755 /var/www/.ssh sudo chmod 0600 /var/www/.ssh/id_rsa sudo chmod 0600 /var/www/.ssh/id_rsa.pub sudo chmod 0644 /var/www/.ssh/known_hosts | 
Далее, клонируем репозиторий от имени пользователя www-data с ключем —mirror. Это в общем пустой репозиторий, без файлов. В гайде описывалось почему именно —mirror.
| 1 2 | cd /var/www/git sudo -u www-data git clone --mirror git@bitbucket.org:username/example.git | 
Копируем непосредственно файлы репозитория
| 1 2 | cd example.git sudo -u www-data GIT_WORK_TREE=/var/www/example.com/public_html git checkout -f master | 
Обратите внимание на путь GIT_WORK_TREE. Суть в том, что у нас файлы сайта будут храниться отдельно от папки .git.
В примере выше я копирую ветку master.
Далее, создаем скрипт деплоя
| 1 2 3 4 5 | cd /var/www/example.com/public_html sudo -u www-data mkdir deploy cd deploy sudo -u www-data touch deploy.log sudo -u www-data nano deploy.php | 
Рекомендуется обозвать папку и сам файл deploy.php каким-нибудь неадекватным набором символов вроде deploy-fseuo77w7rwegfe.php.
Собственно сам скрипт deploy.php, рассчитанный на 2 ветки, master (можно переименовать её в dev например и production.
| 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 | <?php // Examine the Bitbucket payload that’s being sent to deployment script file_put_contents('deploy.log', serialize($_POST['payload']) . "\n", FILE_APPEND); $repo_dir = '/var/git-repos/example.git'; $master_dir = '/var/www/dev.example.com/public_html'; $production_dir = '/var/www/example.com/public_html'; // Full path to git binary is required if git is not in your PHP user's path. Otherwise just use 'git'. $git_bin_path = 'git'; $update = false; // Parse data from Bitbucket hook payload $payload = json_decode($_POST['payload']); if (empty($payload->commits)){     // When merging and pushing to bitbucket, the commits array will be empty.     // In this case there is no way to know what branch was pushed to, so we will do an update.     $update = true; } else {     foreach ($payload->commits as $commit) {         $branch = $commit->branch;         if ($branch === 'master' || isset($commit->branches) && in_array('master', $commit->branches)) {             $update = true;             break;         }         elseif ($branch === 'production' || isset($commit->branches) && in_array('production', $commit->branches)) {             $update = true;             break;         }     } } if ($update) {     // Do a git checkout to the web root     exec('cd ' . $repo_dir . ' && ' . $git_bin_path  . ' fetch');     exec('cd ' . $repo_dir . ' && GIT_WORK_TREE=' . $master_dir . ' ' . $git_bin_path  . ' checkout -f master');     exec('cd ' . $repo_dir . ' && GIT_WORK_TREE=' . $production_dir . ' ' . $git_bin_path  . ' checkout -f production');     // Log the deployment     $commit_hash = shell_exec('cd ' . $repo_dir . ' && ' . $git_bin_path  . ' rev-parse --short HEAD');     file_put_contents('deploy.log', date('m/d/Y h:i:s a') . " Deployed branch: " .  $branch . " Commit: " . $commit_hash . "\n", FILE_APPEND); } ?> | 
Остается только добавить post hook с ссылкой на deploy.php (Settings -> Hooks).
Получается что каждый раз когда мы пушим изменения в репозиторий (не важно в какую ветку) обновляются файлы на сервере в обоих ветках.