In this tutorial, we'll learn how to set up a Jenkins CI/CD server on AlmaLinux 9.
When it comes to building reliable, repeatable software pipelines, Jenkins remains one of the most popular open-source automation servers in the DevOps world. In this guide, we’ll walk through how to set up a dedicated Jenkins CI/CD server on AlmaLinux—so that we can automate our builds, tests, and deployments with confidence.
Throughout, we’ll explain why each step matters, share best practices for security (firewall & SELinux), and show you how to get from a fresh AlmaLinux install to a fully-functional Jenkins dashboard in minutes. Let’s dive in!
Prerequisites
Before starting, make sure our new Ubuntu server is ready. The following components should be installed and configured:
- A AlmaLinux 9 installed dedicated server or KVM VPS.
- A root user or normal user with administrative privileges.
- Basic knowledge of Linux commands.
Set up a Jenkins CI/CD Server on AlmaLinux
1. Prepare & Update the System
Before we install anything critical, we always make sure our OS packages are current. This helps avoid conflicts and ensures we have the latest security patches.
sudo dnf upgrade -y
sudo dnf update -y
2. Install and Configure Java
Jenkins runs on the JVM, and modern Jenkins (as of 2025) requires Java 21 for best compatibility and performance. Let’s install OpenJDK 21:
sudo dnf install -y java-21-openjdk java-21-openjdk-devel
If you have multiple Java install in your server, you can select Java 21 by following command:
update-alternatives --config java
Output:
There are 3 programs which provide 'java'.
Selection Command
-----------------------------------------------
1 java-1.8.0-openjdk.x86_64 (/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.442.b06-2.el9.x86_64/jre/bin/java)
*+ 2 java-17-openjdk.x86_64 (/usr/lib/jvm/java-17-openjdk-17.0.15.0.6-2.el9.alma.1.x86_64/bin/java)
3 java-21-openjdk.x86_64 (/usr/lib/jvm/java-21-openjdk-21.0.7.0.6-1.el9.alma.1.x86_64/bin/java)
Enter to keep the current selection[+], or type selection number: 3
Verify with:
java --version
Output similar like:
# openjdk version "21.0.xx" 202x-xx-xx LTS
3. Add the Official Jenkins YUM Repository
Rather than using a community package, we’ll point our package manager at Jenkins’s own stable repository. That way, we get trusted updates directly from the project.
# (Optional) Enable EPEL for extra dependencies
sudo dnf install -y epel-release
# Download Jenkins repo definition
sudo curl -o /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
# Import the Jenkins GPG signing key
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
# Refresh metadata
sudo dnf makecache
4. Install Jenkins
With Java ready and the Jenkins repo enabled, installation is a breeze:
sudo dnf install -y jenkins
This pulls in the Jenkins core (version 2.xxx+) along with any required libraries.
5. Secure the Server: SELinux
# (If SELinux enforcing) Allow Jenkins on 8080
sudo semanage port -a -t http_port_t -p tcp 8080
6. Enable & Start Jenkins
Now we tell systemd to start Jenkins on boot and then fire it up:
sudo systemctl daemon-reload
sudo systemctl enable --now jenkins
Check its status:
sudo systemctl status jenkins
You should see Active: active (running).
7. Install & Enable Nginx
First, let’s get Nginx on our system and ensure it runs on boot.
sudo dnf install -y nginx
sudo systemctl enable --now nginx
Check status:
sudo systemctl status nginx
8. Open HTTP and HTTPS in the Firewall
We need to allow incoming traffic on ports 80 (HTTP) and 443 (HTTPS):
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
9. (Optional) SELinux Adjustments
If SELinux is enforcing, allow Nginx to make network connections (so it can proxy to Jenkins on 8080):
sudo setsebool -P httpd_can_network_connect on
10. Create an Nginx Site Configuration
We’ll create a server block that listens on port 80
and proxies requests to Jenkins on http://127.0.0.1:8080
. Replace ci.example.com
with the domain you’ve pointed at this server.
sudo tee /etc/nginx/conf.d/jenkins.conf > /dev/null <<EOF
server {
listen 80;
server_name ci.example.com;
# Increase buffering so large Jenkins pages don’t 502
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
location / {
proxy_pass http://127.0.0.1:8080;
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;
}
}
EOF
Test and reload:
sudo nginx -t
sudo systemctl reload nginx
11. Install Certbot & the Nginx Plugin
Certbot will request a free TLS certificate from Let’s Encrypt and configure Nginx for us:
sudo dnf install -y certbot python3-certbot-nginx
Run Certbot in “nginx” mode, specifying our domain (you can include multiple -d flags if needed):
sudo certbot --nginx -d ci.example.com
12. Perform the Initial Web-UI Setup
Retrieve the auto-generated admin password:
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
Point your browser at https://ci.example.com
.
Unlock Jenkins by pasting the password from step 1.
Install suggested plugins (we recommend the defaults for a first server).
Create your first admin user (name, password, email).
Save & finish—you’ll then land on the Jenkins dashboard, ready to configure jobs.
13. Next Steps & Best Practices
- Configure global tools (JDKs, Git, Maven) under Manage Jenkins → Global Tool Configuration.
- Set up credentials (SSH keys, tokens) in Manage Jenkins → Credentials.
- Define pipelines using either freestyle jobs or Jenkinsfiles in SCM (Git).
- Secure & Monitor: enable HTTPS (via reverse proxy or Jenkins’ built-in support), enforce role-based access, and integrate with systems like Prometheus/Grafana.
In this tutorial, we've learnt how to set up a Jenkins CI/CD server on AlmaLinux 9. By following these steps, we’ve built a solid Jenkins foundation on AlmaLinux—one that can grow with our projects, plug into Git workflows, automate testing, and deploy to any environment. As we scale, we can add agents (nodes), distributed builds, and advanced plugins to suit our team’s needs. Happy building!