Установка собственного репозитория на примере BitBucket

Во многих компаниях, где есть разработчики программного обеспечения(ПО), не обойтись без систем контроля версий(Version Control System, VCS, или Revision Control System). Эти системы нужны, чтобы каждый сотрудник мог работать над своей частью кода не мешая при этом остальным. Одной из самых популярных является Git. В интернете много онлайн сервисов поддерживают данную VCS. Но иногда требуется иметь полный контроль над хранимым кодом, но при этом чтобы наши разработчики могли работать удаленно и всегда имелась актуальная версия. Для нужд нашей компании было принято решение использовать приватный репозиторий. Как дополнительным условием было поддержка Git. Выбор пал на Bitbucket.

Проверка требований

Перед установкой проверяем минимальные требования:

  • У вас должен быть root доступ
  • ОС Windows или Linux (MacOS может не поддерживаться);
  • 2+ ядер процессоров и 3ГБ+ оперативной памяти (предполагается, что на сам bitbucket сервер 1ГБ и 2ГБ на операции git);
  • СУБД PostgreSQL или Oracle (а вот MySQL не рекомендуется);
  • git версии 2.9.4 и выше.

Для более подробной информации можно посмотреть на официальной странице.

По своему опыту скажу, что запустить можно и на 2ГБ оперативной памяти для тестов, но придется отключить Elastixsearch, и иногда будет Bitbucket вылетать с ошибкой о нехватки памяти, особенно если у Вас не настроен swap.

В качестве операционной системы будем использовать CentOS 7 как хорошо зарекомендовавшая себя в серверных решениях. СУБД PostgreSQL завершит наш выбор.

Предварительная настройка

Для начала установим несколько удобных пакетов:

# yum install epel-release mc net-tools

Cоздадим пользователя supp:

# useradd supp

И зададим ему пароль:

# passwd supp

Затем отредактируем файл /etc/ssh/sshd_config

Раскоментируем строчку: PermitRootLogin no и добавим ниже строку AllowUsers supp

PermitRootLogin no
AllowUsers supp

Перезапустим sshd сервис

# systemctl restart sshd

Далее поправим файл /etc/sudoers

Находим строку root ALL=(ALL) ALL и после нее добавляем supp ALL=(ALL) ALL

root      ALL=(ALL)       ALL
supp      ALL=(ALL)       ALL

Установка Git

Перед установкой требуется установить git.

В CentOS последний git старой версии 1.8.3.1

Можно поставить git из исходников или со стороннего репозитория.

Со стороннего репозитория:

$ wget https://centos7.iuscommunity.org/ius-release.rpm
$ sudo rpm -i ./ius-release.rpm
$ sudo yum update
$ sudo yum install git2u.x86_64

Таким образом установим версию 2.16.5

Если требуется установить более позднюю версию(на текущий момент доступна версия 2.19.1), то устанавливаем из исходников:

$ wget https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.19.1.tar.gz
$ wget https://mirrors.edge.kernel.org/pub/software/scm/git/git-manpages-2.19.1.tar.gz
$ tar -xzf ./git-2.19.1.tar.gz
$ cd ./git-2.19.1
$ sudo yum -y install autoconf gcc zlib-devel.x86_64 asciidoc xmlto curl-devel
$ make configure
$ ./configure --prefix=/usr 
$ make all doc 
# sudo make install install-doc install-html

Проверяем установленную версию:

$ git --version
git version 2.19.1

Установка PostgreSQL

Затем устанавливаем PostgreSQL. В репозиториях CentOS версия 9.2.24, bitbucket требует версии от 9.3.6 и до 10, 11-я пока в поддержке не описана. Будем ставить 10-ю версию.

$ sudo yum -y install https://download.postgresql.org/pub/repos/yum/10/redhat/rhel-7-x86_64/pgdg-centos10-10-2.noarch.rpm
$ sudo yum -y install postgresql10 postgresql10-server
$ sudo /usr/pgsql-10/bin/postgresql-10-setup initdb
$ sudo systemctl enable postgresql-10
$ sudo systemctl start postgresql-10

Затем редактриуем файл /var/lib/pgsql/10/data/pg_hba.conf и добавим строчку:

