Installing Buildbot Master and Worker on CentOS 7 with Nginx Reverse Proxy

Buildbot is an open-source tool based on Python, designed to automate software compilation, testing, and deployment processes. It operates through one or multiple Buildbot masters and several workers. The Buildbot master, known as the Buildmaster, centrally controls the system by managing the environment, coordinating workers, and assigning tasks. Upon detecting changes in the code repository, the Buildmaster distributes jobs to the workers for execution. After completing the assigned tasks, workers send the results back to the Buildmaster, which then informs developers through various supported notification methods. This guide will demonstrate how to set up a Buildbot master and worker on CentOS 7, along with configuring authentication and a secure Nginx reverse proxy.

Requirements

  • A CentOS 7 server instance with at least 1GB RAM.
  • A sudo-enabled user account.
  • A registered domain name directed to your server’s IP address.

Throughout this tutorial, the IP address 192.168.1.1 and the domain name ci.example.com are used as placeholders for your actual server IP and domain. Ensure you replace these with your real information when following the steps.

First, update your system’s base packages following the instructions in the guide How to Update CentOS 7. Once the system update is complete, proceed to the installation of PostgreSQL.

Install Python Dependencies

Begin by installing Pip, the package manager for Python, along with other essential dependencies:

sudo yum -y install epel-release
sudo yum -y install python-pip gcc python-devel git
sudo pip install --upgrade pip

Install PostgreSQL

Buildbot is compatible with several database servers including MySQL, PostgreSQL, and SQLite. For this guide, we will utilize PostgreSQL to serve as the database backend for Buildbot.

PostgreSQL is a robust, object-relational database system renowned for its performance and reliability. Since the version available in CentOS 7’s default yum repository is outdated, it is necessary to add the official PostgreSQL repository first:

sudo yum -y install https://download.postgresql.org/pub/repos/yum/10/redhat/rhel-7-x86_64/pgdg-centos10-10-1.noarch.rpm

Next, install the PostgreSQL database server:

sudo yum -y install postgresql10-server postgresql10-contrib postgresql10

Initialize the PostgreSQL database:

sudo /usr/pgsql-10/bin/postgresql-10-setup initdb

Start the PostgreSQL service and enable it to launch at boot:

sudo systemctl start postgresql-10
sudo systemctl enable postgresql-10

Set a new password for the default PostgreSQL user:

Switch to the PostgreSQL user account:

Create a new PostgreSQL user for Buildbot:

Feel free to choose a different username if desired. Then, access the PostgreSQL shell:

Assign a password to the new PostgreSQL user:

ALTER USER bb_user WITH ENCRYPTED password 'DBPassword';

Replace DBPassword with a strong password of your choosing.

Now, create a database that Buildbot will use:

CREATE DATABASE buildbot OWNER bb_user;

Exit the PostgreSQL shell:

Return to the sudo user account:

Edit the pg_hba.conf file to configure MD5 authentication:

sudo nano /var/lib/pgsql/10/data/pg_hba.conf

Locate the following entries and modify the METHOD column values from peer and ident to trust and md5 accordingly:

# TYPE  DATABASE        USER            ADDRESS                 METHOD
# "local" is for Unix domain socket connections only
local   all             all                                     peer
# IPv4 local connections:
host    all             all             127.0.0.1/32            ident
# IPv6 local connections:
host    all             all             ::1/128                 ident

Update PostgreSQL Configuration

After modifying the configuration, your pg_hba.conf file should resemble the following:

# TYPE  DATABASE        USER            ADDRESS                 METHOD
# "local" is for Unix domain socket connections only
local   all             all                                     trust
# IPv4 local connections:
host    all             all             127.0.0.1/32            md5
# IPv6 local connections:
host    all             all             ::1/128                 md5

Save your changes and close the text editor.

Install PostgreSQL Adapter for Python

Install psycopg2, the PostgreSQL adapter for Python:

Restart the PostgreSQL service to apply the new settings:

sudo systemctl restart postgresql-10

Install Buildbot

Install Buildbot along with its web interface and additional plugins using Pip:

sudo pip install 'buildbot[bundle]' pyopenssl service_identity

This command installs Buildbot, buildbot-www, buildbot-worker, and multiple web views like buildbot-waterfall-view.

Verify that Buildbot has been installed by checking its version:

The output should look similar to this:

[user@centron~]$ buildbot --version
Buildbot version: 0.9.15.post1
Twisted version: 17.9.0

Open Port for Buildbot Web Interface

Modify your firewall settings to allow traffic on port 8010, which Buildbot uses for its web interface:

sudo firewall-cmd --zone=public --add-port=8010/tcp --permanent
sudo firewall-cmd --reload

Configure the Buildbot Master

First, create a new non-root user to handle the Buildbot master and worker services. It is highly discouraged to operate Buildbot as the root user:

