Full pipeline sketch
pipeline {
agent any
environment {
REGISTRY = 'ghcr.io'
IMAGE_NAME = 'ghcr.io/my-org/my-app'
GITHUB_CREDS = credentials('github-token')
}
stages {
stage('Build & Test') {
agent { docker { image 'node:20-alpine' } }
steps {
sh 'npm ci'
sh 'npm test'
sh 'npm run build'
}
}
stage('Build Docker Image') {
steps {
sh """
docker build \
--build-arg GIT_SHA=${env.GIT_COMMIT} \
-t ${IMAGE_NAME}:${env.GIT_COMMIT.take(7)} \
-t ${IMAGE_NAME}:latest \
.
"""
}
}
stage('Push Image') {
when { branch 'main' }
steps {
sh """
echo \$GITHUB_CREDS_PSW | docker login ${REGISTRY} \
-u \$GITHUB_CREDS_USR --password-stdin
docker push ${IMAGE_NAME}:${env.GIT_COMMIT.take(7)}
docker push ${IMAGE_NAME}:latest
"""
}
}
stage('Deploy') {
when { branch 'main' }
steps {
sshagent(['deploy-key']) {
sh """
ssh deploy@prod.example.com '
docker pull ${IMAGE_NAME}:latest &&
docker stop app || true &&
docker run -d --name app --restart unless-stopped \
-p 3000:3000 ${IMAGE_NAME}:latest
'
"""
}
}
}
}
post {
always {
sh 'docker image prune -f'
}
}
}Jenkins container + Docker socket (lab)
docker run -d \
--name jenkins \
-p 8080:8080 \
-v jenkins_home:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
jenkins/jenkins:lts-jdk21Install Docker CLI inside the container and add jenkins to the docker group so pipelines can run docker build.
Mounting /var/run/docker.sock grants near-root access to the host. For production, prefer remote build agents, Kaniko, or BuildKit — not a privileged socket on the controller.