host bitbucket bitbucketuser 127.0.0.1/32 md5

Создадим пользователя bitbucketuser и базу данных bitbucket:

$ sudo su
# su postgres
$ psql
postgres=# CREATE ROLE bitbucketuser WITH LOGIN PASSWORD 'UserPass' VALID UNTIL 'infinity';
postgres=# CREATE DATABASE bitbucket WITH ENCODING='UTF8' OWNER=bitbucketuser CONNECTION LIMIT=-1;
postgres=# \q

Перезагрузим PostgreSQL для применения настроек в файле pg_hba.conf:

$ /usr/pgsql-10/bin/pg_ctl restart -D /var/lib/pgsql/10/data/

Установка Bitbucket

Скачать BitBucket можно на официальном сайте.

Либо прямо из командной строки:

$ wget https://www.atlassian.com/software/stash/downloads/binary/atlassian-bitbucket-5.15.0-x64.bin

Переходим в папку, где скачан файл bitbucket и вводим команду

$ chmod a+x ./atlassian-bitbucket-5.15.0-x64.bin

Затем, по рекомендации официальной документации, используем sudo, что позволит использовать bitbucket как сервис.

$ sudo ./atlassian-bitbucket-5.15.0-x64.bin

Во время установки, ингалятор будет спрашивать различные вопросы. Можно везде просто нажимать Enter, но мы сменим место установки самого Bitbucket (/home/bitbucket) и его application (/home/bitbucketapp):

---------------
Unpacking JRE ...
Starting Installer ...
 
Bitbucket 5.15.0 installation wizard
 
Would you like to install or upgrade an instance?
Install a new instance [1, Enter], Upgrade an existing instance [2]
 
Install Bitbucket 5.15.0
What type of instance are you looking to install?
Install a Server instance [1, Enter], Install a Data Center instance [2], Install a Smart Mirroring instance [3]
 
Where should Bitbucket be installed?
 
Select the folder where you would like Bitbucket 5.15.0 to be installed, then click Next.
[/opt/atlassian/bitbucket/5.15.0]
/home/bitbucket
Default location for Bitbucket home directory
 
The location for Bitbucket data.
This will be the default location for repositories, plugins, and other data.
 
Ensure that this location is not used by another Bitbucket installation.
[/var/atlassian/application-data/bitbucket]
/home/bitbucketapp
Configure which ports Bitbucket will use.
 
Configure TCP Ports
Bitbucket requires a TCP port that isn't being used by other applications.
The HTTP port is where users access Bitbucket through their browsers.
 
Bitbucket also requires ports 7992 and 7993 are available to run an embedded
Elasticsearch instance that provides search functionality to Bitbucket.
HTTP Port Number
[7990]
 
Run as a service
For a production server we recommend that you run Bitbucket as a Windows/Linux service because Bitbucket will restart automatically when the computer restarts.
Install Bitbucket as a service?
Yes [y, Enter], No [n]
 
Please review your Bitbucket installation settings
 
Installation Summary
Installation Directory: /home/bitbucket
Home Directory: /home/bitbucketapp
HTTP Port: 7990
Install as a service: Yes
 
Install [i, Enter], Exit [e]
 
Extracting files ...
 
Installation of Bitbucket is complete
Would you like to launch Bitbucket?
Yes [y, Enter], No [n]
 
Please wait a few moments while Bitbucket starts up.
Launching Bitbucket ...
 
Installation of Bitbucket 5.15.0 is complete
Your installation of Bitbucket 5.15.0 is now ready and can be accessed via your browser.
Bitbucket 5.15.0 can be accessed at http://localhost:7990
Launch Bitbucket 5.15.0 in browser?
Yes [y, Enter], No [n]
 
Finishing installation ...

Если вы везде нажимали Enter, то папка по умолчанию для самого bitbucket /opt/atlassian/bitbucket/5.15.0.

Папка по-умолчанию для репозиторий, плагинов и других данных /var/atlassian/application-data/bitbucket.

Настройка межсетевого экрана

Теперь требуется настроить межсетевой экран (firewall). По-умолчанию в CentOS 7 идет firewalld. Создадим отдельный сервис под управление www доступом:

