Installing Your Own Repository Using BitBucket

In many companies with software developers, version control systems (VCS, or Revision Control System) are essential. These systems are needed so that every employee can work on his part of the code without interfering with others. Git is one of the most popular of such systems. On the Internet, many online services support this VCS. Nevertheless, sometimes it is necessary to have full control over the stored code, but at the same time to provide our developers an opportunity to work remotely and always have an up-to-date version. For the needs of our company it was decided to use a private repository. Git support was an additional condition. Our choice fell on Bitbucket.

Requirements Check-Up

Before installation, let's check the minimum requirements:

  • You must have root access
  • Windows or Linux OS (MacOS may not be supported);
  • 2+ processor cores and 3GB+ RAM (assuming that the bitbucket server itself uses 1GB and git operations require additional 2GB);
  • PostgreSQL or Oracle DBMS (MySQL, however, is not recommended);
  • Git version 2.9.4 or higher.

For more information, please visit the official page.

In my experience, you can run on 2GB of RAM for tests, but you have to disable Elastixsearch, and sometimes Bitbucket crashes with a lack of memory error, especially if you do not have swap file set up.

As an operating system, we will use CentOS 7, which is a well-proven server solution. PostgreSQL will be a DBMS of our choice.

Preconfiguration

To begin with, we install several convenient packages:

# yum install epel-release mc net-tools

Let's create the supp user:

# useradd supp

And set up a password for it:

# passwd supp

Then edit the /etc/ssh/sshd_config file​

Let's uncomment the following line: PermitRootLogin no and add an AllowUsers supp line below

PermitRootLogin no
AllowUsers supp

Let's restart sshd service

# systemctl restart sshd

Next, let's fix the /etc/sudoers file​

Let's find root ALL= (ALL) ALL line and add supp ALL= (ALL) ALL after it.

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

Git Installation

It is necessary to install git before installation.

CentOS has git of old version 1.8.3.1

It is possible to install git from source or from a third-party repository.

From a third-party repository:

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

Thus, we will install version 2.16.5

If you want to install a later version (currently version 2.19.1 is available), install from the source:

$ 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

Let's check the installed version:

$ git --version
git version 2.19.1

PostgreSQL Installation

Then let's install PostgreSQL. In CentOS repositories of version 9.2.24, bitbucket requires version from 9.3.6 and up to 10, version 11 is not yet described as supported. We will be installing version 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

Then we edit the /var/lib/pgsql/10/data/pg_hba.conf file and add the line:

host bitbucket bitbucketuser 127.0.0.1/32 md5

Let's create a bitbucket user and a bitbucket database:

$ 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

Then we reboot PostgreSQL to apply the settings in the pg_hba.conf file:

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

Установка Bitbucket

Download BitBucket from the official website.

Or straight from the command line:

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

Go to the folder to where the bitbucket file was downloaded and enter the command

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

Then, as is written in the official documentation, use sudo, which will allow bitbucket to be used as a service.

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

During installation, the installer asks various questions. You can simply press Enter for each question, but we change the installation location of Bitbucket itself (/home/bitbucket) and of its 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 ...

If you pressed Enter for each question, then the default folder for bitbucket itself would be /opt/atlassian/bitbucket/5.15.0.​

The default folder for repository, plugins and other data would be /var/atlassian/application-data/bitbucket.

Firewall Configuration

You now need to configure a firewall. By default, CentOS 7 has firewalld. Let's create a separate service for www access control:

$ 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

Similarly, we create a service for ssh access:

$ 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

To apply the settings, we'll reload the rules:

$ sudo firewall-cmd --reload

Checking:

$ 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:

Or you can make it even easier and simply add ports (7990 for www and 7999 for ssh) to the zone:

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

If you do not want to use firewalld and are used to iptables, then you just need to write in following lines, disabling the default firewall beforehand:

$ 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

or if you have the last rule that forbids everything, then you can enter a command, where num_line is the number of the line where the rule will be inserted:

$ 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

Checking the rules:

$ sudo iptables -L -n -v

The final touches of the installation

Go to the link http://localhost:7990 or, if are not installing on a local machine like I do, go to http://your_domain:7990

The language is set to English, but we can change that a little bit later, if you need to. Bitbucket can use an internal database to store repositories, but we have installed PostgreSQL for a reason, so select "External" and enter information.

At this point we enter the information of our Bitbucket user. It's all quite simple here.