sudo adduser buildbot
sudo passwd buildbot

Switch to the newly created buildbot user:

Set up the Buildbot master inside the directory /home/buildbot/master, which will store configuration files, logs, and status information:

buildbot create-master --db 'postgresql://bb_user:DBPassword@localhost/buildbot' ~/master

Be sure to replace the database credentials appropriately in the command above.

Note: If you prefer using SQLite instead of PostgreSQL, simply skip the --db option. In that case, Buildbot will automatically create a SQLite database in the master directory.

The above command creates the ~/master directory, stores Buildbot’s configuration files, and writes data into the PostgreSQL database. You should see an output similar to the following:

[buildbot@centron~]$ buildbot create-master --db 'postgresql://bb_user:DBPassword@localhost/buildbot' ~/master
mkdir /home/buildbot/master
creating /home/buildbot/master/master.cfg.sample
creating database (postgresql://bb_user:DBPassword@localhost/buildbot)
buildmaster configured in /home/buildbot/master

Copy the sample configuration file to the live configuration location:

cp ~/master/master.cfg.sample ~/master/master.cfg

Edit the configuration file to make the necessary adjustments:

Locate the following configuration lines:

c['workers'] = [worker.Worker("example-worker", "pass")]
...
c['builders'].append(
    util.BuilderConfig(name="runtests", workernames=["example-worker"], factory=factory)
)
...
c['title'] = "Hello World CI"
c['titleURL'] = "https://buildbot.github.io/hello-world/"
...
c['buildbotURL'] = "http://localhost:8010/"
...
c['db'] = {
    'db_url' : "postgresql://bb_user:DBpassword@localhost/buildbot",
}

The sample configuration includes a preconfigured worker. Adjust it by:

  • Changing example-worker to a new, meaningful name for your local worker.
  • Updating pass with a new secure password.
  • Modifying the worker name in the list of builders accordingly.
  • Personalizing the application title and project URL fields to reflect your own project information.

Remember to note down the worker name and password, as you will need them later in the setup process.

Update the Buildbot URL and Finalize Configuration

Update the buildbotURL setting in the configuration file, replacing localhost with your server’s domain name or public IP address. Additionally, double-check that the database connection details match your actual PostgreSQL credentials.

At the bottom of the configuration file, add the following line to disable sending version and plugin usage statistics to Buildbot developers:

c['buildbotNetUsageData'] = None

If you prefer to share usage data, you can instead set this parameter to Full.

After the modifications, your configuration should resemble the following:

c['workers'] = [worker.Worker("localhost-worker", "Password123")]
...
c['builders'].append(
    util.BuilderConfig(name="runtests", workernames=["localhost-worker"], factory=factory)
)
...
c['title'] = "My Application CI"
c['titleURL'] = "https://example.com/my-app"
...
c['buildbotURL'] = "http://192.168.1.1:8010/"
...
c['db'] = {
    'db_url' : "postgresql://bb_user:DBpassword@localhost/buildbot",
}
...
c['buildbotNetUsageData'] = None

Save the configuration file and exit the editor.

Verify the Buildbot Configuration

Run the following command to validate your Buildbot configuration:

buildbot checkconfig ~/master

If there are no errors, you should see an output like this:

[buildbot@centron~]$ buildbot checkconfig ~/master
Config file is good!

Start the Buildbot Master

Once the configuration is validated, start the Buildbot master with the following command:

Upon successful startup, you will see output similar to:

[buildbot@centron~]$ buildbot start ~/master
Following twistd.log until startup finished..
The buildmaster appears to have (re)started correctly.

With the Buildbot master running successfully, you can now access the web interface by visiting:

http://192.168.1.1:8010

The Buildbot web interface should now be displayed.

Configure the Buildbot Worker

Since we have already adjusted the worker settings inside ~/master/master.cfg, we can now create a new worker process:

buildbot-worker create-worker ~/worker localhost localhost-worker Password123

Ensure you use exactly the same worker name and password as defined in the ~/master/master.cfg file. A mismatch will prevent the worker from connecting to the Buildbot master.

After executing the command successfully, you should see output similar to the following:

[buildbot@centron~]$ buildbot-worker create-worker ~/worker localhost example-worker pass
mkdir /home/buildbot/worker
mkdir /home/buildbot/worker/info
Creating info/admin, you need to edit it appropriately.
Creating info/host, you need to edit it appropriately.
Not creating info/access_uri - add it if you wish
Please edit the files in /home/buildbot/worker/info appropriately.
worker configured in /home/buildbot/worker

The worker’s metadata is stored inside the /info directory. Update the administrative details:

Edit the admin information file:

Replace the example entry with your real name and email address:

Your Name <mail@example.com>

Next, update the host information:

Replace the placeholder content with actual host details:

These information fields are primarily informative and help users identify the host system. You can optionally add more details, such as the Buildbot version or Twisted version.

Start the Buildbot Worker

Launch the worker service by running the following command:

buildbot-worker start ~/worker

Upon successful startup, you should see output like this:

[buildbot@centron~]$ buildbot-worker start ~/worker
Following twistd.log until startup finished..
The buildbot-worker appears to have (re)started correctly.

Verify Worker Registration

To confirm that the worker has successfully registered, open the Buildbot web interface. Navigate to Builds >> Workers from the left-hand menu. The worker should be listed as active and ready for building tasks.

Run a Sample Build

To perform a test build, go to Builds >> Builders in the Buildbot interface. Click on the runtests builder to open its page. Then click the Force button to manually trigger a build.

Enter your name in the prompt and press Start Build. This simple build test will complete within a few seconds. Upon completion, you should receive a success message along with the build results.

Set Up Buildbot as a Systemd Service

Although you can start and stop the Buildbot master and worker manually, it is highly recommended to configure them as Systemd services. This setup ensures that the services automatically restart after a system reboot or failure.

Note: Return to your sudo user account by executing either exit or su <username>. All further commands should be performed using the sudo user.

Stop the Running Buildbot Services

First, stop any currently running Buildbot master and worker services:

sudo su buildbot -c "buildbot stop /home/buildbot/master"
sudo su buildbot -c "buildbot-worker stop ~/worker"

Create a Systemd Unit File for the Buildbot Master

Create a new Systemd service file for the Buildbot master:

sudo nano /etc/systemd/system/buildbot.service

Insert the following content into the file:

[Unit]
Description=BuildBot master service
After=network.target

[Service]
Type=forking
User=buildbot
Group=buildbot
WorkingDirectory=/home/buildbot/master
ExecStart=/usr/bin/buildbot start
ExecStop=/usr/bin/buildbot stop
ExecReload=/usr/bin/buildbot restart

[Install]
WantedBy=multi-user.target

Start the Buildbot master service and enable it to start automatically at system boot:

sudo systemctl start buildbot
sudo systemctl enable buildbot

Create a Systemd Unit File for the Buildbot Worker

Now, create a Systemd service file for the Buildbot worker:

sudo nano /etc/systemd/system/buildbot-worker.service

Add the following configuration to the file:

[Unit]
Description=BuildBot worker service
After=network.target

[Service]
Type=forking
User=buildbot
Group=buildbot
WorkingDirectory=/home/buildbot/worker
ExecStart=/usr/bin/buildbot-worker start
ExecStop=/usr/bin/buildbot-worker stop
ExecReload=/usr/bin/buildbot-worker restart

[Install]
WantedBy=multi-user.target

Start the Buildbot worker service and set it to launch at boot:

sudo systemctl start buildbot-worker
sudo systemctl enable buildbot-worker

Verify the Status of Buildbot Services

Check the status of both services to ensure they are running smoothly:

sudo systemctl status buildbot buildbot-worker

If everything is operating correctly, you will see output similar to the following:

[user@centron~]$ sudo systemctl status buildbot buildbot-worker
● buildbot.service - BuildBot master service
   ...
   Active: active (running) since Fri 2018-01-12 16:00:59 UTC; 1min 25s ago
   ...
   Jan 12 16:00:59 centron.guest systemd[1]: Started BuildBot master service.
● buildbot-worker.service - BuildBot worker service
   ...
   Active: active (running) since Fri 2018-01-12 16:02:00 UTC; 24s ago
   ...
   Jan 12 16:02:00 centron.guest systemd[1]: Started BuildBot worker service.

Enable Authentication in the Buildbot Web Interface

By default, the Buildbot web interface does not have authentication enabled. For public-facing installations, it is highly recommended to configure authentication to restrict administrative actions to authorized users only.

Edit the Buildbot Master Configuration

Open the Buildbot master configuration file for editing:

sudo su buildbot -c "nano /home/buildbot/master/master.cfg"

Add the following lines at the end of the file to enable authentication:

c['www']['authz'] = util.Authz(
    allowRules = [
        util.AnyEndpointMatcher(role="admins")
    ],
    roleMatchers = [
        util.RolesFromUsername(roles=['admins'], usernames=['admin_user'])
    ]
)
c['www']['auth'] = util.UserPasswordAuth({'admin_user': 'AdminPassword'})

Replace both instances of admin_user with your desired username and substitute AdminPassword with a secure password.

Validate the Configuration

Check the configuration for syntax errors before applying the changes:

sudo su buildbot -c "buildbot checkconfig /home/buildbot/master"

Restart Buildbot Master Service

Restart the Buildbot master so the new authentication settings take effect:

sudo systemctl restart buildbot

Test the Authentication Setup

Visit the Buildbot web interface. Anonymous users should now only be able to view basic server information. To access administrative features, log in with the username and password configured in the master.cfg file.

After logging in, all administrative options will become accessible exclusively to the authenticated admin user.

Secure Buildbot with Let’s Encrypt SSL and Nginx

By default, Buildbot operates over an unsecured HTTP connection on port 8010. To protect the data transmitted between the browser and server, it is advisable to secure the Buildbot web interface with HTTPS. In this section, we will install and configure Nginx as a reverse proxy secured with Let’s Encrypt free SSL certificates.

Install and Configure Nginx

Install the Nginx web server:

Start the Nginx service and enable it to start automatically at boot:

sudo systemctl start nginx
sudo systemctl enable nginx

Install Certbot for SSL Certificate Management

Install Certbot, the client used for requesting certificates from Let’s Encrypt:

sudo yum -y install certbot

Adjust Firewall Settings

Open ports 80 and 443 for HTTP and HTTPS traffic, and remove the unsecured 8010 port:

sudo firewall-cmd --zone=public --add-service=http --permanent
sudo firewall-cmd --zone=public --add-service=https --permanent
sudo firewall-cmd --zone=public --remove-port=8010/tcp --permanent
sudo firewall-cmd --reload

Note: Your domain must point to your server’s IP address before requesting an SSL certificate. Update your DNS settings and wait for propagation if necessary.

Generate Let’s Encrypt SSL Certificates

Request SSL certificates for your domain:

sudo certbot certonly --webroot -w /usr/share/nginx/html -d ci.example.com

The certificates will typically be stored in /etc/letsencrypt/live/ci.example.com/ as fullchain.pem and privkey.pem.

Set Up SSL Certificate Auto-Renewal

Open the crontab file for the root user:

Add the following line to renew certificates daily at 5:30 AM:

30 5 * * * /usr/bin/certbot renew --quiet

Configure Nginx for HTTPS

Remove the default_server directive from the default Nginx configuration:

sudo sed -i 's/default_server//g' /etc/nginx/nginx.conf

Create a new Nginx configuration file for Buildbot:

sudo nano /etc/nginx/conf.d/buildbot.conf

Insert the following content into the file:

upstream buildbot {
    server 127.0.0.1:8010;
}

server {
    listen 80 default_server;
    server_name ci.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2 default_server;
    server_name ci.example.com;
    root html;
    index index.html index.htm;

    ssl on;
    ssl_certificate /etc/letsencrypt/live/ci.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/ci.example.com/privkey.pem;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1440m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
    ssl_prefer_server_ciphers on;
    add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";

    access_log /var/log/nginx/buildbot.access.log;

    proxy_set_header HOST $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-Host $host;

    location / {
        proxy_pass http://buildbot;
    }

    location /sse/ {
        proxy_buffering off;
        proxy_pass http://buildbot/sse/;
    }

    location /ws {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_pass http://buildbot/ws;
        proxy_read_timeout 6000s;
    }
}

Test and Reload Nginx Configuration

Check the syntax of the new configuration:

If successful, the output will confirm that the configuration test passed.

If no errors are detected, restart the Nginx service:

sudo systemctl restart nginx

Update Buildbot URL to HTTPS

Open the Buildbot master configuration file:

sudo su buildbot -c "nano /home/buildbot/master/master.cfg"

Find the following line:

c['buildbotURL'] = "http://192.168.1.1:8010/"

Replace it with your secured domain URL:

c['buildbotURL'] = "https://ci.example.com/"

Restart the Buildbot master service to apply the change:

sudo systemctl restart buildbot

Access the Buildbot Dashboard

You can now visit your secured Buildbot web interface at https://ci.example.com. Log in with your admin credentials to start managing your builds securely.

Conclusion

By completing this guide, you have successfully installed and configured a secure Buildbot environment on CentOS 7. You set up both the Buildbot master and worker, configured PostgreSQL as the backend database, and secured the web interface using Nginx and Let’s Encrypt SSL certificates. Additionally, you enabled authentication to protect administrative access and ensured that Buildbot services automatically restart after system reboots with Systemd.

With this fully operational and secured Buildbot setup, you are now ready to start automating your software build and deployment pipelines confidently and efficiently. You can further customize the configuration according to your project needs, add more workers, and define complex workflows to streamline your continuous integration and delivery processes.

Source: vultr.com

Create a Free Account

Register now and get access to our Cloud Services.

Posts you might be interested in:

Moderne Hosting Services mit Cloud Server, Managed Server und skalierbarem Cloud Hosting für professionelle IT-Infrastrukturen

How to Install and Secure Apache OpenMeetings on CentOS 7

Apache, Tutorial

Linux file permissions with this comprehensive guide. Understand how to utilize chmod and chown commands to assign appropriate access rights, and gain insights into special permission bits like SUID, SGID, and the sticky bit to enhance your system’s security framework.