$ sudo firewall-cmd --permanent --new-service=bitbucket-www
$ sudo firewall-cmd --permanent --service=bitbucket-www --set-description="Bitbucket is more than just Git code management. Bitbucket gives teams one place to plan projects, collaborate on code, test, and deploy. Service make a access via www."
$ sudo firewall-cmd --permanent --service=bitbucket-www --set-short="Bitbucket www access"
$ sudo firewall-cmd --permanent --service=bitbucket-www --add-port=7990/tcp
$ sudo firewall-cmd --permanent --zone=public --add-service=bitbucket-www

Аналогично создаем сервис для доступа по ssh:

$ sudo firewall-cmd --permanent --new-service=bitbucket-ssh
$ sudo firewall-cmd --permanent --service=bitbucket-ssh --set-description="Bitbucket is more than just Git code management. Bitbucket gives teams one place to plan projects, collaborate on code, test, and deploy. Service make a access via ssh."
$ sudo firewall-cmd --permanent --service=bitbucket-ssh --set-short="Bitbucket ssh access"
$ sudo firewall-cmd --permanent --service=bitbucket-ssh --add-port=7999/tcp
$ sudo firewall-cmd --permanent --zone=public --add-service=bitbucket-ssh

Для применения настроек перезагружаем правила:

$ sudo firewall-cmd --reload

Проверяем:

$ sudo firewall-cmd --list-all
public
  target: default
  icmp-block-inversion: no
  interfaces:
  sources:
  services: ssh bitbucket-www bitbucket-ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

Либо можно сделать ещё проще и просто добавить в зону порты (7990 - www и 7999 - ssh):

$ sudo firewall-cmd --permanent --zone=public --add-port=7990/tcp
$ sudo firewall-cmd --permanent --zone=public --add-port=7999/tcp
$ sudo firewall-cmd --reload

Если же Вы не хотите использовать firewalld и привыкли к iptables, то Вам достаточно прописать, предварительно отключив межсетевой экран по умолчанию:

$ sudo yum -y iptables-services
$ sudo systemctl stop firewalld
$ sudo systemctl disable firewalld
$ sudo iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
$ sudo iptables -A INPUT -s 0.0.0.0/0 -p TCP --dport 7990 -j ACCEPT
$ sudo iptables -A INPUT -s 0.0.0.0/0 -p TCP --dport 7999 -j ACCEPT
$ sudo iptables -A INPUT -s 0.0.0.0/0 -p TCP --dport 22 -j ACCEPT
$ sudo iptables -P INPUT DROP
$ sudo iptables -P FORWARD DROP

или если у вас последнее правило - все запрещает, то вводим такую команду, где num_line - номер строки, куда будет вставлено правило:

$ sudo iptables -I INPUT num_line -s 0.0.0.0/0 -p TCP --dport 7999 -j ACCEPT
$ sudo iptables -I INPUT num_line -s 0.0.0.0/0 -p TCP --dport 7990 -j ACCEPT
$ sudo iptables-save > /etc/sysconfig/iptables

Проверяем правила:

$ sudo iptables -L -n -v

Последние штрихи установки

Переходим по ссылке http://localhost:7990 или если не с локальной машины как я, то заходим на http://your_domain:7990

Пока язык английский, но мы это исправим чуть дальше. Bitbucket может использовать внутреннюю базу для хранения репозиториев, но мы не зря устанавливали PostgreSQL, поэтому выбираем External и вводим данные.

Здесь уже вводим данные нашего пользователя Bitbucket. Здесь все просто.

Теперь надо ввести данные лицензии. Для начала сделаем тестовую лицензию на 30 дней, жмем Create an account для создания аккаунта на atlassian. После регистрации мы попадаем в окно для получения лицензии:

Server ID копируем со страницы ввода лицензии. Если вдруг что-то случится, то лицензионный код будет на сайте.

Bitbucket установлен и можно начинать пользоваться.

Мигрировать на PostgreSQL можно и позже из меню настроек:

В правом верхнем углу нажимаем шестеренку, Database.