Now you need to enter the information on the license. First, we will generate a test license for 30 days, click Create an account to create an account on atlassian. After registration, the window that allows us to obtain a license pops up:

Copy Server ID from the license entry page.

If anything happens, the license key will be on the website.

Bitbucket is installed and you can start using it.

In the upper right corner click the gear, choose Database.

For completeness of the basic configuration, let's configure the mail server. Click on the gear in the upper right corner again, then choose Mail Server. I will show an example configuring mail on mail.ru. Messages, including forgotten passwords, will be sent on behalf of this address.

Now the server can be used.

The Final Touches of the Installation

Now let's set something up to make Bitbucket more comfortable to use. First of all, if you want to use the interface in a different language, here’s how you can do that. We will use Russian as an example. The Russian language, as well as many others, doesn't come with standard add-ons, but there is a community that translates this software into different languages. Let's go to the product site and look for the language we need. We need the Russian language. It says in the description that a bit more than 53% of translation is complete, but that is more than enough for most users. Next, we download a package to your computer.

After that, go to the settings (the gear in the upper right corner) and find the Manage apps item.

Click Upload app - and choose the downloaded Russian language package (or any other). Wait a little, while it is setting up. Then go to the server settings and select in the drop-down list Language - Русский (Россия), click Save.

Security

By default, Bitbucket works on HTTP, which means all passwords are passed in an open form. Let's improve safety by allowing only HTTPS. It is not possible to enable HTTPS by Bitbucket with free Let's Encrypt certificates because they do not contain information about the organization (name, organization, location). In addition, the developer does not guarantee stable support and work, so we will implement HTTPS on nginx. We will have Let's Encrypt as a certification center. Certbot will help us with installation. Click on the link to select it by yourself or use the instructions below. In the console, type the following commands:

$ 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

Allow access to 80 (default for HTTP) and 443 (default for HTTPS) ports in firewall. With HTTP, we make forwarding to HTTPS a little further.

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

In this case, we added services that have ports 80 and 443, you can add those ports:

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

If you decide not to use firewalld and are more used to iptables, then:

$ 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

Start the certificate issuing procedure and, when asked about forwarding to HTTPS, select item 2 (forward):

$ 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

Now we have certificates. Let’s automate the renewal of the certificate, since the current certificate will expire on 2019-01-25. For this, we add a daily attempt to reissue the certificate to cron. Before the certificate expires, depending on the settings, it will be reissued. Add the following line to cron:

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

Let's check the result:

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

Now let's switch Bitbucket into proxy mode. To do this, in the application installation folder (we installed in the /home/bitbucketapp folder, by default it is /var/atlassian/application-data/bitbucket) find the shared/bitbucket.properties file and add the following lines:

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

Save changes. Then change the base URL in the server settings of the web interface to the following URL: https://your_domain

Now you can restart Bitbucket

$ sudo service atlbitbucket stop
$ sudo service atlbitbucket start

Now go to NGINX settings (/etc/nginx/nginx.conf by default) and in the server section that listens to port 443 add the following:

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;
        }

Next:

$ sudo nginx -s reload

Bitbucket restarts for 3 minutes, so don't worry if nothing else works. Moreover, do not forget to close access to port 7990 in the firewall, leave 7999 for ssh:

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

Alternatively, for iptables, first look at the rule number for port 7990, and then delete:

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

Goodies

Bitbucket can be restarted in several ways, which depend on the way it was installed. If it was installed as a service, you can restart it the following way:

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

If you installed Bitbucket not as a service, then you can use the following commands to restart it (we installed in /home/bitbucket folder, default is /opt/atlassian/bitbucket/5.15.0):

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

If you need to run Bitbucket without Elastixsearch, use the command:

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

Logs when errors occur can be found in the installation folder for applications /home/bitbucketapp/log/ (we installed in /home/bitbucketapp folder, default is /var/atlassian/application-data/bitbucket).

The system in the web interface supports hotkeys, the full list of which can be viewed by pressing Shift+? or you can click the question mark in the upper right corner and select Keyboard shortcuts.

Conclusion

After a few hours of installation, we have a full-scale personal Git repository. Our server is online and is accessible from anywhere in the world. For greater security, you can restrict access to the server to a list of IP addresses. Alternatively, you can set up the VPN through which access to the repository will be made. Moreover, if external access to the server is not necessary, then it is not necessary to transfer to HTTPS, and the server works faster. But that is a topic for a separate article. It wasn't that hard, was it?