如何创建Jenkins Pipeline任务实现PostgreSQL安装(含阶段规划)
Alright, let's walk through exactly how to build a Jenkins Pipeline that handles PostgreSQL installation — since you already have it running locally, I'm assuming you want this pipeline to set up PostgreSQL on your Jenkins agents (whether they're on-prem VMs or cloud instances). We'll make this configurable with user inputs and break everything into clear, maintainable stages.
1. First, Define Configurable User Inputs
We'll start by making the pipeline flexible with parameterized build inputs. These let you adjust settings each time you run the pipeline:
- PostgreSQL Version: String parameter (default:
14) — pick the specific version you want to install - Installation Path: String parameter (default:
/usr/local/pgsql) — where PostgreSQL will be installed - DB Admin Username: String parameter (default:
postgres) — the superuser for your PostgreSQL instance - DB Admin Password: Password parameter — secure input for the superuser password
- Initialize Database: Boolean parameter (default:
true) — toggle whether to set up an initial database cluster - Allow Remote Connections: Boolean parameter (default:
false) — enable if you need to connect to this PostgreSQL instance from outside the agent
2. Core Pipeline Stages
Here's how to structure the pipeline into logical stages, each with a clear purpose:
Stage 1: Environment Validation
First, we check if the Jenkins agent meets the prerequisites:
stage('Validate Environment') { steps { script { // Check OS type (Debian/Ubuntu vs RHEL/CentOS/Rocky) def osType = sh(script: 'lsb_release -is || cat /etc/redhat-release || echo "Unknown"', returnStdout: true).trim() if (osType.contains("Ubuntu") || osType.contains("Debian")) { env.OS_FAMILY = "DEBIAN" } else if (osType.contains("Red Hat") || osType.contains("CentOS") || osType.contains("Rocky")) { env.OS_FAMILY = "RHEL" } else { error("Unsupported OS: ${osType}") } // Verify sudo access sh('sudo -n true || { echo "Jenkins user needs passwordless sudo access"; exit 1; }') } } }
Stage 2: Install PostgreSQL Packages
Install PostgreSQL based on the OS family and selected version:
stage('Install PostgreSQL') { steps { script { if (env.OS_FAMILY == "DEBIAN") { // Add PostgreSQL repo for Debian/Ubuntu sh("echo \"deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main\" | sudo tee /etc/apt/sources.list.d/pgdg.list") sh("wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -") sh("sudo apt-get update && sudo apt-get install -y postgresql-${params.POSTGRES_VERSION} postgresql-contrib-${params.POSTGRES_VERSION}") } else if (env.OS_FAMILY == "RHEL") { // Add PostgreSQL repo for RHEL-based systems sh("sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %rhel)-x86_64/pgdg-redhat-repo-latest.noarch.rpm") sh("sudo yum -y install postgresql${params.POSTGRES_VERSION}-server postgresql${params.POSTGRES_VERSION}-contrib") } // Verify installation sh("psql --version") } } }
Stage 3: Configure PostgreSQL
Adjust configuration files to match your inputs:
stage('Configure PostgreSQL') { steps { script { def pgConfPath = env.OS_FAMILY == "DEBIAN" ? "/etc/postgresql/${params.POSTGRES_VERSION}/main/postgresql.conf" : "/var/lib/pgsql/${params.POSTGRES_VERSION}/data/postgresql.conf" def pgHbaPath = env.OS_FAMILY == "DEBIAN" ? "/etc/postgresql/${params.POSTGRES_VERSION}/main/pg_hba.conf" : "/var/lib/pgsql/${params.POSTGRES_VERSION}/data/pg_hba.conf" // Set listen addresses (allow remote if enabled) sh("sudo sed -i \"s/#listen_addresses = 'localhost'/listen_addresses = '*'/\" ${pgConfPath}") // Update authentication rules if (params.ALLOW_REMOTE_CONNECTIONS) { sh("sudo echo 'host all all 0.0.0.0/0 scram-sha-256' | sudo tee -a ${pgHbaPath}") } // Set custom installation path if specified (optional) if (params.INSTALL_PATH != "/usr/local/pgsql") { sh("sudo mkdir -p ${params.INSTALL_PATH} && sudo chown postgres:postgres ${params.INSTALL_PATH}") sh("sudo sed -i \"s|data_directory =.*|data_directory = '${params.INSTALL_PATH}/data'|\" ${pgConfPath}") } } } }
Stage 4: Initialize & Start Service
Set up the database cluster and start the service:
stage('Initialize & Start Service') { when { expression { params.INITIALIZE_DATABASE } } steps { script { if (env.OS_FAMILY == "DEBIAN") { sh("sudo systemctl start postgresql@${params.POSTGRES_VERSION}-main") sh("sudo systemctl enable postgresql@${params.POSTGRES_VERSION}-main") } else if (env.OS_FAMILY == "RHEL") { sh("sudo /usr/pgsql-${params.POSTGRES_VERSION}/bin/postgresql-${params.POSTGRES_VERSION}-setup initdb") sh("sudo systemctl start postgresql-${params.POSTGRES_VERSION}") sh("sudo systemctl enable postgresql-${params.POSTGRES_VERSION}") } // Verify service status sh("sudo systemctl is-active postgresql*") } } }
Stage 5: Create Admin User & Initial DB
Set up the admin user with your chosen password:
stage('Configure Admin User') { steps { script { def psqlCmd = env.OS_FAMILY == "DEBIAN" ? "sudo -u postgres psql" : "sudo -u postgres /usr/pgsql-${params.POSTGRES_VERSION}/bin/psql" // Set password for admin user sh("${psqlCmd} -c \"ALTER USER ${params.DB_ADMIN_USERNAME} WITH PASSWORD '${params.DB_ADMIN_PASSWORD}';\"") // Create initial database (optional) sh("${psqlCmd} -c \"CREATE DATABASE ${params.DB_ADMIN_USERNAME};\"") } } }
3. Full Jenkinsfile Example
Putting it all together, here's the complete pipeline script you can paste into a Jenkins Pipeline job:
pipeline { agent any parameters { string(name: 'POSTGRES_VERSION', defaultValue: '14', description: 'PostgreSQL version to install') string(name: 'INSTALL_PATH', defaultValue: '/usr/local/pgsql', description: 'Installation directory for PostgreSQL') string(name: 'DB_ADMIN_USERNAME', defaultValue: 'postgres', description: 'PostgreSQL superuser name') password(name: 'DB_ADMIN_PASSWORD', description: 'Password for the PostgreSQL superuser') booleanParam(name: 'INITIALIZE_DATABASE', defaultValue: true, description: 'Initialize the database cluster') booleanParam(name: 'ALLOW_REMOTE_CONNECTIONS', defaultValue: false, description: 'Allow remote connections to PostgreSQL') } stages { stage('Validate Environment') { steps { script { def osType = sh(script: 'lsb_release -is || cat /etc/redhat-release || echo "Unknown"', returnStdout: true).trim() if (osType.contains("Ubuntu") || osType.contains("Debian")) { env.OS_FAMILY = "DEBIAN" } else if (osType.contains("Red Hat") || osType.contains("CentOS") || osType.contains("Rocky")) { env.OS_FAMILY = "RHEL" } else { error("Unsupported OS: ${osType}") } sh('sudo -n true || { echo "Jenkins user needs passwordless sudo access"; exit 1; }') } } } stage('Install PostgreSQL') { steps { script { if (env.OS_FAMILY == "DEBIAN") { sh("echo \"deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main\" | sudo tee /etc/apt/sources.list.d/pgdg.list") sh("wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -") sh("sudo apt-get update && sudo apt-get install -y postgresql-${params.POSTGRES_VERSION} postgresql-contrib-${params.POSTGRES_VERSION}") } else if (env.OS_FAMILY == "RHEL") { sh("sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %rhel)-x86_64/pgdg-redhat-repo-latest.noarch.rpm") sh("sudo yum -y install postgresql${params.POSTGRES_VERSION}-server postgresql${params.POSTGRES_VERSION}-contrib") } sh("psql --version") } } } stage('Configure PostgreSQL') { steps { script { def pgConfPath = env.OS_FAMILY == "DEBIAN" ? "/etc/postgresql/${params.POSTGRES_VERSION}/main/postgresql.conf" : "/var/lib/pgsql/${params.POSTGRES_VERSION}/data/postgresql.conf" def pgHbaPath = env.OS_FAMILY == "DEBIAN" ? "/etc/postgresql/${params.POSTGRES_VERSION}/main/pg_hba.conf" : "/var/lib/pgsql/${params.POSTGRES_VERSION}/data/pg_hba.conf" sh("sudo sed -i \"s/#listen_addresses = 'localhost'/listen_addresses = '*'/\" ${pgConfPath}") if (params.ALLOW_REMOTE_CONNECTIONS) { sh("sudo echo 'host all all 0.0.0.0/0 scram-sha-256' | sudo tee -a ${pgHbaPath}") } if (params.INSTALL_PATH != "/usr/local/pgsql") { sh("sudo mkdir -p ${params.INSTALL_PATH} && sudo chown postgres:postgres ${params.INSTALL_PATH}") sh("sudo sed -i \"s|data_directory =.*|data_directory = '${params.INSTALL_PATH}/data'|\" ${pgConfPath}") } } } } stage('Initialize & Start Service') { when { expression { params.INITIALIZE_DATABASE } } steps { script { if (env.OS_FAMILY == "DEBIAN") { sh("sudo systemctl start postgresql@${params.POSTGRES_VERSION}-main") sh("sudo systemctl enable postgresql@${params.POSTGRES_VERSION}-main") } else if (env.OS_FAMILY == "RHEL") { sh("sudo /usr/pgsql-${params.POSTGRES_VERSION}/bin/postgresql-${params.POSTGRES_VERSION}-setup initdb") sh("sudo systemctl start postgresql-${params.POSTGRES_VERSION}") sh("sudo systemctl enable postgresql-${params.POSTGRES_VERSION}") } sh("sudo systemctl is-active postgresql*") } } } stage('Configure Admin User') { steps { script { def psqlCmd = env.OS_FAMILY == "DEBIAN" ? "sudo -u postgres psql" : "sudo -u postgres /usr/pgsql-${params.POSTGRES_VERSION}/bin/psql" sh("${psqlCmd} -c \"ALTER USER ${params.DB_ADMIN_USERNAME} WITH PASSWORD '${params.DB_ADMIN_PASSWORD}';\"") sh("${psqlCmd} -c \"CREATE DATABASE ${params.DB_ADMIN_USERNAME};\"") } } } } post { success { echo "PostgreSQL ${params.POSTGRES_VERSION} installed successfully! Admin user: ${params.DB_ADMIN_USERNAME}" } failure { echo "PostgreSQL installation failed. Check logs for details." } } }
4. Key Tips & Troubleshooting
- Sudo Access: Make sure the Jenkins user on your agent has passwordless sudo access (add
jenkins ALL=(ALL) NOPASSWD: ALLto/etc/sudoers). - Firewall Rules: If you enabled remote connections, open port 5432 on the agent's firewall (e.g.,
sudo ufw allow 5432for Ubuntu,sudo firewall-cmd --add-port=5432/tcp --permanentfor RHEL). - OS Compatibility: This pipeline supports Debian/Ubuntu and RHEL/CentOS/Rocky. For other OSes, you'll need to adjust the installation commands.
- Version Availability: Double-check that your chosen PostgreSQL version is available for the agent's OS version.
内容的提问来源于stack exchange,提问作者prajul chauhan




