← all posts
;Jenkins
Jenkins VM Server Installation Guide (to be automated with Ansible later)
- Install Jenkins on a VM
- Update apt
- Install Java environment
- Import the GPG key for the Jenkins repository
- Add the Jenkins repository to the system
- Once the Jenkins repository is added and enabled, update the package list and install the latest version of Jenkins
- apt install Jenkins:
sudo apt install jenkins -y - Check Jenkins status:
systemctl status jenkins - Open port 8080 (on GCP this is more involved — you need to create a new firewall rule in GCP Firewalls, then attach it to the GCP VM via a network tag)
- Copy the key from the VM:
sudo cat /var/lib/jenkins/secrets/initialAdminPassword sudo -i=> switch to root =>gpasswd -a jenkins root(add the Jenkins account to the root group)groups jenkinsshould show rootvisudo=> addjenkins ALL=NOPASSWD:ALLso Jenkins can run system-level commands (e.g. Docker) without entering a passwordsudo usermod -aG docker $USER— fixes "dial unix /var/run/docker.sock: connect: permission denied" when Jenkins has no permission to run Docker (adds Jenkins to the Docker group) On Linux, the default home directory is /home/user, but Jenkins' home directory is /var/lib/jenkins, so any commands Jenkins needs to run must be installed under that path — for example, GitHub SSH keys should go there.- After switching to the Jenkins user, run
ssh-keygento generate a GitHub access key
- For master-node coordination:
ssh-keyscan -H <ip-address> >> /var/lib/jenkins/.ssh/known_hosts— skips the yes/no prompt, optional — adds the host record to known_hosts- Give the public key to master, place it in authorized_keys:
echo "content" >> ~/.ssh/authorized_keys
Jenkins Credential Types
- Secret text — tokens such as API tokens (e.g. GitHub personal access tokens)
- Username and password — can be stored as separate fields or as a colon-separated string: username:password
- Secret file — encrypted content stored in a file
- SSH Username with private key — SSH public/private key pair
- Certificate — a PKCS#12 certificate file and optional password
- Docker Host Certificate Authentication credentials
Jenkins Plugins Required
- AnsiColor: colorizes Console Output
- Blue Ocean
- pipeline: AWS steps
- CloudBees AWS Credentials: stores access key and secret key
- CloudBees Docker AWS Credentials
- Role-Based Authorization Strategy
- Email Extension Plugin
- Docker
- Docker pipeline
- Bitbucket Plugin
- Slack Notification Plugin
- Azure Credentials plugin
DevOps Jenkins 01
- Jenkins
- An open-source application that enables CI/CD, integrating with a wide range of testing and deployment technologies.
- Improves efficiency: CD with a web project => web farm (web server farm), with deployment status easily tracked from the dashboard.
- CI
- Automatically verifies the build using unit tests and packages the solution for each new code change submitted.
- Compile == Build == CI (source code/text files => binary) => .exe, lib, pkg
- CD
- Takes executable files (validated code packages) from the build process and deploys them into staging or production environments.
- Developers can track which deployments succeeded or failed and narrow down issues to specific package versions.
- Two server sets alternate between staging and production (see diagram) — blue/green deployment. https://blog.inedo.com/blue-green-deployment-best-practices Jenkins can also be used to orchestrate other cloud services such as AWS CodeBuild/CodeDeploy — a useful complement to existing infrastructure. Note: M1 Macs use the ARM architecture (RISC), so running Docker likely goes through Rosetta2 translation. Running Jenkins inside Docker on M1 feels extremely slow — roughly 10x slower than on Windows.
DevOps Jenkins & Intranet Tunneling 02
- Install Jenkins locally
- On Windows, run
sudo service docker startto start the Ubuntu Docker engine (can connect Docker engine to Ubuntu as shown in diagram 2) - Run Jenkins container
- Get admin password to complete Jenkins setup
- On Windows, run
- ngrok (reverse proxy / intranet tunneling)
- Visit ngrok website to get an auth token
- Local installation:
- Windows: change permissions → extract → configure token → open port 80
- macOS: use
brew install --cask ngrok(no manual PATH configuration needed), rest is the same as Windows - Copy the tunnel URL to Jenkins configuration => Jenkins URL
- Connect GitHub with Jenkins
- Add new item
- Freestyle project
- Configure with Git + Repo URL with .git connection
- Build triggers => GitHub hook trigger for GITScm polling
- Branches to build: choose
*/masteror leave empty to trigger on all branches - Add webhook in GitHub => go to git repository
- Payload URL must end with
github-webhook/e.g.http://XXXX.ngrok.io/github-webhook/ - Select "Just the push event" as the trigger
- Check "Active" to enable the webhook
Windows/Ubuntu users need to prepend sudo to most commands.
Installing ngrok on macOS:
https://gist.github.com/wosephjeber/aa174fb851dfe87e644e?permalink_comment_id=3621858
DevOps Azure Docker Jenkins 1
- Create VM
- Check connection settings in the server
- Open ports 22, 80, and 443
- Allocate 64GB SSD; check "delete on termination" for both disk and public IP
- Open port 8080 for demo
- SSH into server => install Jenkins via Docker
sudo apt updatesudo apt install docker-composesudo docker run XXX
- NS delegation from AWS to Azure (subdomain)
nslookup -type=NS shawnwong.click— check DNS name servers- Add the domain name in Azure DNS (e.g. sure.XXX.XXX)
- Copy NS records from Azure DNS to the domain registrar (NS delegation)
nslookup -type=NS nz.shawnwong.click— verify DNS name servers- Add a new record set in Azure DNS with type A and alias
- Install Nginx on Azure VM
apt install nginxsystemctl enable nginx(enable auto-start on boot)
- Add SSL
- Modify Nginx configuration files
- Restart Nginx:
sudo systemctl restart nginx systemctl status nginx— check service status
Gotchas:
- WSL Ubuntu cannot modify file permissions for Windows files
- Copy the file into the Linux directory using
cp - Directly modify file permissions via
/etc/wsl.conf
- Copy the file into the Linux directory using
DevOps with Private GitHub 2 & Nginx Config
Configure DNS for a specific domain (from AWS to Azure):
- Create in Azure DNS; Name can be set to
XXX.<yourdomainname> - Copy NS records to AWS Route53 as delegation
- Create a record set => use an alias record set to point directly to a VM resource
- Or use an A record pointing to the public IP address
Install Nginx & add certificate to Jenkins server:
sudo apt install nginxsudo systemctl enable nginx— enable auto-start on boot- Add certificate
sudo systemctl status nginx— check service statussudo systemctl restart nginx— restart Nginx
Narrow way to add SSH public key:
- Add SSH key in specific GitHub repository => Settings => Deploy Keys to restrict access to that repository only
Troubleshooting guide:
- If Jenkins is running inside Docker, add the
.sshkey inside the container (usesudo docker exec -it <cont_id> shto enter the container, then runssh-keygen) - No need to add credentials in Jenkins dashboard => pipeline => Source Code Management; set credentials to "None"
- Restart container with:
sudo docker restart <cont_id> - When modifying Nginx configuration, remember to comment out the 404 redirect
DevOps Jenkins Blue Ocean
- Mainly covers CI and CD (content delivery) as a multibranch pipeline; does not cover content deployment
- Content deployment involves production data (user data, databases, live workloads)
git push origin <new-branch>orgit push origin HEAD— push a new branch to GitHubgit pull . master— pull files from master into the current branch (syncs locally)- Difference between a Plugin and Docker Engine?
- One is a tool that uses Docker; the other is Docker itself — Arno
- Blue Ocean workflow:
- Connect GitHub => GitHub Settings => Developer Settings => Personal access tokens => grant permissions (user, write, etc.) => create a pipeline
- Install Docker Engine on Linux
- Run
which docker=> find the Docker Engine path, then add it to global configuration - Configure Docker path in Jenkins and add the Docker Pipeline and Docker plugins
- Add
HOME '.'in Jenkinsfile to run files in the current user's directory (/bin/sh) rather than the root directory
DevOps Jenkins Master-Node Coordination
AZ-GCP-Local Jenkins
- Start AZ, GCP VM + local machine
- Add Docker environment
- Add JDK 11+ environment
- Add local node: Manage Jenkins => Manage Nodes and Clouds => Add a new node
- Note: in Configure Global Security, add a fixed TCP port 5003
- Download the agent jar to the local machine via wget
- Open inbound port 5003 on the Azure VM
- Since this is local, the agent may go offline — configure it to start only when a job matching its label is triggered
- Choose "Launch agent by connecting it to the controller" (Azure VM proactively calls the local machine to execute tasks)
- Add GCP node
visudo— used to edit/etc/sudoersto grant sudo permissions to a regular user without a password. Add:jenkins ALL=NOPASSWD:ALL- Use this node as much as possible
/var/lib/jenkinsis equivalent to the Jenkins user's home directory, similar to/rootor/home/<username>- Generate an SSH key for the Jenkins user:
/var/lib/jenkins/.ssh/id_rsa ssh-keyscan -H 34.129.185.248 >> /var/lib/jenkins/.ssh/known_hosts— add the GCP node host to the trusted list- Add the
id_rsa.pubkey to GCP for passwordless access:echo 'keyxxx' >> ~/.ssh/authorized_keys - Add the
id_rsaprivate key to Jenkins credentials to complete authentication with the GCP VM
Jenkinsfile Generator
Jenkinsfile code can be generated using Jenkins' built-in pipeline code generator, which includes a Snippet Generator and a Declarative Directive Generator.
pipeline— starts the code pipelineagentany— any available agentlabel— run on an agent matching a labeldocker— run inside a Docker containerdockerfile— build from an image matching a label
stages— pipeline entry pointpost— execute logic after all stages complete (useful for cleanup or notifications based on build outcome)parameters
Snippet Generator:
cleanWs()— delete workspace when build is donegit— git credentialstimeout + input
Troubleshooting guide:
- When using
withCredentialsfrom the Snippet Generator, select "Username and Password (separate)", link to your Jenkins credentials. The variable name you define (e.g.dockerPwd) will be referenced in the Jenkinsfile and mapped to the actual password at runtime — providing credential masking in the console output. credentialsIdis the name you gave the credential in Jenkins.- When
parametersis configured, a "Build with Parameters" option appears in Jenkins, allowing the pipeline to be triggered with custom parameter values.