I'm not dead yet, it's true!
So today is a short topic because I found out that installing SonarQube server with PostgreSQL is a piece of rock ... heheh!
No use case, today, install SonarQube server with PostgreSQL
So, let's start with a fresh Ubuntu 16.04 with some basic packages such as:
wget --quiet -0 - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo aptkey add -
sudo add-apt-repository "deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main"
sudo apt-get update
sudo apt install postgresql-10 postgresql-contrib
Then you can verify the postfresql service and its cluster with
systemctl status postgresql.service
pg_lsclusters
Postgresql doesn't have user and group concept but they are using role which is mapping with the system user (I haven't researched more on this). So beside the default admin role 'postgres', you have to create a local system user on your machine then add this into the database role.
sudo adduser sonar
...
sudo -u postgres createuser --interactive
Then enter 'sonar' user name and confirm this is a superuser.
As mentioned in the platform requirements, with Postgresql, we have to configure the encoding for the database to UTF8. Open psql with 'postgres' user/role (sorry that I still familiar with user term but actually it's role), you can't use sonar user now because it doesn't have the database associate it it.
Launch psql with postgres
sudo -u postgres psql
\l # list all database to verify the collate and encoding
\q # exit psql
Now, you will setup password for sonar user and create the database with UTF8 encoding for this user
sudo -u postgres psql
ALTER USER sonar WITH ENCRYPTED password <password>;
CREATE DATABASE sonar WITH ENCODING='UTF8' LC_CTYPE='en_US.UTF-8' LC_COLLATE='en_US.UTF8' OWNER=sonar TEMPLATE=template0 CONNECTION LIMIT=-1;
Please note that if your Ubuntu locale default setting should be en_US so you have to set the locale to en_US.UTF-8. Checkout this thread for more information. For the create database command, you have to use template0 in order to apply custom locale (still not know why). Now you can verify the new database encoding by listing all existing database and launch psql with this user. This is it for Postgresql
You can set the virtual memory and max file descriptor by sysctl command
Permanent change for service based system, you will add those lines into /etc/sysctl.conf or create a profile for sonar user at /etc/sysctl.d/99-sonar.conf
vm.max_map_count = 262144
fs.file-max = 65536
You can also set the limit for current session with
ulimit -n 65536
ulimit -u 2048
or permanently change into the limits configuration at /etc/security/limits.conf (or /etc/security/limits.d/99-sonar.conf)
sonar - nofile 65536
sonar - nproc 65536
Ubuntu will ignore the limits.conf when processes started by init.d, in order to enable the limits.conf, open /etc/pam.d/su file and uncommend this line
session required pam_limits.so
Those are the preparation steps for the system configuration, so now we will download SonarQube and configure it with Postgresql. I will use the LTS version 6.7.5, so I switch to user sonar
curl https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-6.7.5.zip -o sonarqube-6.7.5.zip
unzip sonarqube-6.7.5.zip
So the $SONAR_HOME should be /home/sonar/sonarqube-6.7.5/
Open $SONAR_HOME/conf/sonar.properties to edit the configuration
sonar.jdbc.username=sonar
sonar.jdbc.password=<password>
soanr.jdbc.url=jdbc:postgresql://localhost:5432/sonar
...
sonar.web.javaOpts=-server -Xmx2g -Xms2g -XX:+HeapDumpOnOutOfMemoryError
The jdbc url will use the default Postgresql port is 5432, by some reasons I couldn't connect with default setting so I add the port by this help. The last line to setup the java option to play as server and heap size for the JVM, based on the requirement of ElasticSearch, you should set around 2GB for the heap size, you can pass the ES_JAVA_OPS to sonar.sh but it's not recommended (they prohibit that action too). Again, with the requirement for ElasticSearch, you can't run with 'root' user (in case you start sonar as service then sonar service will fail at elasticsearch), so you have to open $SONAR_HOME/bin/linux-x86-64/sonar.sh and update this line
RUN_AS_USER=sonar
To make sonarqube process running as a service with systemd, create this file /etc/init.d/sonar
#!/bin/sh
#
# rc file for SonarQube
#
# chkconfig: 345 96 10
# description: SonarQube system (www.sonarsource.org)
#
### BEGIN INIT INFO
# Provides: sonar
# Required-Start: $network
# Required-Stop: $network
# Default-Start: 3 4 5
# Default-Stop: 0 1 2 6
# Short-Description: SonarQube system (www.sonarsource.org)
# Description: SonarQube system (www.sonarsource.org)
### END INIT INFO
/usr/bin/sonar $*
Then create a symlink from bin/linux-x86-64/sonar.sh to your service executable /usr/bin/sonar and enable it at boot time
sudo ln -s $SONAR_HOME/bin/linux-x86-64/sonar.sh /usr/bin/sonar
sudo chmod 755 /etc/init.d/sonar
sudo update-rc.d sonar defaults
When using systemd to start sonar service, you have to specify the system limits into the service unit (you can create /etc/systemd/system/sonar.service.d/override.conf) or using this command
sudo systemctl edit sonar
enter this content
[Service]
LimitMEMLOCK=infinity
LimitNOFILE=65536
LimitNPROC=2048
then reload the daemon
sudo systemctl daemon-reload
So now, you have sonar service ready and it will be update after reboot too. Login to your Sonarqube server by admin/admin credential.
One note here that I encounter issue with Postgresql service after reboot on version 9.5 but not with 10, the postgresql cluster can't start.
Alright, that's for now!
Until then, Happy Thanks Giving my friends!
So today is a short topic because I found out that installing SonarQube server with PostgreSQL is a piece of rock ... heheh!
No use case, today, install SonarQube server with PostgreSQL
So, let's start with a fresh Ubuntu 16.04 with some basic packages such as:
- openjdk-8-jre
- wget
- curl
- unzip
- apt-transport-https
Scan through the requirements from Sonar doc and take note on the Supported Platforms and scan through the note on ElasticSearch site for the requirements and configurations for ElasticSearch.
Setting Up PostgreSQL
The default postgresql in Ubuntu apt repository is 9.5 is the LTS, however, 9.3 has just discontinued so I select 10.6 so we have to add postgresql repository to our machine
You can also take a look on this guide to have more information on the basic installation
wget --quiet -0 - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo aptkey add -
sudo add-apt-repository "deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main"
sudo apt-get update
sudo apt install postgresql-10 postgresql-contrib
Then you can verify the postfresql service and its cluster with
systemctl status postgresql.service
pg_lsclusters
Postgresql doesn't have user and group concept but they are using role which is mapping with the system user (I haven't researched more on this). So beside the default admin role 'postgres', you have to create a local system user on your machine then add this into the database role.
sudo adduser sonar
...
sudo -u postgres createuser --interactive
Then enter 'sonar' user name and confirm this is a superuser.
As mentioned in the platform requirements, with Postgresql, we have to configure the encoding for the database to UTF8. Open psql with 'postgres' user/role (sorry that I still familiar with user term but actually it's role), you can't use sonar user now because it doesn't have the database associate it it.
Launch psql with postgres
sudo -u postgres psql
\l # list all database to verify the collate and encoding
\q # exit psql
Now, you will setup password for sonar user and create the database with UTF8 encoding for this user
sudo -u postgres psql
ALTER USER sonar WITH ENCRYPTED password <password>;
CREATE DATABASE sonar WITH ENCODING='UTF8' LC_CTYPE='en_US.UTF-8' LC_COLLATE='en_US.UTF8' OWNER=sonar TEMPLATE=template0 CONNECTION LIMIT=-1;
Please note that if your Ubuntu locale default setting should be en_US so you have to set the locale to en_US.UTF-8. Checkout this thread for more information. For the create database command, you have to use template0 in order to apply custom locale (still not know why). Now you can verify the new database encoding by listing all existing database and launch psql with this user. This is it for Postgresql
Setting up SonarQube
As mentioned earlier, the complicated part is the requirements for ElasticSearch which is part of SonarQube architecture. The requirement on Linux system:- vm.max_map_count is greater or equals to 262144
- fs.file-max is greater or equals to 65536
- the user running SonarQube can open at least 65536 file descriptors
- the user running SonarQube can open at least 2048 threads
To verify those categories
sudo sysctl vm.max_map_count
sudo sysctl fs.file-max
ulimit -n
ulimit -u
ulimit -a # you can use this to view all limit settings of current user
You can set the virtual memory and max file descriptor by sysctl command
sudo sysctl vm.max_map_count=262144
sudo sysctl fs.file-max=65536
vm.max_map_count = 262144
fs.file-max = 65536
You can also set the limit for current session with
ulimit -n 65536
ulimit -u 2048
or permanently change into the limits configuration at /etc/security/limits.conf (or /etc/security/limits.d/99-sonar.conf)
sonar - nofile 65536
sonar - nproc 65536
Ubuntu will ignore the limits.conf when processes started by init.d, in order to enable the limits.conf, open /etc/pam.d/su file and uncommend this line
session required pam_limits.so
Those are the preparation steps for the system configuration, so now we will download SonarQube and configure it with Postgresql. I will use the LTS version 6.7.5, so I switch to user sonar
curl https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-6.7.5.zip -o sonarqube-6.7.5.zip
unzip sonarqube-6.7.5.zip
So the $SONAR_HOME should be /home/sonar/sonarqube-6.7.5/
Open $SONAR_HOME/conf/sonar.properties to edit the configuration
sonar.jdbc.username=sonar
sonar.jdbc.password=<password>
soanr.jdbc.url=jdbc:postgresql://localhost:5432/sonar
...
sonar.web.javaOpts=-server -Xmx2g -Xms2g -XX:+HeapDumpOnOutOfMemoryError
The jdbc url will use the default Postgresql port is 5432, by some reasons I couldn't connect with default setting so I add the port by this help. The last line to setup the java option to play as server and heap size for the JVM, based on the requirement of ElasticSearch, you should set around 2GB for the heap size, you can pass the ES_JAVA_OPS to sonar.sh but it's not recommended (they prohibit that action too). Again, with the requirement for ElasticSearch, you can't run with 'root' user (in case you start sonar as service then sonar service will fail at elasticsearch), so you have to open $SONAR_HOME/bin/linux-x86-64/sonar.sh and update this line
RUN_AS_USER=sonar
To make sonarqube process running as a service with systemd, create this file /etc/init.d/sonar
#!/bin/sh
#
# rc file for SonarQube
#
# chkconfig: 345 96 10
# description: SonarQube system (www.sonarsource.org)
#
### BEGIN INIT INFO
# Provides: sonar
# Required-Start: $network
# Required-Stop: $network
# Default-Start: 3 4 5
# Default-Stop: 0 1 2 6
# Short-Description: SonarQube system (www.sonarsource.org)
# Description: SonarQube system (www.sonarsource.org)
### END INIT INFO
/usr/bin/sonar $*
Then create a symlink from bin/linux-x86-64/sonar.sh to your service executable /usr/bin/sonar and enable it at boot time
sudo ln -s $SONAR_HOME/bin/linux-x86-64/sonar.sh /usr/bin/sonar
sudo chmod 755 /etc/init.d/sonar
sudo update-rc.d sonar defaults
When using systemd to start sonar service, you have to specify the system limits into the service unit (you can create /etc/systemd/system/sonar.service.d/override.conf) or using this command
sudo systemctl edit sonar
enter this content
[Service]
LimitMEMLOCK=infinity
LimitNOFILE=65536
LimitNPROC=2048
then reload the daemon
sudo systemctl daemon-reload
So now, you have sonar service ready and it will be update after reboot too. Login to your Sonarqube server by admin/admin credential.
Automate with Ansible
In order to use the postgresql module in Ansible you have to have python module psycopg2
So setup postgresql with the flow above should be
- name: add postgresql repo key
apt_key:
url: https://www.postgresql.org/media/keys/ACCC4CF8.asc
- name: add postgresql repo to sources.list.d
apt_repository:
repo: "deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main"
filename: postgresql
- name: install postgresql
apt:
name: "{{ item }}"
state: present
update_cache: yes
with_items:
- postgressql-10
- postgresql-contrib
- name: install pip packages for postgresql with ansible
pip:
name: psycopg2
- name: add sonar user
user:
name: "{{ admin_user }}"
password: "{{ admin_pwd | password_hash('sha512') }}"
- name: create sonar db in postgresql
postgresql_db:
name: "{{ admin_user }}"
encoding: UTF-8
lc_collate: en_US.UTF-8
lc_ctype: en_US.UTF-8
template: template0
become_user: postgres
- name: create sonar role in postgresql
postgresql_user:
name: "{{ admin_user }}"
password: "{{ admin_pwd }}"
role_attr_flags: SUPERUSER
db: "{{ admin_user }}"
become_user: postgres
Using user module will need to input the encrypted password so you have to pipe the raw password with password_hash tool. For creating db and user in postgresql, as you will use the default 'postgres' role/user so you will escalate to this user by become_user.
Next for the sonar configuration, you can set the sysctl and security limits with (just some sample, please add the other config into your code)
- name: set vm.max_map_count in sysctl.conf
sysctl:
name: vm.max_map_count
value: 262144
state: present
- name: Add or modify nproc limit for sonar user
pam_limits:
domain: "{{ admin_user }}"
limit_type: '-'
limit_item: nproc
value: 2048
Make sure download sonarqube by 'sonar' user
- name: download and unzip sonaqube
unarchive:
remote_src: yes
src: https://binaries.sonarsource.com/CommercialDistribution/sonarqube-developer/sonarqube-developer-7.4.zip
dest: "/home/{{ admin_user }}"
become_user: "{{ admin_user }}"
Then update the configuration in conf/sonar.properties and bin/linux-x86-64/sonar.sh
- name: update web server properties in sonar.properties
lineinfile:
path: "{{ sonar_home }}/conf/sonar.properties"
regexp: '^#sonar.web.javaOpts='
line: "sonar.web.javaOpts=-server -Xmx2g -Xms2g -XX:+HeapDumpOnOutOfMemoryError"
backrefs: yes
- name: update service user in sonar.sh
lineinfile:
path: "{{ sonar_home }}/bin/linux-x86-64/sonar.sh"
regexp: '^#RUN_AS_USER='
line: "RUN_AS_USER={{ admin_user }}"
backrefs: yes
You can either create a service file or copy it (store in to source control) to /etc/init.d and make sure it is accessed and executed by root user. Create symlink of bin/linux-x86-64/sonar.sh to /usr/bin/sonar. At this time, sonar service hasn't run yet so we have to create the service directory first then create the override file for the limits setting. Finally, enable the service unit
- name: copy service file to /etc/init.d
copy:
src: files/sonar
dest: /etc/init.d/
owner: root
group: root
mode: 0755
- name: link sonar.sh to /usr/bin/sonar in service file
file:
src: "{{ sonar_home }}/bin/linux-x86-64/sonar.sh"
path: /usr/bin/sonar
state: link
- name: create service directory
file:
path: /etc/systemd/system/sonar.service.d
state: directory
- name: create service unit override file
copy:
dest: /etc/systemd/system/sonar.service.d/override.conf
content: |
[Service]
LimitMEMLOCK=infinity
LimitNOFILE=65536
LimitNPROC=2048
- name: enable service
systemd:
name: sonar
state: started
enabled: yes
daemon_reload: yes
So you should have an automation script to provision a Sonarqube machine now
Troubleshooting
Sonar log files are located at $SONAR_HOME/logs, refer to this document from sonar for the detail and you can scan through them by the listed order via your troubleshooting.One note here that I encounter issue with Postgresql service after reboot on version 9.5 but not with 10, the postgresql cluster can't start.
Alright, that's for now!
Until then, Happy Thanks Giving my friends!
Comments
Post a Comment