Для полноты базовой настройки настроим почтовый сервер. Снова нажимаем шестеренку в правом верхнем углу, затем Mail Server. Я покажу пример настройки для почты mail.ru. От имени этой почты будут рассылаться сообщения, в том числе о забытых паролях.

Теперь сервер можно использовать.

Последние штрихи установки

Теперь сделаем некоторые настройки для комфорта работы с Bitbucket. В первую очередь русифицируем его. В стандартных дополнениях русского языка, да и многих других - нет, но есть сообщество, которое переводит на разные языки. Переходим на сайт продукта и ищем нужный нам язык. Нам нужен русский. В описании сказано, что переведено чуть более 53% - но этого более чем достаточно для большинства пользователей. Скачиваем себе на компьютер пакет.

После этого заходим в настройки (шестеренка в правом верхнем углу) и находим пункт Manage apps.

Нажимаем Upload app - и указываем загруженный пакет русификации. Ждем немного, пока установится. Затем идем в настройки сервера (Server settings) и выбираем в выпадающем списке Language - русский (Россия), жмем Сохранить.

Безопасность

По умолчанию Bitbucket работает на протоколе HTTP, а значит все пароли передаются в открытом виде. Будем улучшать безопасность. Разрешим использование только HTTPS. С помощью бесплатных сертификатов Let’s Encrypt нельзя включить HTTPS средствами Bitbucket потому, что в них отсутствуют данные об организации (name, organization, location). К тому же нормальную поддержку и работу не гарантирует разработчик, поэтому будем реализовывать HTTPS на nginx. Центром сертификации у нас будет Let’s Encrypt. Ставить будем с помощью Certbot. Переходим по ссылке для самостоятельного выбора или воспользуемся инструкцией ниже. В консоли набираем следующие команды:

$ sudo yum -y install yum-utils nginx
$ sudo yum-config-manager --enable rhui-REGION-rhel-server-extras rhui-REGION-rhel-server-optional
$ sudo yum -y install python2-certbot-nginx
$ sudo systemctl enable nginx
$ sudo systemctl start nginx

Разрешим доступ в нашем межсетевом экране доступ по 80 (используется по умолчанию для протокола HTTP) и 443 (используется по умолчанию для HTTPS) портам. С HTTP сделаем переадресацию на HTTPS чуть дальше.

$ sudo firewall-cmd --permanent --zone=public --add-service=http
$ sudo firewall-cmd --permanent --zone=public --add-service=https
$ sudo firewall-cmd --reload

В данном случае бы добавили сервисы, в которых прописаны порты 80 и 443, можно вместо этого прописать порты:

$ sudo firewall-cmd --permanent --zone=public --add-port=80/tcp
$ sudo firewall-cmd --permanent --zone=public --add-port=443/tcp

Если Вы решили не использовать firewalld и больше привыкли к iptables, то:

$ sudo iptables -A INPUT -s 0.0.0.0/0 -p TCP --dport 80 -j ACCEPT
$ sudo iptables -A INPUT -s 0.0.0.0/0 -p TCP --dport 443 -j ACCEPT
$ sudo iptables-save > /etc/sysconfig/iptables

Запускаем процедуру выпуска сертификата и здесь же, когда спросит о переадресации на HTTPS выберем пункт 2 (переадресовывать):

$ sudo certbot --nginx -d your_domain
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): your_email
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. 
You must agree in order to register with the ACME server at https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier Foundation, a founding partner of the Let's Encrypt project and the non-profit organization that develops Certbot? We'd like to send you email about our work encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
Starting new HTTPS connection (1): supporters.eff.org
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for your_domain
Waiting for verification...
Cleaning up challenges
Deploying Certificate to VirtualHost /etc/nginx/nginx.conf
Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
Redirecting all traffic on port 80 to ssl in /etc/nginx/nginx.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://your_domain
You should test your configuration at: https://www.ssllabs.com/ssltest/analyze.html?d=your_domain
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IMPORTANT NOTES:
Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/your_domain/fullchain.pem
Your key file has been saved at: /etc/letsencrypt/live/your_domain/privkey.pem
Your cert will expire on 2019-01-25. To obtain a new or tweaked version of this certificate in the future, simply run certbot again with the "certonly" option. To non-interactively renew *all* of your certificates, run "certbot renew"
Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal.
If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate 
Donating to EFF: https://eff.org/donate-le

