我想通过 Jenkinsfile 在远程 EC2 上重新部署 docker 容器,但我很难找到适用于 ssh 的解决方案。我想必须查找容器是否已经存在并首先将其删除。
我尝试过的: 我编写了一个可以在本地计算机上运行的脚本,但不需要 ssh。
这是我的 Jenkinsfile 的工作阶段。
stage('Deploy Docker container on HOST') {
steps {
script {
// Check if container exists
def containerId = sh(script: "docker ps --quiet --filter name=$CONTAINER_NAME", returnStdout: true).trim()
if (containerId.isEmpty()) {
echo "Container $CONTAINER_NAME not found. Skipping stop/remove steps."
} else {
echo "Stopping and removing existing container $CONTAINER_NAME ..."
sh "docker stop $CONTAINER_NAME"
sh "docker rm $CONTAINER_NAME"
sh "docker rmi $DOCKERH_REPO/$IMAGE_TAG:latest" // Remove leftover image if needed
sh "docker rmi $DOCKERH_REPO/$IMAGE_TAG:$BUILD_VERSION" // Remove leftover image if needed
}
// Always run the container regardless of previous existence
echo "Starting container $CONTAINER_NAME ..."
sh "$DOCKER_RUN"
sh "docker image prune --force"
}
}
}
现在我希望能够通过 SSH 在远程服务器上执行相同的操作。我将脚本移至外部groovy,以使该阶段更加干净。
舞台
stage('Deploy Docker container on EC2') {
steps {
script {
sshagent(['aws-ssh']) {
sh "ssh -o StrictHostKeyChecking=no [email protected] 'xgs.buildEC2()'"
}
}
}
}
jenkins.groovy 脚本
def buildEC2() {
// Check if container exists
def containerId = sh(script: "docker ps --quiet --filter name=$CONTAINER_NAME", returnStdout: true).trim()
if (containerId.isEmpty()) {
echo "Container $CONTAINER_NAME not found. Skipping stop/remove steps."
} else {
echo "Stopping and removing existing container $CONTAINER_NAME ..."
sh "docker stop $CONTAINER_NAME"
sh "docker rm $CONTAINER_NAME"
sh "docker rmi $DOCKERH_REPO/$IMAGE_TAG:latest" // Remove leftover image if needed
sh "docker rmi $DOCKERH_REPO/$IMAGE_TAG:$BUILD_VERSION" // Remove leftover image if needed
}
// Always run the container regardless of previous existence
echo "Starting container $CONTAINER_NAME ..."
sh "$DOCKER_RUN"
sh "docker image prune --force"
}
return this
仅部署容器就可以很好地工作(执行带有参数的 docker run 等命令)。
我未能实现的是通过首先定义
containerId
变量并运行条件语句,在远程 EC2 上运行与前一阶段相同的逻辑。我收到此错误:
bash: -c: line 1: syntax error near unexpected token `('
bash: -c: line 1: `def containerId = sh(script: \"docker ps --quiet --filter name=$CONTAINER_NAME\", returnStdout: true).trim()'
我尝试用单引号封装并转义,但它不起作用,或者我缺乏知识阻碍了我理解正确的方法。
任何帮助将不胜感激。
附注我是 SE 世界的新手,仍在学习中。
经过进一步修改,我改变了逻辑,并通过简单地在 jenkins 文件中执行 wget 命令来采取解决方法,该命令从 git 中提取 bash 脚本并执行所有需要的命令。
这并不是问题的直接答案,但底线可以实现我想要实现的目标。我还利用 docker-compose 简化了命令。
詹金斯阶段:
stage('Deploy Docker container on EC2') {
steps {
script {
sshagent(['aws-ssh']) {
echo "Deploying Docker container on EC2 ..."
sh "ssh -o StrictHostKeyChecking=no [email protected] 'bash -c \"\$(wget -qLO - https://raw.githubusercontent.com/juronja/DiluteRight/refs/heads/main/ec2-commands.sh)\"'"
}
}
}
}
bash脚本:
#!/bin/bash
# Downloading and overwriting the compose file
wget -O compose.yaml https://raw.githubusercontent.com/juronja/DiluteRight/refs/heads/main/compose.yaml
# Stoping and starting the container
docker-compose down
docker-compose up -d