← Back to Articles
Tech Ethics

Automation on a Budget with Jenkins

When your web developer is a part-time volunteer, a broken donation form at 11 PM is a crisis. Jenkins on a Raspberry Pi gives your organization automated testing and deployment so fixes ship immediately — no cloud subscription required.

Continuous integration and automated deployment are usually treated as enterprise luxuries, but they are arguably more important for small nonprofits than for large companies. When your web developer is a part-time volunteer who commits code on Saturday evenings, you cannot afford manual deployment mistakes. When your donation form breaks, you need it fixed and redeployed immediately—not Monday morning. Jenkins on a Raspberry Pi gives you automated testing and deployment for the cost of a $75 computer and a few hours of setup.

Cost Reality

Cloud CI services like GitHub Actions, CircleCI, or Travis CI bill by the minute. For modest usage, this seems cheap—until you exceed free tiers or need private repositories. A Raspberry Pi running Jenkins has no per-build cost, no seat limits, and no restrictions on private repos. Annual electricity cost is under $5. The hardware pays for itself in under a month compared to paid CI tiers.

More importantly, the build logs stay local. Failed test output, deployment credentials, and environment variables never transit through a third-party service. For organizations handling sensitive participant data, that architectural isolation is not optional—it is protective.

What Jenkins Can Do for You

On a Pi, Jenkins is best suited to lightweight automation:

Do not expect a Pi to compile large native applications or run heavy browser automation. Match the workload to the hardware.

Installation

Update your Pi and install Java, which Jenkins requires:

sudo apt update && sudo apt upgrade -y
sudo apt install openjdk-17-jre
java --version

Add the Jenkins repository and install:

curl -fsSL https://pkg.jenkins.io/debian/jenkins.io-2023.key | sudo tee \
  /usr/share/keyrings/jenkins-archive-keyring.gpg > /dev/null

echo "deb [signed-by=/usr/share/keyrings/jenkins-archive-keyring.gpg] \
  https://pkg.jenkins.io/debian binary/" | sudo tee \
  /etc/apt/sources.list.d/jenkins.list > /dev/null

sudo apt update
sudo apt install jenkins

Start and enable the service:

sudo systemctl start jenkins
sudo systemctl enable jenkins

Jenkins listens on port 8080. Open it in your browser at http://YOUR_PI_IP:8080.

Unlocking and Configuring Jenkins

Retrieve the initial admin password:

sudo cat /var/lib/jenkins/secrets/initialAdminPassword

Paste it into the web wizard. When prompted to install plugins, choose "Install suggested plugins." For a Pi with limited RAM, this is safer than selecting dozens of extras.

Create an admin user with a strong password. Disable sign-ups unless you want every volunteer to have full admin rights—which you probably do not.

A Sample Pipeline for Static Sites

Create a new Pipeline job and paste this Jenkinsfile concept into the script box. Adapt the commands to match your static site generator or build script:

pipeline {
    agent any
    stages {
        stage('Checkout') {
            steps {
                git branch: 'main',
                    url: 'https://github.com/your-org/your-site.git'
            }
        }
        stage('Build') {
            steps {
                sh 'python3 build.py'
            }
        }
        stage('Test') {
            steps {
                sh 'python3 -m pytest tests/ || true'
            }
        }
        stage('Deploy') {
            steps {
                sh 'rsync -avz --delete output/ /var/www/html/'
            }
        }
    }
}

Trigger the pipeline manually the first time. Then enable webhook (a URL your server exposes so external services can trigger a job by sending it a notification) triggers from your Git host so that every push to main rebuilds and redeploys automatically.

Resource Management

A Pi 4 with 4 GB RAM can handle several Jenkins jobs, but it will strain under parallel builds. Constrain Jenkins to one executor (the Jenkins term for a worker slot — each executor can run one job at a time) to avoid swapping:

  1. Manage Jenkins → Configure System
  2. Set "Number of executors" to 1
  3. Save

Schedule heavy jobs at night when no one is using the Pi for other tasks. If builds routinely time out, consider adding a second Pi dedicated to Jenkins.

Securing Jenkins

A CI server with deployment credentials is a high-value target. Protect it:

  1. Firewall: Restrict port 8080 to your local network:

    sudo ufw allow from 192.168.1.0/24 to any port 8080
    
  2. Reverse Proxy: Run Jenkins behind Nginx or Apache with SSL. Do not expose port 8080 directly to the internet.

  3. Credentials: Store deployment SSH keys in Jenkins' built-in Credentials plugin, never in the Jenkinsfile itself.

  4. Updates: Jenkins publishes security advisories regularly. Subscribe to them and patch promptly.

Training Volunteers

Jenkins is most valuable when multiple volunteers understand it. Create a simple onboarding checklist:

Print screenshots of the dashboard and circle the important buttons. For many volunteers, visual references are faster than written instructions.

Why This Matters for Nonprofits

Automated deployment is not about convenience—it is about continuity. When the volunteer who originally built your website moves away, Jenkins preserves the deployment process in code. The next volunteer does not need to reverse-engineer a manual routine; they read the pipeline. That codified knowledge outlasts individual contributors, which is exactly the kind of institutional memory that small organizations struggle to build. And because it runs on a Pi you already own, the infrastructure investment is nearly zero.

💬
Continue the conversation in the forum
Town Square · Community Tool Shed · The Tech Collective · Sustainable Communities · and more
Join the Forum →