Теперь у нас есть сертификаты. Автоматизируем обновление сертификата, потому что текущий сертификат закончится 2019-01-25. Для добавим в cron ежедневную попытку перевыпустить сертификат. До истечения срока сертификата в зависимости от настроек он будет перевыпущен. Добавим в cron следующую строку:

$ sudo crontab -e
0 0 * * * /usr/bin/certbot renew

Проверяем результат:

$ sudo crontab -l
0 0 * * * /usr/bin/certbot renew

Переводим Bitbucket в режим работы за прокси. Для этого в папке установки приложений (мы устанавливали в папку /home/bitbucketapp, по умолчанию /var/atlassian/application-data/bitbucket) находим файл shared/bitbucket.properties и добавим следующие строки:

#behind proxy NGINX
server.port=7990
server.secure=true
server.scheme=https
server.proxy-port=443
server.proxy-name=your_domain
server.context-path=/

Сохраняем изменения. Затем меняем в настройках сервера в web интерфейсе базовый URL на следующий: https://your_domain

Теперь можно перезагрузить Bitbucket

$ sudo service atlbitbucket stop
$ sudo service atlbitbucket start

Теперь заходим в настройки NGINX (по умолчанию /etc/nginx/nginx.conf) и в секции server, что слушает на 443 порту добавляем следующее:

location / {
            proxy_pass          http://localhost:7990;
            proxy_set_header    X-Forwarded-Host $host;
            proxy_set_header    X-Forwarded-Server $host;
            proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header    X-Real-IP $remote_addr;
            proxy_redirect      off;
        }

Далее:

$ sudo nginx -s reload

Bitbucket перезагружается 3 минуты, поэтому не переживаем, если еще ничего не работает. И не забудем закрыть доступ в межсетевом экране по порту 7990, 7999 оставим для ssh:

$ sudo firewall-cmd --permanent --zone=public --remove-service=bitbucket-www
$ sudo firewall-cmd --reload

Ну или для iptables. Сначала посмотрим номер правила для порта 7990, а уже потом удалим:

$ sudo iptables -L -n -v --line-numbers
$ sudo iptables -D INPUT number_line
$ sudo iptables-save > /etc/sysconfig/iptables

Полезности

Перезагружать Bitbucket можно несколькими способами и зависит от варианта установки. Для перезагрузки в случае установки как сервиса:

$ sudo service atlbitbucket status 
$ sudo service atlbitbucket stop 
$ sudo service atlbitbucket start

Если же при установке Bitbucket Вы выбрали вариант не как сервис, то для перезагрузки используем следующие команды (мы устанавливали в папку /home/bitbucket, по умолчанию /opt/atlassian/bitbucket/5.15.0):

$ sudo /home/bitbucket/bin/stop-bitbucket.sh 
$ sudo /home/bitbucket/bin/start-bitbucket.sh 

Если нужно запустить Bitbucket без Elastixsearch, то используем команду:

$ sudo /home/bitbucket/bin/start-bitbucket.sh --no-search

Логи при возникновении ошибок смотреть в папке установки для приложений /home/bitbucketapp/log/ (мы устанавливали в папку /home/bitbucketapp, по умолчанию /var/atlassian/application-data/bitbucket).

Система в web интерфейсе поддерживает горячие клавиши, полный список которых Вы можете посмотреть нажав Shift+? или в правом верхнем углу нажать вопрос и выбрать Keyboard shortcuts.

Заключение

Спустя несколько часов установки мы имеем полноценный персональный Git репозиторий. Наш сервер смотрит в интернет и доступен из любой точки мира. Для большей безопасности можно ограничить доступ к серверу списком ip адресов. Или поднять VPN, через который будет осуществляться доступ к репозиторию. А если снаружи доступ к серверу не нужен, то и переводить на HTTPS не обязательно, сервер работать быстрее будет. Но все это уже тема для отдельной статьи. Было ведь не сложно, правда?