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:
sudo passwd postgres
Switch to the PostgreSQL user account:
sudo su - postgres
Create a new PostgreSQL user for Buildbot:
createuser bb_user
Feel free to choose a different username if desired. Then, access the PostgreSQL shell:
psql
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:
\q
Return to the sudo user account:
exit
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:
sudo pip install psycopg2
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:
buildbot --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:
sudo su - buildbot
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:
nano ~/master/master.cfg
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:
buildbot start ~/master
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:
nano ~/worker/info/admin
Replace the example entry with your real name and email address:
Your Name <mail@example.com>
Next, update the host information:
nano ~/worker/info/host
Replace the placeholder content with actual host details:
Localhost, CentOS 7
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:
sudo yum -y install nginx
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:
sudo crontab -e
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:
sudo nginx -t
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.